x509: stricter parsing
No binary (build failed)
—
(log yok)
| @@ -1694,8 +1694,8 @@ CURLcode Curl_gtls_verifyserver(struct Curl_cfilter *cf, | |
| goto out; | |
| for(i = 0; i < chain.num_certs; i++) { | |
| - | const char *beg = (const char *)chain.certs[i].data; |
| - | const char *end = beg + chain.certs[i].size; |
| + | const uint8_t *beg = chain.certs[i].data; |
| + | const uint8_t *end = beg + chain.certs[i].size; |
| result = Curl_extract_certinfo(data, (int)i, beg, end); | |
| if(result) | |
| @@ -433,9 +433,8 @@ static void mbed_extract_certinfo(struct Curl_easy *data, | |
| result = Curl_ssl_init_certinfo(data, cert_count); | |
| for(i = 0, cur = crt; result == CURLE_OK && cur; ++i, cur = cur->next) { | |
| - | const char *beg = (const char *)cur->raw.p; |
| - | const char *end = beg + cur->raw.len; |
| - | result = Curl_extract_certinfo(data, i, beg, end); |
| + | result = Curl_extract_certinfo(data, i, cur->raw.p, |
| + | cur->raw.p + cur->raw.len); |
| } | |
| } | |
| @@ -1257,15 +1257,10 @@ static CURLcode cr_connect(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| (int)errorlen, errorbuf); | |
| return map_error(rresult); | |
| } | |
| - | { |
| - | const char *beg; |
| - | const char *end; |
| - | beg = (const char *)der_data; |
| - | end = (const char *)(der_data + der_len); |
| - | result = Curl_extract_certinfo(data, (int)i, beg, end); |
| - | if(result) |
| - | return result; |
| - | } |
| + | result = Curl_extract_certinfo(data, (int)i, |
| + | der_data, der_data + der_len); |
| + | if(result) |
| + | return result; |
| } | |
| } | |
| @@ -1118,7 +1118,7 @@ static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf, | |
| do { | |
| SECURITY_STATUS sspi_status; | |
| - | const char *x509_der; |
| + | uint8_t *x509_der; |
| DWORD x509_der_len; | |
| struct Curl_X509certificate x509_parsed; | |
| struct Curl_asn1Element *pubkey; | |
| @@ -1139,7 +1139,7 @@ static CURLcode schannel_pkp_pin_peer_pubkey(struct Curl_cfilter *cf, | |
| (pCertContextServer->cbCertEncoded > 0))) | |
| break; | |
| - | x509_der = (const char *)pCertContextServer->pbCertEncoded; |
| + | x509_der = (uint8_t *)pCertContextServer->pbCertEncoded; |
| x509_der_len = pCertContextServer->cbCertEncoded; | |
| memset(&x509_parsed, 0, sizeof(x509_parsed)); | |
| if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len)) | |
| @@ -1552,12 +1552,12 @@ static bool add_cert_to_certinfo(const CERT_CONTEXT *ccert_context, | |
| struct Adder_args *args = (struct Adder_args *)raw_arg; | |
| args->result = CURLE_OK; | |
| if(valid_cert_encoding(ccert_context)) { | |
| - | const char *beg = (const char *)ccert_context->pbCertEncoded; |
| - | const char *end = beg + ccert_context->cbCertEncoded; |
| int insert_index = reverse_order ? (args->certs_count - 1) - args->idx : | |
| args->idx; | |
| args->result = Curl_extract_certinfo(args->data, insert_index, | |
| - | beg, end); |
| + | ccert_context->pbCertEncoded, |
| + | ccert_context->pbCertEncoded + |
| + | ccert_context->cbCertEncoded); |
| args->idx++; | |
| } | |
| return args->result == CURLE_OK; | |
| @@ -1589,7 +1589,7 @@ CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, | |
| if(pinnedpubkey) { | |
| #ifdef KEEP_PEER_CERT | |
| - | const char *x509_der; |
| + | const uint8_t *x509_der; |
| int x509_der_len; | |
| struct Curl_X509certificate x509_parsed; | |
| struct Curl_asn1Element *pubkey; | |
| @@ -1602,7 +1602,7 @@ CURLcode Curl_wssl_verify_pinned(struct Curl_cfilter *cf, | |
| goto end; | |
| } | |
| - | x509_der = (const char *)wolfSSL_X509_get_der(x509, &x509_der_len); |
| + | x509_der = wolfSSL_X509_get_der(x509, &x509_der_len); |
| if(!x509_der) { | |
| failf(data, "SSL: failed retrieving ASN.1 server certificate"); | |
| goto end; | |
| @@ -127,11 +127,11 @@ static const struct Curl_OID OIDtable[] = { | |
| #define CURL_ASN1_MAX_RECURSIONS 16 | |
| - | static const char *getASN1Element_(struct Curl_asn1Element *elem, |
| - | const char *beg, const char *end, |
| - | size_t lvl) |
| + | static const uint8_t *getASN1Element_(struct Curl_asn1Element *elem, |
| + | const uint8_t *beg, const uint8_t *end, |
| + | size_t lvl) |
| { | |
| - | unsigned char b; |
| + | uint8_t b; |
| size_t len; | |
| struct Curl_asn1Element lelem; | |
| @@ -146,7 +146,7 @@ static const char *getASN1Element_(struct Curl_asn1Element *elem, | |
| /* Process header byte. */ | |
| elem->header = beg; | |
| - | b = (unsigned char)*beg++; |
| + | b = *beg++; |
| elem->constructed = (b & 0x20) != 0; | |
| elem->eclass = (b >> 6) & 3; | |
| b &= 0x1F; | |
| @@ -157,7 +157,7 @@ static const char *getASN1Element_(struct Curl_asn1Element *elem, | |
| /* Process length. */ | |
| if(beg >= end) | |
| return NULL; | |
| - | b = (unsigned char)*beg++; |
| + | b = *beg++; |
| if(!(b & 0x80)) | |
| len = b; | |
| else { | |
| @@ -178,7 +178,7 @@ static const char *getASN1Element_(struct Curl_asn1Element *elem, | |
| elem->end = beg; | |
| return beg + 1; | |
| } | |
| - | else if((unsigned)b > (size_t)(end - beg)) |
| + | else if(b > (size_t)(end - beg)) |
| return NULL; /* Does not fit in source. */ | |
| else { | |
| /* Get long length. */ | |
| @@ -186,7 +186,7 @@ static const char *getASN1Element_(struct Curl_asn1Element *elem, | |
| do { | |
| if(len & 0xFF000000L) | |
| return NULL; /* Lengths > 32 bits are not supported. */ | |
| - | len = (len << 8) | (unsigned char) *beg++; |
| + | len = (len << 8) | *beg++; |
| } while(--b); | |
| } | |
| } | |
| @@ -200,10 +200,10 @@ static const char *getASN1Element_(struct Curl_asn1Element *elem, | |
| /* | |
| * @unittest 1657 | |
| */ | |
| - | UNITTEST const char *getASN1Element(struct Curl_asn1Element *elem, |
| - | const char *beg, const char *end); |
| - | UNITTEST const char *getASN1Element(struct Curl_asn1Element *elem, |
| - | const char *beg, const char *end) |
| + | UNITTEST const uint8_t *getASN1Element(struct Curl_asn1Element *elem, |
| + | const uint8_t *beg, const uint8_t *end); |
| + | UNITTEST const uint8_t *getASN1Element(struct Curl_asn1Element *elem, |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| return getASN1Element_(elem, beg, end, 0); | |
| } | |
| @@ -231,12 +231,12 @@ static const struct Curl_OID *searchOID(const char *oid) | |
| */ | |
| static CURLcode bool2str(struct dynbuf *store, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| uint8_t val; | |
| if(end - beg != 1) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| - | val = (uint8_t)*beg; |
| + | val = *beg; |
| if((val != 0xff) && (val != 0x00)) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| return curlx_dyn_add(store, val ? "TRUE" : "FALSE"); | |
| @@ -248,22 +248,23 @@ static CURLcode bool2str(struct dynbuf *store, | |
| * Return error code. | |
| */ | |
| static CURLcode octet2str(struct dynbuf *store, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| CURLcode result = CURLE_OK; | |
| while(!result && beg < end) | |
| - | result = curlx_dyn_addf(store, "%02x:", (unsigned char)*beg++); |
| + | result = curlx_dyn_addf(store, "%02x:", *beg++); |
| return result; | |
| } | |
| - | static CURLcode bit2str(struct dynbuf *store, const char *beg, const char *end) |
| + | static CURLcode bit2str(struct dynbuf *store, |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| /* Convert an ASN.1 bit string to a printable string. */ | |
| if(beg < end) { | |
| - | uint8_t unused_bits = (uint8_t)*beg++; |
| + | uint8_t unused_bits = *beg++; |
| if(unused_bits > 7) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| } | |
| @@ -277,13 +278,14 @@ static CURLcode bit2str(struct dynbuf *store, const char *beg, const char *end) | |
| * | |
| * Returns error. | |
| */ | |
| - | static CURLcode int2str(struct dynbuf *store, const char *beg, const char *end) |
| + | static CURLcode int2str(struct dynbuf *store, |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| uint32_t uval = 0; | |
| int32_t sval = 0; | |
| size_t n = end - beg; | |
| size_t i; | |
| - | const unsigned char *p = (const unsigned char *)beg; |
| + | const uint8_t *p = beg; |
| if(!n) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| @@ -315,8 +317,8 @@ static CURLcode int2str(struct dynbuf *store, const char *beg, const char *end) | |
| * | |
| * Returns error. | |
| */ | |
| - | static CURLcode utf8asn1str(struct dynbuf *to, int type, const char *from, |
| - | const char *end) |
| + | static CURLcode utf8asn1str(struct dynbuf *to, int type, |
| + | const uint8_t *from, const uint8_t *end) |
| { | |
| size_t inlength = end - from; | |
| int size = 1; | |
| @@ -357,14 +359,14 @@ static CURLcode utf8asn1str(struct dynbuf *to, int type, const char *from, | |
| switch(size) { | |
| case 4: | |
| - | wc = (wc << 8) | *(const unsigned char *)from++; |
| - | wc = (wc << 8) | *(const unsigned char *)from++; |
| + | wc = (wc << 8) | *from++; |
| + | wc = (wc << 8) | *from++; |
| FALLTHROUGH(); | |
| case 2: | |
| - | wc = (wc << 8) | *(const unsigned char *)from++; |
| + | wc = (wc << 8) | *from++; |
| FALLTHROUGH(); | |
| default: /* case 1: */ | |
| - | wc = (wc << 8) | *(const unsigned char *)from++; |
| + | wc = (wc << 8) | *from++; |
| } | |
| if(wc >= 0x00000080) { | |
| if(wc >= 0x00000800) { | |
| @@ -404,9 +406,9 @@ static CURLcode utf8asn1str(struct dynbuf *to, int type, const char *from, | |
| * @unittest 1666 | |
| */ | |
| UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| - | const char *beg, const char *end); |
| + | const uint8_t *beg, const uint8_t *end); |
| UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| uint32_t x; | |
| uint32_t y; | |
| @@ -417,7 +419,7 @@ UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| /* Process the first two numbers. The initial digit cannot be larger than | |
| 2 */ | |
| - | y = *(const unsigned char *)beg++; |
| + | y = *beg++; |
| if(y <= 80) | |
| x = y / 40; | |
| else | |
| @@ -434,7 +436,7 @@ UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| do { | |
| if((t & 0xFE000000) || (beg >= end)) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| - | y = *(const unsigned char *)beg++; |
| + | y = *beg++; |
| t = (t << 7) | (y & 0x7F); | |
| } while(y & 0x80); | |
| y = t; | |
| @@ -454,7 +456,7 @@ UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| else if((x & 0xFE000000) || (beg == end)) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| - | y = *(const unsigned char *)beg++; |
| + | y = *beg++; |
| x = (x << 7) | (y & 0x7F); | |
| } while(y & 0x80); | |
| result = curlx_dyn_addf(store, ".%u", x); | |
| @@ -469,7 +471,7 @@ UNITTEST CURLcode encodeOID(struct dynbuf *store, | |
| */ | |
| static CURLcode OID2str(struct dynbuf *store, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| CURLcode result = CURLE_OK; | |
| if(beg < end) { | |
| @@ -651,10 +653,12 @@ UNITTEST CURLcode ASN1tostr(struct dynbuf *store, | |
| result = OID2str(store, elem->beg, elem->end); | |
| break; | |
| case CURL_ASN1_UTC_TIME: | |
| - | result = UTime2str(store, elem->beg, elem->end); |
| + | result = UTime2str(store, (const char *)elem->beg, |
| + | (const char *)elem->end); |
| break; | |
| case CURL_ASN1_GENERALIZED_TIME: | |
| - | result = GTime2str(store, elem->beg, elem->end); |
| + | result = GTime2str(store, (const char *)elem->beg, |
| + | (const char *)elem->end); |
| break; | |
| case CURL_ASN1_UTF8_STRING: | |
| case CURL_ASN1_NUMERIC_STRING: | |
| @@ -682,10 +686,10 @@ static CURLcode encodeDN(struct dynbuf *store, struct Curl_asn1Element *dn) | |
| struct Curl_asn1Element atv; | |
| struct Curl_asn1Element oid; | |
| struct Curl_asn1Element value; | |
| - | const char *p1; |
| - | const char *p2; |
| - | const char *p3; |
| - | const char *str; |
| + | const uint8_t *p1; |
| + | const uint8_t *p2; |
| + | const uint8_t *p3; |
| + | const uint8_t *str; |
| CURLcode result = CURLE_OK; | |
| bool added = FALSE; | |
| struct dynbuf temp; | |
| @@ -717,7 +721,7 @@ static CURLcode encodeDN(struct dynbuf *store, struct Curl_asn1Element *dn) | |
| if(result) | |
| goto error; | |
| - | str = curlx_dyn_ptr(&temp); |
| + | str = curlx_dyn_uptr(&temp); |
| if(!str) { | |
| result = CURLE_BAD_FUNCTION_ARGUMENT; | |
| @@ -738,7 +742,7 @@ static CURLcode encodeDN(struct dynbuf *store, struct Curl_asn1Element *dn) | |
| } | |
| /* Encode attribute name. */ | |
| - | result = curlx_dyn_add(store, str); |
| + | result = curlx_dyn_add(store, (const char *)str); |
| if(result) | |
| goto error; | |
| @@ -770,13 +774,14 @@ error: | |
| * See RFC 5280. | |
| */ | |
| int Curl_parseX509(struct Curl_X509certificate *cert, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| struct Curl_asn1Element elem; | |
| struct Curl_asn1Element tbsCertificate; | |
| - | const char *ccp; |
| - | static const char defaultVersion = 0; /* v1. */ |
| + | const uint8_t *ccp; |
| + | static const uint8_t defaultVersion = 0; /* v1. */ |
| + | memset(cert, 0, sizeof(*cert)); |
| cert->certificate.header = NULL; | |
| cert->certificate.beg = beg; | |
| cert->certificate.end = end; | |
| @@ -832,6 +837,9 @@ int Curl_parseX509(struct Curl_X509certificate *cert, | |
| return -1; | |
| if(!getASN1Element(&cert->notAfter, ccp, elem.end)) | |
| return -1; | |
| + | /* These two fields MUST consume all of the validity elem */ |
| + | if(elem.end != cert->notAfter.end) |
| + | return -1; |
| /* Get subject. */ | |
| beg = getASN1Element(&cert->subject, beg, end); | |
| if(!beg) | |
| @@ -852,10 +860,10 @@ int Curl_parseX509(struct Curl_X509certificate *cert, | |
| cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; | |
| cert->extensions.tag = elem.tag = 0; | |
| cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL; | |
| - | cert->issuerUniqueID.beg = cert->issuerUniqueID.end = ""; |
| - | cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; |
| + | cert->issuerUniqueID.beg = cert->issuerUniqueID.end = beg; |
| + | cert->subjectUniqueID.beg = cert->subjectUniqueID.end = beg; |
| cert->extensions.header = NULL; | |
| - | cert->extensions.beg = cert->extensions.end = ""; |
| + | cert->extensions.beg = cert->extensions.end = beg; |
| if(beg < end) { | |
| beg = getASN1Element(&elem, beg, end); | |
| if(!beg) | |
| @@ -889,7 +897,7 @@ int Curl_parseX509(struct Curl_X509certificate *cert, | |
| static CURLcode dumpAlgo(struct dynbuf *store, | |
| struct Curl_asn1Element *param, | |
| - | const char *beg, const char *end) |
| + | const uint8_t *beg, const uint8_t *end) |
| { | |
| struct Curl_asn1Element oid; | |
| @@ -902,7 +910,7 @@ static CURLcode dumpAlgo(struct dynbuf *store, | |
| param->tag = 0; | |
| param->beg = param->end = end; | |
| if(beg < end) { | |
| - | const char *p = getASN1Element(param, beg, end); |
| + | const uint8_t *p = getASN1Element(param, beg, end); |
| if(!p) | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| } | |
| @@ -973,7 +981,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, const char *algo, | |
| { | |
| struct Curl_asn1Element elem; | |
| struct Curl_asn1Element pk; | |
| - | const char *p; |
| + | const uint8_t *p; |
| /* Generate all information records for the public key. */ | |
| @@ -1005,7 +1013,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, const char *algo, | |
| return 1; | |
| if(curl_strequal(algo, "rsaEncryption")) { | |
| - | const char *q; |
| + | const uint8_t *q; |
| size_t len; | |
| p = getASN1Element(&elem, pk.beg, pk.end); | |
| @@ -1018,7 +1026,7 @@ static int do_pubkey(struct Curl_easy *data, int certnum, const char *algo, | |
| len = ((elem.end - q) * 8); | |
| if(len) { | |
| unsigned int i; | |
| - | for(i = *(const unsigned char *)q; !(i & 0x80); i <<= 1) |
| + | for(i = *q; !(i & 0x80); i <<= 1) |
| len--; | |
| } | |
| if(len > 32) | |
| @@ -1084,8 +1092,8 @@ static CURLcode DNtostr(struct dynbuf *store, struct Curl_asn1Element *dn) | |
| CURLcode Curl_extract_certinfo(struct Curl_easy *data, | |
| int certnum, | |
| - | const char *beg, |
| - | const char *end) |
| + | const uint8_t *beg, |
| + | const uint8_t *end) |
| { | |
| struct Curl_X509certificate cert; | |
| struct Curl_asn1Element param; | |
| @@ -1094,7 +1102,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, | |
| struct dynbuf out; | |
| CURLcode result = CURLE_OK; | |
| unsigned int version; | |
| - | const char *ptr; |
| + | const uint8_t *ptr; |
| int rc; | |
| if(!data->set.ssl.certinfo) | |
| @@ -1133,7 +1141,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, | |
| /* Version (always fits in less than 32 bits). */ | |
| version = 0; | |
| for(ptr = cert.version.beg; ptr < cert.version.end; ptr++) | |
| - | version = (version << 8) | *(const unsigned char *)ptr; |
| + | version = (version << 8) | *ptr; |
| if(data->set.ssl.certinfo) { | |
| result = curlx_dyn_addf(&out, "%x", version); | |
| if(result) | |
| @@ -77,11 +77,11 @@ struct Curl_asn1Element; | |
| /* ASN.1 parsed element. */ | |
| struct Curl_asn1Element { | |
| - | const char *header; /* Pointer to header byte. */ |
| - | const char *beg; /* Pointer to element data. */ |
| - | const char *end; /* Pointer to 1st byte after element. */ |
| - | unsigned char eclass; /* ASN.1 element class. */ |
| - | unsigned char tag; /* ASN.1 element tag. */ |
| + | const uint8_t *header; /* Pointer to header byte. */ |
| + | const uint8_t *beg; /* Pointer to element data. */ |
| + | const uint8_t *end; /* Pointer to 1st byte after element. */ |
| + | uint8_t eclass; /* ASN.1 element class. */ |
| + | uint8_t tag; /* ASN.1 element tag. */ |
| BIT(constructed); /* Element is constructed. */ | |
| }; | |
| @@ -109,11 +109,11 @@ struct Curl_X509certificate { | |
| */ | |
| int Curl_parseX509(struct Curl_X509certificate *cert, | |
| - | const char *beg, const char *end); |
| + | const uint8_t *beg, const uint8_t *end); |
| CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum, | |
| - | const char *beg, const char *end); |
| + | const uint8_t *beg, const uint8_t *end); |
| CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data, | |
| - | const char *beg, const char *end); |
| + | const uint8_t *beg, const uint8_t *end); |
| #endif /* USE_GNUTLS || USE_WOLFSSL || USE_SCHANNEL || USE_MBEDTLS || | |
| USE_RUSTLS */ | |
| #endif /* HEADER_CURL_X509ASN1_H */ | |
| @@ -32,7 +32,7 @@ static CURLcode test_unit1651(const char *arg) | |
| /* cert captured from gdb when connecting to curl.se on October 26 | |
| 2018. */ | |
| - | static unsigned char cert[] = { |
| + | static uint8_t cert[] = { |
| 0x30, 0x82, 0x0F, 0x5B, 0x30, 0x82, 0x0E, 0x43, 0xA0, 0x03, 0x02, 0x01, | |
| 0x02, 0x02, 0x0C, 0x08, 0x77, 0x99, 0x2C, 0x6B, 0x67, 0xE1, 0x18, 0xD6, | |
| 0x66, 0x66, 0x9E, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, | |
| @@ -364,8 +364,8 @@ static CURLcode test_unit1651(const char *arg) | |
| }; | |
| CURLcode result; | |
| - | const char *beg = (const char *)&cert[0]; |
| - | const char *end = (const char *)&cert[sizeof(cert)]; |
| + | const uint8_t *beg = &cert[0]; |
| + | const uint8_t *end = &cert[sizeof(cert)]; |
| struct Curl_easy *data; | |
| int i; | |
| int byte; | |
| @@ -23,7 +23,8 @@ | |
| ***************************************************************************/ | |
| #include "unitcheck.h" | |
| - | #if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_MBEDTLS) |
| + | #if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ |
| + | defined(USE_MBEDTLS) || defined(USE_RUSTLS) |
| #include "vtls/x509asn1.h" | |
| struct test1657_spec { | |
| @@ -37,8 +38,8 @@ static CURLcode make1657_nested(const struct test1657_spec *spec, | |
| { | |
| CURLcode result; | |
| size_t i; | |
| - | unsigned char open_undef[] = { 0x32, 0x80 }; |
| - | unsigned char close_undef[] = { 0x00, 0x00 }; |
| + | uint8_t open_undef[] = { 0x32, 0x80 }; |
| + | uint8_t close_undef[] = { 0x00, 0x00 }; |
| for(i = 0; i < spec->n; ++i) { | |
| result = curlx_dyn_addn(buf, open_undef, sizeof(open_undef)); | |
| @@ -65,8 +66,8 @@ static bool do_test1657(const struct test1657_spec *spec, size_t i, | |
| { | |
| CURLcode result; | |
| struct Curl_asn1Element elem; | |
| - | const char *in; |
| - | const char *ptr; |
| + | const uint8_t *in; |
| + | const uint8_t *ptr; |
| memset(&elem, 0, sizeof(elem)); | |
| curlx_dyn_reset(buf); | |
| @@ -75,7 +76,7 @@ static bool do_test1657(const struct test1657_spec *spec, size_t i, | |
| curl_mfprintf(stderr, "test %zu: error setting buf %d\n", i, (int)result); | |
| return FALSE; | |
| } | |
| - | in = curlx_dyn_ptr(buf); |
| + | in = curlx_dyn_uptr(buf); |
| ptr = getASN1Element(&elem, in, in + curlx_dyn_len(buf)); | |
| result = ptr ? CURLE_OK : CURLE_BAD_FUNCTION_ARGUMENT; | |
| if(result != spec->result_exp) { | |
| @@ -86,6 +87,59 @@ static bool do_test1657(const struct test1657_spec *spec, size_t i, | |
| return TRUE; | |
| } | |
| + | struct test1657_cert_spec { |
| + | const char * const pem; |
| + | bool exp_success; |
| + | }; |
| + | |
| + | static const struct test1657_cert_spec test1657_certs[] = { |
| + | { /* a valid certificate */ |
| + | "MIIBGTCBzKADAgECAhQ8Ssn8BaVsqlKKccv81NFuKY1vATAFBgMrZXAwADAeFw0y" |
| + | "NjA5MDIwNDU0MjZaFw0yNjEwMDIwNDU0MjZaMAAwKjAFBgMrZXADIQBeG0S343s9" |
| + | "5yRmIK8xZmGvUmiiYvRH5ZMcPq6rvHHKwqNYMFYwNQYDKgMEBC4wADAqMAUGAytl" |
| + | "cAMhAPP5TXSe2WHt/bebbP8eHPXrG3LNxYz8TnHNgpwTFsT7MB0GA1UdDgQWBBR6" |
| + | "aqL9LrZiIpgYCy0X4fNrhgFQsTAFBgMrZXADQQALU0OHGcIvfTwyin/+u9csJ9hZ" |
| + | "W0c+XdHJY5uDdCR1O92K4Vnozf/QCe7ITOJ8aUnCs7Jgf5xrDgyXZNdum04A", |
| + | TRUE |
| + | }, |
| + | { /* a certificate with "validity" element that has too long length */ |
| + | "MIIBGTCBzKADAgECAhQ8Ssn8BaVsqlKKccv81NFuKY1vATAFBgMrZXAwADBZFw0y" |
| + | "NjA5MDIwNDU0MjZaFw0yNjEwMDIwNDU0MjZaMAAwKjAFBgMrZXADIQBeG0S343s9" |
| + | "5yRmIK8xZmGvUmiiYvRH5ZMcPq6rvHHKwqNYMFYwNQYDKgMEBC4wADAqMAUGAytl" |
| + | "cAMhAPP5TXSe2WHt/bebbP8eHPXrG3LNxYz8TnHNgpwTFsT7MB0GA1UdDgQWBBR6" |
| + | "aqL9LrZiIpgYCy0X4fNrhgFQsTAFBgMrZXADQQALU0OHGcIvfTwyin/+u9csJ9hZ" |
| + | "W0c+XdHJY5uDdCR1O92K4Vnozf/QCe7ITOJ8aUnCs7Jgf5xrDgyXZNdum04A", |
| + | FALSE |
| + | } |
| + | }; |
| + | |
| + | static bool test1657_parse_cert(size_t i, |
| + | const struct test1657_cert_spec *spec) |
| + | { |
| + | struct Curl_X509certificate cert; |
| + | CURLcode result; |
| + | uint8_t *cert_der; |
| + | size_t cert_der_len; |
| + | bool success; |
| + | |
| + | result = curlx_base64_decode(spec->pem, &cert_der, &cert_der_len); |
| + | if(result) { |
| + | curl_mfprintf(stderr, "cert %zu: base64 decoding failed: %d\n", |
| + | i, (int)result); |
| + | return FALSE; |
| + | } |
| + | |
| + | success = !Curl_parseX509(&cert, cert_der, cert_der + cert_der_len); |
| + | if(success != spec->exp_success) { |
| + | curl_mfprintf(stderr, "cert %zu: parsing DER %sfailed\n", i, |
| + | spec->exp_success ? "" : "should have "); |
| + | return FALSE; |
| + | } |
| + | |
| + | curlx_free(cert_der); |
| + | return TRUE; |
| + | } |
| + | |
| static CURLcode test_unit1657(const char *arg) | |
| { | |
| UNITTEST_BEGIN_SIMPLE | |
| @@ -105,7 +159,14 @@ static CURLcode test_unit1657(const char *arg) | |
| if(!do_test1657(&test1657_specs[i], i, &dbuf)) | |
| all_ok = FALSE; | |
| } | |
| - | fail_unless(all_ok, "some tests of getASN1Element() fails"); |
| + | fail_unless(all_ok, "some getASN1Element() tests failed"); |
| + | |
| + | all_ok = TRUE; |
| + | for(i = 0; i < CURL_ARRAYSIZE(test1657_certs); ++i) { |
| + | if(!test1657_parse_cert(i, &test1657_certs[i])) |
| + | all_ok = FALSE; |
| + | } |
| + | fail_unless(all_ok, "some certificate tests failed"); |
| curlx_dyn_free(&dbuf); | |
| curl_global_cleanup(); | |
| @@ -29,20 +29,20 @@ | |
| #include "vtls/vtls.h" | |
| struct test_1666 { | |
| - | const char *oid; |
| + | const uint8_t *oid; |
| const size_t size; | |
| const char *dotted; | |
| CURLcode result_exp; | |
| }; | |
| /* the size of the object needs to deduct the null-terminator */ | |
| - | #define OID(x) STRCONST(x) |
| + | #define OID(x) (const uint8_t *)STRCONST(x) |
| static bool test1666(const struct test_1666 *spec, size_t i, | |
| struct dynbuf *dbuf) | |
| { | |
| CURLcode result; | |
| - | const char *oid = spec->oid; |
| + | const uint8_t *oid = spec->oid; |
| bool ok = TRUE; | |
| curlx_dyn_reset(dbuf); | |
| @@ -71,8 +71,8 @@ static CURLcode test_unit1666(const char *arg) | |
| UNITTEST_BEGIN_SIMPLE | |
| static const struct test_1666 test_specs[] = { | |
| - | { "", 0, "", CURLE_BAD_FUNCTION_ARGUMENT }, |
| - | { "\x81", 0, "", CURLE_BAD_FUNCTION_ARGUMENT }, |
| + | { OID(""), "", CURLE_BAD_FUNCTION_ARGUMENT }, |
| + | { (const uint8_t *)"\x81", 0, "", CURLE_BAD_FUNCTION_ARGUMENT }, |
| { OID("\x8F\xFF\xFF\xFF\x7F"), "2.4294967215", CURLE_OK }, | |
| { OID("\x90\x80\x80\x80\x00"), "", CURLE_BAD_FUNCTION_ARGUMENT }, | |
| { OID("\x88\x80\x80\x80\x4F"), "2.2147483647", CURLE_OK }, | |
| @@ -49,7 +49,7 @@ static bool test1667(const struct test_1667 *spec, size_t i, | |
| /* setup private struct for this invoke */ | |
| elem.tag = spec->tag; | |
| elem.header = NULL; | |
| - | elem.beg = spec->asn1; |
| + | elem.beg = (const uint8_t *)spec->asn1; |
| elem.end = elem.beg + spec->size; | |
| elem.eclass = 0; | |
| elem.constructed = 0; | |
| @@ -44,7 +44,7 @@ static CURLcode test_unit1676(const char *arg) | |
| * | |
| * OID 1.2.840.10046.2.1 = dhpublicnumber | |
| */ | |
| - | static const unsigned char cert[] = { |
| + | static const uint8_t cert[] = { |
| 0x30, 0x81, 0x85, 0x30, 0x72, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, | |
| 0x01, 0x30, 0x0B, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, | |
| 0x01, 0x0B, 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04, | |
| @@ -60,8 +60,8 @@ static CURLcode test_unit1676(const char *arg) | |
| }; | |
| CURLcode result; | |
| - | const char *beg = (const char *)&cert[0]; |
| - | const char *end = (const char *)&cert[sizeof(cert)]; |
| + | const uint8_t *beg = &cert[0]; |
| + | const uint8_t *end = &cert[sizeof(cert)]; |
| struct Curl_easy *data; | |
| struct curl_slist *slist; | |
| const char *dhp_value = NULL; | |