Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guard from undefined behaviour in case of an INT_MAX max_pathlen #3192

Merged
merged 1 commit into from
Apr 16, 2020

Conversation

AndrzejKurek
Copy link
Contributor

@AndrzejKurek AndrzejKurek commented Apr 14, 2020

When parsing a certificate with the basic constraints extension, the max_pathlen that was read from it was incremented regardless of its value. However, if the max_pathlen is equal to INT_MAX (which is highly unlikely), an undefined behaviour would occur. This commit adds a check to ensure that such value is not accepted as valid. Relevant tests for INT_MAX and INT_MAX-1 are also introduced.

Certificates added in this commit were generated using the test_suite_x509write, function test_x509_crt_check. Input data taken from the "Certificate write check Server1 SHA1" test case, so the generated files are like the "server1.crt", but with the "is_ca" field set to 1 and max_pathlen as described by the file name.

This PR addresses IOTSSL-2774.

@AndrzejKurek AndrzejKurek added enhancement mbed TLS team needs-review Every commit must be reviewed by at least two team members, component-x509 needs-ci Needs to pass CI tests labels Apr 14, 2020
@AndrzejKurek
Copy link
Contributor Author

AndrzejKurek commented Apr 14, 2020

Attaching a dump of certificates with the changed max_pathlen:
server1_pathlen_int_max.crt:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
        Validity
            Not Before: Feb 10 14:44:06 2019 GMT
            Not After : Feb 10 14:44:06 2029 GMT
        Subject: C=NL, O=PolarSSL, CN=PolarSSL Server 1
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a9:02:1f:3d:40:6a:d5:55:53:8b:fd:36:ee:82:
                    65:2e:15:61:5e:89:bf:b8:e8:45:90:db:ee:88:16:
                    52:d3:f1:43:50:47:96:12:59:64:87:6b:fd:2b:e0:
                    46:f9:73:be:dd:cf:92:e1:91:5b:ed:66:a0:6f:89:
                    29:79:45:80:d0:83:6a:d5:41:43:77:5f:39:7c:09:
                    04:47:82:b0:57:39:70:ed:a3:ec:15:19:1e:a8:33:
                    08:47:c1:05:42:a9:fd:4c:c3:b4:df:dd:06:1f:4d:
                    10:51:40:67:73:13:0f:40:f8:6d:81:25:5f:0a:b1:
                    53:c6:30:7e:15:39:ac:f9:5a:ee:7f:92:9e:a6:05:
                    5b:e7:13:97:85:b5:23:92:d9:d4:24:06:d5:09:25:
                    89:75:07:dd:a6:1a:8f:3f:09:19:be:ad:65:2c:64:
                    eb:95:9b:dc:fe:41:5e:17:a6:da:6c:5b:69:cc:02:
                    ba:14:2c:16:24:9c:4a:dc:cd:d0:f7:52:67:73:f1:
                    2d:a0:23:fd:7e:f4:31:ca:2d:70:ca:89:0b:04:db:
                    2e:a6:4f:70:6e:9e:ce:bd:58:89:e2:53:59:9e:6e:
                    5a:92:65:e2:88:3f:0c:94:19:a3:dd:e5:e8:9d:95:
                    13:ed:29:db:ab:70:12:dc:5a:ca:6b:17:ab:52:82:
                    54:b1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:TRUE, pathlen:2147483647
            X509v3 Subject Key Identifier: 
                1F:74:D6:3F:29:C1:74:74:45:3B:05:12:2C:3D:A8:BD:43:59:02:A6
            X509v3 Authority Key Identifier: 
                keyid:B4:5A:E4:A5:B3:DE:D2:52:F6:B9:D5:A6:95:0F:EB:3E:BC:C7:FD:FF

    Signature Algorithm: sha1WithRSAEncryption
         7b:98:cf:3c:cc:96:ac:a6:06:96:32:47:da:e8:75:80:48:7b:
         2a:86:21:98:62:14:7d:8b:b9:03:c6:76:a2:ed:38:c8:56:61:
         2c:3c:96:26:79:04:fe:aa:4d:68:8c:37:90:fb:a8:c8:60:53:
         b4:00:d8:ce:db:4f:bf:1a:de:b5:49:9a:33:2b:5e:39:07:bc:
         0c:af:e6:9a:bf:2f:97:e8:1b:e7:86:4f:da:35:04:f9:1d:bb:
         26:9e:46:48:67:e5:db:42:cd:55:30:64:28:99:68:4b:20:da:
         57:33:c8:de:8c:e3:7b:69:40:b1:7b:22:97:c3:53:29:b5:49:
         b5:f8:d9:f6:e9:fe:98:6a:e9:cb:04:95:ed:1a:59:0b:63:f3:
         9c:61:5d:a9:07:a1:c3:09:ce:b1:cc:f4:71:57:8c:42:a1:9c:
         31:11:f7:0f:90:64:d9:28:d5:7b:10:9a:3e:ee:3b:41:2c:84:
         7c:d9:ba:70:04:e2:34:78:f0:ff:67:60:e4:0b:9e:ed:ee:0a:
         f9:1e:a5:7b:ec:58:dd:0c:bc:e4:5a:bf:94:a0:de:32:66:eb:
         25:1a:cd:c8:9f:65:6e:50:9e:8a:15:1d:aa:19:00:10:f7:a5:
         a5:aa:b9:65:13:3a:71:82:50:a2:8d:00:93:ae:23:e2:cb:e3:
         39:97:85:d2

