diff --git a/certs/csr.attr.der b/certs/csr.attr.der new file mode 100644 index 000000000..bceadd777 Binary files /dev/null and b/certs/csr.attr.der differ diff --git a/csr.signed.der b/certs/csr.signed.der similarity index 100% rename from csr.signed.der rename to certs/csr.signed.der diff --git a/configure.ac b/configure.ac index e449615e4..51b6a04c2 100644 --- a/configure.ac +++ b/configure.ac @@ -4316,6 +4316,11 @@ then ENABLED_SESSIONCERTS="yes" AM_CFLAGS="$AM_CFLAGS -DSESSION_CERTS" fi + + if test "x$ENABLED_DSA" = "xno" + then + AC_MSG_WARN([Enabling DSA with --enable-dsa is recommended for libest]) + fi fi # MD4 diff --git a/src/internal.c b/src/internal.c index f74a3f979..62bbeaa8c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9567,6 +9567,37 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) else x509->subjectCN[0] = '\0'; +#ifdef WOLFSSL_CERT_REQ + /* CSR attributes */ + if (dCert->cPwd) { + if (dCert->cPwdLen < CTC_NAME_SIZE) { + XMEMCPY(x509->challengePw, dCert->cPwd, dCert->cPwdLen); + x509->challengePw[dCert->cPwdLen] = '\0'; + if (x509->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(x509->challengePwAttr); + } + x509->challengePwAttr = wolfSSL_X509_ATTRIBUTE_new(); + if (x509->challengePwAttr) { + x509->challengePwAttr->value->value.asn1_string = + wolfSSL_ASN1_STRING_new(); + if (wolfSSL_ASN1_STRING_set( + x509->challengePwAttr->value->value.asn1_string, + dCert->cPwd, dCert->cPwdLen) != WOLFSSL_SUCCESS) { + ret = MEMORY_E; + } + x509->challengePwAttr->value->type = V_ASN1_PRINTABLESTRING; + } + else { + ret = MEMORY_E; + } + } + else { + WOLFSSL_MSG("Challenge password too long"); + ret = MEMORY_E; + } + } +#endif + #ifdef WOLFSSL_SEP { int minSz = min(dCert->deviceTypeSz, EXTERNAL_SERIAL_SIZE); diff --git a/src/ssl.c b/src/ssl.c index 75a33fba6..47ff87855 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -442,7 +442,7 @@ WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method) int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx) { int refCount = SSL_CTX_RefCount(ctx, 1); - return ((refCount > 1) ? 1 : 0); + return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE); } #endif @@ -3586,12 +3586,18 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) DYNAMIC_TYPE_CERT_MANAGER); if (cm) { XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER)); + cm->refCount = 1; if (wc_InitMutex(&cm->caLock) != 0) { WOLFSSL_MSG("Bad mutex init"); wolfSSL_CertManagerFree(cm); return NULL; } + if (wc_InitMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Bad mutex init"); + wolfSSL_CertManagerFree(cm); + return NULL; + } #ifdef WOLFSSL_TRUST_PEER_CERT if (wc_InitMutex(&cm->tpLock) != 0) { @@ -3623,37 +3629,62 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void) void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm) { + int doFree = 0; WOLFSSL_ENTER("wolfSSL_CertManagerFree"); if (cm) { - #ifdef HAVE_CRL - if (cm->crl) - FreeCRL(cm->crl, 1); - #endif - #ifdef HAVE_OCSP - if (cm->ocsp) - FreeOCSP(cm->ocsp, 1); - XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); - #if !defined(NO_WOLFSSL_SERVER) && \ - (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ - defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) - if (cm->ocsp_stapling) - FreeOCSP(cm->ocsp_stapling, 1); - #endif - #endif - FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->caLock); + if (wc_LockMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock cm mutex"); + } + cm->refCount--; + if (cm->refCount == 0) + doFree = 1; + wc_UnLockMutex(&cm->refMutex); + if (doFree) { + #ifdef HAVE_CRL + if (cm->crl) + FreeCRL(cm->crl, 1); + #endif + #ifdef HAVE_OCSP + if (cm->ocsp) + FreeOCSP(cm->ocsp, 1); + XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL); + #if !defined(NO_WOLFSSL_SERVER) && \ + (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \ + defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)) + if (cm->ocsp_stapling) + FreeOCSP(cm->ocsp_stapling, 1); + #endif + #endif + FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->caLock); - #ifdef WOLFSSL_TRUST_PEER_CERT - FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); - wc_FreeMutex(&cm->tpLock); - #endif + #ifdef WOLFSSL_TRUST_PEER_CERT + FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap); + wc_FreeMutex(&cm->tpLock); + #endif - XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); + XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER); + } } } +int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm) +{ + if (cm) { + if (wc_LockMutex(&cm->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock cm mutex"); + } + cm->refCount++; + wc_UnLockMutex(&cm->refMutex); + + return WOLFSSL_SUCCESS; + } + + return WOLFSSL_FAILURE; +} + #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) #if defined(WOLFSSL_SIGNER_DER_CERT) /****************************************************************************** @@ -15333,15 +15364,20 @@ int wolfSSL_set_compression(WOLFSSL* ssl) void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str) { - if (ctx == NULL || str == NULL) { + if (ctx == NULL || str == NULL || ctx->cm == str->cm) { return; } + if (wolfSSL_CertManager_up_ref(str->cm) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CertManager_up_ref error"); + return; + } /* free cert manager if have one */ if (ctx->cm != NULL) { wolfSSL_CertManagerFree(ctx->cm); } ctx->cm = str->cm; + ctx->x509_store.cm = str->cm; /* free existing store if it exists */ if (ctx->x509_store_pt != NULL) { @@ -15888,6 +15924,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) wc_RemoveErrorNode(0); } } while (ret >= 0); + wolfSSL_BIO_write(bio, "", 1); } #endif /* !NO_BIO */ #endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ @@ -19534,6 +19571,98 @@ WOLFSSL_STACK *wolfSSL_NCONF_get_section( return NULL; } +static char* expandValue(WOLFSSL_CONF *conf, const char* section, + char *str) +{ + int strLen = XSTRLEN(str); + char* ret = NULL; + + /* Check to see if there is anything to expand */ + if (XSTRNSTR(str, "$", strLen)) { + int idx = 0; + char* strIdx = str; + ret = (char*)XMALLOC(strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret) { + WOLFSSL_MSG("malloc error"); + return str; + } + + while (*strIdx) { + if (*strIdx == '$') { + /* Expand variable */ + char* startIdx = ++strIdx; + char* endIdx; + const char* s = section; + const char* value; + char prevValue; + + if (*startIdx == '{') { + /* First read the section. Ex: ${ENV::COUNT} */ + s = ++startIdx; + while (*strIdx && *strIdx != ':') strIdx++; + if (!strIdx || s == strIdx || strIdx[1] != ':') { + WOLFSSL_MSG("invalid section name in " + "variable expansion"); + goto expand_cleanup; + } + *strIdx = '\0'; + *strIdx += 2; + startIdx = strIdx; + } + while (*strIdx && (XISALPHA(*strIdx) || *strIdx == '_')) + strIdx++; + endIdx = strIdx; + if (startIdx == endIdx) { + WOLFSSL_MSG("invalid variable name in config"); + goto expand_cleanup; + } + if (s != section) { + /* We are expecting a trailing '}' */ + if (*strIdx != '}') { + WOLFSSL_MSG("Missing '}' in variable"); + goto expand_cleanup; + } + strIdx++; + } + /* Save char value at the end of the name so that we can place + * a null char there. */ + prevValue = *endIdx; + *endIdx = '\0'; + value = wolfSSL_NCONF_get_string(conf, s, startIdx); + *endIdx = prevValue; + /* Skip copy if no value or zero-length value */ + if (value && *value) { + int valueLen = XSTRLEN(value); + char* newRet; + /* This will allocate slightly more memory than necessary + * but better be safe */ + strLen += valueLen; + newRet = (char*)XREALLOC(ret, strLen + 1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (!newRet) { + WOLFSSL_MSG("realloc error"); + goto expand_cleanup; + } + ret = newRet; + XMEMCPY(ret + idx, value, valueLen); + idx += valueLen; + } + } + else { + ret[idx++] = *strIdx++; + } + } + ret[idx] = '\0'; + } + + return ret ? ret : str; + +expand_cleanup: + if (ret) + XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; +} + #define SKIP_WHITESPACE(idx, max_idx) \ while (idx < max_idx && (*idx == ' ' || *idx == '\t')) \ {idx++;} @@ -19632,6 +19761,7 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) char* name; int nameLen; char* value; + char* exValue; /* expanded value */ int valueLen; WOLFSSL_CONF_VALUE* newVal = NULL; @@ -19663,12 +19793,22 @@ int wolfSSL_NCONF_load(WOLFSSL_CONF *conf, const char *file, long *eline) name[nameLen] = '\0'; value[valueLen] = '\0'; - if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, - name, value))) { - WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); + if (!(exValue = expandValue(conf, section->section, value))) { + WOLFSSL_MSG("Variable expansion failed"); goto cleanup; } + if (!(newVal = wolfSSL_CONF_VALUE_new_values(section->section, + name, exValue))) { + WOLFSSL_MSG("wolfSSL_CONF_VALUE_new_values error"); + if (exValue != value) + XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL); + goto cleanup; + } + + if (exValue != value) + XFREE(exValue, NULL, DYNAMIC_TYPE_OPENSSL); + if (wolfSSL_CONF_add_string(conf, section, newVal) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("wolfSSL_CONF_add_string error"); @@ -27089,6 +27229,13 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at) case V_ASN1_GENERALIZEDTIME: wolfSSL_ASN1_TIME_free(at->value.generalizedtime); break; + case V_ASN1_UTF8STRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_IA5STRING: + case V_ASN1_UNIVERSALSTRING: + wolfSSL_ASN1_STRING_free(at->value.asn1_string); + break; default: WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE"); break; @@ -27190,10 +27337,14 @@ int wolfSSL_X509_PUBKEY_get0_param(WOLFSSL_ASN1_OBJECT **ppkalg, WOLFSSL_EVP_PKEY* wolfSSL_X509_PUBKEY_get(WOLFSSL_X509_PUBKEY* key) { WOLFSSL_ENTER("wolfSSL_X509_PUBKEY_get"); - if(key == NULL || key->pkey == NULL){ + if (key == NULL || key->pkey == NULL) { WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_FUNC_ARG); return NULL; } + if (wolfSSL_EVP_PKEY_up_ref(key->pkey) != WOLFSSL_SUCCESS) { + WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", BAD_MUTEX_E); + return NULL; + } WOLFSSL_LEAVE("wolfSSL_X509_PUBKEY_get", WOLFSSL_SUCCESS); return key->pkey; } @@ -29775,6 +29926,10 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { "jurisdictionCountryName"}, { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName, oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"}, +#ifdef WOLFSSL_CERT_REQ + { NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID, + oidCsrAttrType, "challengePassword", "challengePassword"}, +#endif #endif #ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */ /* oidHashType */ @@ -38425,10 +38580,10 @@ int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) rsa->refCount++; wc_UnLockMutex(&rsa->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } /* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */ @@ -38441,10 +38596,10 @@ int wolfSSL_X509_up_ref(WOLFSSL_X509* x509) x509->refCount++; wc_UnLockMutex(&x509->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } #endif /* OPENSSL_EXTRA || OPENSSL_ALL */ @@ -39182,6 +39337,12 @@ void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl) if (req->keyUsageSet) cert->keyUsage = req->keyUsage; /* Extended Key Usage not supported. */ + #endif + #ifdef WOLFSSL_CERT_REQ + if (XSTRLEN(cert->challengePw) > 0) { + XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE); + cert->challengePwPrintableString = 1; + } #endif } @@ -41552,6 +41713,7 @@ err: { word32 oid = 0; word32 idx = 0; + int ret; WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid"); @@ -41569,9 +41731,29 @@ err: if (o->nid > 0) return o->nid; - if (GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz) < 0) { - WOLFSSL_MSG("Issue getting OID of object"); - return -1; + if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) { + if (ret == ASN_OBJECT_ID_E) { + /* Put ASN object tag in front and try again */ + int len = SetObjectId(o->objSz, NULL) + o->objSz; + byte* buf = XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (!buf) { + WOLFSSL_MSG("malloc error"); + return -1; + } + idx = SetObjectId(o->objSz, buf); + XMEMCPY(buf + idx, o->obj, o->objSz); + idx = 0; + ret = GetObjectId(buf, &idx, &oid, o->grp, len); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (ret < 0) { + WOLFSSL_MSG("Issue getting OID of object"); + return -1; + } + } + else { + WOLFSSL_MSG("Issue getting OID of object"); + return -1; + } } return oid2nid(oid, o->grp); @@ -47149,6 +47331,7 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl, int oid2nid(word32 oid, int grp) { + size_t i; /* get OID type */ switch (grp) { /* oidHashType */ @@ -47470,9 +47653,23 @@ int oid2nid(word32 oid, int grp) } break; + case oidCsrAttrType: + switch (oid) { + case CHALLENGE_PASSWORD_OID: + return NID_pkcs9_challengePassword; + case SERIAL_NUMBER_OID: + return NID_serialNumber; + } + break; + default: WOLFSSL_MSG("NID not in table"); - return -1; + } + /* If not found in above switch then try the table */ + for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) { + if (wolfssl_object_info[i].id == (int)oid) { + return wolfssl_object_info[i].nid; + } } return -1; @@ -50270,6 +50467,11 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, int hashOID = p7->hashOID; byte version = p7->version; + if (!certs->data.x509 || !certs->data.x509->derCert) { + WOLFSSL_MSG("Missing cert"); + return WOLFSSL_FAILURE; + } + if (wc_PKCS7_InitWithCert(p7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_InitWithCert error"); @@ -50283,6 +50485,10 @@ int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs, /* Add the certs to the PKCS7 struct */ while (certs) { + if (!certs->data.x509 || !certs->data.x509->derCert) { + WOLFSSL_MSG("Missing cert"); + return WOLFSSL_FAILURE; + } if (wc_PKCS7_AddCertificate(p7, certs->data.x509->derCert->buffer, certs->data.x509->derCert->length) != 0) { WOLFSSL_MSG("wc_PKCS7_AddCertificate error"); @@ -51165,7 +51371,11 @@ int wolfSSL_X509_REQ_sign(WOLFSSL_X509 *req, WOLFSSL_EVP_PKEY *pkey, int wolfSSL_X509_REQ_sign_ctx(WOLFSSL_X509 *req, WOLFSSL_EVP_MD_CTX* md_ctx) { - return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey, wolfSSL_EVP_MD_CTX_md(md_ctx)); + if (md_ctx && md_ctx->pctx) + return wolfSSL_X509_REQ_sign(req, md_ctx->pctx->pkey, + wolfSSL_EVP_MD_CTX_md(md_ctx)); + else + return WOLFSSL_FAILURE; } #ifndef NO_WOLFSSL_STUB @@ -51176,22 +51386,6 @@ int wolfSSL_X509_REQ_add_extensions(WOLFSSL_X509* req, (void)ext; return WOLFSSL_FAILURE; } - -int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, - int nid, int type, - const unsigned char *bytes, - int len) -{ - WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID"); - WOLFSSL_STUB("wolfSSL_X509_REQ_add1_attr_by_NID"); - (void)req; - (void)nid; - (void)type; - (void)bytes; - (void)len; - return WOLFSSL_FAILURE; -} - int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const char *attrname, int type, const unsigned char *bytes, int len) @@ -51205,28 +51399,157 @@ int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, (void)len; return WOLFSSL_FAILURE; } +#endif /* NO_WOLFSSL_STUB */ +int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, + int nid, int type, + const unsigned char *bytes, + int len) +{ + WOLFSSL_ENTER("wolfSSL_X509_REQ_add1_attr_by_NID"); + + if (!req || !bytes || type != MBSTRING_ASC) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FAILURE; + } + + switch (nid) { + case NID_pkcs9_challengePassword: + if (len < 0) + len = XSTRLEN((char*)bytes); + if (len < CTC_NAME_SIZE) { + XMEMCPY(req->challengePw, bytes, len); + req->challengePw[len] = '\0'; + } + else { + WOLFSSL_MSG("Challenge password too long"); + return WOLFSSL_FAILURE; + } + if (req->challengePwAttr) { + wolfSSL_X509_ATTRIBUTE_free(req->challengePwAttr); + } + req->challengePwAttr = wolfSSL_X509_ATTRIBUTE_new(); + if (req->challengePwAttr) { + req->challengePwAttr->value->value.asn1_string = + wolfSSL_ASN1_STRING_new(); + if (wolfSSL_ASN1_STRING_set( + req->challengePwAttr->value->value.asn1_string, + bytes, len) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error"); + return WOLFSSL_FAILURE; + } + req->challengePwAttr->value->type = V_ASN1_PRINTABLESTRING; + } + else { + WOLFSSL_MSG("wolfSSL_X509_ATTRIBUTE_new error"); + return WOLFSSL_FAILURE; + } + break; + default: + WOLFSSL_MSG("Unsupported attribute"); + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; +} + + +/* Return NID as the attr index */ int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, int nid, int lastpos) { WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID"); - WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr_by_NID"); - (void)req; - (void)nid; - (void)lastpos; - return WOLFSSL_FATAL_ERROR; + + /* Since we only support 1 attr per attr type then a lastpos of >= 0 + * indicates that one was already returned */ + if (!req || lastpos >= 0) { + WOLFSSL_MSG("Bad parameter"); + return WOLFSSL_FATAL_ERROR; + } + + switch (nid) { + case NID_pkcs9_challengePassword: + return req->challengePwAttr ? nid : WOLFSSL_FATAL_ERROR; + default: + WOLFSSL_MSG("Unsupported attribute"); + return WOLFSSL_FATAL_ERROR; + } } +/** + * @param req X509_REQ containing attribute + * @param loc NID of the attribute to return + */ WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( const WOLFSSL_X509 *req, int loc) { WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr"); - WOLFSSL_STUB("wolfSSL_X509_REQ_get_attr"); - (void)req; - (void)loc; - return NULL; + + if (!req) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + switch (loc) { + case NID_pkcs9_challengePassword: + return req->challengePwAttr; + default: + WOLFSSL_MSG("Unsupported attribute"); + return NULL; + } +} + +WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void) +{ + WOLFSSL_X509_ATTRIBUTE* ret; + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_new"); + ret = (WOLFSSL_X509_ATTRIBUTE*)XMALLOC(sizeof(WOLFSSL_X509_ATTRIBUTE), + NULL, DYNAMIC_TYPE_OPENSSL); + if (!ret) { + WOLFSSL_MSG("malloc error"); + return NULL; + } + XMEMSET(ret, 0, sizeof(WOLFSSL_X509_ATTRIBUTE)); + ret->object = wolfSSL_ASN1_OBJECT_new(); + ret->value = wolfSSL_ASN1_TYPE_new(); + /* Don't allocate ret->set since WOLFSSL_ASN1_TYPE + * is not supported as a stack type */ + if (!ret->object || !ret->value) { + WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new or wolfSSL_ASN1_TYPE_new error"); + wolfSSL_X509_ATTRIBUTE_free(ret); + return NULL; + } + return ret; +} + +void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr) +{ + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_free"); + if (attr) { + if (attr->object) { + wolfSSL_ASN1_OBJECT_free(attr->object); + } + if (attr->value) { + wolfSSL_ASN1_TYPE_free(attr->value); + } + if (attr->set) { + wolfSSL_sk_free(attr->set); + } + XFREE(attr, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type( + WOLFSSL_X509_ATTRIBUTE *attr, int idx) +{ + WOLFSSL_ENTER("wolfSSL_X509_ATTRIBUTE_get0_type"); + + if (!attr || idx != 0) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + return attr->value; } -#endif WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md) diff --git a/tests/api.c b/tests/api.c index 5e198011a..24278065c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30086,7 +30086,8 @@ static void test_wolfSSL_ERR_print_errors(void) AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 57); AssertIntEQ(XSTRNCMP("error:295:wolfSSL library:unknown error number:asn.c:100", buf, 56), 0); - AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0); + AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 1); + AssertIntEQ(buf[0], '\0'); AssertIntEQ(ERR_get_error_line(NULL, NULL), 0); BIO_free(bio); @@ -33280,9 +33281,9 @@ static void test_wolfSSL_get_ciphers_compat(void) static void test_wolfSSL_X509_PUBKEY_get(void) { - WOLFSSL_X509_PUBKEY pubkey; + WOLFSSL_X509_PUBKEY pubkey = {0}; WOLFSSL_X509_PUBKEY* key; - WOLFSSL_EVP_PKEY evpkey; + WOLFSSL_EVP_PKEY evpkey = {0}; WOLFSSL_EVP_PKEY* evpPkey; WOLFSSL_EVP_PKEY* retEvpPkey; @@ -37887,26 +37888,51 @@ static void test_wolfSSL_X509_CRL(void) static void test_wolfSSL_d2i_X509_REQ(void) { - const char* csrFile = "./csr.signed.der"; + const char* csrFile = "./certs/csr.signed.der"; + const char* csrPopFile = "./certs/csr.attr.der"; BIO* bio = NULL; X509* req = NULL; EVP_PKEY *pub_key = NULL; - AssertNotNull(bio = BIO_new_file(csrFile, "rb")); - AssertNotNull(d2i_X509_REQ_bio(bio, &req)); + { + AssertNotNull(bio = BIO_new_file(csrFile, "rb")); + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); - /* - * Extract the public key from the CSR - */ - AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); - /* - * Verify the signature in the CSR - */ - AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); - X509_free(req); - BIO_free(bio); + X509_free(req); + BIO_free(bio); + } + { + AssertNotNull(bio = BIO_new_file(csrPopFile, "rb")); + AssertNotNull(d2i_X509_REQ_bio(bio, &req)); + + /* + * Extract the public key from the CSR + */ + AssertNotNull(pub_key = X509_REQ_get_pubkey(req)); + + /* + * Verify the signature in the CSR + */ + AssertIntEQ(X509_REQ_verify(req, pub_key), 1); + + /* + * Obtain the challenge password from the CSR + */ + AssertIntGE(X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1), 0); + + X509_free(req); + BIO_free(bio); + } } static void test_wolfSSL_PEM_read_X509(void) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e5062c3d8..d686dfb39 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1660,6 +1660,13 @@ static const byte extExtKeyUsageCodeSigningOid[] = {43, 6, 1, 5, 5, 7, 3, 3}; static const byte extExtKeyUsageEmailProtectOid[] = {43, 6, 1, 5, 5, 7, 3, 4}; static const byte extExtKeyUsageTimestampOid[] = {43, 6, 1, 5, 5, 7, 3, 8}; static const byte extExtKeyUsageOcspSignOid[] = {43, 6, 1, 5, 5, 7, 3, 9}; + +#ifdef WOLFSSL_CERT_REQ +/* csrAttrType */ +static const byte attrChallengePasswordOid[] = {42, 134, 72, 134, 247, 13, 1, 9, 7}; +static const byte attrSerialNumberOid[] = {85, 4, 5}; +#endif + /* kdfType */ static const byte pbkdf2Oid[] = {42, 134, 72, 134, 247, 13, 1, 5, 12}; @@ -2287,6 +2294,20 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) } break; #endif /* WOLFSSL_APACHE_HTTPD */ +#ifdef WOLFSSL_CERT_REQ + case oidCsrAttrType: + switch (id) { + case CHALLENGE_PASSWORD_OID: + oid = attrChallengePasswordOid; + *oidSz = sizeof(attrChallengePasswordOid); + break; + case SERIAL_NUMBER_OID: + oid = attrSerialNumberOid; + *oidSz = sizeof(attrSerialNumberOid); + break; + } + break; +#endif case oidIgnoreType: default: break; @@ -2454,8 +2475,11 @@ int SetObjectId(int len, byte* output) { int idx = 0; - output[idx++] = ASN_OBJECT_ID; - idx += SetLength(len, output + idx); + if (output) + output[idx++] = ASN_OBJECT_ID; + else + idx++; + idx += SetLength(len, output ? output + idx : NULL); return idx; } @@ -5453,6 +5477,7 @@ static int GetKey(DecodedCert* cert) } #endif /* NO_DSA */ default: + WOLFSSL_MSG("Unknown or not compiled in key OID"); return ASN_UNKNOWN_OID_E; } } @@ -9480,9 +9505,67 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) } if (len) { - WOLFSSL_MSG("Non-empty attributes. wolfSSL doesn't support " - "parsing CSR attributes."); - return ASN_VERSION_E; + word32 attrMaxIdx = cert->srcIdx + len; + word32 oid; + byte tag; + + if (attrMaxIdx > cert->maxIdx) { + WOLFSSL_MSG("Attribute length greater than CSR length"); + return ASN_PARSE_E; + } + + while (cert->srcIdx < attrMaxIdx) { + /* Attributes have the structure: + * SEQ -> OID -> SET -> ATTRIBUTE */ + if (GetSequence(cert->source, &cert->srcIdx, &len, + attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetSequence error"); + return ASN_PARSE_E; + } + if (GetObjectId(cert->source, &cert->srcIdx, &oid, + oidCsrAttrType, attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetObjectId error"); + return ASN_PARSE_E; + } + if (GetSet(cert->source, &cert->srcIdx, &len, + attrMaxIdx) < 0) { + WOLFSSL_MSG("attr GetSet error"); + return ASN_PARSE_E; + } + /* For now all supported attributes have the type value + * of ASN_PRINTABLE_STRING or ASN_UTF8STRING but as more + * attributes are supported then this will have to be done + * on a per attribute basis. */ + if (GetHeader(cert->source, &tag, + &cert->srcIdx, &len, attrMaxIdx, 1) < 0) { + WOLFSSL_MSG("attr GetHeader error"); + return ASN_PARSE_E; + } + if (tag != ASN_PRINTABLE_STRING && tag != ASN_UTF8STRING && + tag != ASN_IA5_STRING) { + WOLFSSL_MSG("Unsupported attribute value format"); + return ASN_PARSE_E; + } + switch (oid) { + case CHALLENGE_PASSWORD_OID: + cert->cPwd = (char*)cert->source + cert->srcIdx; + cert->cPwdLen = len; + cert->srcIdx += len; + break; + case SERIAL_NUMBER_OID: + cert->sNum = (char*)cert->source + cert->srcIdx; + cert->sNumLen = len; + cert->srcIdx += len; + if (cert->sNumLen <= EXTERNAL_SERIAL_SIZE) { + XMEMCPY(cert->serial, cert->sNum, cert->sNumLen); + cert->serialSz = cert->sNumLen; + } + break; + default: + WOLFSSL_MSG("Unsupported attribute type"); + return ASN_PARSE_E; + } + } } } #endif @@ -13883,9 +13966,6 @@ int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz, static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, int extSz) { - const byte cpOid[] = - { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x09, 0x07 }; const byte erOid[] = { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e }; @@ -13916,8 +13996,11 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, cpStrSz = SetUTF8String(pwSz, cpStr); } cpSetSz = SetSet(cpStrSz + pwSz, cpSet); - cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq); - cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz; + /* +2 for tag and length parts of the TLV triplet */ + cpSeqSz = SetSequence(2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpStrSz + pwSz, cpSeq); + cpSz = cpSeqSz + 2 + sizeof(attrChallengePasswordOid) + cpSetSz + + cpStrSz + pwSz; } if (extSz) { @@ -13932,8 +14015,10 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, if (cpSz) { XMEMCPY(&output[sz], cpSeq, cpSeqSz); sz += cpSeqSz; - XMEMCPY(&output[sz], cpOid, sizeof(cpOid)); - sz += sizeof(cpOid); + sz += SetObjectId(sizeof(attrChallengePasswordOid), output + sz); + XMEMCPY(&output[sz], attrChallengePasswordOid, + sizeof(attrChallengePasswordOid)); + sz += sizeof(attrChallengePasswordOid); XMEMCPY(&output[sz], cpSet, cpSetSz); sz += cpSetSz; XMEMCPY(&output[sz], cpStr, cpStrSz); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8dd4773db..2f268a18f 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1330,7 +1330,6 @@ int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx) WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e) { WOLFSSL_EVP_PKEY_CTX* ctx; - int type = NID_undef; if (pkey == NULL) return 0; if (e != NULL) return 0; @@ -1344,15 +1343,8 @@ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_E #if !defined(NO_RSA) && !defined(HAVE_USER_RSA) ctx->padding = RSA_PKCS1_PADDING; #endif - type = wolfSSL_EVP_PKEY_type(pkey->type); - - if (type != NID_undef) { - if (wc_LockMutex(&pkey->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock pkey mutex"); - } - pkey->references++; - - wc_UnLockMutex(&pkey->refMutex); + if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Couldn't increase key reference count"); } return ctx; } @@ -1925,7 +1917,7 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, #ifndef NO_DSA case EVP_PKEY_DSA: if (from->dsa) { - WOLFSSL_BIGNUM cpy; + WOLFSSL_BIGNUM* cpy; if (!to->dsa && !(to->dsa = wolfSSL_DSA_new())) { WOLFSSL_MSG("wolfSSL_DSA_new error"); return WOLFSSL_FAILURE; @@ -1935,12 +1927,12 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, return WOLFSSL_FAILURE; } to->dsa->p = cpy; - if (!(cpy = wolfSSL_BN_dup(from->dsa->q)) { + if (!(cpy = wolfSSL_BN_dup(from->dsa->q))) { WOLFSSL_MSG("wolfSSL_BN_dup error"); return WOLFSSL_FAILURE; } to->dsa->q = cpy; - if (!(cpy = wolfSSL_BN_dup(from->dsa->g)) { + if (!(cpy = wolfSSL_BN_dup(from->dsa->g))) { WOLFSSL_MSG("wolfSSL_BN_dup error"); return WOLFSSL_FAILURE; } @@ -2375,21 +2367,16 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, ctx->isHMAC = 1; } - else { - int ret; + else if (wolfSSL_EVP_DigestInit(ctx, type) != 1) + return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { - ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); - if (ctx->pctx == NULL) - return WOLFSSL_FAILURE; - } - - ret = wolfSSL_EVP_DigestInit(ctx, type); - if (ret == WOLFSSL_SUCCESS && pctx != NULL) - *pctx = ctx->pctx; - return ret; + if (ctx->pctx == NULL) { + ctx->pctx = wolfSSL_EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return WOLFSSL_FAILURE; } - + if (pctx != NULL) + *pctx = ctx->pctx; return WOLFSSL_SUCCESS; } @@ -2399,10 +2386,7 @@ static int wolfSSL_evp_digest_pk_init(WOLFSSL_EVP_MD_CTX *ctx, static int wolfssl_evp_digest_pk_update(WOLFSSL_EVP_MD_CTX *ctx, const void *d, unsigned int cnt) { - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - + if (ctx->isHMAC) { if (wc_HmacUpdate(&ctx->hash.hmac, (const byte *)d, cnt) != 0) return WOLFSSL_FAILURE; @@ -2421,12 +2405,9 @@ static int wolfssl_evp_digest_pk_final(WOLFSSL_EVP_MD_CTX *ctx, { int ret; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { Hmac hmacCopy; - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - if (wolfSSL_HmacCopy(&hmacCopy, &ctx->hash.hmac) != WOLFSSL_SUCCESS) return WOLFSSL_FAILURE; ret = wc_HmacFinal(&hmacCopy, md) == 0; @@ -2561,10 +2542,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, return WOLFSSL_FAILURE; /* Return the maximum size of the signaure when sig is NULL. */ - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; - + if (ctx->isHMAC) { hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); if (sig == NULL) { @@ -2594,7 +2572,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { /* Copy the HMAC result as signature. */ if ((unsigned int)(*siglen) > hashLen) *siglen = hashLen; @@ -2679,9 +2657,7 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, if (ctx == NULL || sig == NULL) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { - if (!ctx->isHMAC) - return WOLFSSL_FAILURE; + if (ctx->isHMAC) { hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); @@ -2693,7 +2669,7 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0) return WOLFSSL_FAILURE; - if (ctx->pctx == NULL) { + if (ctx->isHMAC) { /* Check HMAC result matches the signature. */ if (XMEMCMP(sig, digest, siglen) == 0) return WOLFSSL_SUCCESS; @@ -5766,11 +5742,15 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key) if ((pkey == NULL) || (key == NULL)) return WOLFSSL_FAILURE; + if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_RSA_up_ref failed"); + return WOLFSSL_FAILURE; + } if (pkey->rsa != NULL && pkey->ownRsa == 1) { wolfSSL_RSA_free(pkey->rsa); } pkey->rsa = key; - pkey->ownRsa = 0; /* pkey does not own RSA */ + pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */ pkey->type = EVP_PKEY_RSA; if (key->inSet == 0) { if (SetRsaInternal(key) != WOLFSSL_SUCCESS) { @@ -6623,10 +6603,10 @@ int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey) pkey->references++; wc_UnLockMutex(&pkey->refMutex); - return 1; + return WOLFSSL_SUCCESS; } - return 0; + return WOLFSSL_FAILURE; } #ifndef NO_RSA diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 471961588..78a368ef0 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2269,8 +2269,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd, byte signingTime[MAX_TIME_STRING_SZ]; - if (pkcs7 == NULL || (pkcs7->contentSz > 0 && pkcs7->content == NULL) || - pkcs7->hashOID == 0 || + if (pkcs7 == NULL || pkcs7->hashOID == 0 || output == NULL || outputSz == NULL || *outputSz == 0 || hashSz == 0 || hashBuf == NULL) { return BAD_FUNC_ARG; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 4c398e4bf..53d2c1545 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2029,6 +2029,8 @@ struct WOLFSSL_CERT_MANAGER { #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum allowed ECC key size */ #endif + wolfSSL_Mutex refMutex; /* reference count mutex */ + int refCount; /* reference count */ }; WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*); @@ -3762,6 +3764,7 @@ struct WOLFSSL_X509 { byte serial[EXTERNAL_SERIAL_SIZE]; char subjectCN[ASN_NAME_MAX]; /* common name short cut */ #ifdef WOLFSSL_CERT_REQ + WOLFSSL_X509_ATTRIBUTE* challengePwAttr; char challengePw[CTC_NAME_SIZE]; /* for REQ certs */ #endif WOLFSSL_X509_NAME issuer; diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 5d6029173..31c88d619 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -242,6 +242,9 @@ 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 +#ifndef NO_WOLFSSL_STUB +#define PEM_write_bio_ECPKParameters(...) 0 +#endif /* EVP_KEY */ #define PEM_read_bio_PrivateKey wolfSSL_PEM_read_bio_PrivateKey #define PEM_read_PUBKEY wolfSSL_PEM_read_PUBKEY diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6d3c10c6c..0b097c1ca 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -390,6 +390,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_REQ_add1_attr_by_txt wolfSSL_X509_REQ_add1_attr_by_txt #define X509_REQ_get_attr_by_NID wolfSSL_X509_REQ_get_attr_by_NID #define X509_REQ_get_attr wolfSSL_X509_REQ_get_attr +#define X509_ATTRIBUTE_get0_type wolfSSL_X509_ATTRIBUTE_get0_type #define X509_to_X509_REQ wolfSSL_X509_to_X509_REQ #define X509_REQ_set_subject_name wolfSSL_X509_REQ_set_subject_name #define X509_REQ_set_pubkey wolfSSL_X509_REQ_set_pubkey @@ -654,6 +655,11 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size #define BIO_f_ssl wolfSSL_BIO_f_ssl #define BIO_new_socket wolfSSL_BIO_new_socket +#ifndef NO_WOLFSSL_STUB +#define BIO_new_connect(...) NULL +#define BIO_set_conn_port(...) 0 +#define BIO_do_connect(...) 0 +#endif #define SSL_set_bio wolfSSL_set_bio #define BIO_set_ssl wolfSSL_BIO_set_ssl #define BIO_eof wolfSSL_BIO_eof diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 55e49c6b1..c09990a12 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -334,6 +334,7 @@ struct WOLFSSL_ASN1_TYPE { struct WOLFSSL_X509_ATTRIBUTE { WOLFSSL_ASN1_OBJECT *object; + WOLFSSL_ASN1_TYPE *value; WOLF_STACK_OF(WOLFSSL_ASN1_TYPE) *set; }; @@ -2771,6 +2772,7 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl); WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap); WOLFSSL_API WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void); WOLFSSL_API void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER*); + WOLFSSL_API int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER*); WOLFSSL_API int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER*, const char* f, const char* d); @@ -3603,7 +3605,10 @@ WOLFSSL_API int wolfSSL_X509_REQ_add1_attr_by_txt(WOLFSSL_X509 *req, const unsigned char *bytes, int len); WOLFSSL_API WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( const WOLFSSL_X509 *req, int loc); - +WOLFSSL_API WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void); +WOLFSSL_API void wolfSSL_X509_ATTRIBUTE_free(WOLFSSL_X509_ATTRIBUTE* attr); +WOLFSSL_API WOLFSSL_ASN1_TYPE *wolfSSL_X509_ATTRIBUTE_get0_type( + WOLFSSL_X509_ATTRIBUTE *attr, int idx); WOLFSSL_API WOLFSSL_X509 *wolfSSL_X509_to_X509_REQ(WOLFSSL_X509 *x, WOLFSSL_EVP_PKEY *pkey, const WOLFSSL_EVP_MD *md); #endif diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index a1628c04a..c99608915 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -100,6 +100,7 @@ enum ASN_Tags { ASN_SEQUENCE = 0x10, ASN_SET = 0x11, ASN_PRINTABLE_STRING = 0x13, + ASN_IA5_STRING = 0x16, ASN_UTC_TIME = 0x17, ASN_OTHER_TYPE = 0x00, ASN_RFC822_TYPE = 0x01, @@ -427,6 +428,7 @@ enum Oid_Types { oidCertNameType = 17, oidTlsExtType = 18, oidCrlExtType = 19, + oidCsrAttrType = 20, oidIgnoreType }; @@ -593,6 +595,13 @@ enum KeyIdType { }; #endif +#ifdef WOLFSSL_CERT_REQ +enum CsrAttyType { + CHALLENGE_PASSWORD_OID = 659, + SERIAL_NUMBER_OID = 94, +}; +#endif + /* Key usage extension bits (based on RFC 5280) */ #define KEYUSE_DIGITAL_SIG 0x0080 #define KEYUSE_CONTENT_COMMIT 0x0040 @@ -894,6 +903,14 @@ struct DecodedCert { int extCertPoliciesNb; #endif /* defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) */ +#ifdef WOLFSSL_CERT_REQ + /* CSR attributes */ + char* cPwd; /* challengePassword */ + int cPwdLen; + char* sNum; /* Serial Number */ + int sNumLen; +#endif /* WOLFSSL_CERT_REQ */ + Signer* ca; #ifndef NO_CERTS SignatureCtx sigCtx;