From 2945d70d969430fd04ac9a8bff5b9a98c141e988 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 19 Jul 2024 16:12:11 +0200 Subject: [PATCH] init sssd support - wolfSSL_BIO_reset: fix return - CheckCertCRL_ex: return CRL_CERT_DATE_ERR instead of ASN_AFTER_DATE_E - CheckCertCRL_ex: return most relevant error code - i2d/d2i APIs: correct parameters handling and return codes - Custom ASN1 structures: major refactor to make it much more versatile - Use WOLFSSL_ASSERT_SIZEOF_GE where applicable - wolfSSL_EVP_SignFinal: implement ecc - wolfSSL_EVP_VerifyFinal: implement ecc - OBJ_NAME_do_all: bring closer to OpenSSL functionality - Implement: - OCSP_REQ_CTX API - d2i_ECPKParameters - wolfSSL_sk_insert - OCSP_parse_url - X509_STORE_set1_param - X509_get0_subject_key_id - X509_OBJECT_retrieve_by_subject --- src/bio.c | 8 +- src/crl.c | 10 +- src/internal.c | 2 + src/ocsp.c | 202 ++++++ src/pk.c | 19 +- src/ssl.c | 267 +++++--- src/ssl_asn1.c | 1161 +++++++++++++++++++++++++++-------- src/ssl_crypto.c | 33 +- src/ssl_p7p12.c | 2 +- src/x509.c | 309 +++++++--- src/x509_str.c | 12 + tests/api.c | 503 +++++++++++++-- wolfcrypt/src/asn.c | 53 +- wolfcrypt/src/evp.c | 102 ++- wolfssl/internal.h | 10 +- wolfssl/ocsp.h | 22 + wolfssl/openssl/asn1.h | 184 +++++- wolfssl/openssl/ec.h | 1 + wolfssl/openssl/include.am | 1 + wolfssl/openssl/ocsp.h | 22 +- wolfssl/openssl/pem.h | 6 +- wolfssl/openssl/rsa.h | 3 + wolfssl/openssl/safestack.h | 40 ++ wolfssl/openssl/ssl.h | 35 +- wolfssl/openssl/x509v3.h | 14 + wolfssl/ssl.h | 39 +- wolfssl/wolfcrypt/asn.h | 4 + wolfssl/wolfcrypt/types.h | 1 + 28 files changed, 2437 insertions(+), 628 deletions(-) create mode 100644 wolfssl/openssl/safestack.h diff --git a/src/bio.c b/src/bio.c index bd6bbdc1d9..e0fb0b09cb 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1704,13 +1704,13 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) if (XFSEEK(bio->ptr.fh, 0, XSEEK_SET) != 0) return WOLFSSL_BIO_ERROR; else - return 0; + return WOLFSSL_SUCCESS; #endif case WOLFSSL_BIO_BIO: bio->rdIdx = 0; bio->wrIdx = 0; - return 0; + return WOLFSSL_SUCCESS; case WOLFSSL_BIO_MEMORY: bio->rdIdx = 0; @@ -1729,7 +1729,7 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) bio->mem_buf->max = 0; } } - return 0; + return WOLFSSL_SUCCESS; #ifndef WOLFCRYPT_ONLY case WOLFSSL_BIO_MD: @@ -1740,7 +1740,7 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) wolfSSL_EVP_MD_CTX_init(bio->ptr.md_ctx); wolfSSL_EVP_DigestInit(bio->ptr.md_ctx, md); } - return 0; + return WOLFSSL_SUCCESS; #endif /* WOLFCRYPT_ONLY */ default: diff --git a/src/crl.c b/src/crl.c index 10c83afb02..563fd89c7f 100644 --- a/src/crl.c +++ b/src/crl.c @@ -440,7 +440,7 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, break; } else if (foundEntry == 0) { - ret = ASN_AFTER_DATE_E; + ret = CRL_CERT_DATE_ERR; } } } @@ -481,8 +481,8 @@ int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, if (foundEntry == 0) { /* perform embedded lookup */ if (crl->crlIOCb) { - ret = crl->crlIOCb(crl, (const char*)extCrlInfo, extCrlInfoSz); - if (ret == WOLFSSL_CBIO_ERR_WANT_READ) { + int cbRet = crl->crlIOCb(crl, (const char*)extCrlInfo, extCrlInfoSz); + if (cbRet == WOLFSSL_CBIO_ERR_WANT_READ) { ret = OCSP_WANT_READ; } else if (ret >= 0) { @@ -505,9 +505,9 @@ int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash, byte* serial, /* When not set the folder or not use hash_dir, do nothing. */ if ((foundEntry == 0) && (ret != WC_NO_ERR_TRACE(OCSP_WANT_READ))) { if (crl->cm != NULL && crl->cm->x509_store_p != NULL) { - ret = LoadCertByIssuer(crl->cm->x509_store_p, + int loadRet = LoadCertByIssuer(crl->cm->x509_store_p, (WOLFSSL_X509_NAME*)issuerName, X509_LU_CRL); - if (ret == WOLFSSL_SUCCESS) { + if (loadRet == WOLFSSL_SUCCESS) { /* try again */ ret = CheckCertCRLList(crl, issuerHash, serial, serialSz, serialHash, &foundEntry); diff --git a/src/internal.c b/src/internal.c index 324ec932cd..0f05ffac6a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4572,6 +4572,8 @@ void FreeX509(WOLFSSL_X509* x509) x509->authKeyId = NULL; XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT); x509->subjKeyId = NULL; + wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr); + x509->subjKeyIdStr = NULL; if (x509->authInfo != NULL) { XFREE(x509->authInfo, x509->heap, DYNAMIC_TYPE_X509_EXT); x509->authInfo = NULL; diff --git a/src/ocsp.c b/src/ocsp.c index b8f4fdd377..db97d751e3 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -1143,6 +1143,9 @@ int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data) { int size; + if (request == NULL) + return BAD_FUNC_ARG; + size = EncodeOcspRequest(request, NULL, 0); if (size <= 0 || data == NULL) return size; @@ -1392,6 +1395,205 @@ WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0(WOLFSSL_OCSP_BASICRESP *bs, int return single; } +/******************************************************************************* + * START OF WOLFSSL_OCSP_REQ_CTX API + ******************************************************************************/ + +enum ocspReqStates { + ORS_INVALID = 0, + ORS_HEADER_ADDED, + ORS_REQ_DONE +}; + +WOLFSSL_OCSP_REQ_CTX* wolfSSL_OCSP_REQ_CTX_new(WOLFSSL_BIO *bio, int maxline) +{ + WOLFSSL_OCSP_REQ_CTX* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_new"); + + if (maxline <= 0) + maxline = OCSP_MAX_REQUEST_SZ; + + ret = (WOLFSSL_OCSP_REQ_CTX*)XMALLOC(sizeof(*ret), NULL, + DYNAMIC_TYPE_OPENSSL); + if (ret != NULL) { + XMEMSET(ret, 0, sizeof(*ret)); + ret->buf = (byte*)XMALLOC(maxline, NULL, DYNAMIC_TYPE_OPENSSL); + if (ret->buf == NULL) + goto error; + ret->resp = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); + ret->bufLen = maxline; + ret->bio = bio; + } + + return ret; +error: + wolfSSL_OCSP_REQ_CTX_free(ret); + return NULL; +} + +void wolfSSL_OCSP_REQ_CTX_free(WOLFSSL_OCSP_REQ_CTX *ctx) +{ + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_free"); + if (ctx != NULL) { + if (ctx->buf != NULL) + XFREE(ctx->buf, NULL, DYNAMIC_TYPE_OPENSSL); + if (ctx->resp != NULL) + wolfSSL_BIO_free(ctx->resp); + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +WOLFSSL_OCSP_REQ_CTX* wolfSSL_OCSP_sendreq_new(WOLFSSL_BIO *bio, + const char *path, OcspRequest *req, int maxline) +{ + WOLFSSL_OCSP_REQ_CTX* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_OCSP_sendreq_new"); + + ret = wolfSSL_OCSP_REQ_CTX_new(bio, maxline); + if (ret == NULL) + return NULL; + + if (wolfSSL_OCSP_REQ_CTX_http(ret, "POST", path) != WOLFSSL_SUCCESS) + goto error; + + if (req != NULL && + wolfSSL_OCSP_REQ_CTX_set1_req(ret, req) != WOLFSSL_SUCCESS) + goto error; + + return ret; +error: + wolfSSL_OCSP_REQ_CTX_free(ret); + return NULL; +} + +int wolfSSL_OCSP_REQ_CTX_add1_header(WOLFSSL_OCSP_REQ_CTX *ctx, + const char *name, const char *value) +{ + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_add1_header"); + + if (name == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_puts(ctx->resp, name) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_puts error"); + return WOLFSSL_FAILURE; + } + if (value != NULL) { + if (wolfSSL_BIO_write(ctx->resp, ": ", 2) != 2) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_puts(ctx->resp, value) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_puts error"); + return WOLFSSL_FAILURE; + } + } + if (wolfSSL_BIO_write(ctx->resp, "\r\n", 2) != 2) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + + ctx->state = ORS_HEADER_ADDED; + + return WOLFSSL_SUCCESS; +} + +int wolfSSL_OCSP_REQ_CTX_http(WOLFSSL_OCSP_REQ_CTX *ctx, const char *op, + const char *path) +{ + static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; + + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_http"); + + if (ctx == NULL || op == NULL) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + if (path == NULL) + path = "/"; + + if (wolfSSL_BIO_printf(ctx->resp, http_hdr, op, path) <= 0) { + WOLFSSL_MSG("WOLFSSL_OCSP_REQ_CTX: wolfSSL_BIO_printf error"); + return WOLFSSL_FAILURE; + } + + ctx->state = ORS_HEADER_ADDED; + + return WOLFSSL_SUCCESS; +} + +int wolfSSL_OCSP_REQ_CTX_set1_req(WOLFSSL_OCSP_REQ_CTX *ctx, OcspRequest *req) +{ + static const char req_hdr[] = + "Content-Type: application/ocsp-request\r\n" + "Content-Length: %d\r\n\r\n"; + /* Should be enough to hold Content-Length */ + char req_hdr_buf[sizeof(req_hdr) + 10]; + int req_hdr_buf_len; + int req_len = wolfSSL_i2d_OCSP_REQUEST(req, NULL); + + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_set1_req"); + + if (ctx == NULL || req == NULL) { + WOLFSSL_MSG("Bad parameters"); + return WOLFSSL_FAILURE; + } + + if (req_len <= 0) { + WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request len error"); + return WOLFSSL_FAILURE; + } + + req_hdr_buf_len = + XSNPRINTF(req_hdr_buf, sizeof(req_hdr_buf), req_hdr, req_len); + if (req_hdr_buf_len >= (int)sizeof(req_hdr_buf)) { + WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request too long"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_BIO_write(ctx->resp, req_hdr_buf, req_hdr_buf_len) <= 0) { + WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_i2d_OCSP_REQUEST_bio(ctx->resp, req) <= 0) { + WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request i2d error"); + return WOLFSSL_FAILURE; + } + + ctx->state = ORS_REQ_DONE; + + return WOLFSSL_SUCCESS; +} + + +int wolfSSL_OCSP_REQ_CTX_nbio(WOLFSSL_OCSP_REQ_CTX *ctx) +{ + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_nbio"); + (void)ctx; + // TODO implement + WOLFSSL_MSG("Error wolfSSL_OCSP_REQ_CTX_nbio not yet implemented"); + return WOLFSSL_FAILURE; +} + +int wolfSSL_OCSP_sendreq_nbio(OcspResponse **presp, WOLFSSL_OCSP_REQ_CTX *ctx) +{ + WOLFSSL_ENTER("wolfSSL_OCSP_sendreq_nbio"); + (void)presp; + (void)ctx; + // TODO implement + WOLFSSL_MSG("Error wolfSSL_OCSP_sendreq_nbio not yet implemented"); + return WOLFSSL_FAILURE; +} + +/******************************************************************************* + * END OF WOLFSSL_OCSP_REQ_CTX API + ******************************************************************************/ + #endif /* OPENSSL_ALL || APACHE_HTTPD || WOLFSSL_HAPROXY */ #ifdef OPENSSL_EXTRA diff --git a/src/pk.c b/src/pk.c index c9935c6699..3d470bc579 100644 --- a/src/pk.c +++ b/src/pk.c @@ -9176,13 +9176,19 @@ void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) * @return NULL on error. */ static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group, - const unsigned char* in, long inSz) + const unsigned char** in_pp, long inSz) { int err = 0; WOLFSSL_EC_GROUP* ret = NULL; word32 idx = 0; word32 oid = 0; int id = 0; + const unsigned char* in; + + if (in_pp == NULL || *in_pp == NULL) + return NULL; + + in = *in_pp; /* Use the group passed in. */ if ((group != NULL) && (*group != NULL)) { @@ -9231,6 +9237,9 @@ static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group, } ret = NULL; } + else { + *in_pp += idx; + } return ret; } @@ -9262,7 +9271,8 @@ WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, } if (!err) { /* Create EC group from DER encoding. */ - ret = wolfssl_ec_group_d2i(group, der->buffer, der->length); + const byte** p = (const byte**)&der->buffer; + ret = wolfssl_ec_group_d2i(group, p, der->length); if (ret == NULL) { WOLFSSL_ERROR_MSG("Error loading DER buffer into WOLFSSL_EC_GROUP"); } @@ -9273,6 +9283,11 @@ WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, return ret; } +WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out, + const unsigned char **in, long len) +{ + return wolfssl_ec_group_d2i(out, in, len); +} #endif /* !NO_BIO */ #if defined(OPENSSL_ALL) && !defined(NO_CERTS) diff --git a/src/ssl.c b/src/ssl.c index 6beb751818..11b94a5905 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13623,64 +13623,77 @@ static WC_INLINE int compare_WOLFSSL_CIPHER( /* return 1 on success 0 on fail */ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) +{ + WOLFSSL_ENTER("wolfSSL_sk_push"); + + return wolfSSL_sk_insert(sk, data, 0); +} + +/* return 1 on success 0 on fail */ +int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx) { WOLFSSL_STACK* node; #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) WOLFSSL_CIPHER ciph; #endif - WOLFSSL_ENTER("wolfSSL_sk_push"); + WOLFSSL_ENTER("wolfSSL_sk_insert"); - if (!sk) { + if (!sk || !data) { return WOLFSSL_FAILURE; } - /* Check if empty data */ - switch (sk->type) { - case STACK_TYPE_CIPHER: + if (idx == 0 || sk->num == 0) { + /* Check if empty data */ + switch (sk->type) { + case STACK_TYPE_CIPHER: #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - /* check if entire struct is zero */ - XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER)); - if (compare_WOLFSSL_CIPHER(&sk->data.cipher, &ciph) == 0) { - sk->data.cipher = *(WOLFSSL_CIPHER*)data; - sk->num = 1; - if (sk->hash_fn) { - sk->hash = sk->hash_fn(&sk->data.cipher); + /* check if entire struct is zero */ + XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER)); + if (compare_WOLFSSL_CIPHER(&sk->data.cipher, &ciph) == 0) { + sk->data.cipher = *(WOLFSSL_CIPHER*)data; + sk->num = 1; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(&sk->data.cipher); + } + return WOLFSSL_SUCCESS; } - return WOLFSSL_SUCCESS; - } - break; + if (sk->num == 0) + sk->num = 1; /* confirmed at least one element */ + break; #endif - case STACK_TYPE_X509: - case STACK_TYPE_GEN_NAME: - case STACK_TYPE_BIO: - case STACK_TYPE_OBJ: - case STACK_TYPE_STRING: - case STACK_TYPE_ACCESS_DESCRIPTION: - case STACK_TYPE_X509_EXT: - case STACK_TYPE_X509_REQ_ATTR: - case STACK_TYPE_NULL: - case STACK_TYPE_X509_NAME: - case STACK_TYPE_X509_NAME_ENTRY: - case STACK_TYPE_CONF_VALUE: - case STACK_TYPE_X509_INFO: - case STACK_TYPE_BY_DIR_entry: - case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: - case STACK_TYPE_DIST_POINT: - case STACK_TYPE_X509_CRL: - default: - /* All other types are pointers */ - if (!sk->data.generic) { - sk->data.generic = (void*)data; - sk->num = 1; + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + /* All other types are pointers */ + if (!sk->data.generic) { + sk->data.generic = (void*)data; + sk->num = 1; #ifdef OPENSSL_ALL - if (sk->hash_fn) { - sk->hash = sk->hash_fn(sk->data.generic); - } + if (sk->hash_fn) + sk->hash = sk->hash_fn(sk->data.generic); #endif - return WOLFSSL_SUCCESS; - } - break; + return WOLFSSL_SUCCESS; + } + if (sk->num == 0) + sk->num = 1; /* confirmed at least one element */ + break; + } } /* stack already has value(s) create a new node and add more */ @@ -13689,26 +13702,71 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) WOLFSSL_MSG("Memory error"); return WOLFSSL_FAILURE; } - - /* push new x509 onto head of stack */ - node->next = sk->next; node->type = sk->type; - sk->next = node; sk->num += 1; - #ifdef OPENSSL_ALL node->hash_fn = sk->hash_fn; - node->hash = sk->hash; - sk->hash = 0; #endif + + if (idx == 0) { + /* Special case where we need to change the values in the head element + * to avoid changing the initial pointer. */ + /* push new item onto head of stack */ + node->next = sk->next; + sk->next = node; +#ifdef OPENSSL_ALL + node->hash = sk->hash; + sk->hash = 0; +#endif + switch (sk->type) { + case STACK_TYPE_CIPHER: +#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + node->data.cipher = sk->data.cipher; + sk->data.cipher = *(WOLFSSL_CIPHER*)data; + if (sk->hash_fn) { + sk->hash = sk->hash_fn(&sk->data.cipher); + } + break; +#endif + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + /* All other types are pointers */ + node->data.generic = sk->data.generic; + sk->data.generic = (void*)data; +#ifdef OPENSSL_ALL + if (sk->hash_fn) + sk->hash = sk->hash_fn(sk->data.generic); +#endif + break; + } + + return WOLFSSL_SUCCESS; + } + + /* populate node */ switch (sk->type) { case STACK_TYPE_CIPHER: #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) - node->data.cipher = sk->data.cipher; - sk->data.cipher = *(WOLFSSL_CIPHER*)data; - if (sk->hash_fn) { - sk->hash = sk->hash_fn(&sk->data.cipher); - } + node->data.cipher = *(WOLFSSL_CIPHER*)data; + if (node->hash_fn) + node->hash = node->hash_fn(&node->data.cipher); break; #endif case STACK_TYPE_X509: @@ -13731,15 +13789,20 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) case STACK_TYPE_X509_CRL: default: /* All other types are pointers */ - node->data.generic = sk->data.generic; - sk->data.generic = (void*)data; + node->data.generic = (void*)data; #ifdef OPENSSL_ALL - if (sk->hash_fn) { - sk->hash = sk->hash_fn(sk->data.generic); - } + if (node->hash_fn) + node->hash = node->hash_fn(node->data.generic); #endif break; } + /* insert node into chain */ + while (idx != 0 && sk->next != NULL) { + sk = sk->next; + idx--; + } + node->next = sk->next; + sk->next = node; return WOLFSSL_SUCCESS; } @@ -14958,20 +15021,78 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, return ret; } - -#ifndef NO_WOLFSSL_STUB -int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path, - int* ssl) +int wolfSSL_OCSP_parse_url(const char* url, char** host, char** port, + char** path, int* ssl) { - (void)url; - (void)host; - (void)port; - (void)path; - (void)ssl; - WOLFSSL_STUB("OCSP_parse_url"); - return 0; + const char* u = url; + const char* upath; /* path in u */ + const char* uport; /* port in u */ + const char* hostEnd; + + WOLFSSL_ENTER("OCSP_parse_url"); + + *host = NULL; + *port = NULL; + *path = NULL; + *ssl = 0; + + if (*(u++) != 'h') goto err; + if (*(u++) != 't') goto err; + if (*(u++) != 't') goto err; + if (*(u++) != 'p') goto err; + if (*u == 's') { + *ssl = 1; + u++; + *port = CopyString("443", -1, NULL, DYNAMIC_TYPE_OPENSSL); + } + else if (*u == ':') { + *ssl = 0; + *port = CopyString("80", -1, NULL, DYNAMIC_TYPE_OPENSSL); + } + else + goto err; + if (*port == NULL) + goto err; + if (*(u++) != ':') goto err; + if (*(u++) != '/') goto err; + if (*(u++) != '/') goto err; + + /* Look for path */ + upath = XSTRSTR(u, "/"); + *path = CopyString(upath == NULL ? "/" : upath, -1, NULL, + DYNAMIC_TYPE_OPENSSL); + + /* Look for port */ + uport = XSTRSTR(u, ":"); + if (uport != NULL) { + /* port must be before path */ + if (uport >= upath) + goto err; + XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL); + *port = CopyString(uport, upath != NULL ? upath - uport : -1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (*port == NULL) + goto err; + hostEnd = uport; + } + else + hostEnd = upath; + + *host = CopyString(u, hostEnd != NULL ? hostEnd - u : -1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (*host == NULL) + goto err; + + return WOLFSSL_SUCCESS; +err: + XFREE(*host, NULL, DYNAMIC_TYPE_OPENSSL); + *host = NULL; + XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL); + *port = NULL; + XFREE(*path, NULL, DYNAMIC_TYPE_OPENSSL); + *path = NULL; + return WOLFSSL_FAILURE; } -#endif #ifndef NO_WOLFSSL_STUB WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void) diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index 0cae277dc8..44f3f5377f 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -46,212 +46,197 @@ #ifdef OPENSSL_ALL -/* Create an ASN1 item of the specified type. - * - * @param [out] item Pointer to location to place new ASN1 item. - * @param [in] type Type of ASN1 item to create. - * @return 0 on success. - * @return 1 when item type not supported. - * @return 1 when item type allocation fails. - */ -static int wolfssl_asn1_item_new(void** item, int type) +/* Provides access to the member of the obj offset by offset */ +#define asn1Mem(obj, offset) (*(void**)(((byte*)(obj)) + (offset))) +#define asn1Type(obj, offset) (*(int*)(((byte*)(obj)) + (offset))) + +static void* asn1_new_tpl(const WOLFSSL_ASN1_TEMPLATE *mem) { - int err = 0; + if (mem->sequence) + return wolfSSL_sk_new_null(); + else + return mem->new_func(); +} + +static void* asn1_item_alloc(const WOLFSSL_ASN1_ITEM* item) +{ + void* ret = NULL; - switch (type) { - case WOLFSSL_X509_ALGOR_ASN1: - *(WOLFSSL_X509_ALGOR**)item = wolfSSL_X509_ALGOR_new(); + /* allocation */ + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + case WOLFSSL_ASN1_CHOICE: + ret = (void *)XMALLOC(item->size, NULL, DYNAMIC_TYPE_OPENSSL); + if (ret != NULL) + XMEMSET(ret, 0, item->size); break; - case WOLFSSL_ASN1_BIT_STRING_ASN1: - *(WOLFSSL_ASN1_BIT_STRING**)item = wolfSSL_ASN1_BIT_STRING_new(); + case WOLFSSL_ASN1_OBJECT_TYPE: + if (item->mcount != 1 || item->members->offset) { + WOLFSSL_MSG("incorrect member count or offset"); + return NULL; + } + ret = asn1_new_tpl(item->members); break; - case WOLFSSL_ASN1_INTEGER_ASN1: - *(WOLFSSL_ASN1_INTEGER**)item = wolfSSL_ASN1_INTEGER_new(); - break; default: - WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_new"); - *(void**)item = NULL; + WOLFSSL_MSG("ASN1 type not implemented"); + return NULL; } - /* Check whether an item was put in. */ - if (*(void**)item == NULL) { - err = 1; + + return ret; +} + +static int asn1_item_init(void* obj, const WOLFSSL_ASN1_ITEM* item) +{ + const WOLFSSL_ASN1_TEMPLATE *mem = NULL; + size_t i; + int ret = 0; + + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) { + asn1Mem(obj, mem->offset) = asn1_new_tpl(mem); + if (asn1Mem(obj, mem->offset) == NULL) { + ret = -1; + break; + } + } + break; + case WOLFSSL_ASN1_OBJECT_TYPE: + /* Initialized by new_func. Nothing to do. */ + break; + case WOLFSSL_ASN1_CHOICE: + asn1Type(obj, item->toffset) = -1; + /* We don't know what to initialize. Nothing to do. */ + break; + default: + WOLFSSL_MSG("ASN1 type not implemented"); + ret = -1; + break; } - return err; + return ret; } /* Create a new ASN1 item based on a template. * - * @param [in] tpl Template of ASN1 items. + * @param [in] item Info about ASN1 items. * @return A new ASN1 item on success. - * @return NULL when tpl is NULL, dynamic memory allocation fails or ASN1 + * @return NULL when item is NULL, dynamic memory allocation fails or ASN1 * item type not supported. */ -void* wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM* tpl) +void* wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM* item) { - int err = 0; void* ret = NULL; - const WOLFSSL_ASN1_TEMPLATE *mem = NULL; - size_t i; WOLFSSL_ENTER("wolfSSL_ASN1_item_new"); - if (tpl != NULL) { - ret = (void *)XMALLOC(tpl->size, NULL, DYNAMIC_TYPE_OPENSSL); - } + if (item == NULL) + return NULL; - if (ret != NULL) { - XMEMSET(ret, 0, tpl->size); - for (mem = tpl->members, i = 0; i < tpl->mcount; mem++, i++) { - if ((err = wolfssl_asn1_item_new( - (void**)(((byte*)ret) + mem->offset), mem->type))) { - break; - } - } - } + /* allocation */ + ret = asn1_item_alloc(item); + if (ret == NULL) + return NULL; - if (err) { - wolfSSL_ASN1_item_free(ret, tpl); + /* initialization */ + if (asn1_item_init(ret, item) != 0) { + wolfSSL_ASN1_item_free(ret, item); ret = NULL; } + return ret; } -/* Dispose of an ASN1 item of the specified type. - * - * @param [in, out] item Pointer to an anonymized ASN1 item to free. - * @param [in] type Type of ASN1 item to free. - */ -static void wolfssl_asn1_item_free(void** item, int type) +static void asn1_free_tpl(void *obj, const WOLFSSL_ASN1_TEMPLATE *mem) { - switch (type) { - case WOLFSSL_X509_ALGOR_ASN1: - wolfSSL_X509_ALGOR_free(*(WOLFSSL_X509_ALGOR**)item); - break; - case WOLFSSL_ASN1_BIT_STRING_ASN1: - wolfSSL_ASN1_BIT_STRING_free(*(WOLFSSL_ASN1_BIT_STRING**)item); - break; - case WOLFSSL_ASN1_INTEGER_ASN1: - wolfSSL_ASN1_INTEGER_free(*(WOLFSSL_ASN1_INTEGER**)item); - break; - default: - WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_free"); + if (obj != NULL) { + if (mem->sequence) + wolfSSL_sk_pop_free(obj, mem->free_func); + else + mem->free_func(obj); } } /* Dispose of ASN1 item based on a template. * * @param [in, out] val ASN item to free. - * @param [in, tpl Template of ASN1 items. + * @param [in, item Info about ASN1 items. */ -void wolfSSL_ASN1_item_free(void *items, const WOLFSSL_ASN1_ITEM *tpl) +void wolfSSL_ASN1_item_free(void *obj, const WOLFSSL_ASN1_ITEM *item) { const WOLFSSL_ASN1_TEMPLATE *mem = NULL; size_t i; WOLFSSL_ENTER("wolfSSL_ASN1_item_free"); - if (items != NULL) { - for (mem = tpl->members, i = 0; i < tpl->mcount; mem++, i++) { - wolfssl_asn1_item_free((void**)(((byte*)items) + mem->offset), - mem->type); + if (obj != NULL) { + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) + asn1_free_tpl(asn1Mem(obj, mem->offset), mem); + XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL); + break; + case WOLFSSL_ASN1_CHOICE: + if (asn1Type(obj, item->toffset) < 0) + break; /* type not set */ + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) { + if (asn1Type(obj, item->toffset) == mem->tag) { + asn1_free_tpl(asn1Mem(obj, mem->offset), mem); + break; + } + } + XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL); + break; + case WOLFSSL_ASN1_OBJECT_TYPE: + asn1_free_tpl(obj, item->members); + break; + default: + WOLFSSL_MSG("ASN1 type not implemented"); + break; } } - XFREE(items, NULL, DYNAMIC_TYPE_OPENSSL); } -/* Offset buf if not NULL or NULL. */ -#define bufLenOrNull(buf, len) (((buf) != NULL) ? ((buf) + (len)) : NULL) - -/* Encode X509 algorithm as DER. - * - * @param [in] algor X509 algorithm object. - * @param [in, out] buf Buffer to encode into. May be NULL. - * @return Length of DER encoding on success. - * @return 0 on failure. - */ -static int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* algor, byte* buf) +static int i2d_asn1_items(const void* obj, byte** buf, + const WOLFSSL_ASN1_TEMPLATE* mem) { + int len = 0; int ret; - word32 oid = 0; - word32 idx = 0; - - if (algor->algorithm == 0) { - WOLFSSL_MSG("X509_ALGOR algorithm not set"); - ret = 0; - } - else if (GetObjectId(algor->algorithm->obj, &idx, &oid, - (word32)algor->algorithm->grp, algor->algorithm->objSz) < 0) { - WOLFSSL_MSG("Issue getting OID of object"); - ret = 0; - } - else { - ret = (int)SetAlgoID((int)oid, buf, algor->algorithm->grp, 0); - } - - return ret; -} - -/* Encode ASN.1 BIT_STRING as DER. - * - * @param [in] bit_str BIT_STRING object. - * @param [in, out] buf Buffer to encode into. May be NULL. - * @return Length of DER encoding on success. - */ -static int wolfSSL_i2d_ASN1_BIT_STRING(const WOLFSSL_ASN1_BIT_STRING* bit_str, - byte* buf) -{ - int len; - - len = (int)SetBitString((word32)bit_str->length, 0, buf); - if ((buf != NULL) && (bit_str->data != NULL)) { - XMEMCPY(buf + len, bit_str->data, (size_t)bit_str->length); - } - - return len + bit_str->length; -} - -/* Encode ASN item as DER. - * - * @param [in] item Pointer to anonymized ASN item. - * @param [in, out] buf Buffer to encode into. May be NULL. - * @return Length of DER encoding on success. - * @return 0 on failure. - */ -static int wolfssl_i2d_asn1_item(void** item, int type, byte* buf) -{ - int len; - - switch (type) { - case WOLFSSL_X509_ALGOR_ASN1: - len = wolfSSL_i2d_X509_ALGOR(*(const WOLFSSL_X509_ALGOR**)item, - buf); - break; - case WOLFSSL_ASN1_BIT_STRING_ASN1: - len = wolfSSL_i2d_ASN1_BIT_STRING( - *(const WOLFSSL_ASN1_BIT_STRING**)item, buf); - break; - case WOLFSSL_ASN1_INTEGER_ASN1: - { - byte *tmp_buf = buf; - len = wolfSSL_i2d_ASN1_INTEGER( - *(const WOLFSSL_ASN1_INTEGER**)item, &tmp_buf); - if ((buf == NULL) && (tmp_buf != NULL)) { - XFREE(tmp_buf, NULL, DYNAMIC_TYPE_ASN1); - tmp_buf = NULL; + if (mem->sequence) { + const WOLFSSL_STACK* sk = asn1Mem(obj, mem->offset); + int ski; /* stack index */ + int innerLen = 0; + /* Figure out the inner length first */ + for (ski = 0; ski < wolfSSL_sk_num(sk); ski++) { + ret = mem->i2d_func(wolfSSL_sk_value(sk, ski), NULL); + if (ret <= 0) + break; + innerLen += ret; + } + if (ret <= 0) + return 0; + if (buf != NULL && *buf != NULL) { + /* Now write it out */ + int writeLen = 0; + *buf += SetSequence((word32)innerLen, *buf); + for (ski = 0; ski < wolfSSL_sk_num(sk); ski++) { + ret = mem->i2d_func(wolfSSL_sk_value(sk, ski), buf); + if (ret <= 0) + break; + writeLen += ret; } + if (ret <= 0 || writeLen != innerLen) + return 0; } - break; - default: - WOLFSSL_MSG("Type not support in processMembers"); - len = 0; + len = (int)SetSequence((word32)innerLen, NULL) + innerLen; } - - if (len < 0) { - len = 0; /* wolfSSL_i2d_ASN1_INTEGER can return a value less than 0 - * on error */ + else { + ret = mem->i2d_func(asn1Mem(obj, mem->offset), + buf != NULL && *buf != NULL ? buf : NULL); + if (ret <= 0) + return 0; + len = ret; } - return len; } @@ -264,7 +249,7 @@ static int wolfssl_i2d_asn1_item(void** item, int type, byte* buf) * @return Length of DER encoding on success. * @return 0 on failure. */ -static int wolfssl_i2d_asn1_items(const void* src, byte*buf, +static int wolfssl_i2d_asn1_items(const void* obj, byte* buf, const WOLFSSL_ASN1_TEMPLATE* members, size_t mcount) { const WOLFSSL_ASN1_TEMPLATE* mem = NULL; @@ -275,12 +260,34 @@ static int wolfssl_i2d_asn1_items(const void* src, byte*buf, WOLFSSL_ENTER("wolfssl_i2d_asn1_items"); for (mem = members, i = 0; i < mcount; mem++, i++) { - ret = wolfssl_i2d_asn1_item((void**)(((byte*)src) + mem->offset), - mem->type, bufLenOrNull(buf, len)); - if (ret == 0) { + byte* tmp = buf; + if (mem->explicit && mem->tag >= 0) { + /* Figure out the inner length */ + int innerLen = 0; + int hdrLen = 0; + ret = i2d_asn1_items(obj, NULL, mem); + if (ret <= 0) { + len = 0; + break; + } + innerLen = ret; + hdrLen = SetExplicit((byte)mem->tag, (word32)innerLen, buf, 0); + len += hdrLen; + if (buf != NULL) + buf += hdrLen; + } + + ret = i2d_asn1_items(obj, &buf, mem); + if (ret <= 0) { len = 0; break; } + if (buf != NULL && !mem->explicit && mem->tag >= 0) { + /* Encode the implicit tag */ + byte imp[ASN_TAG_SZ + MAX_LENGTH_SZ]; + SetImplicit(tmp[0], mem->tag, 0, imp, 0); + tmp[0] = imp[0]; + } len += ret; } @@ -297,25 +304,55 @@ static int wolfssl_i2d_asn1_items(const void* src, byte*buf, * @return Length of DER encoding on success. * @return 0 on failure. */ -static int i2d_ASN_SEQUENCE(const void* src, byte* buf, - const WOLFSSL_ASN1_ITEM* tpl) +static int i2d_ASN_SEQUENCE(const void* obj, byte* buf, + const WOLFSSL_ASN1_ITEM* item) { word32 seq_len; word32 len = 0; - seq_len = (word32)wolfssl_i2d_asn1_items(src, NULL, tpl->members, - tpl->mcount); + seq_len = (word32)wolfssl_i2d_asn1_items(obj, NULL, item->members, + item->mcount); if (seq_len != 0) { len = SetSequence(seq_len, buf); if (buf != NULL) { - wolfssl_i2d_asn1_items(src, buf + len, tpl->members, tpl->mcount); + if (wolfssl_i2d_asn1_items(obj, buf + len, item->members, + item->mcount) > 0) + len += seq_len; /* success */ + else + len = 0; /* error */ } - len += seq_len; + else + len += seq_len; } return (int)len; } +static int i2d_ASN_CHOICE(const void* obj, byte* buf, + const WOLFSSL_ASN1_ITEM* item) +{ + const WOLFSSL_ASN1_TEMPLATE* mem = NULL; + size_t i; + + if (asn1Type(obj, item->toffset) < 0) + return 0; /* type not set */ + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) { + if (asn1Type(obj, item->toffset) == mem->tag) { + return wolfssl_i2d_asn1_items(obj, buf, mem, 1); + } + } + return 0; +} + +static int i2d_ASN_OBJECT_TYPE(const void* obj, byte* buf, + const WOLFSSL_ASN1_ITEM* item) +{ + /* To be able to use wolfssl_i2d_asn1_items without any modifications, + * pass in a pointer to obj so that asn1Mem uses the correct pointer. */ + const void ** obj_pp = &obj; + return wolfssl_i2d_asn1_items(obj_pp, buf, item->members, item->mcount); +} + /* Encode ASN1 template item. * * @param [in] src ASN1 items to encode. @@ -324,14 +361,20 @@ static int i2d_ASN_SEQUENCE(const void* src, byte* buf, * @return Length of DER encoding on success. * @return 0 on failure. */ -static int wolfssl_asn1_item_encode(const void* src, byte* buf, - const WOLFSSL_ASN1_ITEM* tpl) +static int wolfssl_asn1_item_encode(const void* obj, byte* buf, + const WOLFSSL_ASN1_ITEM* item) { int len; - switch (tpl->type) { - case ASN_SEQUENCE: - len = i2d_ASN_SEQUENCE(src, buf, tpl); + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + len = i2d_ASN_SEQUENCE(obj, buf, item); + break; + case WOLFSSL_ASN1_OBJECT_TYPE: + len = i2d_ASN_OBJECT_TYPE(obj, buf, item); + break; + case WOLFSSL_ASN1_CHOICE: + len = i2d_ASN_CHOICE(obj, buf, item); break; default: WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_i2d"); @@ -347,10 +390,10 @@ static int wolfssl_asn1_item_encode(const void* src, byte* buf, * @param [in, out] dest Pointer to buffer to encode into. May be NULL. * @param [in] tpl Template of ASN1 items. * @return Length of DER encoding on success. - * @return 0 on failure. + * @return WOLFSSL_FATAL_ERROR on failure. */ -int wolfSSL_ASN1_item_i2d(const void* src, byte** dest, - const WOLFSSL_ASN1_ITEM* tpl) +int wolfSSL_ASN1_item_i2d(const void* obj, byte** dest, + const WOLFSSL_ASN1_ITEM* item) { int ret = 1; int len = 0; @@ -359,35 +402,319 @@ int wolfSSL_ASN1_item_i2d(const void* src, byte** dest, WOLFSSL_ENTER("wolfSSL_ASN1_item_i2d"); /* Validate parameters. */ - if ((src == NULL) || (tpl == NULL)) { + if ((obj == NULL) || (item == NULL)) { ret = 0; } - if ((ret == 1) && ((len = wolfssl_asn1_item_encode(src, NULL, tpl)) == 0)) { + if ((ret == 1) && ((len = wolfssl_asn1_item_encode(obj, NULL, item)) == 0)) ret = 0; - } if ((ret == 1) && (dest != NULL)) { if (*dest == NULL) { buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1); if (buf == NULL) ret = 0; - *dest = buf; } + else + buf = *dest; if (ret == 1) { - len = wolfssl_asn1_item_encode(src, *dest, tpl); + len = wolfssl_asn1_item_encode(obj, buf, item); + if (len <= 0) + ret = 0; + } + + if (ret == 1) { + if (*dest == NULL) + *dest = buf; + else + *dest += len; } } if (ret == 0) { - XFREE(buf, NULL, DYNAMIC_TYPE_ASN1); - len = 0; + if (*dest == NULL) + XFREE(buf, NULL, DYNAMIC_TYPE_ASN1); + len = WOLFSSL_FATAL_ERROR; } WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", len); return len; } +static void* d2i_obj(const WOLFSSL_ASN1_TEMPLATE* mem, const byte** src, + long* len) +{ + void* ret; + const byte* tmp = *src; + ret = mem->d2i_func(NULL, &tmp, *len); + if (ret == NULL) { + WOLFSSL_MSG("d2i error"); + return NULL; + } + if (tmp <= *src) { + WOLFSSL_MSG("ptr not advanced"); + mem->free_func(ret); /* never a stack so we can call this directly */ + return NULL; + } + *len -= (tmp - *src); + *src = tmp; + return ret; +} + +static void* d2i_generic_obj(const WOLFSSL_ASN1_TEMPLATE* mem, const byte** src, + long* len) +{ + void* ret = NULL; + if (mem->sequence) { + long skl = 0; + int slen = 0; + WOLFSSL_STACK* sk = NULL; + word32 idx = 0; + const byte* tmp = *src; + if (GetSequence(tmp, &idx, &slen, (word32)*len) < 0) + goto error; + skl = (long)slen; + tmp += idx; + ret = sk = wolfSSL_sk_new_null(); + while (skl > 0) { + void* new_obj = d2i_obj(mem, &tmp, &skl); + if (new_obj == NULL) { + WOLFSSL_MSG("d2i_obj failed"); + goto error; + } + if (wolfSSL_sk_insert(sk, new_obj, -1) != WOLFSSL_SUCCESS) { + mem->free_func(new_obj); + WOLFSSL_MSG("push failed"); + goto error; + } + } + if (skl != 0) { + WOLFSSL_MSG("l not zero after sequence"); + goto error; + } + len -= (long)slen; + *src = tmp; + } + else { + ret = d2i_obj(mem, src, len); + } + return ret; +error: + asn1_free_tpl(ret, mem); + return NULL; +} + +static int d2i_handle_tags(const WOLFSSL_ASN1_TEMPLATE* mem, const byte** src, + long* len, byte** impBuf, int* asnLen) +{ + if (mem->tag >= 0) { + byte tag = 0; + word32 idx = 0; + if (mem->explicit) { + if (GetASNTag(*src, &idx, &tag, (word32)*len) < 0 || + (byte)(ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | mem->tag) + != tag || + GetLength(*src, &idx, asnLen, (word32)*len) < 0) { + WOLFSSL_MSG("asn tag error"); + return -1; + } + *len -= idx; + *src += idx; + } + else { + /* Underlying d2i functions won't be able to handle the implicit + * tag so we substitute it for the expected tag. */ + if (mem->first_byte == 0) { + WOLFSSL_MSG("first byte not set"); + return -1; + } + if (GetASNTag(*src, &idx, &tag, (word32)*len) < 0 || + (byte)mem->tag != (tag & ASN_TYPE_MASK) || + GetLength(*src, &idx, asnLen, (word32)*len) < 0) { + WOLFSSL_MSG("asn tag error"); + return -1; + } + *asnLen += idx; /* total buffer length */ + *impBuf = (byte*)XMALLOC(*asnLen, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (*impBuf == NULL) { + WOLFSSL_MSG("malloc error"); + return -1; + } + XMEMCPY(*impBuf, *src, *asnLen); + (*impBuf)[0] = mem->first_byte; + } + } + return 0; +} + +static void* d2i_generic(const WOLFSSL_ASN1_TEMPLATE* mem, + const byte** src, long* len) +{ + int asnLen = -1; + const byte *tmp = NULL; + void* ret = NULL; + byte* impBuf = NULL; + long l; + + if (*len <= 0) { + WOLFSSL_MSG("buffer too short"); + return NULL; + } + + if (d2i_handle_tags(mem, src, len, &impBuf, &asnLen) != 0) { + WOLFSSL_MSG("tags error"); + goto error; + } + + if (impBuf != NULL) + tmp = impBuf; + else + tmp = *src; + l = (long)(asnLen >= 0 ? asnLen : *len); + ret = d2i_generic_obj(mem, &tmp, &l); + if (l < 0) { + WOLFSSL_MSG("ptr advanced too far"); + goto error; + } + if (impBuf != NULL) { + tmp = *src + (tmp - impBuf); /* for the next calculation */ + XFREE(impBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + if (asnLen >= 0 && (int)(tmp - *src) != asnLen) { + WOLFSSL_MSG("ptr not advanced enough"); + goto error; + } + *len -= tmp - *src; + *src = tmp; + return ret; +error: + asn1_free_tpl(ret, mem); + if (impBuf != NULL) + XFREE(impBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return NULL; +} + +static int d2i_ASN_SEQUENCE(void* obj, const byte **src, long len, + const WOLFSSL_ASN1_ITEM* item) +{ + const WOLFSSL_ASN1_TEMPLATE* mem = NULL; + int err; + word32 idx = 0; + int slen = 0; + size_t i; + const byte* s = *src; + + err = GetSequence(s, &idx, &slen, (word32)len); + if (err <= 0) { + WOLFSSL_MSG("GetSequence error"); + return -1; + } + s += idx; + len -= idx; + + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) { + asn1Mem(obj, mem->offset) = d2i_generic(mem, &s, &len); + if (asn1Mem(obj, mem->offset) == NULL) { + WOLFSSL_MSG("d2i error"); + return -1; + } + } + *src = s; + return 0; +} + +static int d2i_ASN_CHOICE(void* obj, const byte **src, long len, + const WOLFSSL_ASN1_ITEM* item) +{ + const WOLFSSL_ASN1_TEMPLATE* mem = NULL; + size_t i; + + for (mem = item->members, i = 0; i < item->mcount; mem++, i++) { + asn1Mem(obj, mem->offset) = d2i_generic(mem, src, &len); + if (asn1Mem(obj, mem->offset) != NULL) { + asn1Type(obj, item->toffset) = mem->tag; + return 0; + } + } + WOLFSSL_MSG("der does not decode with any CHOICE"); + return -1; +} + +static void* d2i_ASN_OBJECT_TYPE(const byte **src, long len, + const WOLFSSL_ASN1_ITEM* item) +{ + return d2i_generic(item->members, src, &len); +} + +void* wolfSSL_ASN1_item_d2i(void** dst, const byte **src, long len, + const WOLFSSL_ASN1_ITEM* item) +{ + void* obj = NULL; + int err = 0; + const byte *tmp; + + WOLFSSL_ENTER("wolfSSL_ASN1_item_d2i"); + + if (src == NULL || *src == NULL || len <= 0 || item == NULL) { + WOLFSSL_LEAVE("wolfSSL_ASN1_item_d2i", 0); + return NULL; + } + + tmp = *src; + + /* Create an empty object. */ + + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + case WOLFSSL_ASN1_CHOICE: + obj = asn1_item_alloc(item); + if (obj == NULL) + return NULL; + break; + case WOLFSSL_ASN1_OBJECT_TYPE: + /* allocated later */ + break; + default: + WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_d2i"); + return NULL; + } + + switch (item->type) { + case WOLFSSL_ASN1_SEQUENCE: + err = d2i_ASN_SEQUENCE(obj, &tmp, len, item); + break; + case WOLFSSL_ASN1_CHOICE: + err = d2i_ASN_CHOICE(obj, &tmp, len, item); + break; + case WOLFSSL_ASN1_OBJECT_TYPE: + obj = d2i_ASN_OBJECT_TYPE(&tmp, len, item); + if (obj == NULL) + err = -1; + break; + default: + WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_d2i"); + err = -1; + break; + } + + if (err == 0) + *src = tmp; + else { + wolfSSL_ASN1_item_free(obj, item); + obj = NULL; + } + + if (dst != NULL && obj != NULL) { + if (*dst != NULL) + wolfSSL_ASN1_item_free(*dst, item); + *dst = obj; + } + + WOLFSSL_LEAVE("wolfSSL_ASN1_item_d2i", obj != NULL); + return obj; +} + #endif /* OPENSSL_ALL */ #endif /* OPENSSL_EXTRA */ @@ -453,9 +780,6 @@ int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* bitStr, return bit; } -#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ - -#if defined(OPENSSL_ALL) && !defined(NO_CERTS) /* Grow data to require length. * @@ -478,7 +802,8 @@ static int wolfssl_asn1_bit_string_grow(WOLFSSL_ASN1_BIT_STRING* bitStr, } else { /* Clear out new, top bytes. */ - XMEMSET(tmp + bitStr->length, 0, (size_t)(len - bitStr->length)); + if (len > bitStr->length) + XMEMSET(tmp + bitStr->length, 0, (size_t)(len - bitStr->length)); bitStr->data = tmp; bitStr->length = len; } @@ -527,7 +852,93 @@ int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* bitStr, int idx, return ret; } -#endif /* OPENSSL_ALL && !NO_CERTS */ +/* Serialize object to DER encoding + * + * @param bstr Object to serialize + * @param pp Output + * @return Length on success + * Negative number on failure + */ +int wolfSSL_i2d_ASN1_BIT_STRING(const WOLFSSL_ASN1_BIT_STRING* bstr, + unsigned char** pp) +{ + int len; + unsigned char* buf; + + if (bstr == NULL || (bstr->data == NULL && bstr->length != 0)) + return WOLFSSL_FATAL_ERROR; + + len = (int)SetBitString((word32)bstr->length, 0, NULL) + bstr->length; + if (pp != NULL) { + word32 idx; + + if (*pp != NULL) + buf = *pp; + else { + buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1); + if (buf == NULL) + return WOLFSSL_FATAL_ERROR; + } + + idx = SetBitString((word32)bstr->length, 0, buf); + if (bstr->length > 0) + XMEMCPY(buf + idx, bstr->data, (size_t)bstr->length); + + if (*pp != NULL) + *pp += len; + else + *pp = buf; + } + + return len; +} + +WOLFSSL_ASN1_BIT_STRING* wolfSSL_d2i_ASN1_BIT_STRING( + WOLFSSL_ASN1_BIT_STRING** out, const byte** src, long len) +{ + WOLFSSL_ASN1_BIT_STRING* ret = NULL; + word32 idx = 0; + byte tag = 0; + int length = 0; + + WOLFSSL_ENTER("wolfSSL_d2i_ASN1_BIT_STRING"); + + if (src == NULL || *src == NULL || len == 0) + return NULL; + + if (GetASNTag(*src, &idx, &tag, len) < 0) + return NULL; + if (tag != ASN_BIT_STRING) + return NULL; + if (GetLength(*src, &idx, &length, len) < 0) + return NULL; + if (GetASN_BitString(*src, idx, length) != 0) + return NULL; + idx++; /* step over unused bits */ + length--; + + ret = wolfSSL_ASN1_BIT_STRING_new(); + if (ret == NULL) + return NULL; + + if (wolfssl_asn1_bit_string_grow(ret, length) != 1) { + wolfSSL_ASN1_BIT_STRING_free(ret); + return NULL; + } + + XMEMCPY(ret->data, *src + idx, length); + *src += idx + (word32)length; + + if (out != NULL) { + if (*out != NULL) + wolfSSL_ASN1_BIT_STRING_free(*out); + *out = ret; + } + + return ret; +} + +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ /******************************************************************************* * ASN1_INTEGER APIs @@ -772,7 +1183,7 @@ static void wolfssl_twos_compl(byte* data, int length) /* Calculate 2's complement of DER encoding. * - * @param [in] data Array that is number. + * @param [in|out] data Array that is number. * @param [in] length Number of bytes in array. * @param [out] neg When NULL, 2's complement data. * When not NULL, check for negative first and return. @@ -811,60 +1222,48 @@ static int wolfssl_asn1_int_twos_compl(byte* data, int length, byte* neg) * @return -1 when a is NULL or no data, out is NULL, dynamic memory allocation * fails or encoding length fails. */ -int wolfSSL_i2d_ASN1_INTEGER(const WOLFSSL_ASN1_INTEGER* a, unsigned char** out) +int wolfSSL_i2d_ASN1_INTEGER(const WOLFSSL_ASN1_INTEGER* a, unsigned char** pp) { - int ret = 0; - byte* buf = NULL; - WOLFSSL_ENTER("wolfSSL_i2d_ASN1_INTEGER"); /* Validate parameters. */ - if ((a == NULL) || (a->data == NULL) || (a->length <= 0) || (out == NULL)) { + if (a == NULL || a->data == NULL || a->length <= 0) { WOLFSSL_MSG("Bad parameter."); - ret = -1; + return WOLFSSL_FATAL_ERROR; } - if ((ret == 0) && (*out == NULL)) { - /* Allocate buffer to hold encoding. */ - buf = (unsigned char*)XMALLOC((size_t)a->length, NULL, - DYNAMIC_TYPE_ASN1); - if (buf == NULL) { - WOLFSSL_MSG("Failed to allocate output buffer."); - ret = -1; + if (pp != NULL) { + byte* buf; + + if (*pp != NULL) + buf = *pp; + else { + buf = (byte*)XMALLOC((size_t)a->length, NULL, DYNAMIC_TYPE_ASN1); + if (buf == NULL) + return WOLFSSL_FATAL_ERROR; } - /* Return any allocated buffer. */ - *out = buf; - } - if (ret == 0) { + /* Copy the data (including tag and length) into output buffer. */ - XMEMCPY(*out, a->data, (size_t)a->length); + XMEMCPY(buf, a->data, (size_t)a->length); /* Only magnitude of the number stored (i.e. the sign isn't encoded). * The "negative" field is 1 if the value must be interpreted as * negative and we need to output the 2's complement of the value in * the DER output. */ - if (a->negative) { - ret = wolfssl_asn1_int_twos_compl(*out, a->length, NULL); + if (a->negative && + wolfssl_asn1_int_twos_compl(buf, a->length, NULL) != 0) { + if (*pp == NULL) + XFREE(buf, NULL, DYNAMIC_TYPE_ASN1); + return WOLFSSL_FATAL_ERROR; } - } - if (ret == 0) { - ret = a->length; - /* Move pointer on passed encoding when buffer passed in. */ - if (buf == NULL) { - *out += a->length; - } - } - /* Dispose of any dynamically allocated data on error. */ - else if (buf != NULL) { - /* Dispose of buffer allocated locally on error. */ - XFREE(buf, NULL, DYNAMIC_TYPE_ASN1); - /* Don't return freed buffer. */ - *out = NULL; - } - WOLFSSL_LEAVE("wolfSSL_i2d_ASN1_INTEGER", ret); + if (*pp != NULL) + *pp += a->length; + else + *pp = buf; + } - return ret; + return a->length; } /* Decode DER encoding of ASN.1 INTEGER. @@ -1700,6 +2099,36 @@ int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, return ret; } +int wolfssl_asn1_obj_set(WOLFSSL_ASN1_OBJECT* obj, const byte* der, word32 len, + int addHdr) +{ + word32 idx = 0; + + if (obj == NULL || der == NULL || len == 0) + return WOLFSSL_FAILURE; + + if (addHdr) + idx = SetHeader(ASN_OBJECT_ID, (word32)len, NULL, 0); + + if (obj->obj != NULL) { + XFREE((void*)obj->obj, obj->heap, DYNAMIC_TYPE_ASN1); + obj->obj = NULL; + obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; + } + + obj->obj =(unsigned char*)XMALLOC(idx + len, obj->heap, DYNAMIC_TYPE_ASN1); + if (obj->obj == NULL) + return WOLFSSL_FAILURE; + + if (addHdr) + SetHeader(ASN_OBJECT_ID, (word32)len, (byte*)obj->obj, 0); + + XMEMCPY((byte*)obj->obj + idx, der, len); + obj->objSz = (unsigned int)(idx + len); + obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; + return WOLFSSL_SUCCESS; +} + /* Creates and ASN.1 OBJECT_ID object from DER encoding. * * @param [out] a Pointer to return new ASN.1 OBJECT_ID through. @@ -1714,38 +2143,43 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, const unsigned char **der, long length) { WOLFSSL_ASN1_OBJECT* ret = NULL; - int err = 0; - const unsigned char *d; - long len = 0; - int tag = 0; - int cls; + int len = 0; + word32 idx = 0; WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT"); /* Validate parameters. */ if ((der == NULL) || (*der == NULL) || (length <= 0)) { WOLFSSL_MSG("Bad parameter"); - err = 1; + return NULL; } - if (!err) { - /* Get pointer to be modified along the way. */ - d = *der; - /* Move d to value and get length and tag. */ - if (wolfSSL_ASN1_get_object(&d, &len, &tag, &cls, length) & 0x80) { - WOLFSSL_MSG("wolfSSL_ASN1_get_object error"); - err = 1; - } + if (GetASNHeader(*der, ASN_OBJECT_ID, &idx, &len, (word32)length) < 0) { + WOLFSSL_MSG("error getting tag"); + return NULL; } - /* Check it DER encoding is of an OBJECT_ID. */ - if ((!err) && (tag != ASN_OBJECT_ID)) { - WOLFSSL_MSG("Not an ASN object"); - err = 1; + + if (len <= 0) { + WOLFSSL_MSG("zero length"); + return NULL; } - /* Create an ASN.1 OBJECT_ID_object from value. TODO: not DER encoding? */ - if ((!err) && ((ret = wolfSSL_c2i_ASN1_OBJECT(a, &d, len)) != NULL)) { - /* Update pointer to after decoded bytes. */ - *der = d; + + ret = wolfSSL_ASN1_OBJECT_new(); + if (ret == NULL) { + WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error"); + return NULL; + } + + if (wolfssl_asn1_obj_set(ret, *der, idx + len, 0) != WOLFSSL_SUCCESS) { + wolfSSL_ASN1_OBJECT_free(ret); + return NULL; + } + + *der += idx + len; + if (a != NULL) { + if (*a != NULL) + wolfSSL_ASN1_OBJECT_free(*a); + *a = ret; } return ret; @@ -1821,7 +2255,6 @@ int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp) WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, const unsigned char **pp, long len) { - int err = 0; WOLFSSL_ASN1_OBJECT* ret = NULL; WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT"); @@ -1829,40 +2262,29 @@ WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a, /* Validate parameters. */ if ((pp == NULL) || (*pp == NULL) || (len <= 0)) { WOLFSSL_MSG("Bad parameter"); - err = 1; + return NULL; } /* Create a new ASN.1 OBJECT_ID object. */ - if ((!err) && ((ret = wolfSSL_ASN1_OBJECT_new()) == NULL)) { + ret = wolfSSL_ASN1_OBJECT_new(); + if (ret == NULL) { WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error"); - err = 1; + return NULL; } - if (!err) { - /* Allocate memory for content octets. */ - ret->obj = (const unsigned char*)XMALLOC((size_t)len, NULL, - DYNAMIC_TYPE_ASN1); - if (ret->obj == NULL) { - WOLFSSL_MSG("error allocating asn data memory"); - wolfSSL_ASN1_OBJECT_free(ret); - ret = NULL; - err = 1; - } + if (wolfssl_asn1_obj_set(ret, *pp, (word32)len, 1) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfssl_asn1_obj_set error"); + wolfSSL_ASN1_OBJECT_free(ret); + return NULL; } - if (!err) { - /* Content octets buffer was dynamically allocated. */ - ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; - /* Copy in content octets and set size. */ - XMEMCPY((byte*)ret->obj, *pp, (size_t)len); - ret->objSz = (unsigned int)len; - - /* Move pointer to after data copied out. */ - *pp += len; - /* Return ASN.1 OBJECT_ID object through a if required. */ - if (a != NULL) { - *a = ret; - } + /* Move pointer to after data copied out. */ + *pp += len; + /* Return ASN.1 OBJECT_ID object through a if required. */ + if (a != NULL) { + if (*a != NULL) + wolfSSL_ASN1_OBJECT_free(*a); + *a = ret; } return ret; @@ -2397,6 +2819,154 @@ char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, return ret; } + +static int i2d_ASN1_STRING(WOLFSSL_ASN1_STRING* s, + unsigned char **pp, byte tag) +{ + int idx; + int len; + unsigned char* out; + + if (s == NULL || s->data == NULL || s->length == 0) + return -1; + + len = SetHeader(tag, s->length, NULL, 0) + s->length; + + if (pp == NULL) + return len; + + if (*pp == NULL) { + out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1); + if (out == NULL) + return WOLFSSL_FATAL_ERROR; + } + else { + out = *pp; + } + + idx = (int)SetHeader(tag, s->length, out, 0); + XMEMCPY(out + idx, s->data, s->length); + if (*pp == NULL) + *pp = out; + else + *pp += len; + + return len; +} + +int wolfSSL_i2d_ASN1_GENERALSTRING(WOLFSSL_ASN1_STRING* s, unsigned char **pp) +{ + WOLFSSL_ENTER("wolfSSL_i2d_ASN1_GENERALSTRING"); + + return i2d_ASN1_STRING(s, pp, ASN_GENERALSTRING); +} + +int wolfSSL_i2d_ASN1_OCTET_STRING(WOLFSSL_ASN1_STRING* s, unsigned char **pp) +{ + WOLFSSL_ENTER("wolfSSL_i2d_ASN1_OCTET_STRING"); + + return i2d_ASN1_STRING(s, pp, ASN_OCTET_STRING); +} + +int wolfSSL_i2d_ASN1_UTF8STRING(WOLFSSL_ASN1_STRING* s, unsigned char **pp) +{ + WOLFSSL_ENTER("wolfSSL_i2d_ASN1_UTF8STRING"); + + return i2d_ASN1_STRING(s, pp, ASN_UTF8STRING); +} + +int wolfSSL_i2d_ASN1_SEQUENCE(WOLFSSL_ASN1_STRING* s, + unsigned char **pp) +{ + unsigned char* out; + + if (s == NULL || s->data == NULL || s->length == 0) + return -1; + + if (pp == NULL) + return s->length; + + if (*pp == NULL) { + out = (unsigned char*)XMALLOC(s->length, NULL, DYNAMIC_TYPE_ASN1); + if (out == NULL) + return WOLFSSL_FATAL_ERROR; + } + else { + out = *pp; + } + + XMEMCPY(out, s->data, s->length); + if (*pp == NULL) + *pp = out; + else + *pp += s->length; + + return s->length; +} + +static WOLFSSL_ASN1_STRING* d2i_ASN1_STRING(WOLFSSL_ASN1_STRING** out, + const byte** src, long len, byte expTag) +{ + WOLFSSL_ASN1_STRING* ret = NULL; + word32 idx = 0; + byte tag = 0; + int length = 0; + + WOLFSSL_ENTER("d2i_ASN1_GENERALSTRING"); + + if (src == NULL || *src == NULL || len == 0) + return NULL; + + if (GetASNTag(*src, &idx, &tag, len) < 0) + return NULL; + if (tag != expTag) + return NULL; + if (GetLength(*src, &idx, &length, len) < 0) + return NULL; + + ret = wolfSSL_ASN1_STRING_new(); + if (ret == NULL) + return NULL; + + if (wolfSSL_ASN1_STRING_set(ret, *src + idx, length) != 1) { + wolfSSL_ASN1_STRING_free(ret); + return NULL; + } + + if (out != NULL) { + if (*out != NULL) + wolfSSL_ASN1_STRING_free(*out); + *out = ret; + } + *src += idx + length; + + return ret; +} + +WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_GENERALSTRING(WOLFSSL_ASN1_STRING** out, + const byte** src, long len) +{ + WOLFSSL_ENTER("wolfSSL_d2i_ASN1_GENERALSTRING"); + + return d2i_ASN1_STRING(out, src, len, ASN_GENERALSTRING); +} + +WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_OCTET_STRING(WOLFSSL_ASN1_STRING** out, + const byte** src, long len) +{ + WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OCTET_STRING"); + + return d2i_ASN1_STRING(out, src, len, ASN_OCTET_STRING); +} + +WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_UTF8STRING(WOLFSSL_ASN1_STRING** out, + const byte** src, long len) +{ + WOLFSSL_ENTER("wolfSSL_d2i_ASN1_UTF8STRING"); + + return d2i_ASN1_STRING(out, src, len, ASN_UTF8STRING); +} + #endif /* OPENSSL_EXTRA */ #endif /* NO_ASN */ @@ -2470,7 +3040,7 @@ unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn) * @return String length on success. * @return 0 when asn is NULL or no data set. */ -int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn) +int wolfSSL_ASN1_STRING_length(const WOLFSSL_ASN1_STRING* asn) { int len = 0; @@ -4006,6 +4576,7 @@ static void wolfssl_asn1_type_free_value(WOLFSSL_ASN1_TYPE* at) #endif break; case V_ASN1_UTF8STRING: + case V_ASN1_OCTET_STRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_IA5STRING: @@ -4033,6 +4604,41 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at) XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL); } +int wolfSSL_i2d_ASN1_TYPE(WOLFSSL_ASN1_TYPE* at, unsigned char** pp) +{ + int ret = WOLFSSL_FATAL_ERROR; + + if (at == NULL) + return WOLFSSL_FATAL_ERROR; + + switch (at->type) { + case V_ASN1_NULL: + break; + case V_ASN1_OBJECT: + ret = wolfSSL_i2d_ASN1_OBJECT(at->value.object, pp); + break; + case V_ASN1_UTF8STRING: + ret = wolfSSL_i2d_ASN1_UTF8STRING(at->value.utf8string, pp); + break; + case V_ASN1_GENERALIZEDTIME: + ret = wolfSSL_i2d_ASN1_GENERALSTRING(at->value.utf8string, pp); + break; + case V_ASN1_SEQUENCE: + ret = wolfSSL_i2d_ASN1_SEQUENCE(at->value.sequence, pp); + break; + case V_ASN1_UTCTIME: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_IA5STRING: + case V_ASN1_UNIVERSALSTRING: + default: + WOLFSSL_MSG("asn1 i2d type not supported"); + break; + } + + return ret; +} + #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS) || \ @@ -4070,6 +4676,7 @@ void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value) case V_ASN1_UTCTIME: case V_ASN1_GENERALIZEDTIME: case V_ASN1_UTF8STRING: + case V_ASN1_OCTET_STRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_IA5STRING: @@ -4089,6 +4696,14 @@ void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value) } } +int wolfSSL_ASN1_TYPE_get(const WOLFSSL_ASN1_TYPE *a) +{ + if (a != NULL && (a->type == V_ASN1_BOOLEAN || a->type == V_ASN1_NULL + || a->value.ptr != NULL)) + return a->type; + return 0; +} + #endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_WPAS */ #endif /* !NO_ASN */ diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 296e74a14f..b529708fe8 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -45,8 +45,7 @@ void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4) { /* Ensure WOLFSSL_MD4_CTX is big enough for wolfCrypt Md4. */ - typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1]; - (void)sizeof(ok); + WOLFSSL_ASSERT_SIZEOF_GE(md4->buffer, Md4); WOLFSSL_ENTER("MD4_Init"); @@ -97,8 +96,7 @@ void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4) int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5) { /* Ensure WOLFSSL_MD5_CTX is big enough for wolfCrypt wc_Md5. */ - typedef char md5_test[sizeof(WOLFSSL_MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1]; - (void)sizeof(md5_test); + WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_MD5_CTX, wc_Md5); WOLFSSL_ENTER("MD5_Init"); @@ -212,8 +210,7 @@ unsigned char* wolfSSL_MD5(const unsigned char* data, size_t len, int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha) { /* Ensure WOLFSSL_SHA_CTX is big enough for wolfCrypt wc_Sha. */ - typedef char sha_test[sizeof(WOLFSSL_SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(WOLFSSL_SHA_CTX, wc_Sha); WOLFSSL_ENTER("SHA_Init"); @@ -362,8 +359,7 @@ int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha, const unsigned char* data) int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha224) { /* Ensure WOLFSSL_SHA224_CTX is big enough for wolfCrypt wc_Sha224. */ - typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA224_CTX, wc_Sha224); WOLFSSL_ENTER("SHA224_Init"); @@ -422,8 +418,7 @@ int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha224) int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256) { /* Ensure WOLFSSL_SHA256_CTX is big enough for wolfCrypt wc_Sha256. */ - typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA256_CTX, wc_Sha256); WOLFSSL_ENTER("SHA256_Init"); @@ -512,8 +507,7 @@ int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256, int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha384) { /* Ensure WOLFSSL_SHA384_CTX is big enough for wolfCrypt wc_Sha384. */ - typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA384_CTX, wc_Sha384); WOLFSSL_ENTER("SHA384_Init"); @@ -572,8 +566,7 @@ int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha384) int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha512) { /* Ensure WOLFSSL_SHA512_CTX is big enough for wolfCrypt wc_Sha512. */ - typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA512_CTX, wc_Sha512); WOLFSSL_ENTER("SHA512_Init"); @@ -809,8 +802,7 @@ int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512, int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha3_224) { /* Ensure WOLFSSL_SHA3_224_CTX is big enough for wolfCrypt wc_Sha3. */ - typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA3_224_CTX, wc_Sha3); WOLFSSL_ENTER("SHA3_224_Init"); @@ -869,8 +861,7 @@ int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha3) int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256) { /* Ensure WOLFSSL_SHA3_256_CTX is big enough for wolfCrypt wc_Sha3. */ - typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA3_256_CTX, wc_Sha3); WOLFSSL_ENTER("SHA3_256_Init"); @@ -929,8 +920,7 @@ int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha3) int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha3_384) { /* Ensure WOLFSSL_SHA3_384_CTX is big enough for wolfCrypt wc_Sha3. */ - typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA3_384_CTX, wc_Sha3); WOLFSSL_ENTER("SHA3_384_Init"); @@ -989,8 +979,7 @@ int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha3) int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha3_512) { /* Ensure WOLFSSL_SHA3_512_CTX is big enough for wolfCrypt wc_Sha3. */ - typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; - (void)sizeof(sha_test); + WOLFSSL_ASSERT_SIZEOF_GE(SHA3_512_CTX, wc_Sha3); WOLFSSL_ENTER("SHA3_512_Init"); diff --git a/src/ssl_p7p12.c b/src/ssl_p7p12.c index 11b6c40a9a..b337b5a989 100644 --- a/src/ssl_p7p12.c +++ b/src/ssl_p7p12.c @@ -1168,7 +1168,7 @@ PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in, } XMEMSET(boundary, 0, (word32)(boundLen+1)); boundary[0] = boundary[1] = '-'; - XSTRNCPY(&boundary[2], curParam->value, boundLen-2); + XSTRCPY(&boundary[2], curParam->value); /* Parse up to first boundary, ignore everything here. */ lineLen = wolfSSL_BIO_gets(in, section, remainLen); diff --git a/src/x509.c b/src/x509.c index 09c56dc8c3..42b30898db 100644 --- a/src/x509.c +++ b/src/x509.c @@ -362,39 +362,9 @@ WOLFSSL_STACK* wolfSSL_sk_new_x509_ext(void) * OpenSSL. */ int wolfSSL_sk_X509_EXTENSION_push(WOLFSSL_STACK* sk,WOLFSSL_X509_EXTENSION* ext) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_X509_EXTENSION_push"); - if (sk == NULL || ext == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.ext == NULL) { - sk->data.ext = ext; - sk->num += 1; - return (int)sk->num; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_X509); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.ext = sk->data.ext; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.ext = ext; - sk->num += 1; - - return (int)sk->num; + return wolfSSL_sk_push(sk, ext); } /* Free the structure for X509_EXTENSION stack @@ -535,8 +505,8 @@ int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, if (lastpos < 0) lastpos = 0; for (; lastpos < wolfSSL_sk_num(sk); lastpos++) - if (wolfSSL_OBJ_cmp((WOLFSSL_ASN1_OBJECT*)wolfSSL_sk_value(sk, - lastpos), obj) == 0) + if (wolfSSL_OBJ_cmp(wolfSSL_sk_X509_EXTENSION_value(sk, + lastpos)->obj, obj) == 0) return lastpos; return -1; } @@ -556,10 +526,10 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns, WOLFSSL_GENERAL_NAME* gn) { int ret = 0; - WOLFSSL_ASN1_OBJECT* obj; - WOLFSSL_ASN1_TYPE* type; - WOLFSSL_ASN1_STRING* str; - byte tag; + WOLFSSL_ASN1_OBJECT* obj = NULL; + WOLFSSL_ASN1_TYPE* type = NULL; + WOLFSSL_ASN1_STRING* str = NULL; + byte tag = 0; unsigned char* p = (unsigned char *)dns->name; long len = dns->len; @@ -594,7 +564,7 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns, goto err; } - tag = ASN_UTF8STRING; + tag = V_ASN1_UTF8STRING; } else #endif @@ -604,39 +574,23 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns, /* Create an object id for general name from DER encoding. */ obj = wolfSSL_d2i_ASN1_OBJECT(NULL, (const unsigned char**)&p, len); - if (obj == NULL) { + if (obj == NULL) goto err; - } /* Pointer moved on and now update length of remaining data. */ len -= (long)((size_t)p - (size_t)dns->name); - /* Next is: [0]. Check tag and length. */ - if (GetASNTag(p, &idx, &tag, (word32)len) < 0) { - wolfSSL_ASN1_OBJECT_free(obj); + /* Next is "value [0] EXPLICIT ANY DEFINED BY type-id" */ + if (GetASNHeader(p, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0, + &idx, &nameLen, (word32)len) < 0) goto err; - } - if (tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) { - wolfSSL_ASN1_OBJECT_free(obj); - goto err; - } - if (GetLength(p, &idx, &nameLen, (word32)len) <= 1) { - wolfSSL_ASN1_OBJECT_free(obj); - goto err; - } - - /* Next is a string of some type. */ - if (GetASNTag(p, &idx, &tag, (word32)len) < 0) { - wolfSSL_ASN1_OBJECT_free(obj); - goto err; - } - if (GetLength(p, &idx, &nameLen, (word32)len) <= 0) { - wolfSSL_ASN1_OBJECT_free(obj); - goto err; - } p += idx; len -= idx; + + /* Set the tag to object so that it gets output in raw form */ + tag = V_ASN1_SEQUENCE; } + /* Create a WOLFSSL_ASN1_STRING from the DER. */ str = wolfSSL_ASN1_STRING_type_new(tag); if (str == NULL) { @@ -647,11 +601,8 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns, /* Wrap string in a WOLFSSL_ASN1_TYPE. */ type = wolfSSL_ASN1_TYPE_new(); - if (type == NULL) { - wolfSSL_ASN1_OBJECT_free(obj); - wolfSSL_ASN1_STRING_free(str); + if (type == NULL) goto err; - } wolfSSL_ASN1_TYPE_set(type, tag, str); /* Store the object and string in general name. */ @@ -660,6 +611,10 @@ static int wolfssl_dns_entry_othername_to_gn(DNS_entry* dns, ret = 1; err: + if (ret != 1) { + wolfSSL_ASN1_OBJECT_free(obj); + wolfSSL_ASN1_STRING_free(str); + } return ret; } #endif /* OPENSSL_ALL || WOLFSSL_WPAS_SMALL */ @@ -1249,7 +1204,7 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) */ if (x509->ext_sk == NULL) x509->ext_sk = wolfSSL_sk_new_x509_ext(); - if (wolfSSL_sk_X509_EXTENSION_push(x509->ext_sk, ext) == WOLFSSL_FAILURE) { + if (wolfSSL_sk_insert(x509->ext_sk, ext, -1) == WOLFSSL_FAILURE) { wolfSSL_X509_EXTENSION_free(ext); ext = NULL; } @@ -2560,6 +2515,44 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, case EXT_KEY_USAGE_OID: if (x509->extKeyUsageSrc != NULL) { + const byte* ekuSrc = x509->extKeyUsageSrc; + word32 i; + + sk = wolfSSL_sk_new_asn1_obj(); + if (sk == NULL) { + WOLFSSL_MSG("Issue creating stack"); + return NULL; + } + + for (i = 0; i < x509->extKeyUsageCount; i++) { + long ekuSrcLen = x509->extKeyUsageSz - + (ekuSrc - x509->extKeyUsageSrc); + WOLFSSL_ASN1_OBJECT* ekuObj = wolfSSL_d2i_ASN1_OBJECT(NULL, + &ekuSrc, ekuSrcLen); + if (ekuObj == NULL) { + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); + WOLFSSL_MSG("d2i obj error"); + return NULL; + } + ekuObj->type = EXT_KEY_USAGE_OID; + ekuObj->grp = oidCertExtType; + /* Push to end to maintain order */ + if (wolfSSL_sk_insert(sk, ekuObj, -1) != + WOLFSSL_SUCCESS) { + wolfSSL_ASN1_OBJECT_free(ekuObj); + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); + WOLFSSL_MSG("d2i obj error"); + return NULL; + } + } + + if (ekuSrc - x509->extKeyUsageSrc != x509->extKeyUsageSz || + i != x509->extKeyUsageCount) { + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); + WOLFSSL_MSG("incorrect eku count or buffer not exhausted"); + return NULL; + } + if (c != NULL) { if (x509->extKeyUsageCount > 1) { *c = -2; @@ -2568,15 +2561,6 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, *c = x509->extKeyUsageCrit; } } - obj = wolfSSL_ASN1_OBJECT_new(); - if (obj == NULL) { - WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); - return NULL; - } - obj->type = EXT_KEY_USAGE_OID; - obj->grp = oidCertExtType; - obj->obj = x509->extKeyUsageSrc; - obj->objSz = x509->extKeyUsageSz; } else { WOLFSSL_MSG("No Extended Key Usage set"); @@ -5069,19 +5053,9 @@ int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk) /* returns null on failure and pointer to internal value on success */ WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( - WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx) + const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx) { - WOLFSSL_STACK* ret; - - if (sk == NULL) { - return NULL; - } - - ret = wolfSSL_sk_get_node(sk, idx); - if (ret != NULL) { - return ret->data.ext; - } - return NULL; + return wolfSSL_sk_value(sk, idx); } /* frees all of the nodes and the values in stack */ @@ -5778,6 +5752,37 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return id; } + + const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id( + WOLFSSL_X509 *x509) + { + WOLFSSL_ASN1_STRING* ret = NULL; + + WOLFSSL_ENTER("wolfSSL_X509_get0_subject_key_id"); + + if (x509 != NULL && x509->subjKeyIdSet) { + if (x509->subjKeyIdStr == NULL) { + x509->subjKeyIdStr = wolfSSL_ASN1_STRING_new(); + if (x509->subjKeyIdStr != NULL) { + if (wolfSSL_ASN1_STRING_set(x509->subjKeyIdStr, + x509->subjKeyId, x509->subjKeyIdSz) == 1) { + ret = x509->subjKeyIdStr; + } + else { + wolfSSL_ASN1_STRING_free(x509->subjKeyIdStr); + x509->subjKeyIdStr = NULL; + } + } + } + else { + ret = x509->subjKeyIdStr; + } + } + + WOLFSSL_LEAVE("wolfSSL_X509_get0_subject_key_id", ret != NULL); + + return ret; + } #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ @@ -8817,7 +8822,7 @@ const WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_VERIFY_PARAM_lookup(const char *na int wolfSSL_X509_VERIFY_PARAM_inherit(WOLFSSL_X509_VERIFY_PARAM *to, const WOLFSSL_X509_VERIFY_PARAM *from) { - int ret = WOLFSSL_FAILURE; + int ret = WOLFSSL_SUCCESS; int isOverWrite = 0; int isDefault = 0; unsigned int flags; @@ -9371,6 +9376,110 @@ int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj return WOLFSSL_SUCCESS; } +/** + * Serialize object to DER encoding + * + * @param alg Object to serialize + * @param pp Output + * @return Length on success + * Negative number on failure + */ +int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg, + unsigned char** pp) +{ + int len; + word32 oid = 0; + word32 idx = 0; + unsigned char* buf = NULL; + + if (alg == NULL || alg->algorithm == 0) { + WOLFSSL_MSG("alg is NULL or algorithm not set"); + return WOLFSSL_FATAL_ERROR; + } + + if (GetObjectId(alg->algorithm->obj, &idx, &oid, + (word32)alg->algorithm->grp, alg->algorithm->objSz) < 0) { + WOLFSSL_MSG("Issue getting OID of object"); + return WOLFSSL_FATAL_ERROR; + } + + len = (int)SetAlgoID((int)oid, NULL, alg->algorithm->grp, 0); + if (len == 0) { + WOLFSSL_MSG("SetAlgoID error"); + return WOLFSSL_FATAL_ERROR; + } + + if (pp != NULL) { + if (*pp != NULL) + buf = *pp; + else { + buf = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1); + if (buf == NULL) + return WOLFSSL_FATAL_ERROR; + } + + len = (int)SetAlgoID((int)oid, buf, alg->algorithm->grp, 0); + if (len == 0) { + WOLFSSL_MSG("SetAlgoID error"); + if (*pp == NULL) + XFREE(buf, NULL, DYNAMIC_TYPE_ASN1); + return WOLFSSL_FATAL_ERROR; + } + + if (*pp != NULL) + *pp += len; + else + *pp = buf; + } + + return len; +} + +WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out, + const byte** src, long len) +{ + WOLFSSL_X509_ALGOR* ret = NULL; + word32 idx = 0; + word32 oid = 0; + int grp; + + WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR"); + + if (src == NULL || *src == NULL || len == 0) + return NULL; + + if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0) + return NULL; + + /* Try to guess the type */ + for (grp = 0; grp < oidIgnoreType; grp++) { + word32 oidSz; + if (OidFromId(oid, (word32)grp, &oidSz) != NULL) + break; + } + if (grp == oidIgnoreType) + return NULL; + + ret = wolfSSL_X509_ALGOR_new(); + if (ret == NULL) + return NULL; + + ret->algorithm = wolfSSL_OBJ_nid2obj(oid2nid(oid, grp)); + if (ret->algorithm == NULL) { + wolfSSL_X509_ALGOR_free(ret); + return NULL; + } + *src += idx; + + if (out != NULL) { + if (*out != NULL) + wolfSSL_X509_ALGOR_free(*out); + *out = ret; + } + + return ret; +} + /** * Allocate a new WOLFSSL_X509_PUBKEY object. * @@ -13293,6 +13402,28 @@ void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj) XFREE(obj, NULL, DYNAMIC_TYPE_OPENSSL); } } + +WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject( + WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk, + WOLFSSL_X509_LOOKUP_TYPE type, + WOLFSSL_X509_NAME *name) +{ + int i; + + WOLFSSL_ENTER("wolfSSL_X509_OBJECT_retrieve_by_subject"); + + if (sk == NULL || name == NULL) + return NULL; + + for (i = 0; i < wolfSSL_sk_X509_OBJECT_num(sk); i++) { + WOLFSSL_X509_OBJECT* obj = wolfSSL_sk_X509_OBJECT_value(sk, i); + if (obj != NULL && obj->type == type && + wolfSSL_X509_NAME_cmp( + wolfSSL_X509_get_subject_name(obj->data.x509), name) == 0) + return obj; + } + return NULL; +} #endif /* OPENSSL_ALL */ #ifndef NO_WOLFSSL_STUB diff --git a/src/x509_str.c b/src/x509_str.c index bfdaf413dc..3ec291463b 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -225,6 +225,10 @@ int GetX509Error(int e) case WC_NO_ERR_TRACE(ASN_SIG_HASH_E): case WC_NO_ERR_TRACE(ASN_SIG_KEY_E): return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE; + /* We can't disambiguate if its the before or after date that caused + * the error. Assume expired. */ + case WC_NO_ERR_TRACE(CRL_CERT_DATE_ERR): + return X509_V_ERR_CRL_HAS_EXPIRED; case WC_NO_ERR_TRACE(CRL_CERT_REVOKED): return WOLFSSL_X509_V_ERR_CERT_REVOKED; case WC_NO_ERR_TRACE(CRL_MISSING): @@ -1385,6 +1389,14 @@ WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param( return NULL; return ctx->param; } + +int wolfSSL_X509_STORE_set1_param(WOLFSSL_X509_STORE *ctx, + WOLFSSL_X509_VERIFY_PARAM *param) +{ + if (ctx == NULL) + return WOLFSSL_FAILURE; + return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, param); +} #endif /******************************************************************************* diff --git a/tests/api.c b/tests/api.c index 61d95ee635..0b52b3ba5c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -40716,6 +40716,9 @@ static int test_wolfSSL_ASN1_BIT_STRING(void) EXPECT_DECLS; #if !defined(NO_CERTS) && defined(OPENSSL_ALL) ASN1_BIT_STRING* str = NULL; + ASN1_BIT_STRING* str2 = NULL; + unsigned char* der = NULL; + const unsigned char* tmp = NULL; ExpectNotNull(str = ASN1_BIT_STRING_new()); /* Empty data testing. */ @@ -40751,7 +40754,13 @@ static int test_wolfSSL_ASN1_BIT_STRING(void) ExpectIntEQ(ASN1_BIT_STRING_set_bit(str, 42, 0), 1); ExpectIntEQ(ASN1_BIT_STRING_get_bit(str, 42), 0); + ExpectIntEQ(i2d_ASN1_BIT_STRING(str, NULL), 14); + ExpectIntEQ(i2d_ASN1_BIT_STRING(str, &der), 14); + tmp = der; + ExpectNotNull(d2i_ASN1_BIT_STRING(&str2, &tmp, 14)); + ASN1_BIT_STRING_free(str); + ASN1_BIT_STRING_free(str2); ASN1_BIT_STRING_free(NULL); #endif return EXPECT_RESULT(); @@ -41141,7 +41150,7 @@ static int test_wolfSSL_d2i_ASN1_INTEGER(void) /* Set a to valid value. */ ExpectIntEQ(wolfSSL_ASN1_INTEGER_set(a, 1), WOLFSSL_SUCCESS); /* NULL output buffer. */ - ExpectIntLT(wolfSSL_i2d_ASN1_INTEGER(a, NULL), 0); + ExpectIntEQ(wolfSSL_i2d_ASN1_INTEGER(a, NULL), 3); wolfSSL_ASN1_INTEGER_free(a); a = NULL; @@ -41539,7 +41548,7 @@ static int test_wolfSSL_ASN1_get_object(void) const unsigned char objDerNotObj[] = { 0x02, 0x01, 0x00 }; const unsigned char objDerNoData[] = { 0x06, 0x00 }; const unsigned char* p; - unsigned char objDer[8]; + unsigned char objDer[10]; unsigned char* der; unsigned char* derPtr; int len = sizeof_cliecc_cert_der_256; @@ -41653,13 +41662,13 @@ static int test_wolfSSL_ASN1_get_object(void) ExpectIntEQ(i2d_ASN1_OBJECT(NULL, NULL), 0); ExpectIntEQ(i2d_ASN1_OBJECT(&s, NULL), 0); - ExpectIntEQ(i2d_ASN1_OBJECT(a, NULL), 8); + ExpectIntEQ(i2d_ASN1_OBJECT(a, NULL), 10); der = NULL; - ExpectIntEQ(i2d_ASN1_OBJECT(a, &der), 8); + ExpectIntEQ(i2d_ASN1_OBJECT(a, &der), 10); derPtr = objDer; - ExpectIntEQ(i2d_ASN1_OBJECT(a, &derPtr), 8); + ExpectIntEQ(i2d_ASN1_OBJECT(a, &derPtr), 10); ExpectPtrNE(derPtr, objDer); - ExpectIntEQ(XMEMCMP(der, objDer, 8), 0); + ExpectIntEQ(XMEMCMP(der, objDer, 10), 0); XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL); ASN1_OBJECT_free(a); @@ -41675,8 +41684,6 @@ static int test_wolfSSL_i2a_ASN1_OBJECT(void) ASN1_OBJECT* a = NULL; BIO *bio = NULL; const unsigned char notObjDer[] = { 0x04, 0x01, 0xff }; - const unsigned char badLenDer[] = { 0x06, 0x04, 0x01 }; - const unsigned char goodDer[] = { 0x06, 0x01, 0x01 }; const unsigned char* p; ExpectNotNull(obj = OBJ_nid2obj(NID_sha256)); @@ -41692,22 +41699,10 @@ static int test_wolfSSL_i2a_ASN1_OBJECT(void) ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 0); ASN1_OBJECT_free(a); a = NULL; - /* DER encoding - not OBJECT_ID */ + /* DER encoding */ p = notObjDer; ExpectNotNull(a = c2i_ASN1_OBJECT(NULL, &p, 3)); - ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 0); - ASN1_OBJECT_free(a); - a = NULL; - /* Bad length encoding. */ - p = badLenDer; - ExpectNotNull(a = c2i_ASN1_OBJECT(NULL, &p, 3)); - ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 0); - ASN1_OBJECT_free(a); - a = NULL; - /* Good encoding - but unknown. */ - p = goodDer; - ExpectNotNull(a = c2i_ASN1_OBJECT(NULL, &p, 3)); - ExpectIntGT(wolfSSL_i2a_ASN1_OBJECT(bio, a), 0); + ExpectIntEQ(wolfSSL_i2a_ASN1_OBJECT(bio, a), 5); ASN1_OBJECT_free(a); BIO_free(bio); @@ -42942,7 +42937,7 @@ static int test_wolfSSL_ASN1_TYPE(void) return EXPECT_RESULT(); } -/* Testing code used in dpp.c in hostap */ +/* Testing code used in old dpp.c in hostap */ #if defined(OPENSSL_ALL) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) typedef struct { /* AlgorithmIdentifier ecPublicKey with optional parameters present @@ -42959,6 +42954,57 @@ ASN1_SEQUENCE(DPP_BOOTSTRAPPING_KEY) = { IMPLEMENT_ASN1_FUNCTIONS(DPP_BOOTSTRAPPING_KEY) +typedef struct { + int type; + union { + ASN1_BIT_STRING *str1; + ASN1_BIT_STRING *str2; + ASN1_BIT_STRING *str3; + } d; +} ASN1_CHOICE_TEST; + +ASN1_CHOICE(ASN1_CHOICE_TEST) = { + ASN1_IMP(ASN1_CHOICE_TEST, d.str1, ASN1_BIT_STRING, 1), + ASN1_IMP(ASN1_CHOICE_TEST, d.str2, ASN1_BIT_STRING, 2), + ASN1_IMP(ASN1_CHOICE_TEST, d.str3, ASN1_BIT_STRING, 3) +} ASN1_CHOICE_END(ASN1_CHOICE_TEST) + +IMPLEMENT_ASN1_FUNCTIONS(ASN1_CHOICE_TEST) + +/* Test nested objects */ +typedef struct { + DPP_BOOTSTRAPPING_KEY* key; + ASN1_INTEGER* asnNum; + ASN1_INTEGER* expNum; + STACK_OF(ASN1_GENERALSTRING) *strList; + ASN1_CHOICE_TEST* str; +} TEST_ASN1_NEST1; + +ASN1_SEQUENCE(TEST_ASN1_NEST1) = { + ASN1_SIMPLE(TEST_ASN1_NEST1, key, DPP_BOOTSTRAPPING_KEY), + ASN1_SIMPLE(TEST_ASN1_NEST1, asnNum, ASN1_INTEGER), + ASN1_EXP(TEST_ASN1_NEST1, expNum, ASN1_INTEGER, 0), + ASN1_EXP_SEQUENCE_OF(TEST_ASN1_NEST1, strList, ASN1_GENERALSTRING, 1), + ASN1_SIMPLE(TEST_ASN1_NEST1, str, ASN1_CHOICE_TEST) +} ASN1_SEQUENCE_END(TEST_ASN1_NEST1) + +IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_NEST1) + +typedef struct { + ASN1_INTEGER* num; + DPP_BOOTSTRAPPING_KEY* key; + TEST_ASN1_NEST1* asn1_obj; +} TEST_ASN1_NEST2; + +ASN1_SEQUENCE(TEST_ASN1_NEST2) = { + ASN1_SIMPLE(TEST_ASN1_NEST2, num, ASN1_INTEGER), + ASN1_SIMPLE(TEST_ASN1_NEST2, key, DPP_BOOTSTRAPPING_KEY), + ASN1_SIMPLE(TEST_ASN1_NEST2, asn1_obj, TEST_ASN1_NEST1) +} ASN1_SEQUENCE_END(TEST_ASN1_NEST2) + +IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_NEST2) +/* End nested objects */ + typedef struct { ASN1_INTEGER *integer; } TEST_ASN1; @@ -42969,16 +43015,13 @@ ASN1_SEQUENCE(TEST_ASN1) = { IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1) -typedef struct { - ASN1_OCTET_STRING *octet_string; -} TEST_FAIL_ASN1; +typedef STACK_OF(ASN1_INTEGER) TEST_ASN1_ITEM; -#define WOLFSSL_ASN1_OCTET_STRING_ASN1 4 -ASN1_SEQUENCE(TEST_FAIL_ASN1) = { - ASN1_SIMPLE(TEST_FAIL_ASN1, octet_string, ASN1_OCTET_STRING), -} ASN1_SEQUENCE_END(TEST_FAIL_ASN1) +ASN1_ITEM_TEMPLATE(TEST_ASN1_ITEM) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, MemName, ASN1_INTEGER) +ASN1_ITEM_TEMPLATE_END(TEST_ASN1_ITEM) -IMPLEMENT_ASN1_FUNCTIONS(TEST_FAIL_ASN1) +IMPLEMENT_ASN1_FUNCTIONS(TEST_ASN1_ITEM) #endif static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) @@ -42991,7 +43034,9 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) EVP_PKEY *key = NULL; size_t len = 0; unsigned char *der = NULL; - DPP_BOOTSTRAPPING_KEY *bootstrap = NULL; + unsigned char *der2 = NULL; + const unsigned char *tmp = NULL; + DPP_BOOTSTRAPPING_KEY *bootstrap = NULL, *bootstrap2 = NULL; const unsigned char *in = ecc_clikey_der_256; WOLFSSL_ASN1_OBJECT* ec_obj = NULL; WOLFSSL_ASN1_OBJECT* group_obj = NULL; @@ -42999,7 +43044,7 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) const EC_POINT *point = NULL; int nid; TEST_ASN1 *test_asn1 = NULL; - TEST_FAIL_ASN1 test_fail_asn1; + TEST_ASN1 *test_asn1_2 = NULL; const unsigned char badObjDer[] = { 0x06, 0x00 }; const unsigned char goodObjDer[] = { @@ -43012,9 +43057,9 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) ExpectNotNull(bootstrap = DPP_BOOTSTRAPPING_KEY_new()); der = NULL; - ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(NULL, &der), 0); - ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, NULL), 0); - ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 0); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(NULL, &der), -1); + ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, NULL), -1); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), -1); ExpectNotNull(key = d2i_PrivateKey(EVP_PKEY_EC, NULL, &in, (long)sizeof_ecc_clikey_der_256)); @@ -43067,13 +43112,19 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) ExpectIntGT(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, NULL), 0); der = NULL; - ExpectIntGT(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 0); - ExpectIntGT(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 0); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 49); + tmp = der; + ExpectNotNull(d2i_DPP_BOOTSTRAPPING_KEY(&bootstrap2, &tmp, 49)); + der2 = NULL; + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap2, &der2), 49); + ExpectBufEQ(der, der2, 49); XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + XFREE(der2, NULL, DYNAMIC_TYPE_ASN1); EVP_PKEY_free(key); EC_KEY_free(eckey); DPP_BOOTSTRAPPING_KEY_free(bootstrap); + DPP_BOOTSTRAPPING_KEY_free(bootstrap2); bootstrap = NULL; DPP_BOOTSTRAPPING_KEY_free(NULL); @@ -43097,7 +43148,7 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) } /* Encode with bad OBJECT_ID. */ der = NULL; - ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 0); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), -1); /* Fix OBJECT_ID and encode with empty BIT_STRING. */ if (EXPECT_SUCCESS()) { @@ -43107,7 +43158,7 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) } der = NULL; ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, &der), 16); - ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, &emptyTemplate), 0); + ExpectIntEQ(wolfSSL_ASN1_item_i2d(bootstrap, &der, &emptyTemplate), -1); XFREE(der, NULL, DYNAMIC_TYPE_ASN1); DPP_BOOTSTRAPPING_KEY_free(bootstrap); @@ -43116,24 +43167,223 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) der = NULL; ExpectIntEQ(ASN1_INTEGER_set(test_asn1->integer, 100), 1); ExpectIntEQ(i2d_TEST_ASN1(test_asn1, &der), 5); + tmp = der; + ExpectNotNull(d2i_TEST_ASN1(&test_asn1_2, &tmp, 5)); + der2 = NULL; + ExpectIntEQ(i2d_TEST_ASN1(test_asn1_2, &der2), 5); + ExpectBufEQ(der, der2, 5); XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + XFREE(der2, NULL, DYNAMIC_TYPE_ASN1); TEST_ASN1_free(test_asn1); + TEST_ASN1_free(test_asn1_2); /* Test integer cases. */ ExpectNull(wolfSSL_ASN1_item_new(NULL)); TEST_ASN1_free(NULL); - /* Test error cases. */ - ExpectNull(TEST_FAIL_ASN1_new()); - ExpectNull(wolfSSL_ASN1_item_new(NULL)); - TEST_FAIL_ASN1_free(NULL); - XMEMSET(&test_fail_asn1, 0, sizeof(TEST_FAIL_ASN1)); - ExpectIntEQ(i2d_TEST_FAIL_ASN1(&test_fail_asn1, &der), 0); + /* Test nested asn1 objects */ + { + TEST_ASN1_NEST2 *nested_asn1 = NULL; + TEST_ASN1_NEST2 *nested_asn1_2 = NULL; + int i; + + ExpectNotNull(nested_asn1 = TEST_ASN1_NEST2_new()); + /* Populate nested_asn1 with some random data */ + /* nested_asn1->num */ + ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->num, 30003), 1); + /* nested_asn1->key */ + ec_obj = OBJ_nid2obj(EVP_PKEY_EC); + group_obj = OBJ_nid2obj(NID_secp256k1); + ExpectIntEQ(X509_ALGOR_set0(nested_asn1->key->alg, ec_obj, + V_ASN1_OBJECT, group_obj), 1); + ec_obj = NULL; + group_obj = NULL; + ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->key->pub_key, 50, 1), + 1); + /* nested_asn1->asn1_obj->key */ + ec_obj = OBJ_nid2obj(EVP_PKEY_EC); + group_obj = OBJ_nid2obj(NID_secp256k1); + ExpectIntEQ(X509_ALGOR_set0(nested_asn1->asn1_obj->key->alg, ec_obj, + V_ASN1_OBJECT, group_obj), 1); + ec_obj = NULL; + group_obj = NULL; + ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->asn1_obj->key->pub_key, + 500, 1), 1); + /* nested_asn1->asn1_obj->asnNum */ + ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->asn1_obj->asnNum, 666666), 1); + /* nested_asn1->asn1_obj->expNum */ + ExpectIntEQ(ASN1_INTEGER_set(nested_asn1->asn1_obj->expNum, 22222), 1); + /* nested_asn1->asn1_obj->strList */ + for (i = 10; i >= 0; i--) { + ASN1_GENERALSTRING* genStr; + char fmtStr[20]; + + ExpectIntGT(snprintf(fmtStr, sizeof(fmtStr), "Bonjour #%d", i), 0); + ExpectNotNull(genStr = ASN1_GENERALSTRING_new()); + ExpectIntEQ(ASN1_GENERALSTRING_set(genStr, fmtStr, -1), 1); + ExpectIntEQ( + sk_ASN1_GENERALSTRING_push(nested_asn1->asn1_obj->strList, + genStr), 1); + } + /* nested_asn1->asn1_obj->str */ + ExpectNotNull(nested_asn1->asn1_obj->str->d.str2 + = ASN1_BIT_STRING_new()); + ExpectIntEQ(ASN1_BIT_STRING_set_bit(nested_asn1->asn1_obj->str->d.str2, + 150, 1), 1); + nested_asn1->asn1_obj->str->type = 2; + + der = NULL; + ExpectIntEQ(i2d_TEST_ASN1_NEST2(nested_asn1, &der), 285); + tmp = der; + ExpectNotNull(d2i_TEST_ASN1_NEST2(&nested_asn1_2, &tmp, 285)); + der2 = NULL; + ExpectIntEQ(i2d_TEST_ASN1_NEST2(nested_asn1_2, &der2), 285); + ExpectBufEQ(der, der2, 285); + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + XFREE(der2, NULL, DYNAMIC_TYPE_ASN1); + + TEST_ASN1_NEST2_free(nested_asn1); + TEST_ASN1_NEST2_free(nested_asn1_2); + } + + /* Test ASN1_ITEM_TEMPLATE */ + { + TEST_ASN1_ITEM* asn1_item = NULL; + TEST_ASN1_ITEM* asn1_item2 = NULL; + int i; + + ExpectNotNull(asn1_item = TEST_ASN1_ITEM_new()); + for (i = 0; i < 11; i++) { + ASN1_INTEGER* asn1_num; + + ExpectNotNull(asn1_num = ASN1_INTEGER_new()); + ExpectIntEQ(ASN1_INTEGER_set(asn1_num, i), 1); + ExpectIntEQ(wolfSSL_sk_insert(asn1_item, asn1_num, -1), 1); + } + + der = NULL; + ExpectIntEQ(i2d_TEST_ASN1_ITEM(asn1_item, &der), 35); + tmp = der; + ExpectNotNull(d2i_TEST_ASN1_ITEM(&asn1_item2, &tmp, 35)); + der2 = NULL; + ExpectIntEQ(i2d_TEST_ASN1_ITEM(asn1_item2, &der2), 35); + ExpectBufEQ(der, der2, 35); + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + XFREE(der2, NULL, DYNAMIC_TYPE_ASN1); + + TEST_ASN1_ITEM_free(asn1_item); + TEST_ASN1_ITEM_free(asn1_item2); + } + #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ #endif /* OPENSSL_ALL && HAVE_ECC && USE_CERT_BUFFERS_256 */ return EXPECT_RESULT(); } +static int test_wolfSSL_i2d_ASN1_TYPE(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) + /* Taken from one of sssd's certs othernames */ + unsigned char str_bin[] = { + 0x04, 0x10, 0xa4, 0x9b, 0xc8, 0xf4, 0x85, 0x8e, 0x89, 0x4d, 0x85, 0x8d, + 0x27, 0xbd, 0x63, 0xaa, 0x93, 0x93 + }; + ASN1_TYPE* asn1type = NULL; + unsigned char* der = NULL; + + /* Create ASN1_TYPE manually as we don't have a d2i version yet */ + { + ASN1_STRING* str = NULL; + ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_SEQUENCE)); + ExpectIntEQ(ASN1_STRING_set(str, str_bin, sizeof(str_bin)), 1); + ExpectNotNull(asn1type = ASN1_TYPE_new()); + ASN1_TYPE_set(asn1type, V_ASN1_SEQUENCE, str); + } + + ExpectIntEQ(i2d_ASN1_TYPE(asn1type, NULL), sizeof(str_bin)); + ExpectIntEQ(i2d_ASN1_TYPE(asn1type, &der), sizeof(str_bin)); + ExpectBufEQ(der, str_bin, sizeof(str_bin)); + + ASN1_TYPE_free(asn1type); + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_i2d_ASN1_SEQUENCE(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) + /* Taken from one of sssd's certs othernames */ + unsigned char str_bin[] = { + 0x04, 0x10, 0xa4, 0x9b, 0xc8, 0xf4, 0x85, 0x8e, 0x89, 0x4d, 0x85, 0x8d, + 0x27, 0xbd, 0x63, 0xaa, 0x93, 0x93 + }; + ASN1_STRING* str = NULL; + unsigned char* der = NULL; + + ExpectNotNull(str = ASN1_STRING_type_new(V_ASN1_SEQUENCE)); + ExpectIntEQ(ASN1_STRING_set(str, str_bin, sizeof(str_bin)), 1); + ExpectIntEQ(i2d_ASN1_SEQUENCE(str, NULL), sizeof(str_bin)); + ExpectIntEQ(i2d_ASN1_SEQUENCE(str, &der), sizeof(str_bin)); + + ASN1_STRING_free(str); + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); +#endif + return EXPECT_RESULT(); +} + +static int test_ASN1_strings(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) + char text[] = "\0\0test string"; + unsigned char* der = NULL; + ASN1_STRING* str = NULL; + + /* Set the length byte */ + text[1] = XSTRLEN(text + 2); + + /* GENERALSTRING */ + { + const unsigned char* p = (const unsigned char*)text; + text[0] = ASN_GENERALSTRING; + ExpectNotNull(d2i_ASN1_GENERALSTRING(&str, &p, sizeof(text))); + ExpectIntEQ(i2d_ASN1_GENERALSTRING(str, &der), 13); + ASN1_STRING_free(str); + str = NULL; + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + der = NULL; + } + + /* OCTET_STRING */ + { + const unsigned char* p = (const unsigned char*)text; + text[0] = ASN_OCTET_STRING; + ExpectNotNull(d2i_ASN1_OCTET_STRING(&str, &p, sizeof(text))); + ExpectIntEQ(i2d_ASN1_OCTET_STRING(str, &der), 13); + ASN1_STRING_free(str); + str = NULL; + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + der = NULL; + } + + /* UTF8STRING */ + { + const unsigned char* p = (const unsigned char*)text; + text[0] = ASN_UTF8STRING; + ExpectNotNull(d2i_ASN1_UTF8STRING(&str, &p, sizeof(text))); + ExpectIntEQ(i2d_ASN1_UTF8STRING(str, &der), 13); + ASN1_STRING_free(str); + str = NULL; + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); + der = NULL; + } + +#endif + return EXPECT_RESULT(); +} static int test_wolfSSL_lhash(void) { @@ -48954,15 +49204,19 @@ static int test_X509_STORE_get0_objects(void) switch (X509_OBJECT_get_type(obj)) { case X509_LU_X509: { - WOLFSSL_X509* x509; + X509* x509 = NULL; + X509_NAME *subj_name = NULL; ExpectNotNull(x509 = X509_OBJECT_get0_X509(obj)); ExpectIntEQ(X509_STORE_add_cert(store_cpy, x509), WOLFSSL_SUCCESS); + ExpectNotNull(subj_name = X509_get_subject_name(x509)); + ExpectPtrEq(obj, X509_OBJECT_retrieve_by_subject(objs, X509_LU_X509, + subj_name)); break; } case X509_LU_CRL: #ifdef HAVE_CRL { - WOLFSSL_CRL* crl = NULL; + X509_CRL* crl = NULL; ExpectNotNull(crl = X509_OBJECT_get0_X509_CRL(obj)); ExpectIntEQ(X509_STORE_add_crl(store_cpy, crl), WOLFSSL_SUCCESS); break; @@ -50760,8 +51014,8 @@ static int test_wolfSSL_BIO(void) ExpectIntEQ(BIO_nread(bio3, &bufPt, 10), 0); /* test wrap around... */ - ExpectIntEQ(BIO_reset(bio1), 0); - ExpectIntEQ(BIO_reset(bio3), 0); + ExpectIntEQ(BIO_reset(bio1), 1); + ExpectIntEQ(BIO_reset(bio3), 1); /* fill write buffer, read only small amount then write again */ ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20); @@ -50803,7 +51057,7 @@ static int test_wolfSSL_BIO(void) ExpectNotNull(XMEMCPY(bufPt, buff, 20)); /* test reset on data in bio1 write buffer */ - ExpectIntEQ(BIO_reset(bio1), 0); + ExpectIntEQ(BIO_reset(bio1), 1); ExpectIntEQ((int)BIO_ctrl_pending(bio3), 0); ExpectIntEQ(BIO_nread(bio3, &bufPt, 3), 0); ExpectIntEQ(BIO_nwrite(bio1, &bufPt, 20), 20); @@ -50874,7 +51128,7 @@ static int test_wolfSSL_BIO(void) ExpectIntEQ(BIO_tell(f_bio2),sizeof(cert) + sizeof(msg)); ExpectIntEQ((int)BIO_get_fp(f_bio2, &f2), WOLFSSL_SUCCESS); - ExpectIntEQ(BIO_reset(f_bio2), 0); + ExpectIntEQ(BIO_reset(f_bio2), 1); ExpectIntEQ(BIO_tell(NULL),-1); ExpectIntEQ(BIO_tell(f_bio2),0); ExpectIntEQ(BIO_seek(f_bio2, 4), 0); @@ -52078,8 +52332,11 @@ static int test_wolfSSL_X509_ALGOR_get0(void) X509* x509 = NULL; const ASN1_OBJECT* obj = NULL; const X509_ALGOR* alg = NULL; + X509_ALGOR* alg2 = NULL; int pptype = 0; const void *ppval = NULL; + byte* der = NULL; + const byte* tmp = NULL; ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(cliCertFile, SSL_FILETYPE_PEM)); @@ -52097,7 +52354,13 @@ static int test_wolfSSL_X509_ALGOR_get0(void) /* Make sure NID of X509_ALGOR is Sha256 with RSA */ ExpectIntEQ(OBJ_obj2nid(obj), NID_sha256WithRSAEncryption); + ExpectIntEQ(i2d_X509_ALGOR(alg, &der), 15); + tmp = der; + ExpectNotNull(d2i_X509_ALGOR(&alg2, &tmp, 15)); + + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); X509_free(x509); + X509_ALGOR_free(alg2); #endif return EXPECT_RESULT(); } @@ -57480,7 +57743,7 @@ static int test_wolfSSL_BIO_reset(void) ExpectIntEQ(BIO_write(bio, "WriteToReadonly", 15), 0); ExpectIntEQ(BIO_read(bio, buf, 16), -1); XMEMSET(buf, 0, 16); - ExpectIntEQ(BIO_reset(bio), 0); + ExpectIntEQ(BIO_reset(bio), 1); ExpectIntEQ(BIO_read(bio, buf, 16), 16); ExpectIntEQ(XMEMCMP(buf, "secure your data", 16), 0); BIO_free(bio); @@ -59819,6 +60082,26 @@ static int test_wolfSSL_make_cert(void) return EXPECT_RESULT(); } +static int test_x509_get_key_id(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) + X509 *x509 = NULL; + const ASN1_STRING* str = NULL; + byte* keyId = NULL; + + ExpectNotNull(x509 = X509_load_certificate_file(cliCertFile, + WOLFSSL_FILETYPE_PEM)); + ExpectNotNull(str = X509_get0_subject_key_id(x509)); + ExpectNotNull(keyId = wolfSSL_X509_get_subjectKeyID(x509, NULL, NULL)); + ExpectBufEQ(keyId, ASN1_STRING_data((ASN1_STRING*)str), + ASN1_STRING_length(str)); + + X509_free(x509); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_X509_get_version(void) { @@ -63105,6 +63388,106 @@ static int test_wolfSSL_OCSP_resp_get0(void) return EXPECT_RESULT(); } +static int test_wolfSSL_OCSP_parse_url(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) +#define CK_OPU_OK(u, h, po, pa, s) do { \ + char* host = NULL; \ + char* port = NULL; \ + char* path = NULL; \ + int isSsl = 0; \ + ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 1); \ + ExpectStrEQ(host, h); \ + ExpectStrEQ(port, po); \ + ExpectStrEQ(path, pa); \ + ExpectIntEQ(isSsl, s); \ + XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \ + XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \ + XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \ +} while(0) + +#define CK_OPU_FAIL(u) do { \ + char* host = NULL; \ + char* port = NULL; \ + char* path = NULL; \ + int isSsl = 0; \ + ExpectIntEQ(OCSP_parse_url(u, &host, &port, &path, &isSsl), 0); \ + XFREE(host, NULL, DYNAMIC_TYPE_OPENSSL); \ + XFREE(port, NULL, DYNAMIC_TYPE_OPENSSL); \ + XFREE(path, NULL, DYNAMIC_TYPE_OPENSSL); \ +} while(0) + + CK_OPU_OK("http://localhost", "localhost", "80", "/", 0); + CK_OPU_OK("https://wolfssl.com", "wolfssl.com", "443", "/", 1); + CK_OPU_OK("https://www.wolfssl.com/fips-140-3-announcement-to-the-world/", + "www.wolfssl.com", "443", "/fips-140-3-announcement-to-the-world/", 1); + CK_OPU_OK("http://localhost:1234", "localhost", "1234", "/", 0); + CK_OPU_OK("https://localhost:1234", "localhost", "1234", "/", 1); + + CK_OPU_FAIL("ftp://localhost"); + CK_OPU_FAIL("http//localhost"); + CK_OPU_FAIL("http:/localhost"); + CK_OPU_FAIL("https://localhost/path:1234"); +#endif + return EXPECT_RESULT(); +} + +static int test_wolfSSL_OCSP_REQ_CTX(void) +{ + EXPECT_DECLS; + OCSP_REQ_CTX *ctx = NULL; + OCSP_REQUEST *req = NULL; + OCSP_CERTID *cid = NULL; + OCSP_RESPONSE *rsp = NULL; + BIO* bio1 = NULL; + BIO* bio2 = NULL; + X509* cert = NULL; + X509 *issuer = NULL; + X509_LOOKUP *lookup = NULL; + X509_STORE *store = NULL; + STACK_OF(X509_OBJECT) *str_objs = NULL; + X509_OBJECT *x509_obj = NULL; + + ExpectNotNull(bio1 = BIO_new(BIO_s_bio())); + ExpectNotNull(bio2 = BIO_new(BIO_s_bio())); + ExpectIntEQ(BIO_make_bio_pair(bio1, bio2), WOLFSSL_SUCCESS); + + /* Load the leaf cert */ + ExpectNotNull(cert = wolfSSL_X509_load_certificate_file( + "certs/ocsp/server1-cert.pem", WOLFSSL_FILETYPE_PEM)); + + ExpectNotNull(store = X509_STORE_new()); + ExpectNotNull(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())); + ExpectIntEQ(X509_LOOKUP_load_file(lookup, "certs/ocsp/server1-cert.pem", + X509_FILETYPE_PEM), 1); + ExpectNotNull(str_objs = X509_STORE_get0_objects(store)); + ExpectNotNull(x509_obj = X509_OBJECT_retrieve_by_subject(str_objs, + X509_LU_X509, X509_get_issuer_name(cert))); + ExpectNotNull(issuer = X509_OBJECT_get0_X509(x509_obj)); + + ExpectNotNull(req = OCSP_REQUEST_new()); + ExpectNotNull(cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer)); + ExpectNotNull(OCSP_request_add0_id(req, cid)); + ExpectIntEQ(OCSP_request_add1_nonce(req, NULL, -1), 1); + + ExpectNotNull(ctx = OCSP_sendreq_new(bio1, "/", NULL, -1)); + ExpectIntEQ(OCSP_REQ_CTX_add1_header(ctx, "Host", "127.0.0.1"), + 1); + ExpectIntEQ(OCSP_REQ_CTX_set1_req(ctx, req), 1); + ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), 0); /* not implemented yet */ + + OCSP_REQ_CTX_free(ctx); + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(rsp); + BIO_free(bio1); + BIO_free(bio2); + X509_free(cert); + X509_STORE_free(store); + + return EXPECT_RESULT(); +} + static int test_wolfSSL_EVP_PKEY_derive(void) { EXPECT_DECLS; @@ -69302,12 +69685,18 @@ static int test_wolfSSL_X509_STORE_set_get_crl_ctx_ready2(WOLFSSL_CTX* ctx) #endif X509_STORE_set_verify_cb(cert_store, test_wolfSSL_X509_STORE_set_get_crl_verify); - ExpectNotNull(param = X509_STORE_get0_param(cert_store)); + ExpectNotNull(X509_STORE_get0_param(cert_store)); + ExpectNotNull(param = X509_VERIFY_PARAM_new()); + ExpectIntEQ(X509_VERIFY_PARAM_inherit(param, + X509_STORE_get0_param(cert_store)), 1); ExpectIntEQ(X509_VERIFY_PARAM_set_flags( param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + ExpectIntEQ(X509_STORE_set1_param(cert_store, param), 1); ExpectIntEQ(X509_STORE_set_flags(cert_store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL), 1); + + X509_VERIFY_PARAM_free(param); return EXPECT_RESULT(); } #endif @@ -83376,6 +83765,9 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_ASN1_UTCTIME_print), TEST_DECL(test_wolfSSL_ASN1_TYPE), TEST_DECL(test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS), + TEST_DECL(test_wolfSSL_i2d_ASN1_TYPE), + TEST_DECL(test_wolfSSL_i2d_ASN1_SEQUENCE), + TEST_DECL(test_ASN1_strings), TEST_DECL(test_wolfSSL_lhash), @@ -83633,6 +84025,7 @@ TEST_CASE testCases[] = { #endif TEST_DECL(test_wolfSSL_X509_CA_num), + TEST_DECL(test_x509_get_key_id), TEST_DECL(test_wolfSSL_X509_get_version), #ifndef NO_BIO TEST_DECL(test_wolfSSL_X509_print), @@ -83770,6 +84163,8 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_OCSP_single_get0_status), TEST_DECL(test_wolfSSL_OCSP_resp_count), TEST_DECL(test_wolfSSL_OCSP_resp_get0), + TEST_DECL(test_wolfSSL_OCSP_parse_url), + TEST_DECL(test_wolfSSL_OCSP_REQ_CTX), TEST_DECL(test_wolfSSL_PEM_read), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 16d773c5e7..69434578e8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1092,7 +1092,7 @@ static int GetASN_Integer(const byte* input, word32 idx, int length, * @return 0 on success. * @return ASN_PARSE_E when unused bits is invalid. */ -static int GetASN_BitString(const byte* input, word32 idx, int length) +int GetASN_BitString(const byte* input, word32 idx, int length) { #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)) @@ -2458,7 +2458,7 @@ static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, * @return BUFFER_E when there is not enough data to parse. * @return ASN_PARSE_E when the expected tag is not found or length is invalid. */ -static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len, +int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len, word32 maxIdx) { return GetASNHeader_ex(input, tag, inOutIdx, len, maxIdx, 1); @@ -13500,27 +13500,24 @@ static int AddDNSEntryToList(DNS_entry** lst, DNS_entry* entry) * @return 0 on success. * @return MEMORY_E when dynamic memory allocation fails. */ -static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen, +static int SetDNSEntry(void* heap, const char* str, int strLen, int type, DNS_entry** entries) { DNS_entry* dnsEntry; int ret = 0; - /* Only used for heap. */ - (void)cert; - /* TODO: consider one malloc. */ /* Allocate DNS Entry object. */ - dnsEntry = AltNameNew(cert->heap); + dnsEntry = AltNameNew(heap); if (dnsEntry == NULL) { ret = MEMORY_E; } if (ret == 0) { /* Allocate DNS Entry name - length of string plus 1 for NUL. */ - dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, cert->heap, + dnsEntry->name = (char*)XMALLOC((size_t)strLen + 1, heap, DYNAMIC_TYPE_ALTNAME); if (dnsEntry->name == NULL) { - XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); + XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME); ret = MEMORY_E; } } @@ -13534,18 +13531,18 @@ static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen, #if defined(OPENSSL_ALL) /* store registeredID as a string */ if (type == ASN_RID_TYPE) { - if ((ret = GenerateDNSEntryRIDString(dnsEntry, cert->heap)) != 0) { - XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME); - XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); + if ((ret = GenerateDNSEntryRIDString(dnsEntry, heap)) != 0) { + XFREE(dnsEntry->name, heap, DYNAMIC_TYPE_ALTNAME); + XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME); } } #endif #if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME) /* store IP addresses as a string */ if (type == ASN_IP_TYPE) { - if ((ret = GenerateDNSEntryIPString(dnsEntry, cert->heap)) != 0) { - XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME); - XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); + if ((ret = GenerateDNSEntryIPString(dnsEntry, heap)) != 0) { + XFREE(dnsEntry->name, heap, DYNAMIC_TYPE_ALTNAME); + XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME); } } } @@ -15843,7 +15840,7 @@ word32 SetLengthEx(word32 length, byte* output, byte isIndef) * @param [out] output Buffer to encode into. * @return Number of bytes encoded. */ -static word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef) +word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef) { if (output) { /* Encode tag first. */ @@ -18153,7 +18150,7 @@ static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid) } if (ret == 0) { - ret = SetDNSEntry(cert, buf, (int)bufLen, ASN_OTHER_TYPE, &entry); + ret = SetDNSEntry(cert->heap, buf, (int)bufLen, ASN_OTHER_TYPE, &entry); if (ret == 0) { #ifdef WOLFSSL_FPKI entry->oidSum = oid; @@ -18180,10 +18177,12 @@ static int DecodeOtherHelper(ASNGetData* dataASN, DecodedCert* cert, int oid) * @return BUFFER_E when data in buffer is too small. */ static int DecodeOtherName(DecodedCert* cert, const byte* input, - word32* inOutIdx, word32 maxIdx) + word32* inOutIdx, int len) { DECL_ASNGETDATA(dataASN, otherNameASN_Length); int ret = 0; + word32 maxIdx = *inOutIdx + (word32)len; + const char* name = (const char*)input + *inOutIdx; CALLOC_ASNGETDATA(dataASN, otherNameASN_Length, ret, cert->heap); @@ -18212,7 +18211,9 @@ static int DecodeOtherName(DecodedCert* cert, const byte* input, (int)dataASN[OTHERNAMEASN_IDX_TYPEID].data.oid.sum); break; default: - WOLFSSL_MSG("\tunsupported OID skipping"); + WOLFSSL_MSG("\tadding unsupported OID"); + ret = SetDNSEntry(cert->heap, name, len, ASN_OTHER_TYPE, + &cert->altNames); break; } } @@ -18244,7 +18245,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, /* GeneralName choice: dnsName */ if (tag == (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) { - ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_DNS_TYPE, + ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len, ASN_DNS_TYPE, &cert->altNames); if (ret == 0) { idx += (word32)len; @@ -18263,7 +18264,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, return ASN_PARSE_E; } - ret = SetDNSEntry(cert, (const char*)(input + idxDir), strLen, + ret = SetDNSEntry(cert->heap, (const char*)(input + idxDir), strLen, ASN_DIR_TYPE, &cert->altDirNames); if (ret == 0) { idx += (word32)len; @@ -18271,7 +18272,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, } /* GeneralName choice: rfc822Name */ else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RFC822_TYPE)) { - ret = SetDNSEntry(cert, (const char*)(input + idx), len, + ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len, ASN_RFC822_TYPE, &cert->altEmailNames); if (ret == 0) { idx += (word32)len; @@ -18319,7 +18320,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, } #endif - ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_URI_TYPE, + ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len, ASN_URI_TYPE, &cert->altNames); if (ret == 0) { idx += (word32)len; @@ -18329,7 +18330,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, defined(WOLFSSL_IP_ALT_NAME) /* GeneralName choice: iPAddress */ else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_IP_TYPE)) { - ret = SetDNSEntry(cert, (const char*)(input + idx), len, ASN_IP_TYPE, + ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len, ASN_IP_TYPE, &cert->altNames); if (ret == 0) { idx += (word32)len; @@ -18340,7 +18341,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, #ifdef OPENSSL_ALL /* GeneralName choice: registeredID */ else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_RID_TYPE)) { - ret = SetDNSEntry(cert, (const char*)(input + idx), len, + ret = SetDNSEntry(cert->heap, (const char*)(input + idx), len, ASN_RID_TYPE, &cert->altNames); if (ret == 0) { idx += (word32)len; @@ -18352,7 +18353,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, /* GeneralName choice: otherName */ else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_OTHER_TYPE)) { /* TODO: test data for code path */ - ret = DecodeOtherName(cert, input, &idx, idx + (word32)len); + ret = DecodeOtherName(cert, input, &idx, len); } #endif /* GeneralName choice: dNSName, x400Address, ediPartyName */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index b53d6eca97..a09e86de49 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3957,7 +3957,7 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, (void)siglen; WOLFSSL_ENTER("EVP_SignFinal"); - if (ctx == NULL) + if (ctx == NULL || sigret == NULL || siglen == NULL || pkey == NULL) return WOLFSSL_FAILURE; ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize); @@ -3995,9 +3995,23 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, return WOLFSSL_SUCCESS; } #endif - case EVP_PKEY_EC: - WOLFSSL_MSG("not implemented"); - FALL_THROUGH; +#ifdef HAVE_ECC + case EVP_PKEY_EC: { + WOLFSSL_ECDSA_SIG *ecdsaSig = wolfSSL_ECDSA_do_sign(md, (int)mdsize, + pkey->ecc); + if (ecdsaSig == NULL) + return WOLFSSL_FAILURE; + ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); + if (ret <= 0 || ret > (int)*siglen) + return WOLFSSL_FAILURE; + ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sigret); + wolfSSL_ECDSA_SIG_free(ecdsaSig); + if (ret <= 0 || ret > (int)*siglen) + return WOLFSSL_FAILURE; + *siglen = (size_t)ret; + return WOLFSSL_SUCCESS; + } +#endif default: break; } @@ -4055,7 +4069,8 @@ int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, if (ctx == NULL) return WOLFSSL_FAILURE; WOLFSSL_ENTER("EVP_VerifyFinal"); ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize); - if (ret <= 0) return ret; + if (ret <= 0) + return ret; (void)sig; (void)siglen; @@ -4072,9 +4087,19 @@ int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, (unsigned int)siglen, pkey->rsa); } #endif /* NO_RSA */ - +#ifdef HAVE_ECC + case EVP_PKEY_EC: { + WOLFSSL_ECDSA_SIG *ecdsaSig = wolfSSL_d2i_ECDSA_SIG( + NULL, (const unsigned char **)&sig, (long)siglen); + if (ecdsaSig == NULL) + return WOLFSSL_FAILURE; + ret = wolfSSL_ECDSA_do_verify(md, (int)mdsize, ecdsaSig, + pkey->ecc); + wolfSSL_ECDSA_SIG_free(ecdsaSig); + return ret; + } +#endif case EVP_PKEY_DSA: - case EVP_PKEY_EC: WOLFSSL_MSG("not implemented"); FALL_THROUGH; default: @@ -9873,10 +9898,24 @@ static const struct alias { const char *alias; } digest_alias_tbl[] = { - {"MD4", "ssl3-md4"}, - {"MD5", "ssl3-md5"}, - {"SHA1", "ssl3-sha1"}, + {"MD4", "md4"}, + {"MD5", "md5"}, + {"SHA1", "sha1"}, {"SHA1", "SHA"}, + {"SHA224", "sha224"}, + {"SHA256", "sha256"}, + {"SHA384", "sha384"}, + {"SHA512", "sha512"}, + {"SHA512_224", "sha512_224"}, + {"SHA3_224", "sha3_224"}, + {"SHA3_256", "sha3_256"}, + {"SHA3_384", "sha3_384"}, + {"SHA3_512", "sha3_512"}, + {"SM3", "sm3"}, + {"BLAKE2B512", "blake2b512"}, + {"BLAKE2S256", "blake2s256"}, + {"SHAKE128", "shake128"}, + {"SHAKE256", "shake256"}, { NULL, NULL} }; @@ -10205,7 +10244,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) * @param n message digest type name * @return alias name, otherwise NULL */ - static const char* hasAliasName(const char* n) + static const char* getMdAliasName(const char* n) { const char* aliasnm = NULL; @@ -10236,23 +10275,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) { struct do_all_md *md = (struct do_all_md*)arg; - const struct s_ent *ent; - /* sanity check */ if (md == NULL || nm == NULL || md->fn == NULL || nm->type != WOLFSSL_OBJ_NAME_TYPE_MD_METH) return; - /* loop all md */ - for (ent = md_tbl; ent->name != NULL; ent++){ - /* check if the md has alias */ - if(hasAliasName(ent->name) != NULL) { - md->fn(NULL, ent->name, ent->name, md->arg); - } - else { - md->fn(ent->name, ent->name, NULL, md->arg); - } - } + if (nm->alias) + md->fn(NULL, nm->name, nm->data, md->arg); + else + md->fn((const EVP_MD *)nm->data, nm->name, NULL, md->arg); } /* call md_do_all function to do all md algorithm via a callback function @@ -10287,11 +10318,30 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) if (!fn) return; - objnm.type = type; - switch(type) { case WOLFSSL_OBJ_NAME_TYPE_MD_METH: - fn(&objnm, arg); + { + const struct s_ent *ent; + /* loop all md */ + for (ent = md_tbl; ent->name != NULL; ent++){ + XMEMSET(&objnm, 0, sizeof(objnm)); + + /* populate objnm with info about the md */ + objnm.type = WOLFSSL_OBJ_NAME_TYPE_MD_METH; + objnm.name = ent->name; + objnm.data = (const char*) + wolfSSL_EVP_get_digestbyname(ent->name); + fn(&objnm, arg); + + /* check if the md has alias and also call fn with it */ + objnm.name = getMdAliasName(ent->name); + if (objnm.name != NULL) { + objnm.alias |= WOLFSSL_OBJ_NAME_ALIAS; + objnm.data = ent->name; + fn(&objnm, arg); + } + } + } break; case WOLFSSL_OBJ_NAME_TYPE_CIPHER_METH: case WOLFSSL_OBJ_NAME_TYPE_PKEY_METH: diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a119007679..ff6c2cc98c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2045,7 +2045,7 @@ enum Misc { #define WOLFSSL_ASSERT_EQ(x, y) WOLFSSL_ASSERT_TEST(x, y, ==) #define WOLFSSL_ASSERT_SIZEOF_TEST(x, y, op) \ - WOLFSSL_ASSERT_TEST(sizeof((x)), sizeof((y)), op) + WOLFSSL_ASSERT_TEST(sizeof(x), sizeof(y), op) #define WOLFSSL_ASSERT_SIZEOF_GE(x, y) WOLFSSL_ASSERT_SIZEOF_TEST(x, y, >=) @@ -5223,6 +5223,7 @@ struct WOLFSSL_X509 { byte* authKeyId; /* Points into authKeyIdSrc */ byte* authKeyIdSrc; byte* subjKeyId; + WOLFSSL_ASN1_STRING* subjKeyIdStr; byte* extKeyUsageSrc; #ifdef OPENSSL_ALL byte* subjAltNameSrc; @@ -6937,8 +6938,11 @@ WOLFSSL_LOCAL int CreateCookieExt(const WOLFSSL* ssl, byte* hash, WOLFSSL_LOCAL int TranslateErrorToAlert(int err); #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) -void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type); -WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type); +WOLFSSL_LOCAL void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type); +WOLFSSL_LOCAL WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type); + +WOLFSSL_LOCAL int wolfssl_asn1_obj_set(WOLFSSL_ASN1_OBJECT* obj, + const byte* der, word32 len, int addHdr); #endif #ifdef __cplusplus diff --git a/wolfssl/ocsp.h b/wolfssl/ocsp.h index 52ea54b679..869fe0b90e 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -48,6 +48,14 @@ typedef struct OcspEntry WOLFSSL_OCSP_SINGLERESP; typedef struct OcspRequest WOLFSSL_OCSP_ONEREQ; typedef struct OcspRequest WOLFSSL_OCSP_REQUEST; + +typedef struct { + WOLFSSL_BIO *bio; + WOLFSSL_BIO *resp; + byte* buf; + int bufLen; + int state; +} WOLFSSL_OCSP_REQ_CTX; #endif WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm); @@ -132,6 +140,20 @@ WOLFSSL_API int wolfSSL_OCSP_resp_count(WOLFSSL_OCSP_BASICRESP *bs); WOLFSSL_API WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0( WOLFSSL_OCSP_BASICRESP *bs, int idx); +WOLFSSL_API WOLFSSL_OCSP_REQ_CTX* wolfSSL_OCSP_REQ_CTX_new(WOLFSSL_BIO *bio, + int maxline); +WOLFSSL_API void wolfSSL_OCSP_REQ_CTX_free(WOLFSSL_OCSP_REQ_CTX *ctx); +WOLFSSL_API WOLFSSL_OCSP_REQ_CTX *wolfSSL_OCSP_sendreq_new(WOLFSSL_BIO *bio, + const char *path, OcspRequest *req, int maxline); +WOLFSSL_API int wolfSSL_OCSP_REQ_CTX_set1_req(WOLFSSL_OCSP_REQ_CTX *ctx, + OcspRequest *req); +WOLFSSL_API int wolfSSL_OCSP_REQ_CTX_add1_header(WOLFSSL_OCSP_REQ_CTX *ctx, + const char *name, const char *value); +WOLFSSL_API int wolfSSL_OCSP_REQ_CTX_http(WOLFSSL_OCSP_REQ_CTX *ctx, + const char *op, const char *path); +WOLFSSL_API int wolfSSL_OCSP_REQ_CTX_nbio(WOLFSSL_OCSP_REQ_CTX *ctx); +WOLFSSL_API int wolfSSL_OCSP_sendreq_nbio(OcspResponse **presp, + WOLFSSL_OCSP_REQ_CTX *rctx); #endif #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 2c83b9b8c4..43e0e1ffcc 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -38,7 +38,6 @@ #define c2i_ASN1_OBJECT wolfSSL_c2i_ASN1_OBJECT #define V_ASN1_INTEGER 0x02 -#define V_ASN1_OCTET_STRING 0x04 /* tag for ASN1_OCTET_STRING */ #define V_ASN1_NEG 0x100 #define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) #define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) @@ -73,6 +72,8 @@ #define ASN1_TIME_set wolfSSL_ASN1_TIME_set #define V_ASN1_EOC 0 +#define V_ASN1_BOOLEAN 1 +#define V_ASN1_OCTET_STRING 4 #define V_ASN1_NULL 5 #define V_ASN1_OBJECT 6 #define V_ASN1_UTF8STRING 12 @@ -111,6 +112,7 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER *wolfSSL_BN_to_ASN1_INTEGER( const WOLFSSL_BIGNUM *bn, WOLFSSL_ASN1_INTEGER *ai); WOLFSSL_API void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value); +WOLFSSL_API int wolfSSL_ASN1_TYPE_get(const WOLFSSL_ASN1_TYPE *a); WOLFSSL_API int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag, int *cls, long inLen); @@ -122,47 +124,163 @@ WOLFSSL_API WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a /* IMPLEMENT_ASN1_FUNCTIONS is strictly for external use only. Internally * we don't use this. Some projects use OpenSSL to implement ASN1 types and * this section is only to provide those projects with ASN1 functionality. */ -typedef struct { + +typedef void* (*wolfssl_asn1_new)(void); +typedef void (*wolfssl_asn1_free)(void*); +typedef int (*wolfssl_asn1_i2d)(const void*, unsigned char**); +typedef void* (*wolfssl_asn1_d2i)(void**, const byte **, long); + +struct WOLFSSL_ASN1_TEMPLATE { + /* Type functions */ + wolfssl_asn1_new new_func; + wolfssl_asn1_free free_func; + wolfssl_asn1_i2d i2d_func; + wolfssl_asn1_d2i d2i_func; + /* Member info */ size_t offset; /* Offset of this field in structure */ - byte type; /* The type of the member as defined in - * WOLFSSL_ASN1_TYPES */ -} WOLFSSL_ASN1_TEMPLATE; - -typedef struct { - byte type; /* One of the ASN_Tags types */ - const WOLFSSL_ASN1_TEMPLATE *members; /* If SEQUENCE or CHOICE this - * contains the contents */ + /* DER info */ + int tag; + byte first_byte; /* First expected byte. Required for + * IMPLICIT types. */ + byte explicit:1; + byte sequence:1; +}; + +enum WOLFSSL_ASN1_TYPES { + WOLFSSL_ASN1_SEQUENCE = 0, + WOLFSSL_ASN1_CHOICE, + WOLFSSL_ASN1_OBJECT_TYPE, +}; + +struct WOLFSSL_ASN1_ITEM { + enum WOLFSSL_ASN1_TYPES type; + const struct WOLFSSL_ASN1_TEMPLATE* members; /* If SEQUENCE or CHOICE this + * contains the contents */ size_t mcount; /* Number of members if SEQUENCE * or CHOICE */ size_t size; /* Structure size */ -} WOLFSSL_ASN1_ITEM; + size_t toffset; /* Type offset */ +}; -typedef enum { - WOLFSSL_X509_ALGOR_ASN1 = 0, - WOLFSSL_ASN1_BIT_STRING_ASN1, - WOLFSSL_ASN1_INTEGER_ASN1, -} WOLFSSL_ASN1_TYPES; +typedef struct WOLFSSL_ASN1_TEMPLATE WOLFSSL_ASN1_TEMPLATE; +typedef struct WOLFSSL_ASN1_ITEM WOLFSSL_ASN1_ITEM; -#define ASN1_SEQUENCE(type) \ - static const WOLFSSL_ASN1_TEMPLATE type##_member_data[] +static WC_MAYBE_UNUSED const byte ASN1_BIT_STRING_FIRST_BYTE = ASN_BIT_STRING; -#define ASN1_SIMPLE(type, member, member_type) \ - { OFFSETOF(type, member), \ - WOLFSSL_##member_type##_ASN1 } +#define ASN1_TFLG_EXPLICIT (0x1 << 0) +#define ASN1_TFLG_SEQUENCE_OF (0x1 << 1) +#define ASN1_TFLG_IMPTAG (0x1 << 2) +#define ASN1_TFLG_EXPTAG (0x1 << 3) + +#define ASN1_TFLG_TAG_MASK (ASN1_TFLG_IMPTAG|ASN1_TFLG_EXPTAG) + +#define ASN1_ITEM_TEMPLATE(mtype) \ + static const WOLFSSL_ASN1_TEMPLATE mtype##_member_data -#define ASN1_SEQUENCE_END(type) \ +#define ASN1_ITEM_TEMPLATE_END(mtype) \ ; \ - const WOLFSSL_ASN1_ITEM type##_template_data = { \ - ASN_SEQUENCE, \ - type##_member_data, \ - sizeof(type##_member_data) / sizeof(WOLFSSL_ASN1_TEMPLATE), \ - sizeof(type) \ + const WOLFSSL_ASN1_ITEM mtype##_template_data = { \ + WOLFSSL_ASN1_OBJECT_TYPE, \ + &mtype##_member_data, \ + 1, \ + 0, \ + 0 \ }; +#define ASN1_SEQUENCE(mtype) \ + static const WOLFSSL_ASN1_TEMPLATE mtype##_member_data[] + +#define ASN1_SEQUENCE_END(mtype) \ + ; \ + const WOLFSSL_ASN1_ITEM mtype##_template_data = { \ + WOLFSSL_ASN1_SEQUENCE, \ + mtype##_member_data, \ + sizeof(mtype##_member_data) / sizeof(WOLFSSL_ASN1_TEMPLATE), \ + sizeof(mtype), \ + 0 \ + }; \ + static WC_MAYBE_UNUSED const byte mtype##_FIRST_BYTE = \ + ASN_CONSTRUCTED | ASN_SEQUENCE; + +/* This is what a ASN1_CHOICE type should look like + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + */ + +#define ASN1_CHOICE(mtype) \ + static const WOLFSSL_ASN1_TEMPLATE mtype##_member_data[] + +#define ASN1_CHOICE_END(mtype) \ + ; \ + const WOLFSSL_ASN1_ITEM mtype##_template_data = { \ + WOLFSSL_ASN1_CHOICE, \ + mtype##_member_data, \ + sizeof(mtype##_member_data) / sizeof(WOLFSSL_ASN1_TEMPLATE), \ + sizeof(mtype) ,\ + OFFSETOF(mtype, type) \ + }; + +#define ASN1_TYPE(type, member, tag, first_byte, exp, seq) \ + OFFSETOF(type, member), tag, first_byte, exp, seq + +/* Function callbacks need to be defined immediately otherwise we will + * incorrectly expand the type. Ex: ASN1_INTEGER -> WOLFSSL_ASN1_INTEGER */ + +#define ASN1_SIMPLE(type, member, member_type) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + ASN1_TYPE(type, member, -1, 0, 0, 0) } + +#define ASN1_IMP(type, member, member_type, tag) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + ASN1_TYPE(type, member, tag, member_type##_FIRST_BYTE, 0, 0) } + +#define ASN1_EXP(type, member, member_type, tag) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + ASN1_TYPE(type, member, tag, 0, 1, 0) } + +#define ASN1_SEQUENCE_OF(type, member, member_type) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + ASN1_TYPE(type, member, -1, 0, 0, 1) } + +#define ASN1_EXP_SEQUENCE_OF(type, member, member_type, tag) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + ASN1_TYPE(type, member, tag, 0, 1, 1) } + +#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, member_type) \ + { (wolfssl_asn1_new)member_type##_new, \ + (wolfssl_asn1_free)member_type##_free, \ + (wolfssl_asn1_i2d)i2d_##member_type, \ + (wolfssl_asn1_d2i)d2i_##member_type, \ + 0, flags & ASN1_TFLG_TAG_MASK ? tag : -1, 0, \ + !!(flags & ASN1_TFLG_EXPLICIT), !!(ASN1_TFLG_SEQUENCE_OF) } + WOLFSSL_API void *wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM *tpl); -WOLFSSL_API void wolfSSL_ASN1_item_free(void *val, const WOLFSSL_ASN1_ITEM *tpl); +WOLFSSL_API void wolfSSL_ASN1_item_free(void *obj, + const WOLFSSL_ASN1_ITEM *item); WOLFSSL_API int wolfSSL_ASN1_item_i2d(const void *src, byte **dest, const WOLFSSL_ASN1_ITEM *tpl); +WOLFSSL_API void* wolfSSL_ASN1_item_d2i(void** dst, const byte **src, long len, + const WOLFSSL_ASN1_ITEM* item); /* Need function declaration otherwise compiler complains */ /* // NOLINTBEGIN(readability-named-parameter) */ @@ -178,7 +296,13 @@ WOLFSSL_API int wolfSSL_ASN1_item_i2d(const void *src, byte **dest, int i2d_##type(type *src, byte **dest); \ int i2d_##type(type *src, byte **dest) \ { \ - return wolfSSL_ASN1_item_i2d(src, dest, &type##_template_data);\ + return wolfSSL_ASN1_item_i2d(src, dest, &type##_template_data); \ + } \ + type* d2i_##type(type **dst, const byte **src, long len); \ + type* d2i_##type(type **dst, const byte **src, long len) \ + { \ + return wolfSSL_ASN1_item_d2i((void**)dst, src, len, \ + &type##_template_data); \ } /* // NOLINTEND(readability-named-parameter) */ @@ -186,7 +310,9 @@ WOLFSSL_API int wolfSSL_ASN1_item_i2d(const void *src, byte **dest, #define BN_to_ASN1_INTEGER wolfSSL_BN_to_ASN1_INTEGER #define ASN1_TYPE_set wolfSSL_ASN1_TYPE_set +#define ASN1_TYPE_get wolfSSL_ASN1_TYPE_get #define ASN1_TYPE_new wolfSSL_ASN1_TYPE_new #define ASN1_TYPE_free wolfSSL_ASN1_TYPE_free +#define i2d_ASN1_TYPE wolfSSL_i2d_ASN1_TYPE #endif /* WOLFSSL_ASN1_H_ */ diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 319cf3c3bd..39faf95f2c 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -424,6 +424,7 @@ typedef WOLFSSL_EC_KEY_METHOD EC_KEY_METHOD; #define i2d_ECPrivateKey wolfSSL_i2d_ECPrivateKey #define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form #define EC_KEY_get_conv_form wolfSSL_EC_KEY_get_conv_form +#define d2i_ECPKParameters wolfSSL_d2i_ECPKParameters #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex #define EC_POINT_hex2point wolfSSL_EC_POINT_hex2point diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index dee416cd5f..84e0dbb1f3 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -46,6 +46,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/pkcs7.h \ wolfssl/openssl/rand.h \ wolfssl/openssl/rsa.h \ + wolfssl/openssl/safestack.h \ wolfssl/openssl/sha.h \ wolfssl/openssl/sha3.h \ wolfssl/openssl/srp.h \ diff --git a/wolfssl/openssl/ocsp.h b/wolfssl/openssl/ocsp.h index ac0e44f911..9696173190 100644 --- a/wolfssl/openssl/ocsp.h +++ b/wolfssl/openssl/ocsp.h @@ -27,12 +27,13 @@ #ifdef HAVE_OCSP #include -#define OCSP_REQUEST OcspRequest -#define OCSP_RESPONSE OcspResponse -#define OCSP_BASICRESP WOLFSSL_OCSP_BASICRESP -#define OCSP_SINGLERESP WOLFSSL_OCSP_SINGLERESP -#define OCSP_CERTID WOLFSSL_OCSP_CERTID -#define OCSP_ONEREQ WOLFSSL_OCSP_ONEREQ +typedef OcspRequest OCSP_REQUEST; +typedef OcspResponse OCSP_RESPONSE; +typedef WOLFSSL_OCSP_BASICRESP OCSP_BASICRESP; +typedef WOLFSSL_OCSP_SINGLERESP OCSP_SINGLERESP; +typedef WOLFSSL_OCSP_CERTID OCSP_CERTID; +typedef WOLFSSL_OCSP_ONEREQ OCSP_ONEREQ; +typedef WOLFSSL_OCSP_REQ_CTX OCSP_REQ_CTX; #define OCSP_REVOKED_STATUS_NOSTATUS (-1) @@ -85,6 +86,15 @@ #define OCSP_resp_count wolfSSL_OCSP_resp_count #define OCSP_resp_get0 wolfSSL_OCSP_resp_get0 +#define OCSP_REQ_CTX_new wolfSSL_OCSP_REQ_CTX_new +#define OCSP_REQ_CTX_free wolfSSL_OCSP_REQ_CTX_free +#define OCSP_sendreq_new wolfSSL_OCSP_sendreq_new +#define OCSP_REQ_CTX_set1_req wolfSSL_OCSP_REQ_CTX_set1_req +#define OCSP_REQ_CTX_add1_header wolfSSL_OCSP_REQ_CTX_add1_header +#define OCSP_REQ_CTX_http wolfSSL_OCSP_REQ_CTX_http +#define OCSP_REQ_CTX_nbio wolfSSL_OCSP_REQ_CTX_nbio +#define OCSP_sendreq_nbio wolfSSL_OCSP_sendreq_nbio + #endif /* HAVE_OCSP */ #endif /* WOLFSSL_OCSP_H_ */ diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 6d9d4418b6..27cc12dea1 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -63,6 +63,10 @@ WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, wc_pem_password_cb* cb, void* pass); WOLFSSL_API +WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out, + const unsigned char **in, + long len); +WOLFSSL_API int wolfSSL_PEM_write_mem_RSAPrivateKey(WOLFSSL_RSA* rsa, const WOLFSSL_EVP_CIPHER* cipher, unsigned char* passwd, int len, @@ -243,7 +247,6 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); #define PEM_write_bio_RSA_PUBKEY wolfSSL_PEM_write_bio_RSA_PUBKEY #define PEM_read_bio_RSA_PUBKEY wolfSSL_PEM_read_bio_RSA_PUBKEY #define PEM_read_bio_RSAPublicKey wolfSSL_PEM_read_bio_RSA_PUBKEY -#define PEM_read_bio_ECPKParameters wolfSSL_PEM_read_bio_ECPKParameters #define PEM_write_RSAPrivateKey wolfSSL_PEM_write_RSAPrivateKey #define PEM_write_RSA_PUBKEY wolfSSL_PEM_write_RSA_PUBKEY #define PEM_read_RSA_PUBKEY wolfSSL_PEM_read_RSA_PUBKEY @@ -263,6 +266,7 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh); #define PEM_write_ECPrivateKey wolfSSL_PEM_write_ECPrivateKey #define PEM_read_bio_ECPrivateKey wolfSSL_PEM_read_bio_ECPrivateKey #define PEM_read_bio_EC_PUBKEY wolfSSL_PEM_read_bio_EC_PUBKEY +#define PEM_read_bio_ECPKParameters wolfSSL_PEM_read_bio_ECPKParameters #ifndef NO_WOLFSSL_STUB #define PEM_write_bio_ECPKParameters(...) 0 #endif diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 4d276cc230..2ef55de0b3 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -240,6 +240,9 @@ WOLFSSL_API int wolfSSL_RSA_set_ex_data_with_cleanup( #define RSA_F4 WOLFSSL_RSA_F4 +#define OPENSSL_RSA_MAX_MODULUS_BITS RSA_MAX_SIZE +#define OPENSSL_RSA_MAX_PUBEXP_BITS RSA_MAX_SIZE + #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #ifdef __cplusplus diff --git a/wolfssl/openssl/safestack.h b/wolfssl/openssl/safestack.h new file mode 100644 index 0000000000..ee1f8728f8 --- /dev/null +++ b/wolfssl/openssl/safestack.h @@ -0,0 +1,40 @@ +/* safestack.h + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* stack.h for openSSL */ + +#ifndef WOLFSSL_SAFESTACK_H_ +#define WOLFSSL_SAFESTACK_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 29dbb9a2da..1a99437568 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -488,6 +488,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_get0_notAfter wolfSSL_X509_get_notAfter #define X509_getm_notAfter wolfSSL_X509_get_notAfter #define X509_get_serialNumber wolfSSL_X509_get_serialNumber +#define X509_get0_serialNumber wolfSSL_X509_get_serialNumber #define X509_get0_pubkey_bitstr wolfSSL_X509_get0_pubkey_bitstr #define X509_get_ex_new_index wolfSSL_X509_get_ex_new_index #define X509_get_ex_data wolfSSL_X509_get_ex_data @@ -530,6 +531,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_dup wolfSSL_X509_dup #define X509_add_ext wolfSSL_X509_add_ext #define X509_delete_ext wolfSSL_X509_delete_ext +#define X509_get0_subject_key_id wolfSSL_X509_get0_subject_key_id #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object #define X509_EXTENSION_get_data wolfSSL_X509_EXTENSION_get_data @@ -696,6 +698,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_STORE_set_ex_data wolfSSL_X509_STORE_set_ex_data #define X509_STORE_get_ex_data wolfSSL_X509_STORE_get_ex_data #define X509_STORE_get0_param wolfSSL_X509_STORE_get0_param +#define X509_STORE_set1_param wolfSSL_X509_STORE_set1_param #define X509_STORE_CTX_get1_issuer wolfSSL_X509_STORE_CTX_get1_issuer #define X509_STORE_CTX_set_time wolfSSL_X509_STORE_CTX_set_time #define X509_STORE_CTX_get0_param wolfSSL_X509_STORE_CTX_get0_param @@ -749,6 +752,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_ALGOR_new wolfSSL_X509_ALGOR_new #define X509_ALGOR_free wolfSSL_X509_ALGOR_free +#define i2d_X509_ALGOR wolfSSL_i2d_X509_ALGOR +#define d2i_X509_ALGOR wolfSSL_d2i_X509_ALGOR #define X509_PUBKEY_new wolfSSL_X509_PUBKEY_new #define X509_PUBKEY_free wolfSSL_X509_PUBKEY_free @@ -852,6 +857,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_BIT_STRING_free wolfSSL_ASN1_BIT_STRING_free #define ASN1_BIT_STRING_get_bit wolfSSL_ASN1_BIT_STRING_get_bit #define ASN1_BIT_STRING_set_bit wolfSSL_ASN1_BIT_STRING_set_bit +#define i2d_ASN1_BIT_STRING wolfSSL_i2d_ASN1_BIT_STRING +#define d2i_ASN1_BIT_STRING wolfSSL_d2i_ASN1_BIT_STRING #define sk_ASN1_OBJECT_free wolfSSL_sk_ASN1_OBJECT_free @@ -908,6 +915,22 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_STRING_set_default_mask_asc(...) 1 #endif +#define ASN1_GENERALSTRING WOLFSSL_ASN1_STRING +#define ASN1_GENERALSTRING_new wolfSSL_ASN1_STRING_new +#define ASN1_GENERALSTRING_free wolfSSL_ASN1_STRING_free +#define ASN1_GENERALSTRING_set wolfSSL_ASN1_STRING_set +#define i2d_ASN1_GENERALSTRING wolfSSL_i2d_ASN1_GENERALSTRING +#define i2d_ASN1_OCTET_STRING wolfSSL_i2d_ASN1_OCTET_STRING +#define i2d_ASN1_UTF8STRING wolfSSL_i2d_ASN1_UTF8STRING +#define i2d_ASN1_SEQUENCE wolfSSL_i2d_ASN1_SEQUENCE +#define d2i_ASN1_GENERALSTRING wolfSSL_d2i_ASN1_GENERALSTRING +#define d2i_ASN1_OCTET_STRING wolfSSL_d2i_ASN1_OCTET_STRING +#define d2i_ASN1_UTF8STRING wolfSSL_d2i_ASN1_UTF8STRING + +#define sk_ASN1_GENERALSTRING_num wolfSSL_sk_num +#define sk_ASN1_GENERALSTRING_value wolfSSL_sk_value +#define sk_ASN1_GENERALSTRING_push wolfSSL_sk_push + #define ASN1_OCTET_STRING WOLFSSL_ASN1_STRING #define ASN1_OCTET_STRING_new wolfSSL_ASN1_STRING_new #define ASN1_OCTET_STRING_free wolfSSL_ASN1_STRING_free @@ -1525,10 +1548,8 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define PEM_R_BAD_DECRYPT (-MIN_CODE_E + 4) #define ASN1_R_HEADER_TOO_LONG (-MIN_CODE_E + 5) +#define ERR_LIB_SYS 2 #define ERR_LIB_RSA 4 -#define ERR_LIB_EC 16 -#define ERR_LIB_SSL 20 -#define ERR_LIB_PKCS12 35 #define ERR_LIB_PEM 9 #define ERR_LIB_X509 10 #define ERR_LIB_EVP 11 @@ -1536,6 +1557,9 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define ERR_LIB_DIGEST 13 #define ERR_LIB_CIPHER 14 #define ERR_LIB_USER 15 +#define ERR_LIB_EC 16 +#define ERR_LIB_SSL 20 +#define ERR_LIB_PKCS12 35 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) || \ @@ -1702,11 +1726,16 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define OpenSSL_version(x) wolfSSL_OpenSSL_version() #endif +#define X509_OBJECT_retrieve_by_subject wolfSSL_X509_OBJECT_retrieve_by_subject + #ifndef NO_WOLFSSL_STUB #define OBJ_create_objects(...) WC_DO_NOTHING #define sk_SSL_COMP_free(...) WC_DO_NOTHING #endif +#define ASN1_OBJECT_new wolfSSL_ASN1_OBJECT_new +#define ASN1_OBJECT_free wolfSSL_ASN1_OBJECT_free +#define i2d_ASN1_OBJECT wolfSSL_i2d_ASN1_OBJECT #define OBJ_dup wolfSSL_ASN1_OBJECT_dup #define SSL_set_psk_use_session_callback wolfSSL_set_psk_use_session_callback diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index f488857b50..32801585b0 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -137,6 +137,20 @@ WOLFSSL_API WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get( WOLFSSL_API void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ex); WOLFSSL_API char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method, const WOLFSSL_ASN1_STRING *s); +WOLFSSL_API int wolfSSL_i2d_ASN1_GENERALSTRING(WOLFSSL_ASN1_STRING* s, + unsigned char **pp); +WOLFSSL_API int wolfSSL_i2d_ASN1_SEQUENCE(WOLFSSL_ASN1_STRING* s, + unsigned char **pp); +WOLFSSL_API int wolfSSL_i2d_ASN1_OCTET_STRING(WOLFSSL_ASN1_STRING* s, + unsigned char **pp); +WOLFSSL_API int wolfSSL_i2d_ASN1_UTF8STRING(WOLFSSL_ASN1_STRING* s, + unsigned char **pp); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_GENERALSTRING( + WOLFSSL_ASN1_STRING** out, const byte** src, long len); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_OCTET_STRING( + WOLFSSL_ASN1_STRING** out, const byte** src, long len); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_d2i_ASN1_UTF8STRING(WOLFSSL_ASN1_STRING** out, + const byte** src, long len); WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, unsigned long flag, int indent); WOLFSSL_API int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx, diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 059de3430e..d86de35269 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -213,6 +213,7 @@ typedef struct WOLFSSL_BIO_METHOD WOLFSSL_BIO_METHOD; typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION; typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; +typedef struct WOLFSSL_ASN1_OTHERNAME OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; typedef struct WOLFSSL_OBJ_NAME WOLFSSL_OBJ_NAME; @@ -246,6 +247,9 @@ typedef int (*WOLFSSL_X509_STORE_CTX_check_crl_cb)(WOLFSSL_X509_STORE_CTX *, struct WOLFSSL_OBJ_NAME { int type; + int alias; + const char *name; + const char *data; }; struct WOLFSSL_AUTHORITY_KEYID { @@ -1553,6 +1557,7 @@ WOLFSSL_API WOLFSSL_STACK* wolfSSL_shallow_sk_dup(WOLFSSL_STACK* sk); WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); +WOLFSSL_API int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx); #if defined(HAVE_OCSP) || defined(HAVE_CRL) || (defined(WOLFSSL_CUSTOM_OID) && \ defined(WOLFSSL_ASN_TEMPLATE) && defined(HAVE_OID_DECODING)) @@ -1655,7 +1660,7 @@ WOLFSSL_API int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_ST WOLFSSL_API int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s); WOLFSSL_API int wolfSSL_sk_X509_EXTENSION_num(WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_sk_X509_EXTENSION_value( - WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx); + const WOLF_STACK_OF(WOLFSSL_X509_EXTENSION)* sk, int idx); WOLFSSL_API int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data); #ifdef HAVE_EX_DATA_CLEANUP_HOOKS WOLFSSL_API int wolfSSL_set_ex_data_with_cleanup( @@ -1719,8 +1724,8 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref(WOLF_STACK_OF(WOLFSSL_X509)* chain); #endif -WOLFSSL_API int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, - char** path, int* ssl); +WOLFSSL_API int wolfSSL_OCSP_parse_url(const char* url, char** host, + char** port, char** path, int* ssl); #ifndef NO_BIO #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -1959,6 +1964,8 @@ WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID( WOLFSSL_X509* x509, unsigned char* dst, int* dstLen); WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID( WOLFSSL_X509* x509, unsigned char* dst, int* dstLen); +WOLFSSL_API const WOLFSSL_ASN1_STRING *wolfSSL_X509_get0_subject_key_id( + WOLFSSL_X509 *x509); WOLFSSL_API int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey); #ifdef WOLFSSL_CERT_REQ @@ -2007,7 +2014,7 @@ WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, WOLFSSL_API unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn); WOLFSSL_API const unsigned char* wolfSSL_ASN1_STRING_get0_data( const WOLFSSL_ASN1_STRING* asn); -WOLFSSL_API int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn); +WOLFSSL_API int wolfSSL_ASN1_STRING_length(const WOLFSSL_ASN1_STRING* asn); WOLFSSL_API int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dst, const WOLFSSL_ASN1_STRING* src); WOLFSSL_API int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx); @@ -2035,6 +2042,8 @@ WOLFSSL_API int wolfSSL_X509_STORE_add_cert( WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509); WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param( const WOLFSSL_X509_STORE *ctx); +WOLFSSL_API int wolfSSL_X509_STORE_set1_param(WOLFSSL_X509_STORE *ctx, + WOLFSSL_X509_VERIFY_PARAM *param); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( WOLFSSL_X509_STORE_CTX* ctx); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain( @@ -2149,7 +2158,7 @@ WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_d2i_ASN1_INTEGER( const unsigned char** in, long inSz); WOLFSSL_API int wolfSSL_i2d_ASN1_INTEGER(const WOLFSSL_ASN1_INTEGER* a, - unsigned char** out); + unsigned char** pp); WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime); @@ -2457,12 +2466,6 @@ enum { OCSP_TRUSTOTHER = 512, OCSP_RESPID_KEY = 1024, OCSP_NOTIME = 2048, - - /* OCSP Types */ - OCSP_CERTID = 2, - OCSP_REQUEST = 4, - OCSP_RESPONSE = 8, - OCSP_BASICRESP = 16, #endif SSL_ST_CONNECT = 0x1000, @@ -4864,6 +4867,10 @@ WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_get_bit( const WOLFSSL_ASN1_BIT_STRING* str, int i); WOLFSSL_API int wolfSSL_ASN1_BIT_STRING_set_bit( WOLFSSL_ASN1_BIT_STRING* str, int pos, int val); +WOLFSSL_API int wolfSSL_i2d_ASN1_BIT_STRING(const WOLFSSL_ASN1_BIT_STRING* bstr, + unsigned char** pp); +WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_d2i_ASN1_BIT_STRING( + WOLFSSL_ASN1_BIT_STRING** out, const byte** src, long len); #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ WOLFSSL_API int wolfSSL_version(WOLFSSL* ssl); @@ -4964,6 +4971,11 @@ WOLFSSL_API WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_new(void); WOLFSSL_API void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj); WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_OBJECT_get0_X509(const WOLFSSL_X509_OBJECT *obj); WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_X509_OBJECT_get0_X509_CRL(WOLFSSL_X509_OBJECT *obj); + +WOLFSSL_API WOLFSSL_X509_OBJECT *wolfSSL_X509_OBJECT_retrieve_by_subject( + WOLF_STACK_OF(WOLFSSL_X509_OBJECT) *sk, + WOLFSSL_X509_LOOKUP_TYPE type, + WOLFSSL_X509_NAME *name); #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || HAVE_LIGHTY */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) @@ -5236,8 +5248,13 @@ WOLFSSL_API void wolfSSL_X509_ALGOR_free(WOLFSSL_X509_ALGOR *alg); WOLFSSL_API const WOLFSSL_X509_ALGOR* wolfSSL_X509_get0_tbs_sigalg(const WOLFSSL_X509 *x); WOLFSSL_API void wolfSSL_X509_ALGOR_get0(const WOLFSSL_ASN1_OBJECT **paobj, int *pptype, const void **ppval, const WOLFSSL_X509_ALGOR *algor); WOLFSSL_API int wolfSSL_X509_ALGOR_set0(WOLFSSL_X509_ALGOR *algor, WOLFSSL_ASN1_OBJECT *aobj, int ptype, void *pval); +WOLFSSL_API int wolfSSL_i2d_X509_ALGOR(const WOLFSSL_X509_ALGOR* alg, + unsigned char** pp); +WOLFSSL_API WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out, + const byte** src, long len); WOLFSSL_API WOLFSSL_ASN1_TYPE* wolfSSL_ASN1_TYPE_new(void); WOLFSSL_API void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at); +WOLFSSL_API int wolfSSL_i2d_ASN1_TYPE(WOLFSSL_ASN1_TYPE* at, unsigned char** pp); WOLFSSL_API WOLFSSL_X509_PUBKEY *wolfSSL_X509_PUBKEY_new(void); WOLFSSL_API void wolfSSL_X509_PUBKEY_free(WOLFSSL_X509_PUBKEY *x); WOLFSSL_API WOLFSSL_X509_PUBKEY *wolfSSL_X509_get_X509_PUBKEY(const WOLFSSL_X509* x509); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 625618e1a7..f2f727424f 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2294,6 +2294,8 @@ WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, word32 maxIdx, int check); +WOLFSSL_LOCAL int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, + int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSequence_ex(const byte* input, word32* inOutIdx, int* len, @@ -2333,6 +2335,7 @@ WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, word32 oidType, word32 maxIdx); WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag, word32 inputSz); +WOLFSSL_LOCAL int GetASN_BitString(const byte* input, word32 idx, int length); WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetASNSequence(word32 len, byte* output); @@ -2344,6 +2347,7 @@ WOLFSSL_LOCAL word32 SetASNSet(word32 len, byte* output); WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetLengthEx(word32 length, byte* output, byte isIndef); +WOLFSSL_LOCAL word32 SetHeader(byte tag, word32 len, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); WOLFSSL_LOCAL word32 SetSequenceEx(word32 len, byte* output, byte isIndef); WOLFSSL_LOCAL word32 SetIndefEnd(byte* output); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 641246cbde..aabcec6e3b 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -717,6 +717,7 @@ typedef struct w64wrapper { #define XMEMMOVE(d,s,l) memmove((d),(s),(l)) #define XSTRLEN(s1) strlen((s1)) + #define XSTRCPY(s1,s2) strcpy((s1),(s2)) #define XSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) /* strstr, strncmp, strcmp, and strncat only used by wolfSSL proper, * not required for wolfCrypt only */