server1_pathlen_int_max-1.crt:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=NL, O=PolarSSL, CN=PolarSSL Test CA
        Validity
            Not Before: Feb 10 14:44:06 2019 GMT
            Not After : Feb 10 14:44:06 2029 GMT
        Subject: C=NL, O=PolarSSL, CN=PolarSSL Server 1
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a9:02:1f:3d:40:6a:d5:55:53:8b:fd:36:ee:82:
                    65:2e:15:61:5e:89:bf:b8:e8:45:90:db:ee:88:16:
                    52:d3:f1:43:50:47:96:12:59:64:87:6b:fd:2b:e0:
                    46:f9:73:be:dd:cf:92:e1:91:5b:ed:66:a0:6f:89:
                    29:79:45:80:d0:83:6a:d5:41:43:77:5f:39:7c:09:
                    04:47:82:b0:57:39:70:ed:a3:ec:15:19:1e:a8:33:
                    08:47:c1:05:42:a9:fd:4c:c3:b4:df:dd:06:1f:4d:
                    10:51:40:67:73:13:0f:40:f8:6d:81:25:5f:0a:b1:
                    53:c6:30:7e:15:39:ac:f9:5a:ee:7f:92:9e:a6:05:
                    5b:e7:13:97:85:b5:23:92:d9:d4:24:06:d5:09:25:
                    89:75:07:dd:a6:1a:8f:3f:09:19:be:ad:65:2c:64:
                    eb:95:9b:dc:fe:41:5e:17:a6:da:6c:5b:69:cc:02:
                    ba:14:2c:16:24:9c:4a:dc:cd:d0:f7:52:67:73:f1:
                    2d:a0:23:fd:7e:f4:31:ca:2d:70:ca:89:0b:04:db:
                    2e:a6:4f:70:6e:9e:ce:bd:58:89:e2:53:59:9e:6e:
                    5a:92:65:e2:88:3f:0c:94:19:a3:dd:e5:e8:9d:95:
                    13:ed:29:db:ab:70:12:dc:5a:ca:6b:17:ab:52:82:
                    54:b1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:TRUE, pathlen:2147483646
            X509v3 Subject Key Identifier: 
                1F:74:D6:3F:29:C1:74:74:45:3B:05:12:2C:3D:A8:BD:43:59:02:A6
            X509v3 Authority Key Identifier: 
                keyid:B4:5A:E4:A5:B3:DE:D2:52:F6:B9:D5:A6:95:0F:EB:3E:BC:C7:FD:FF

    Signature Algorithm: sha1WithRSAEncryption
         7e:eb:ea:ec:5a:26:41:34:89:98:62:27:57:04:23:41:d7:60:
         a1:7a:67:98:26:7d:ed:3a:55:ab:b8:c7:2c:21:40:0e:8c:10:
         8d:e8:80:b3:19:83:f2:6c:00:42:ac:3f:07:2d:14:d8:f4:a6:
         41:c4:bb:56:b9:fb:2d:ed:27:14:a3:51:61:8a:ed:a7:1e:6b:
         b1:31:49:cd:2f:ed:42:c8:02:7b:43:df:ce:18:81:80:3d:43:
         87:0e:8f:58:03:e6:cb:e2:65:be:12:45:ed:11:26:16:c3:3c:
         28:74:1d:d3:14:af:27:30:75:80:b3:7d:15:59:67:77:ce:c2:
         ef:76:dd:0c:96:50:65:d9:fd:ef:bf:92:9f:96:a7:00:51:87:
         0d:67:8a:a3:c1:98:69:81:a7:3c:14:2a:91:7d:10:d8:42:96:
         47:bc:ab:c1:c2:8c:a2:03:9e:bf:11:0b:a2:00:74:8d:18:f7:
         2f:e9:c1:a7:3e:e6:3b:62:7a:5d:0f:39:8a:9f:ad:2d:60:06:
         08:41:e8:d2:89:80:21:0a:2b:02:80:92:aa:d2:e2:6b:3e:3b:
         1f:13:9d:34:ad:21:9c:ce:d5:e6:4f:0f:d3:90:15:87:10:da:
         dd:6a:99:f4:59:8c:68:37:3c:8f:c5:ea:98:e8:0a:61:53:02:
         e3:f5:92:d2

