diff --git a/src/bio.c b/src/bio.c index 494234c735..68e678964b 100644 --- a/src/bio.c +++ b/src/bio.c @@ -1702,13 +1702,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; @@ -1727,7 +1727,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: @@ -1738,7 +1738,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/conf.c b/src/conf.c index 8bf4b1ea95..51443bd8cc 100644 --- a/src/conf.c +++ b/src/conf.c @@ -133,7 +133,7 @@ WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num) XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL); goto error; } - if (wolfSSL_sk_push(ret->data, strBuf) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_push(ret->data, strBuf) <= 0) { WOLFSSL_MSG("wolfSSL_sk_push error"); XFREE(strBuf, NULL, DYNAMIC_TYPE_OPENSSL); goto error; @@ -226,7 +226,7 @@ int wolfSSL_TXT_DB_insert(WOLFSSL_TXT_DB *db, WOLFSSL_STRING *row) return WOLFSSL_FAILURE; } - if (wolfSSL_sk_push(db->data, row) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_push(db->data, row) <= 0) { WOLFSSL_MSG("wolfSSL_sk_push error"); return WOLFSSL_FAILURE; } @@ -450,11 +450,11 @@ int wolfSSL_CONF_add_string(WOLFSSL_CONF *conf, sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *)section->value; value->section = section->section; - if (wolfSSL_sk_CONF_VALUE_push(sk, value) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_CONF_VALUE_push(sk, value) <= 0) { WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); return WOLFSSL_FAILURE; } - if (wolfSSL_sk_CONF_VALUE_push(conf->data, value) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_CONF_VALUE_push(conf->data, value) <= 0) { WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); wolfssl_sk_pop_type(sk, STACK_TYPE_CONF_VALUE); return WOLFSSL_FAILURE; @@ -497,7 +497,7 @@ WOLFSSL_CONF_VALUE *wolfSSL_CONF_new_section(WOLFSSL_CONF *conf, ret->value = (char*)sk; - if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_CONF_VALUE_push(conf->data, ret) <= 0) { WOLFSSL_MSG("wolfSSL_sk_CONF_VALUE_push error"); goto error; } diff --git a/src/crl.c b/src/crl.c index 48c1476ec1..38d62ebd94 100644 --- a/src/crl.c +++ b/src/crl.c @@ -437,7 +437,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; } } } @@ -478,8 +478,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) { @@ -502,9 +502,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 219465a1db..262f1bb1a3 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4570,6 +4570,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; XFREE(x509->authInfo, x509->heap, DYNAMIC_TYPE_X509_EXT); x509->authInfo = NULL; XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT); @@ -6915,12 +6917,12 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #endif #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) /* Don't change recv callback if currently using BIO's */ - if (ssl->CBIORecv != BioReceive) + if (ssl->CBIORecv != SslBioReceive) #endif ssl->CBIORecv = ctx->CBIORecv; #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) /* Don't change send callback if currently using BIO's */ - if (ssl->CBIOSend != BioSend) + if (ssl->CBIOSend != SslBioSend) #endif ssl->CBIOSend = ctx->CBIOSend; ssl->verifyDepth = ctx->verifyDepth; @@ -14002,7 +14004,8 @@ int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) ph->hash_value = hash; ph->last_suffix = suffix; - ret = wolfSSL_sk_BY_DIR_HASH_push(entry->hashes, ph); + ret = wolfSSL_sk_BY_DIR_HASH_push(entry->hashes, ph) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } } wc_UnLockMutex(&lookup->dirs->lock); @@ -30290,7 +30293,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, if (ret == 0) { if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name) - == WOLFSSL_FAILURE) + <= 0) { ret = MEMORY_ERROR; } diff --git a/src/ocsp.c b/src/ocsp.c index 89a6f6ffb6..182853e5a8 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -1140,6 +1140,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; @@ -1393,6 +1396,322 @@ WOLFSSL_OCSP_SINGLERESP* wolfSSL_OCSP_resp_get0(WOLFSSL_OCSP_BASICRESP *bs, int return single; } +#endif /* OPENSSL_EXTRA */ + +#ifdef OPENSSL_ALL + +/******************************************************************************* + * START OF WOLFSSL_OCSP_REQ_CTX API + ******************************************************************************/ + +enum ocspReqStates { + ORS_INVALID = 0, + ORS_HEADER_ADDED, + ORS_REQ_DONE +}; + +enum ocspReqIOStates { + ORIOS_INVALID = 0, + ORIOS_WRITE, + ORIOS_READ +}; + +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->reqResp = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); + ret->bufLen = maxline; + ret->bio = bio; + ret->ioState = ORIOS_WRITE; + } + + 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->reqResp != NULL) + wolfSSL_BIO_free(ctx->reqResp); + 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->reqResp, name) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_puts error"); + return WOLFSSL_FAILURE; + } + if (value != NULL) { + if (wolfSSL_BIO_write(ctx->reqResp, ": ", 2) != 2) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_puts(ctx->reqResp, value) <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_puts error"); + return WOLFSSL_FAILURE; + } + } + if (wolfSSL_BIO_write(ctx->reqResp, "\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->reqResp, 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->reqResp, 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->reqResp, req) <= 0) { + WOLFSSL_MSG("wolfSSL_OCSP_REQ_CTX_set1_req: request i2d error"); + return WOLFSSL_FAILURE; + } + + ctx->state = ORS_REQ_DONE; + + return WOLFSSL_SUCCESS; +} + +static int OCSP_REQ_CTX_bio_cb(char *buf, int sz, void *ctx) +{ + return BioReceive((WOLFSSL_BIO*)ctx, NULL, buf, sz); +} + +int wolfSSL_OCSP_REQ_CTX_nbio(WOLFSSL_OCSP_REQ_CTX *ctx) +{ + WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_nbio"); + + if (ctx == NULL) { + WOLFSSL_MSG("Bad parameters"); + return WOLFSSL_FAILURE; + } + + switch ((enum ocspReqIOStates)ctx->ioState) { + case ORIOS_WRITE: + case ORIOS_READ: + break; + case ORIOS_INVALID: + default: + WOLFSSL_MSG("Invalid ctx->ioState state"); + return WOLFSSL_FAILURE; + } + + if (ctx->ioState == ORIOS_WRITE) { + switch ((enum ocspReqStates)ctx->state) { + case ORS_HEADER_ADDED: + /* Write final new line to complete http header */ + if (wolfSSL_BIO_write(ctx->reqResp, "\r\n", 2) != 2) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + break; + case ORS_REQ_DONE: + break; + case ORS_INVALID: + default: + WOLFSSL_MSG("Invalid WOLFSSL_OCSP_REQ_CTX state"); + return WOLFSSL_FAILURE; + } + } + + switch ((enum ocspReqIOStates)ctx->ioState) { + case ORIOS_WRITE: + { + const unsigned char *req; + int reqLen = wolfSSL_BIO_get_mem_data(ctx->reqResp, &req); + if (reqLen <= 0) { + WOLFSSL_MSG("wolfSSL_BIO_get_mem_data error"); + return WOLFSSL_FAILURE; + } + while (ctx->sent < reqLen) { + int sent = wolfSSL_BIO_write(ctx->bio, req + ctx->sent, + reqLen - ctx->sent); + if (sent <= 0) { + if (wolfSSL_BIO_should_retry(ctx->bio)) + return -1; + WOLFSSL_MSG("wolfSSL_BIO_write error"); + ctx->ioState = ORIOS_INVALID; + return 0; + } + ctx->sent += sent; + } + ctx->sent = 0; + ctx->ioState = ORIOS_READ; + (void)wolfSSL_BIO_reset(ctx->reqResp); + FALL_THROUGH; + } + case ORIOS_READ: + { + byte* resp = NULL; + int respLen; + int ret; + + if (ctx->buf == NULL) /* Should be allocated in new call */ + return WOLFSSL_FAILURE; + + ret = wolfIO_HttpProcessResponseOcspGenericIO(OCSP_REQ_CTX_bio_cb, + ctx->bio, &resp, ctx->buf, ctx->bufLen, NULL); + if (ret <= 0) { + if (resp != NULL) + XFREE(resp, NULL, DYNAMIC_TYPE_OCSP); + if (ret == WOLFSSL_CBIO_ERR_WANT_READ || ret == OCSP_WANT_READ) + return -1; + return WOLFSSL_FAILURE; + } + respLen = ret; + ret = wolfSSL_BIO_write(ctx->reqResp, resp, respLen); + XFREE(resp, NULL, DYNAMIC_TYPE_OCSP); + if (ret != respLen) { + WOLFSSL_MSG("wolfSSL_BIO_write error"); + return WOLFSSL_FAILURE; + } + break; + } + case ORIOS_INVALID: + default: + WOLFSSL_MSG("Invalid ctx->ioState state"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + +int wolfSSL_OCSP_sendreq_nbio(OcspResponse **presp, WOLFSSL_OCSP_REQ_CTX *ctx) +{ + int ret; + int len; + const unsigned char *resp = NULL; + + WOLFSSL_ENTER("wolfSSL_OCSP_sendreq_nbio"); + + if (presp == NULL) + return WOLFSSL_FAILURE; + + ret = wolfSSL_OCSP_REQ_CTX_nbio(ctx); + if (ret != WOLFSSL_SUCCESS) + return ret; + + len = wolfSSL_BIO_get_mem_data(ctx->reqResp, &resp); + if (len <= 0) + return WOLFSSL_FAILURE; + return wolfSSL_d2i_OCSP_RESPONSE(presp, &resp, len) != NULL + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + +/******************************************************************************* + * END OF WOLFSSL_OCSP_REQ_CTX API + ******************************************************************************/ + #ifndef NO_WOLFSSL_STUB int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext, int idx) @@ -1585,7 +1904,8 @@ int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs) /* nonces are present but not equal */ return 0; } -#endif /* OPENSSL_EXTRA */ + +#endif /* OPENSSL_ALL */ #else /* HAVE_OCSP */ diff --git a/src/pk.c b/src/pk.c index 34e2727844..0c74cc8aab 100644 --- a/src/pk.c +++ b/src/pk.c @@ -9172,13 +9172,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)) { @@ -9227,6 +9233,9 @@ static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group, } ret = NULL; } + else { + *in_pp += idx; + } return ret; } @@ -9258,7 +9267,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"); } @@ -9269,6 +9279,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 afd505027a..e680f03f1f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11003,12 +11003,12 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if ((flags & WOLFSSL_BIO_FLAG_READ) && (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0))) { - ssl->CBIORecv = BioReceive; + ssl->CBIORecv = SslBioReceive; } if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0))) { - ssl->CBIOSend = BioSend; + ssl->CBIOSend = SslBioSend; } /* User programs should always retry reading from these BIOs */ @@ -11331,8 +11331,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return WOLFSSL_FAILURE; } - if (wolfSSL_sk_X509_NAME_push(ctx->client_ca_names, nameCopy) != - WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_NAME_push(ctx->client_ca_names, nameCopy) <= 0) { WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error"); wolfSSL_X509_NAME_free(nameCopy); return WOLFSSL_FAILURE; @@ -11387,8 +11386,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) */ nameCopy->x509 = NULL; - if (wolfSSL_sk_X509_NAME_push(list, nameCopy) != - WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_NAME_push(list, nameCopy) <= 0) { WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error"); /* Do free in loop because nameCopy is now responsibility * of list to free and adding jumps to cleanup after this @@ -13465,7 +13463,7 @@ static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm, i--; for (; i >= 0; i--) { if (push) { - if (wolfSSL_sk_X509_push(sk, issuer[i]) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(sk, issuer[i]) <= 0) { wolfSSL_X509_free(issuer[i]); ret = WOLFSSL_FATAL_ERROR; push = 0; /* Free the rest of the unpushed certs */ @@ -13517,7 +13515,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) } #endif - if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { + if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) <= 0) { WOLFSSL_MSG("Error decoding cert"); wolfSSL_X509_free(x509); wolfSSL_sk_X509_pop_free(sk, NULL); @@ -13612,66 +13610,80 @@ static WC_INLINE int compare_WOLFSSL_CIPHER( #endif /* OPENSSL_ALL || WOLFSSL_QT */ -/* return 1 on success 0 on fail */ +/* return number of elements 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 number of elements 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) + return WOLFSSL_FATAL_ERROR; + if (!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 (int)sk->num; } - 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 (int)sk->num; + } + 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 */ @@ -13680,26 +13692,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 (int)sk->num; + } + + /* 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: @@ -13722,17 +13779,25 @@ 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 stack. not using sk since we return sk->num after */ + WOLFSSL_STACK* prev_node = sk; + while (idx != 0 && prev_node->next != NULL) { + prev_node = prev_node->next; + idx--; + } + node->next = prev_node->next; + prev_node->next = node; + } - return WOLFSSL_SUCCESS; + return (int)sk->num; } #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ @@ -14949,20 +15014,80 @@ 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) { + if (*(++uport) == '\0') + goto err; + /* port must be before path */ + if (upath != NULL && uport >= upath) + goto err; + XFREE(*port, NULL, DYNAMIC_TYPE_OPENSSL); + *port = CopyString(uport, upath != NULL ? (int)(upath - uport) : -1, + NULL, DYNAMIC_TYPE_OPENSSL); + if (*port == NULL) + goto err; + hostEnd = uport - 1; + } + else + hostEnd = upath; + + *host = CopyString(u, hostEnd != NULL ? (int)(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 74e1381254..50c8a19263 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->ex && 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->ex && 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) <= 0) { + 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->ex) { + 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,99 @@ 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; +#ifdef WOLFSSL_ASN_TEMPLATE + 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, (word32)len) < 0) + return NULL; + if (tag != ASN_BIT_STRING) + return NULL; + if (GetLength(*src, &idx, &length, (word32)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; + } +#else + WOLFSSL_MSG("d2i_ASN1_BIT_STRING needs --enable-asn=template"); + (void)out; + (void)src; + (void)len; +#endif + return ret; +} + +#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ /******************************************************************************* * ASN1_INTEGER APIs @@ -772,7 +1189,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 +1228,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 (ret == 0) { - ret = a->length; - /* Move pointer on passed encoding when buffer passed in. */ - if (buf == NULL) { - *out += a->length; + 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; } - } - /* 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 +2105,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 +2149,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 +2261,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 +2268,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; @@ -1992,16 +2420,9 @@ void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, WOLFSSL_ASN1_OBJECT* obj) { - int ret = 0; - WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push"); - /* Push on when we have a stack and object to work with. */ - if ((sk != NULL) && (obj != NULL)) { - ret = wolfSSL_sk_push(sk, obj); - } - - return ret; + return wolfSSL_sk_push(sk, obj); } /* Pop off a WOLFSSL_ASN1_OBJECT from the stack. @@ -2397,6 +2818,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, (word32)len) < 0) + return NULL; + if (tag != expTag) + return NULL; + if (GetLength(*src, &idx, &length, (word32)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 +3039,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; @@ -4004,6 +4573,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: @@ -4031,6 +4601,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) || \ @@ -4068,6 +4673,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: @@ -4087,6 +4693,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_certman.c b/src/ssl_certman.c index d520f24708..09f2607ee2 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -398,7 +398,7 @@ WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) } /* Decode certificate. */ - if ((!err) && (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)) { + if ((!err) && (wolfSSL_sk_X509_push(sk, x509) <= 0)) { wolfSSL_X509_free(x509); err = 1; } 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_load.c b/src/ssl_load.c index da4279e39e..831d750c03 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -4809,7 +4809,8 @@ int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) } if (ret == 1) { /* Push the X509 object onto stack. */ - ret = wolfSSL_sk_X509_push(ctx->x509Chain, x509); + ret = wolfSSL_sk_X509_push(ctx->x509Chain, x509) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } if (ret != 1) { @@ -4873,7 +4874,8 @@ int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509) } if (ret == 1) { /* Push X509 object onto stack to be freed. */ - ret = wolfSSL_sk_X509_push(ssl->ourCertChain, x509); + ret = wolfSSL_sk_X509_push(ssl->ourCertChain, x509) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; if (ret != 1) { /* Free it now on error. */ wolfSSL_X509_free(x509); diff --git a/src/ssl_p7p12.c b/src/ssl_p7p12.c index a60a356a8e..f5a05b7904 100644 --- a/src/ssl_p7p12.c +++ b/src/ssl_p7p12.c @@ -229,7 +229,7 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) if (!ret) ret = wolfSSL_sk_X509_new_null(); if (x509) { - if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(ret, x509) <= 0) { wolfSSL_X509_free(x509); WOLFSSL_MSG("wolfSSL_sk_X509_push error"); goto error; @@ -294,7 +294,7 @@ WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs, return NULL; } - if (wolfSSL_sk_X509_push(signers, x509) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(signers, x509) <= 0) { wolfSSL_sk_X509_pop_free(signers, NULL); return NULL; } @@ -1152,7 +1152,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); @@ -1929,7 +1929,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, } FreeDecodedCert(DeCert); - if (wolfSSL_sk_X509_push(*ca, x509) != 1) { + if (wolfSSL_sk_X509_push(*ca, x509) <= 0) { WOLFSSL_MSG("Failed to push x509 onto stack"); wolfSSL_X509_free(x509); wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL; diff --git a/src/tls.c b/src/tls.c index a2f3705cf0..11cad8ac7d 100644 --- a/src/tls.c +++ b/src/tls.c @@ -6910,8 +6910,7 @@ static int TLSX_CA_Names_Parse(WOLFSSL *ssl, const byte* input, if (ret == 0) { CopyDecodedName(name, cert, ASN_SUBJECT); - if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name) - == WOLFSSL_FAILURE) + if (wolfSSL_sk_X509_NAME_push(ssl->client_ca_names, name) <= 0) ret = MEMORY_ERROR; } diff --git a/src/wolfio.c b/src/wolfio.c index d6a285a913..823e286d68 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -259,57 +259,47 @@ static int TranslateIoReturnCode(int err, SOCKET_T sd, int direction) #ifdef OPENSSL_EXTRA #ifndef NO_BIO -/* Use the WOLFSSL read BIO for receiving data. This is set by the function - * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv. - * - * ssl WOLFSSL struct passed in that has this function set as the receive - * callback. - * buf buffer to fill with data read - * sz size of buf buffer - * ctx a user set context - * - * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values. - */ -int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) + +int BioReceive(WOLFSSL_BIO* biord, WOLFSSL_BIO* biowr, char* buf, int sz) { int recvd = WOLFSSL_CBIO_ERR_GENERAL; - WOLFSSL_ENTER("BioReceive"); + WOLFSSL_ENTER("SslBioReceive"); - if (ssl->biord == NULL) { + if (biord == NULL) { WOLFSSL_MSG("WOLFSSL biord not set"); return WOLFSSL_CBIO_ERR_GENERAL; } - recvd = wolfSSL_BIO_read(ssl->biord, buf, sz); + recvd = wolfSSL_BIO_read(biord, buf, sz); if (recvd <= 0) { if (/* ssl->biowr->wrIdx is checked for Bind9 */ - wolfSSL_BIO_method_type(ssl->biowr) == WOLFSSL_BIO_BIO && - wolfSSL_BIO_wpending(ssl->biowr) != 0 && + wolfSSL_BIO_method_type(biowr) == WOLFSSL_BIO_BIO && + wolfSSL_BIO_wpending(biowr) != 0 && /* Not sure this pending check is necessary but let's double * check that the read BIO is empty before we signal a write * need */ - wolfSSL_BIO_supports_pending(ssl->biord) && - wolfSSL_BIO_ctrl_pending(ssl->biord) == 0) { + wolfSSL_BIO_supports_pending(biord) && + wolfSSL_BIO_ctrl_pending(biord) == 0) { /* Let's signal to the app layer that we have * data pending that needs to be sent. */ return WOLFSSL_CBIO_ERR_WANT_WRITE; } - else if (ssl->biord->type == WOLFSSL_BIO_SOCKET) { + else if (biord->type == WOLFSSL_BIO_SOCKET) { if (recvd == 0) { - WOLFSSL_MSG("BioReceive connection closed"); + WOLFSSL_MSG("SslBioReceive connection closed"); return WOLFSSL_CBIO_ERR_CONN_CLOSE; } #ifdef USE_WOLFSSL_IO - recvd = TranslateIoReturnCode(recvd, ssl->biord->num.fd, + recvd = TranslateIoReturnCode(recvd, biord->num.fd, SOCKET_RECEIVING); #endif return recvd; } /* If retry and read flags are set, return WANT_READ */ - if ((ssl->biord->flags & WOLFSSL_BIO_FLAG_READ) && - (ssl->biord->flags & WOLFSSL_BIO_FLAG_RETRY)) { + if ((biord->flags & WOLFSSL_BIO_FLAG_READ) && + (biord->flags & WOLFSSL_BIO_FLAG_RETRY)) { return WOLFSSL_CBIO_ERR_WANT_READ; } @@ -317,10 +307,27 @@ int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) return WOLFSSL_CBIO_ERR_GENERAL; } - (void)ctx; return recvd; } +/* Use the WOLFSSL read BIO for receiving data. This is set by the function + * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIORecv. + * + * ssl WOLFSSL struct passed in that has this function set as the receive + * callback. + * buf buffer to fill with data read + * sz size of buf buffer + * ctx a user set context + * + * returns the amount of data read or want read. See WOLFSSL_CBIO_ERR_* values. + */ +int SslBioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) +{ + WOLFSSL_ENTER("SslBioReceive"); + (void)ctx; + return BioReceive(ssl->biord, ssl->biowr, buf, sz); +} + /* Use the WOLFSSL write BIO for sending data. This is set by the function * wolfSSL_set_bio and can also be set by wolfSSL_CTX_SetIOSend. @@ -332,11 +339,11 @@ int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx) * * returns the amount of data sent or want send. See WOLFSSL_CBIO_ERR_* values. */ -int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) +int SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) { int sent = WOLFSSL_CBIO_ERR_GENERAL; - WOLFSSL_ENTER("BioSend"); + WOLFSSL_ENTER("SslBioSend"); if (ssl->biowr == NULL) { WOLFSSL_MSG("WOLFSSL biowr not set"); @@ -1659,8 +1666,9 @@ int wolfIO_DecodeUrl(const char* url, int urlSz, char* outName, char* outPath, return result; } -static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf, - int* recvBufSz, int chunkSz, char* start, int len, int dynType, void* heap) +static int wolfIO_HttpProcessResponseBuf(WolfSSLGenericIORecvCb ioCb, + void* ioCbCtx, byte **recvBuf, int* recvBufSz, int chunkSz, char* start, + int len, int dynType, void* heap) { byte* newRecvBuf = NULL; int newRecvSz = *recvBufSz + chunkSz; @@ -1713,7 +1721,7 @@ static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf, /* receive the remainder of chunk */ while (len < chunkSz) { - int rxSz = wolfIO_Recv(sfd, (char*)&newRecvBuf[pos], chunkSz-len, 0); + int rxSz = ioCb((char*)&newRecvBuf[pos], chunkSz-len, ioCbCtx); if (rxSz > 0) { len += rxSz; pos += rxSz; @@ -1731,8 +1739,9 @@ static int wolfIO_HttpProcessResponseBuf(int sfd, byte **recvBuf, return 0; } -int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, - byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap) +int wolfIO_HttpProcessResponseGenericIO(WolfSSLGenericIORecvCb ioCb, + void* ioCbCtx, const char** appStrList, unsigned char** respBuf, + unsigned char* httpBuf, int httpBufSz, int dynType, void* heap) { static const char HTTP_PROTO[] = "HTTP/1."; static const char HTTP_STATUS_200[] = "200"; @@ -1753,8 +1762,8 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, do { if (state == phr_get_chunk_data) { /* get chunk of data */ - result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, - chunkSz, start, len, dynType, heap); + result = wolfIO_HttpProcessResponseBuf(ioCb, ioCbCtx, respBuf, + &respBufSz, chunkSz, start, len, dynType, heap); state = (result != 0) ? phr_http_end : phr_get_chunk_len; end = NULL; @@ -1768,7 +1777,7 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, * can. */ } - result = wolfIO_Recv(sfd, (char*)httpBuf+len, httpBufSz-len-1, 0); + result = ioCb((char*)httpBuf+len, httpBufSz-len-1, ioCbCtx); if (result > 0) { len += result; start = (char*)httpBuf; @@ -1894,8 +1903,8 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, } while (state != phr_http_end); if (!isChunked) { - result = wolfIO_HttpProcessResponseBuf(sfd, respBuf, &respBufSz, chunkSz, - start, len, dynType, heap); + result = wolfIO_HttpProcessResponseBuf(ioCb, ioCbCtx, respBuf, + &respBufSz, chunkSz, start, len, dynType, heap); } if (result >= 0) { @@ -1907,6 +1916,22 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, return result; } + +static int httpResponseIoCb(char* buf, int sz, void* ctx) +{ + /* Double cast to silence the compiler int/pointer width msg */ + return wolfIO_Recv((SOCKET_T)(uintptr_t)ctx, buf, sz, 0); +} + +int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, + byte** respBuf, byte* httpBuf, int httpBufSz, int dynType, void* heap) +{ + return wolfIO_HttpProcessResponseGenericIO(httpResponseIoCb, + /* Double cast to silence the compiler int/pointer width msg */ + (void*)(uintptr_t)sfd, appStrList, respBuf, httpBuf, httpBufSz, + dynType, heap); +} + int wolfIO_HttpBuildRequest(const char *reqType, const char *domainName, const char *path, int pathLen, int reqSz, const char *contentType, byte *buf, int bufSize) @@ -2028,17 +2053,25 @@ int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path, ocspReqSz, "application/ocsp-request", cacheCtl, buf, bufSize); } +static const char* ocspAppStrList[] = { + "application/ocsp-response", + NULL +}; + +WOLFSSL_API int wolfIO_HttpProcessResponseOcspGenericIO( + WolfSSLGenericIORecvCb ioCb, void* ioCbCtx, unsigned char** respBuf, + unsigned char* httpBuf, int httpBufSz, void* heap) +{ + return wolfIO_HttpProcessResponseGenericIO(ioCb, ioCbCtx, + ocspAppStrList, respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap); +} + /* return: >0 OCSP Response Size * -1 error */ int wolfIO_HttpProcessResponseOcsp(int sfd, byte** respBuf, byte* httpBuf, int httpBufSz, void* heap) { - const char* appStrList[] = { - "application/ocsp-response", - NULL - }; - - return wolfIO_HttpProcessResponse(sfd, appStrList, + return wolfIO_HttpProcessResponse(sfd, ocspAppStrList, respBuf, httpBuf, httpBufSz, DYNAMIC_TYPE_OCSP, heap); } diff --git a/src/x509.c b/src/x509.c index 2e443a023a..3fba07dc23 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); - 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); + /* 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; - } 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 */ @@ -722,7 +677,7 @@ static int wolfssl_x509_alt_names_to_gn(WOLFSSL_X509* x509, } } - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) { WOLFSSL_MSG("Error pushing onto stack"); wolfSSL_GENERAL_NAME_free(gn); wolfSSL_sk_pop_free(sk, NULL); @@ -976,7 +931,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) obj->grp = oidCertAuthInfoType; obj->nid = NID_ad_ca_issuers; - ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj); + ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); wolfSSL_ASN1_OBJECT_free(obj); @@ -1011,7 +967,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) obj->grp = oidCertAuthInfoType; obj->nid = NID_ad_OCSP; - ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj); + ret = wolfSSL_sk_ASN1_OBJECT_push(sk, obj) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); wolfSSL_ASN1_OBJECT_free(obj); @@ -1251,7 +1208,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) <= 0) { wolfSSL_X509_EXTENSION_free(ext); ext = NULL; } @@ -1813,7 +1770,8 @@ static WOLFSSL_AUTHORITY_INFO_ACCESS* wolfssl_x509v3_ext_aia_d2i( break; } /* Push onto AUTHORITY_INFO_ACCESS stack. */ - ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad); + ret = wolfSSL_sk_ACCESS_DESCRIPTION_push(aia, ad) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Error pushing ASN1 AD onto stack"); err = 1; @@ -2311,8 +2269,7 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, } dns = dns->next; - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) != - WOLFSSL_SUCCESS) { + if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); goto err; } @@ -2367,13 +2324,13 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, /* push GENERAL_NAME onto fullname stack */ if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname, - gn) != WOLFSSL_SUCCESS) { + gn) <= 0) { WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error"); goto err; } /* push DIST_POINT onto stack */ - if (wolfSSL_sk_DIST_POINT_push(sk, dp) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_DIST_POINT_push(sk, dp) <= 0) { WOLFSSL_MSG("Error pushing DIST_POINT onto stack"); goto err; } @@ -2488,8 +2445,7 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, obj->grp = oidCertExtType; obj->obj = (byte*)(x509->certPolicies[i]); obj->objSz = MAX_CERTPOL_SZ; - if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) - != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); wolfSSL_ASN1_OBJECT_free(obj); wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); @@ -2565,6 +2521,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 = (long)(x509->extKeyUsageSz - + (word32)(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) <= 0) { + wolfSSL_ASN1_OBJECT_free(ekuObj); + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); + WOLFSSL_MSG("d2i obj error"); + return NULL; + } + } + + if ((word32)(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; @@ -2573,15 +2567,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"); @@ -2628,7 +2613,7 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, } } if (obj) { - if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_ASN1_OBJECT_push(sk, obj) <= 0) { WOLFSSL_MSG("Error pushing ASN1_OBJECT object onto " "stack."); goto err; @@ -2801,7 +2786,7 @@ static WOLFSSL_X509_EXTENSION* createExtFromStr(int nid, const char *value) WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error"); goto err_cleanup; } - if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_GENERAL_NAME_push(gns, gn) <= 0) { WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error"); wolfSSL_GENERAL_NAME_free(gn); goto err_cleanup; @@ -4464,39 +4449,9 @@ int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen, int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk, WOLFSSL_GENERAL_NAME* gn) { - WOLFSSL_STACK* node; WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_push"); - if (sk == NULL || gn == NULL) { - return WOLFSSL_FAILURE; - } - - /* no previous values in stack */ - if (sk->data.gn == NULL) { - sk->data.gn = gn; - sk->num += 1; - - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_ASN1); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->type = STACK_TYPE_GEN_NAME; - node->data.gn = sk->data.gn; - node->next = sk->next; - sk->next = node; - sk->data.gn = gn; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, gn); } #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ @@ -5074,19 +5029,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 */ @@ -5783,6 +5728,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) || \ @@ -7305,8 +7281,7 @@ static int x509AddCertDir(WOLFSSL_BY_DIR *ctx, const char *argc, long argl) XSTRNCPY(entry->dir_name, buf, pathLen); entry->dir_name[pathLen] = '\0'; - if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) - != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_BY_DIR_entry_push(ctx->dir_entry, entry) <= 0) { wolfSSL_BY_DIR_entry_free(entry); #ifdef WOLFSSL_SMALL_STACK XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); @@ -8792,7 +8767,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; @@ -9344,6 +9319,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. * @@ -11851,8 +11930,7 @@ int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* name, unsigned char** out) ret = MEMORY_E; break; } - if (wolfSSL_sk_X509_INFO_push(localSk, current) != - WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_INFO_push(localSk, current) <= 0) { wolfSSL_X509_INFO_free(current); current = NULL; ret = WOLFSSL_FAILURE; @@ -12229,8 +12307,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object( if (name->entries == NULL) { name->entries = wolfSSL_sk_X509_NAME_new(NULL); } - if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current - ) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_NAME_ENTRY_push(name->entries, current) <= 0) { ret = WOLFSSL_FAILURE; } #endif @@ -12861,7 +12938,7 @@ WOLF_STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( for (i = 0; i < num; i++) { name = wolfSSL_X509_NAME_dup(wolfSSL_sk_X509_NAME_value(sk, i)); - if (name == NULL || WOLFSSL_SUCCESS != wolfSSL_sk_X509_NAME_push(copy, name)) { + if (name == NULL || wolfSSL_sk_X509_NAME_push(copy, name) <= 0) { WOLFSSL_MSG("Memory error"); wolfSSL_sk_X509_NAME_pop_free(copy, wolfSSL_X509_NAME_free); wolfSSL_X509_NAME_free(name); @@ -13259,6 +13336,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 @@ -14482,8 +14581,10 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, req->reqAttributes->type = STACK_TYPE_X509_REQ_ATTR; } } - if (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR) - ret = wolfSSL_sk_push(req->reqAttributes, attr); + if (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR) { + ret = wolfSSL_sk_push(req->reqAttributes, attr) > 0 + ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; + } else ret = WOLFSSL_FAILURE; if (ret != WOLFSSL_SUCCESS) diff --git a/src/x509_str.c b/src/x509_str.c index 705cb32dc0..5a80cbb1d7 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -221,6 +221,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): @@ -537,7 +541,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) * signed and that a issuer was found */ if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) != 0) { - if (wolfSSL_sk_X509_push(sk, issuer) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(sk, issuer) <= 0) { WOLFSSL_MSG("Unable to load CA x509 into stack"); error = 1; } @@ -569,7 +573,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) break; } - if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(sk, x509) <= 0) { WOLFSSL_MSG("Unable to load x509 into stack"); wolfSSL_X509_free(x509); error = 1; @@ -688,13 +692,13 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( if (certToFilterName != NULL) { if (wolfSSL_X509_NAME_cmp(certToFilterName, name) == 0) { filteredCert = wolfSSL_X509_dup(certToFilter->data.x509); - if (filteredCert == NULL) { + if (filteredCert == NULL || + wolfSSL_sk_X509_push(filteredCerts, filteredCert) + <= 0) { err = 1; + wolfSSL_X509_free(filteredCert); break; } - else { - wolfSSL_sk_X509_push(filteredCerts, filteredCert); - } } } certToFilter = certToFilter->next; @@ -1248,7 +1252,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) if (CopyDecodedToX509(x509, dCert) == 0) { - if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_push(sk, x509) <= 0) { WOLFSSL_MSG("Unable to load x509 into stack"); wolfSSL_X509_free(x509); goto error; @@ -1327,7 +1331,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error"); goto err_cleanup; } - if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) { WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error"); wolfSSL_X509_OBJECT_free(obj); goto err_cleanup; @@ -1345,7 +1349,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error"); goto err_cleanup; } - if (wolfSSL_sk_X509_OBJECT_push(ret, obj) != WOLFSSL_SUCCESS) { + if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) { WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error"); wolfSSL_X509_OBJECT_free(obj); goto err_cleanup; @@ -1379,6 +1383,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 bb0877d100..49cfcaa602 100644 --- a/tests/api.c +++ b/tests/api.c @@ -41906,6 +41906,8 @@ 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; ExpectNotNull(str = ASN1_BIT_STRING_new()); /* Empty data testing. */ @@ -41941,8 +41943,19 @@ 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); +#ifdef WOLFSSL_ASN_TEMPLATE + { + const unsigned char* tmp = der; + ExpectNotNull(d2i_ASN1_BIT_STRING(&str2, &tmp, 14)); + } +#endif + ASN1_BIT_STRING_free(str); + ASN1_BIT_STRING_free(str2); ASN1_BIT_STRING_free(NULL); + XFREE(der, NULL, DYNAMIC_TYPE_ASN1); #endif return EXPECT_RESULT(); } @@ -42331,7 +42344,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; @@ -42729,7 +42742,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; @@ -42843,13 +42856,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); @@ -42865,8 +42878,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)); @@ -42882,22 +42893,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); @@ -42944,9 +42943,9 @@ static int test_wolfSSL_sk_ASN1_OBJECT(void) sk = NULL; ExpectNotNull(sk = wolfSSL_sk_new_asn1_obj()); - ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, NULL), 0); + ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, NULL), -1); ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(sk, NULL), 0); - ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, obj), 0); + ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(NULL, obj), -1); ExpectIntEQ(wolfSSL_sk_ASN1_OBJECT_push(sk, obj), 1); wolfSSL_sk_ASN1_OBJECT_pop_free(sk, NULL); sk = NULL; @@ -44132,7 +44131,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 @@ -44149,6 +44148,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; @@ -44159,16 +44209,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) @@ -44181,7 +44228,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; @@ -44189,7 +44238,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[] = { @@ -44202,9 +44251,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)); @@ -44255,15 +44304,23 @@ static int test_wolfSSL_IMPLEMENT_ASN1_FUNCTIONS(void) bootstrap->pub_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; } - ExpectIntGT(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, NULL), 0); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap, NULL), 16+len); 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), 16+len); + der2 = NULL; +#ifdef WOLFSSL_ASN_TEMPLATE + tmp = der; + ExpectNotNull(d2i_DPP_BOOTSTRAPPING_KEY(&bootstrap2, &tmp, 16+len)); + ExpectIntEQ(i2d_DPP_BOOTSTRAPPING_KEY(bootstrap2, &der2), 16+len); + ExpectBufEQ(der, der2, 49); +#endif 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); @@ -44287,7 +44344,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()) { @@ -44297,7 +44354,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); @@ -44306,24 +44363,225 @@ 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); + ExpectIntGT( + sk_ASN1_GENERALSTRING_push(nested_asn1->asn1_obj->strList, + genStr), 0); + } + /* 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); +#ifdef WOLFSSL_ASN_TEMPLATE + 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(der2, NULL, DYNAMIC_TYPE_ASN1); +#endif + XFREE(der, 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); + ExpectIntGT(wolfSSL_sk_insert(asn1_item, asn1_num, -1), 0); + } + + 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) { @@ -48726,7 +48984,7 @@ static int test_wolfSSL_PKCS7_certs(void) while (EXPECT_SUCCESS() && (sk_X509_INFO_num(info_sk) > 0)) { X509_INFO* info = NULL; ExpectNotNull(info = sk_X509_INFO_shift(info_sk)); - ExpectIntEQ(sk_X509_push(sk, info->x509), 1); + ExpectIntGT(sk_X509_push(sk, info->x509), 0); if (EXPECT_SUCCESS() && (info != NULL)) { info->x509 = NULL; } @@ -48917,7 +49175,7 @@ static int test_X509_STORE_untrusted_load_cert_to_stack(const char* filename, XFCLOSE(fp); fp = XBADFILE; } - ExpectIntEQ(sk_X509_push(chain, cert), 1); + ExpectIntGT(sk_X509_push(chain, cert), 0); if (EXPECT_FAIL()) X509_free(cert); @@ -49352,7 +49610,7 @@ static int test_wolfSSL_CTX_set_client_CA_list(void) ca_list = SSL_load_client_CA_file(caCertFile); ExpectNotNull(ca_list); ExpectNotNull(name = sk_X509_NAME_value(ca_list, 0)); - ExpectIntEQ(sk_X509_NAME_push(names, name), 1); + ExpectIntEQ(sk_X509_NAME_push(names, name), 2); if (EXPECT_FAIL()) { wolfSSL_X509_NAME_free(name); name = NULL; @@ -50382,15 +50640,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; @@ -52188,8 +52450,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); @@ -52231,7 +52493,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); @@ -52302,7 +52564,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); @@ -53506,8 +53768,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)); @@ -53525,7 +53790,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(); } @@ -57557,6 +57828,8 @@ static int test_othername_and_SID_ext(void) { ASN1_OBJECT* sid_oid = NULL; ASN1_OCTET_STRING *sid_data = NULL; + ASN1_OBJECT* alt_names_oid = NULL; + EVP_PKEY* priv = NULL; XFILE f = XBADFILE; byte* pt = NULL; @@ -57643,17 +57916,23 @@ static int test_othername_and_SID_ext(void) { ExpectIntEQ(sk_X509_EXTENSION_num(exts), 2); /* Check the SID extension. */ - ExpectNotNull(ext = sk_X509_EXTENSION_value(exts, 0)); + ExpectNotNull(sid_oid = OBJ_txt2obj("1.3.6.1.4.1.311.25.2", 1)); + ExpectNotNull(ext = sk_X509_EXTENSION_value(exts, + X509_get_ext_by_OBJ(x509, sid_oid, -1))); ExpectNotNull(extval = X509_EXTENSION_get_data(ext)); ExpectIntEQ(extval->length, sizeof(SidExtension)); ExpectIntEQ(XMEMCMP(SidExtension, extval->data, sizeof(SidExtension)), 0); + ASN1_OBJECT_free(sid_oid); /* Check the AltNames extension. */ - ExpectNotNull(ext = sk_X509_EXTENSION_value(exts, 1)); + ExpectNotNull(alt_names_oid = OBJ_txt2obj("subjectAltName", 0)); + ExpectNotNull(ext = sk_X509_EXTENSION_value(exts, + X509_get_ext_by_OBJ(x509, alt_names_oid, -1))); ExpectNotNull(extval = X509_EXTENSION_get_data(ext)); ExpectIntEQ(extval->length, sizeof(expectedAltName)); ExpectIntEQ(XMEMCMP(expectedAltName, extval->data, sizeof(expectedAltName)), 0); + ASN1_OBJECT_free(alt_names_oid); /* Cleanup */ ExpectNotNull(gns = (GENERAL_NAMES*)X509_get_ext_d2i(x509, @@ -58908,7 +59187,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); @@ -61255,6 +61534,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) { @@ -64542,6 +64841,289 @@ 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) && defined(HAVE_OCSP) +#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(); +} + +#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \ + defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) +static time_t test_wolfSSL_OCSP_REQ_CTX_time_cb(time_t* t) +{ + if (t != NULL) { + *t = 1722006780; + } + + return 1722006780; +} +#endif + +static int test_wolfSSL_OCSP_REQ_CTX(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_ALL) && defined(HAVE_OCSP) && \ + defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM) + /* This buffer was taken from the ocsp-stapling.test test case 1. The ocsp + * response was captured in wireshark. It contains both the http and binary + * parts. The time test_wolfSSL_OCSP_REQ_CTX_time_cb is set exactly so that + * the time check passes. */ + unsigned char ocspRespBin[] = { + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, + 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2d, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3a, 0x20, 0x31, 0x38, 0x32, 0x31, 0x0d, 0x0a, 0x0d, 0x0a, 0x30, 0x82, + 0x07, 0x19, 0x0a, 0x01, 0x00, 0xa0, 0x82, 0x07, 0x12, 0x30, 0x82, 0x07, + 0x0e, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, + 0x04, 0x82, 0x06, 0xff, 0x30, 0x82, 0x06, 0xfb, 0x30, 0x82, 0x01, 0x19, + 0xa1, 0x81, 0xa1, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, + 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, + 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x16, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, + 0x50, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, + 0x1f, 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x09, 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, + 0x66, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x18, 0x0f, 0x32, 0x30, + 0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35, + 0x5a, 0x30, 0x62, 0x30, 0x60, 0x30, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, + 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x71, 0x4d, 0x82, 0x23, 0x40, 0x59, + 0xc0, 0x96, 0xa1, 0x37, 0x43, 0xfa, 0x31, 0xdb, 0xba, 0xb1, 0x43, 0x18, + 0xda, 0x04, 0x04, 0x14, 0x83, 0xc6, 0x3a, 0x89, 0x2c, 0x81, 0xf4, 0x02, + 0xd7, 0x9d, 0x4c, 0xe2, 0x2a, 0xc0, 0x71, 0x82, 0x64, 0x44, 0xda, 0x0e, + 0x02, 0x01, 0x05, 0x80, 0x00, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, + 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x35, 0x5a, 0xa0, 0x11, + 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, 0x37, 0x32, 0x36, 0x31, 0x35, + 0x31, 0x33, 0x30, 0x35, 0x5a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x89, 0x7a, 0xe9, 0x6b, 0x66, 0x47, 0x8e, 0x52, 0x16, 0xf9, 0x8a, + 0x5a, 0x1e, 0x7a, 0x35, 0xbb, 0x1d, 0x6c, 0xd8, 0x31, 0xbb, 0x24, 0xd2, + 0xd7, 0xa4, 0x30, 0x27, 0x06, 0x17, 0x66, 0xd1, 0xf9, 0x8d, 0x24, 0xb0, + 0x49, 0x37, 0x62, 0x13, 0x78, 0x5e, 0xa6, 0x6d, 0xea, 0xe3, 0xd0, 0x30, + 0x82, 0x7d, 0xb6, 0xf6, 0x55, 0x82, 0x11, 0xdc, 0xe7, 0x0f, 0xd6, 0x24, + 0xb4, 0x80, 0x23, 0x4f, 0xfd, 0xa7, 0x9a, 0x4b, 0xac, 0xf2, 0xd3, 0xde, + 0x42, 0x10, 0xfb, 0x4b, 0x29, 0x06, 0x02, 0x7b, 0x47, 0x36, 0x70, 0x75, + 0x45, 0x38, 0x8d, 0x3e, 0x55, 0x9c, 0xce, 0x78, 0xd8, 0x18, 0x45, 0x47, + 0x2d, 0x2a, 0x46, 0x65, 0x13, 0x93, 0x1a, 0x98, 0x90, 0xc6, 0x2d, 0xd5, + 0x05, 0x2a, 0xfc, 0xcb, 0xac, 0x53, 0x73, 0x93, 0x42, 0x4e, 0xdb, 0x17, + 0x91, 0xcb, 0xe1, 0x08, 0x03, 0xd1, 0x33, 0x57, 0x4b, 0x1d, 0xb8, 0x71, + 0x84, 0x01, 0x04, 0x47, 0x6f, 0x06, 0xfa, 0x76, 0x7d, 0xd9, 0x37, 0x64, + 0x57, 0x37, 0x3a, 0x8f, 0x4d, 0x88, 0x11, 0xa5, 0xd4, 0xaa, 0xcb, 0x49, + 0x47, 0x86, 0xdd, 0xcf, 0x46, 0xa6, 0xfa, 0x8e, 0xf2, 0x62, 0x0f, 0xc9, + 0x25, 0xf2, 0x39, 0x62, 0x3e, 0x2d, 0x35, 0xc4, 0x76, 0x7b, 0xae, 0xd5, + 0xe8, 0x85, 0xa1, 0xa6, 0x2d, 0x41, 0xd6, 0x8e, 0x3c, 0xfa, 0xdc, 0x6c, + 0x66, 0xe2, 0x61, 0xe7, 0xe5, 0x90, 0xa1, 0xfd, 0x7f, 0xdb, 0x18, 0xd0, + 0xeb, 0x6d, 0x73, 0x08, 0x5f, 0x6a, 0x65, 0x44, 0x50, 0xad, 0x38, 0x9d, + 0xb6, 0xfb, 0xbf, 0x28, 0x55, 0x84, 0x65, 0xfa, 0x0e, 0x34, 0xfc, 0x43, + 0x19, 0x80, 0x5c, 0x7d, 0x2d, 0x5b, 0xd8, 0x60, 0xec, 0x0e, 0xf9, 0x1e, + 0x6e, 0x32, 0x3f, 0x35, 0xf7, 0xec, 0x7e, 0x47, 0xba, 0xb5, 0xd2, 0xaa, + 0x5a, 0x9d, 0x07, 0x2c, 0xc5, 0xa0, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04, + 0xc2, 0x30, 0x82, 0x04, 0xbe, 0x30, 0x82, 0x03, 0xa6, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x97, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, + 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, + 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, + 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, 0x30, + 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, + 0x30, 0x37, 0x32, 0x36, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x5a, 0x17, + 0x0d, 0x32, 0x37, 0x30, 0x34, 0x32, 0x32, 0x31, 0x35, 0x31, 0x32, 0x30, + 0x34, 0x5a, 0x30, 0x81, 0x9e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x0c, 0x07, 0x53, 0x65, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, + 0x53, 0x53, 0x4c, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x16, + 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x20, 0x4f, 0x43, 0x53, 0x50, + 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, + 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xb8, 0xba, 0x23, 0xb4, 0xf6, 0xc3, 0x7b, 0x14, + 0xc3, 0xa4, 0xf5, 0x1d, 0x61, 0xa1, 0xf5, 0x1e, 0x63, 0xb9, 0x85, 0x23, + 0x34, 0x50, 0x6d, 0xf8, 0x7c, 0xa2, 0x8a, 0x04, 0x8b, 0xd5, 0x75, 0x5c, + 0x2d, 0xf7, 0x63, 0x88, 0xd1, 0x07, 0x7a, 0xea, 0x0b, 0x45, 0x35, 0x2b, + 0xeb, 0x1f, 0xb1, 0x22, 0xb4, 0x94, 0x41, 0x38, 0xe2, 0x9d, 0x74, 0xd6, + 0x8b, 0x30, 0x22, 0x10, 0x51, 0xc5, 0xdb, 0xca, 0x3f, 0x46, 0x2b, 0xfe, + 0xe5, 0x5a, 0x3f, 0x41, 0x74, 0x67, 0x75, 0x95, 0xa9, 0x94, 0xd5, 0xc3, + 0xee, 0x42, 0xf8, 0x8d, 0xeb, 0x92, 0x95, 0xe1, 0xd9, 0x65, 0xb7, 0x43, + 0xc4, 0x18, 0xde, 0x16, 0x80, 0x90, 0xce, 0x24, 0x35, 0x21, 0xc4, 0x55, + 0xac, 0x5a, 0x51, 0xe0, 0x2e, 0x2d, 0xb3, 0x0a, 0x5a, 0x4f, 0x4a, 0x73, + 0x31, 0x50, 0xee, 0x4a, 0x16, 0xbd, 0x39, 0x8b, 0xad, 0x05, 0x48, 0x87, + 0xb1, 0x99, 0xe2, 0x10, 0xa7, 0x06, 0x72, 0x67, 0xca, 0x5c, 0xd1, 0x97, + 0xbd, 0xc8, 0xf1, 0x76, 0xf8, 0xe0, 0x4a, 0xec, 0xbc, 0x93, 0xf4, 0x66, + 0x4c, 0x28, 0x71, 0xd1, 0xd8, 0x66, 0x03, 0xb4, 0x90, 0x30, 0xbb, 0x17, + 0xb0, 0xfe, 0x97, 0xf5, 0x1e, 0xe8, 0xc7, 0x5d, 0x9b, 0x8b, 0x11, 0x19, + 0x12, 0x3c, 0xab, 0x82, 0x71, 0x78, 0xff, 0xae, 0x3f, 0x32, 0xb2, 0x08, + 0x71, 0xb2, 0x1b, 0x8c, 0x27, 0xac, 0x11, 0xb8, 0xd8, 0x43, 0x49, 0xcf, + 0xb0, 0x70, 0xb1, 0xf0, 0x8c, 0xae, 0xda, 0x24, 0x87, 0x17, 0x3b, 0xd8, + 0x04, 0x65, 0x6c, 0x00, 0x76, 0x50, 0xef, 0x15, 0x08, 0xd7, 0xb4, 0x73, + 0x68, 0x26, 0x14, 0x87, 0x95, 0xc3, 0x5f, 0x6e, 0x61, 0xb8, 0x87, 0x84, + 0xfa, 0x80, 0x1a, 0x0a, 0x8b, 0x98, 0xf3, 0xe3, 0xff, 0x4e, 0x44, 0x1c, + 0x65, 0x74, 0x7c, 0x71, 0x54, 0x65, 0xe5, 0x39, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x32, 0x67, 0xe1, 0xb1, 0x79, + 0xd2, 0x81, 0xfc, 0x9f, 0x23, 0x0c, 0x70, 0x40, 0x50, 0xb5, 0x46, 0x56, + 0xb8, 0x30, 0x36, 0x30, 0x81, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x81, 0xbc, 0x30, 0x81, 0xb9, 0x80, 0x14, 0x73, 0xb0, 0x1c, 0xa4, 0x2f, + 0x82, 0xcb, 0xcf, 0x47, 0xa5, 0x38, 0xd7, 0xb0, 0x04, 0x82, 0x3a, 0x7e, + 0x72, 0x15, 0x21, 0xa1, 0x81, 0x9d, 0xa4, 0x81, 0x9a, 0x30, 0x81, 0x97, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, + 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x74, 0x6f, 0x6e, 0x31, 0x10, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x07, 0x53, 0x65, 0x61, + 0x74, 0x74, 0x6c, 0x65, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x07, 0x77, 0x6f, 0x6c, 0x66, 0x53, 0x53, 0x4c, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x6f, 0x6c, 0x66, 0x53, + 0x53, 0x4c, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + 0x01, 0x16, 0x10, 0x69, 0x6e, 0x66, 0x6f, 0x40, 0x77, 0x6f, 0x6c, 0x66, + 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x01, 0x63, 0x30, 0x13, + 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x37, 0xb9, 0x66, 0xd3, 0xa1, 0x08, 0xfc, 0x37, 0x58, + 0x4e, 0xe0, 0x8c, 0xd3, 0x7f, 0xa6, 0x0f, 0x59, 0xd3, 0x14, 0xf7, 0x4b, + 0x36, 0xf7, 0x2e, 0x98, 0xeb, 0x7c, 0x03, 0x3f, 0x3a, 0xd6, 0x9c, 0xcd, + 0xb4, 0x9e, 0x8d, 0x5f, 0x92, 0xa6, 0x6f, 0x63, 0x87, 0x34, 0xe8, 0x83, + 0xfd, 0x6d, 0x34, 0x64, 0xb5, 0xf0, 0x9c, 0x71, 0x02, 0xb8, 0xf6, 0x2f, + 0x10, 0xa0, 0x92, 0x8f, 0x3f, 0x86, 0x3e, 0xe2, 0x01, 0x5a, 0x56, 0x39, + 0x0a, 0x8d, 0xb1, 0xbe, 0x03, 0xf7, 0xf8, 0xa7, 0x88, 0x46, 0xef, 0x81, + 0xa0, 0xad, 0x86, 0xc9, 0xe6, 0x23, 0x89, 0x1d, 0xa6, 0x24, 0x45, 0xf2, + 0x6a, 0x83, 0x2d, 0x8e, 0x92, 0x17, 0x1e, 0x44, 0x19, 0xfa, 0x0f, 0x47, + 0x6b, 0x8f, 0x4a, 0xa2, 0xda, 0xab, 0xd5, 0x2b, 0xcd, 0xcb, 0x14, 0xf0, + 0xb5, 0xcf, 0x7c, 0x76, 0x42, 0x32, 0x90, 0x21, 0xdc, 0xdd, 0x52, 0xfc, + 0x53, 0x7e, 0xff, 0x7f, 0xd9, 0x58, 0x6b, 0x1f, 0x73, 0xee, 0x83, 0xf4, + 0x67, 0xfa, 0x4a, 0x4f, 0x24, 0xe4, 0x2b, 0x10, 0x74, 0x89, 0x52, 0x9a, + 0xf7, 0xa4, 0xe0, 0xaf, 0xf5, 0x63, 0xd7, 0xfa, 0x0b, 0x2c, 0xc9, 0x39, + 0x5d, 0xbd, 0x44, 0x93, 0x69, 0xa4, 0x1d, 0x01, 0xe2, 0x66, 0xe7, 0xc1, + 0x11, 0x44, 0x7d, 0x0a, 0x7e, 0x5d, 0x1d, 0x26, 0xc5, 0x4a, 0x26, 0x2e, + 0xa3, 0x58, 0xc4, 0xf7, 0x10, 0xcb, 0xba, 0xe6, 0x27, 0xfc, 0xdb, 0x54, + 0xe2, 0x60, 0x08, 0xc2, 0x0e, 0x4b, 0xd4, 0xaa, 0x22, 0x23, 0x93, 0x9f, + 0xe1, 0xcb, 0x85, 0xa4, 0x41, 0x6f, 0x26, 0xa7, 0x77, 0x8a, 0xef, 0x66, + 0xd0, 0xf8, 0x33, 0xf6, 0xfd, 0x6d, 0x37, 0x7a, 0x89, 0xcc, 0x88, 0x3b, + 0x82, 0xd0, 0xa9, 0xdf, 0xf1, 0x3d, 0xdc, 0xb0, 0x06, 0x1c, 0xe4, 0x4b, + 0x57, 0xb4, 0x0c, 0x65, 0xb9, 0xb4, 0x6c + }; + 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), -1); + ExpectIntEQ(BIO_write(bio2, ocspRespBin, sizeof(ocspRespBin)), + sizeof(ocspRespBin)); + ExpectIntEQ(wc_SetTimeCb(test_wolfSSL_OCSP_REQ_CTX_time_cb), 0); + ExpectIntEQ(OCSP_sendreq_nbio(&rsp, ctx), 1); + ExpectIntEQ(wc_SetTimeCb(NULL), 0); + + 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); +#endif + return EXPECT_RESULT(); +} + static int test_wolfSSL_EVP_PKEY_derive(void) { EXPECT_DECLS; @@ -70747,12 +71329,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 @@ -70805,7 +71393,7 @@ static int test_wolfSSL_dup_CA_list(void) for (i = 0; i < 3; i++) { name = X509_NAME_new(); ExpectNotNull(name); - ExpectIntEQ(sk_X509_NAME_push(originalStack, name), WOLFSSL_SUCCESS); + ExpectIntEQ(sk_X509_NAME_push(originalStack, name), i+1); if (EXPECT_FAIL()) { X509_NAME_free(name); } @@ -84876,6 +85464,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), @@ -85133,6 +85724,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), @@ -85270,6 +85862,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 59235b940d..83f6a2a3ca 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)) @@ -2471,7 +2471,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); @@ -13525,24 +13525,21 @@ 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) { ret = MEMORY_E; @@ -13557,25 +13554,23 @@ static int SetDNSEntry(DecodedCert* cert, const char* str, int strLen, #ifdef WOLFSSL_RID_ALT_NAME /* store registeredID as a string */ - if (type == ASN_RID_TYPE) { - ret = GenerateDNSEntryRIDString(dnsEntry, cert->heap); - } + if (type == ASN_RID_TYPE) + ret = GenerateDNSEntryRIDString(dnsEntry, heap); #endif + } #ifdef WOLFSSL_IP_ALT_NAME - /* store IP addresses as a string */ - if (type == ASN_IP_TYPE) { - ret = GenerateDNSEntryIPString(dnsEntry, cert->heap); - } + /* store IP addresses as a string */ + if (ret == 0 && type == ASN_IP_TYPE) + ret = GenerateDNSEntryIPString(dnsEntry, heap); #endif - } if (ret == 0) { ret = AddDNSEntryToList(entries, dnsEntry); } /* failure cleanup */ if (ret != 0 && dnsEntry != NULL) { - XFREE(dnsEntry->name, cert->heap, DYNAMIC_TYPE_ALTNAME); - XFREE(dnsEntry, cert->heap, DYNAMIC_TYPE_ALTNAME); + XFREE(dnsEntry->name, heap, DYNAMIC_TYPE_ALTNAME); + XFREE(dnsEntry, heap, DYNAMIC_TYPE_ALTNAME); } return ret; @@ -15853,7 +15848,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. */ @@ -18163,7 +18158,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; @@ -18190,10 +18185,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); @@ -18222,7 +18219,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; } } @@ -18254,7 +18253,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; @@ -18273,7 +18272,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; @@ -18281,7 +18280,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; @@ -18329,7 +18328,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; @@ -18338,7 +18337,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, #ifdef 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; @@ -18348,7 +18347,7 @@ static int DecodeGeneralName(const byte* input, word32* inOutIdx, byte tag, #ifdef WOLFSSL_RID_ALT_NAME /* 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; @@ -18360,7 +18359,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 8b78f620c6..89a4097986 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3953,7 +3953,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); @@ -3991,9 +3991,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 = (unsigned int)ret; + return WOLFSSL_SUCCESS; + } +#endif default: break; } @@ -4051,7 +4065,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; @@ -4068,9 +4083,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: @@ -9855,10 +9880,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} }; @@ -10187,7 +10226,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; @@ -10218,23 +10257,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 @@ -10269,11 +10300,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 88188bd1d1..c8acb96b91 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, >=) @@ -5218,6 +5218,7 @@ struct WOLFSSL_X509 { byte* authKeyId; /* Points into authKeyIdSrc */ byte* authKeyIdSrc; byte* subjKeyId; + WOLFSSL_ASN1_STRING* subjKeyIdStr; byte* extKeyUsageSrc; #ifdef OPENSSL_ALL byte* subjAltNameSrc; @@ -6932,8 +6933,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 b05510cfcf..f2e234f630 100644 --- a/wolfssl/ocsp.h +++ b/wolfssl/ocsp.h @@ -48,6 +48,16 @@ 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 *reqResp; /* First used for request then for response */ + byte* buf; + int bufLen; + int state; + int ioState; + int sent; +} WOLFSSL_OCSP_REQ_CTX; #endif WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm); @@ -130,6 +140,21 @@ 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); + WOLFSSL_API int wolfSSL_OCSP_REQUEST_add_ext(OcspRequest* req, WOLFSSL_X509_EXTENSION* ext, int idx); WOLFSSL_API OcspResponse* wolfSSL_OCSP_response_create(int status, diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 2c83b9b8c4..b2ff24b1e2 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 ex:1; /* explicit, name conflicts with C++ keyword */ + 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), TRUE } + 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/compat_types.h b/wolfssl/openssl/compat_types.h index 93a3b12dac..61cc80aeb1 100644 --- a/wolfssl/openssl/compat_types.h +++ b/wolfssl/openssl/compat_types.h @@ -50,6 +50,8 @@ typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX; typedef struct WOLFSSL_EVP_CIPHER_CTX WOLFSSL_EVP_CIPHER_CTX; typedef struct WOLFSSL_ASN1_PCTX WOLFSSL_ASN1_PCTX; +typedef struct WOLFSSL_BIO WOLFSSL_BIO; + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) typedef WOLFSSL_EVP_MD EVP_MD; typedef WOLFSSL_EVP_MD_CTX EVP_MD_CTX; 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 dde5841377..a14b940c18 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -208,11 +208,11 @@ typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD; typedef struct WOLFSSL_CRL WOLFSSL_X509_CRL; typedef struct WOLFSSL_X509_STORE WOLFSSL_X509_STORE; typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; -typedef struct WOLFSSL_BIO WOLFSSL_BIO; 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 +246,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 +1556,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 +1659,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 +1723,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 +1963,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 +2013,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 +2041,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 +2157,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 +2465,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, @@ -4863,6 +4865,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); @@ -4963,6 +4969,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) @@ -5235,8 +5246,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 acee9e4276..af70846986 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2291,6 +2291,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, @@ -2330,6 +2332,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); @@ -2341,6 +2344,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 a540699e64..e3d06a2eb4 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -723,6 +723,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 */ diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 5fdeac4bb5..acadb3a03a 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -521,8 +521,10 @@ WOLFSSL_API int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, #endif /* WOLFSSL_NO_SOCK */ -WOLFSSL_API int BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); -WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); +WOLFSSL_API int SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); +WOLFSSL_API int BioReceive(WOLFSSL_BIO* biord, WOLFSSL_BIO* biowr, char* buf, + int sz); +WOLFSSL_API int SslBioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); #if defined(USE_WOLFSSL_IO) /* default IO callbacks */ WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); @@ -545,9 +547,14 @@ WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); #endif /* WOLFSSL_DTLS */ #endif /* USE_WOLFSSL_IO */ + +typedef int (*WolfSSLGenericIORecvCb)(char *buf, int sz, void *ctx); #ifdef HAVE_OCSP WOLFSSL_API int wolfIO_HttpBuildRequestOcsp(const char* domainName, const char* path, int ocspReqSz, unsigned char* buf, int bufSize); + WOLFSSL_API int wolfIO_HttpProcessResponseOcspGenericIO( + WolfSSLGenericIORecvCb ioCb, void* ioCbCtx, unsigned char** respBuf, + unsigned char* httpBuf, int httpBufSz, void* heap); WOLFSSL_API int wolfIO_HttpProcessResponseOcsp(int sfd, unsigned char** respBuf, unsigned char* httpBuf, int httpBufSz, void* heap); @@ -578,6 +585,10 @@ WOLFSSL_API int BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); WOLFSSL_LOCAL int wolfIO_HttpBuildRequest_ex(const char* reqType, const char* domainName, const char* path, int pathLen, int reqSz, const char* contentType, const char *exHdrs, unsigned char* buf, int bufSize); + WOLFSSL_API int wolfIO_HttpProcessResponseGenericIO( + WolfSSLGenericIORecvCb ioCb, void* ioCbCtx, const char** appStrList, + unsigned char** respBuf, unsigned char* httpBuf, int httpBufSz, + int dynType, void* heap); WOLFSSL_API int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, unsigned char** respBuf, unsigned char* httpBuf, int httpBufSz, int dynType, void* heap); @@ -604,7 +615,6 @@ WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl); WOLFSSL_API void wolfSSL_SetIOReadFlags( WOLFSSL* ssl, int flags); WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); - #ifdef HAVE_NETX WOLFSSL_LOCAL int NetX_Receive(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_LOCAL int NetX_Send(WOLFSSL *ssl, char *buf, int sz, void *ctx);