Copy link
Contributor

@Patater Patater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks mostly good to me

@@ -524,6 +524,11 @@ static int x509_get_basic_constraints( unsigned char **p,
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );

// Do not accept max_pathlen equal to INT_MAX due to size constraints
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: Use C-style comments; add a period at the end of sentences

@@ -524,6 +524,11 @@ static int x509_get_basic_constraints( unsigned char **p,
return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );

// Do not accept max_pathlen equal to INT_MAX due to size constraints
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the size constraints? Isn't this to avoid undefined behaviour when we would do signed integer overflow on line 532 below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is, maybe calling this a size constraint isn't precise enough? :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the comment said what your commit message said: "to avoid signed integer overflow, which is undefined behavior" that'd be good enough

Zdn977+Sn5anAFGHDWeKo8GYaYGnPBQqkX0Q2EKWR7yrwcKMogOevxELogB0jRj3
L+nBpz7mO2J6XQ85ip+tLWAGCEHo0omAIQorAoCSqtLiaz47HxOdNK0hnM7V5k8P
05AVhxDa3WqZ9FmMaDc8j8XqmOgKYVMC4/WS0g==
-----END CERTIFICATE-----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pathlen is 2147483646, OK

mGrpywSV7RpZC2PznGFdqQehwwnOscz0cVeMQqGcMRH3D5Bk2SjVexCaPu47QSyE
fNm6cATiNHjw/2dg5Aue7e4K+R6le+xY3Qy85Fq/lKDeMmbrJRrNyJ9lblCeihUd
qhkAEPelpaq5ZRM6cYJQoo0Ak64j4svjOZeF0g==
-----END CERTIFICATE-----
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pathlen is 2147483647, OK

@@ -1798,6 +1798,14 @@ X509 CRT ASN1 (TBS, inv extBasicConstraint, no pathlen length)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
x509parse_crt:"3081b030819aa0030201028204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092A864886F70D010101050003190030160210ffffffffffffffffffffffffffffffff0202ffffa100a200a314301230100603551d130101010406300402010102300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_X509_INVALID_EXTENSIONS + MBEDTLS_ERR_ASN1_OUT_OF_DATA

X509 CRT ASN1 (inv extBasicConstraint, pathlen is INT_MAX)
depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI says you didn't depend on MBEDTLS_SHA1_C, but should

@AndrzejKurek AndrzejKurek force-pushed the max_pathlen_overflow branch from 3f43101 to ce50d9d Compare April 15, 2020 08:20
When parsing a certificate with the basic constraints extension
the max_pathlen that was read from it was incremented regardless
of its value. However, if the max_pathlen is equal to INT_MAX (which
is highly unlikely), an undefined behaviour would occur.
This commit adds a check to ensure that such value is not accepted
as valid. Relevant tests for INT_MAX and INT_MAX-1 are also introduced.
Certificates added in this commit were generated using the
test_suite_x509write, function test_x509_crt_check. Input data taken 
from the "Certificate write check Server1 SHA1" test case, so the generated
files are like the "server1.crt", but with the "is_ca" field set to 1 and
max_pathlen as described by the file name.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
@AndrzejKurek AndrzejKurek force-pushed the max_pathlen_overflow branch from ce50d9d to 1605074 Compare April 15, 2020 10:16
@AndrzejKurek AndrzejKurek requested a review from Patater April 15, 2020 14:56
@AndrzejKurek
Copy link
Contributor Author

Only MbedOS fails on the CI.

@piotr-now piotr-now self-requested a review April 16, 2020 09:48
Copy link
Contributor

@piotr-now piotr-now left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@Patater Patater left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Patater
Copy link
Contributor

Patater commented Apr 16, 2020

Only Mbed OS CI is failing, which is a known issue unrelated to this PR and being worked on. Good to go.

@Patater Patater merged commit 31f4cd9 into Mbed-TLS:development Apr 16, 2020
@Patater Patater removed needs-ci Needs to pass CI tests needs-review Every commit must be reviewed by at least two team members, labels Apr 16, 2020
gilles-peskine-arm added a commit to gilles-peskine-arm/mbedtls that referenced this pull request Apr 21, 2020
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
gilles-peskine-arm added a commit to gilles-peskine-arm/mbedtls that referenced this pull request Apr 21, 2020
…low fix

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
gilles-peskine-arm added a commit to gilles-peskine-arm/mbedtls that referenced this pull request Apr 28, 2020
…low fix

Backport of Mbed-TLS#3192

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
gilles-peskine-arm added a commit to gilles-peskine-arm/mbedtls that referenced this pull request Apr 28, 2020
…low fix

Backport of Mbed-TLS#3192

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants