Merge pull request #9713 from padelsbach/crl-generation-cert-updates

Add cert/CRL capabilities: skid, akid, dist point, netscape
This commit is contained in:
Chris Conlon
2026-02-16 15:29:18 -07:00
committed by GitHub
9 changed files with 612 additions and 109 deletions
+2 -6
View File
@@ -95,12 +95,8 @@ check_crl() {
-CRLfile "$crl" \
"$revoked_cert" 2>&1) || verify_rc=$?
verify_rc=${verify_rc:-0}
# Normalize to avoid case/CR differences and accept common OpenSSL error
# formats (some builds report only an error code).
verify_out_norm=$(printf '%s' "$verify_out" | tr '[:upper:]' '[:lower:]' | \
tr -d '\r')
if ! echo "$verify_out_norm" | grep -q "revoked" && \
! echo "$verify_out_norm" | grep -q "error 23"; then
# Avoid pipefail/SIGPIPE false negatives with `grep -q` in a pipeline.
if ! grep -qi "revoked" <<< "$verify_out"; then
echo "expected revoked verification failure for $label CRL"
echo "$verify_out"
return 1
+108 -90
View File
@@ -825,6 +825,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
*/
int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
{
int ret = 0;
CRL_Entry* ent = NULL;
const byte* tbs = NULL;
word32 tbsSz = 0;
@@ -850,7 +851,8 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
outSz = *inOutSz;
/* Access the first CRL entry. */
/* Access the first CRL entry. Lock is held until encoding is complete
* to prevent the entry from being freed by another thread. */
if (wc_LockRwLock_Rd(&crl->crlLock) != 0) {
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
return BAD_MUTEX_E;
@@ -867,59 +869,63 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
sigParamsSz = ent->sigParamsSz;
#endif
}
wc_UnLockRwLock(&crl->crlLock);
if (ent == NULL || tbs == NULL || tbsSz == 0 || sig == NULL || sigSz == 0) {
WOLFSSL_MSG("CRL entry missing toBeSigned/signature data");
return BAD_FUNC_ARG;
ret = BAD_FUNC_ARG;
}
/* Calculate encoded lengths for AlgorithmIdentifier. */
if (ret == 0) {
#ifdef WC_RSA_PSS
if (sigParams != NULL && sigParamsSz > 0) {
/* OID + explicit parameters inside SEQUENCE */
word32 oidSz = 0;
word32 idLen;
const byte* oid = OidFromId(sigOID, oidSigType, &oidSz);
if (oid == NULL) {
WOLFSSL_MSG("Unknown signature OID for CRL");
return WOLFSSL_FATAL_ERROR;
if (sigParams != NULL && sigParamsSz > 0) {
/* OID + explicit parameters inside SEQUENCE */
word32 oidSz = 0;
word32 idLen;
const byte* oid = OidFromId(sigOID, oidSigType, &oidSz);
if (oid == NULL) {
WOLFSSL_MSG("Unknown signature OID for CRL");
ret = WOLFSSL_FATAL_ERROR;
}
else {
/* OBJECT IDENTIFIER header */
idLen = (word32)SetObjectId((int)oidSz, NULL);
algoLen = SetSequence(idLen + oidSz + sigParamsSz, NULL)
+ idLen + oidSz + sigParamsSz;
}
}
/* OBJECT IDENTIFIER header */
idLen = (word32)SetObjectId((int)oidSz, NULL);
algoLen = SetSequence(idLen + oidSz + sigParamsSz, NULL)
+ idLen + oidSz + sigParamsSz;
}
else
else
#endif
{
algoLen = SetAlgoID((int)sigOID, NULL, oidSigType, 0);
if (algoLen == 0) {
WOLFSSL_MSG("SetAlgoID failed");
return WOLFSSL_FATAL_ERROR;
{
algoLen = SetAlgoID((int)sigOID, NULL, oidSigType, 0);
if (algoLen == 0) {
WOLFSSL_MSG("SetAlgoID failed");
ret = WOLFSSL_FATAL_ERROR;
}
}
}
/* BIT STRING header for signature */
bitHdrLen = SetBitString(sigSz, 0, NULL);
if (ret == 0) {
/* BIT STRING header for signature */
bitHdrLen = SetBitString(sigSz, 0, NULL);
/* Compute total DER size. */
totalContentLen = tbsSz + algoLen + bitHdrLen + sigSz;
outerHdrLen = SetSequence(totalContentLen, NULL);
derNeeded = outerHdrLen + totalContentLen;
/* Compute total DER size. */
totalContentLen = tbsSz + algoLen + bitHdrLen + sigSz;
outerHdrLen = SetSequence(totalContentLen, NULL);
derNeeded = outerHdrLen + totalContentLen;
}
if (type == WOLFSSL_FILETYPE_ASN1) {
if (ret == 0 && type == WOLFSSL_FILETYPE_ASN1) {
if (buff == NULL) {
*inOutSz = (long)derNeeded;
return WOLFSSL_SUCCESS;
ret = WOLFSSL_SUCCESS;
}
if ((long)derNeeded > outSz) {
else if ((long)derNeeded > outSz) {
WOLFSSL_MSG("Output buffer too small for DER CRL");
return BUFFER_E;
ret = BUFFER_E;
}
/* Encode DER CRL directly into caller buffer. */
{
else {
/* Encode DER CRL directly into caller buffer. */
word32 pos = 0;
#ifdef WC_RSA_PSS
word32 oidSz = 0;
@@ -938,18 +944,20 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
oid = OidFromId(sigOID, oidSigType, &oidSz);
if (oid == NULL) {
WOLFSSL_MSG("Unknown signature OID for CRL");
return WOLFSSL_FATAL_ERROR;
ret = WOLFSSL_FATAL_ERROR;
}
else {
/* SEQUENCE header for AlgorithmIdentifier */
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
oidSz + sigParamsSz, buff + pos);
/* OBJECT IDENTIFIER header and content */
pos += (word32)SetObjectId((int)oidSz, buff + pos);
XMEMCPY(buff + pos, oid, oidSz);
pos += oidSz;
/* Parameters as captured (already DER encoded) */
XMEMCPY(buff + pos, sigParams, sigParamsSz);
pos += sigParamsSz;
}
/* SEQUENCE header for AlgorithmIdentifier */
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
oidSz + sigParamsSz, buff + pos);
/* OBJECT IDENTIFIER header and content */
pos += (word32)SetObjectId((int)oidSz, buff + pos);
XMEMCPY(buff + pos, oid, oidSz);
pos += oidSz;
/* Parameters as captured (already DER encoded) */
XMEMCPY(buff + pos, sigParams, sigParamsSz);
pos += sigParamsSz;
}
else
#endif
@@ -957,26 +965,29 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
pos += SetAlgoID((int)sigOID, buff + pos, oidSigType, 0);
}
/* signature BIT STRING and bytes */
pos += SetBitString(sigSz, 0, buff + pos);
XMEMCPY(buff + pos, sig, sigSz);
if (ret == 0) {
/* signature BIT STRING and bytes */
pos += SetBitString(sigSz, 0, buff + pos);
XMEMCPY(buff + pos, sig, sigSz);
*inOutSz = (long)derNeeded;
ret = WOLFSSL_SUCCESS;
}
(void)pos; /* pos not used after this point */
}
*inOutSz = (long)derNeeded;
return WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_DER_TO_PEM
else if (type == WOLFSSL_FILETYPE_PEM) {
else if (ret == 0 && type == WOLFSSL_FILETYPE_PEM) {
byte* derTmp = NULL;
int pemSz;
/* Build DER first in a temporary buffer. */
derTmp = (byte*)XMALLOC(derNeeded, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (derTmp == NULL) {
return MEMORY_E;
ret = MEMORY_E;
}
/* Encode DER CRL into temporary buffer. */
{
if (ret == 0) {
/* Encode DER CRL into temporary buffer. */
word32 pos = 0;
#ifdef WC_RSA_PSS
word32 oidSz = 0;
@@ -989,56 +1000,63 @@ int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
if (sigParams != NULL && sigParamsSz > 0) {
oid = OidFromId(sigOID, oidSigType, &oidSz);
if (oid == NULL) {
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FATAL_ERROR;
ret = WOLFSSL_FATAL_ERROR;
}
else {
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
oidSz + sigParamsSz, derTmp + pos);
pos += (word32)SetObjectId((int)oidSz, derTmp + pos);
XMEMCPY(derTmp + pos, oid, oidSz);
pos += oidSz;
XMEMCPY(derTmp + pos, sigParams, sigParamsSz);
pos += sigParamsSz;
}
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
oidSz + sigParamsSz, derTmp + pos);
pos += (word32)SetObjectId((int)oidSz, derTmp + pos);
XMEMCPY(derTmp + pos, oid, oidSz);
pos += oidSz;
XMEMCPY(derTmp + pos, sigParams, sigParamsSz);
pos += sigParamsSz;
}
else
#endif
{
pos += SetAlgoID((int)sigOID, derTmp + pos, oidSigType, 0);
}
pos += SetBitString(sigSz, 0, derTmp + pos);
XMEMCPY(derTmp + pos, sig, sigSz);
if (ret == 0) {
pos += SetBitString(sigSz, 0, derTmp + pos);
XMEMCPY(derTmp + pos, sig, sigSz);
}
(void)pos; /* pos not used after this point */
}
/* Determine required PEM size. */
pemSz = wc_DerToPemEx(derTmp, derNeeded, NULL, 0, NULL, CRL_TYPE);
if (pemSz < 0) {
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FATAL_ERROR;
if (ret == 0) {
pemSz = wc_DerToPemEx(derTmp, derNeeded, NULL, 0, NULL, CRL_TYPE);
if (pemSz < 0) {
ret = WOLFSSL_FATAL_ERROR;
}
else if (buff == NULL) {
*inOutSz = pemSz;
ret = WOLFSSL_SUCCESS;
}
else if (outSz < pemSz) {
WOLFSSL_MSG("Output buffer too small for PEM CRL");
ret = BUFFER_E;
}
else if (wc_DerToPemEx(derTmp, derNeeded, buff, (word32)pemSz,
NULL, CRL_TYPE) < 0) {
ret = WOLFSSL_FATAL_ERROR;
}
else {
*inOutSz = pemSz;
ret = WOLFSSL_SUCCESS;
}
}
if (buff == NULL) {
*inOutSz = pemSz;
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_SUCCESS;
}
if (outSz < pemSz) {
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_MSG("Output buffer too small for PEM CRL");
return BUFFER_E;
}
if (wc_DerToPemEx(derTmp, derNeeded, buff, (word32)pemSz, NULL,
CRL_TYPE) < 0) {
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FATAL_ERROR;
}
*inOutSz = pemSz;
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_DER_TO_PEM */
else {
return BAD_FUNC_ARG;
else if (ret == 0) {
ret = BAD_FUNC_ARG;
}
wc_UnLockRwLock(&crl->crlLock);
return ret;
}
#ifdef HAVE_CRL_UPDATE_CB
-1
View File
@@ -11509,7 +11509,6 @@ void wolfSSL_set_dynlock_destroy_callback(
(void)f;
}
/* Sets the DNS hostname to name.
* Hostname is cleared if name is NULL or empty. */
int wolfSSL_set1_host(WOLFSSL * ssl, const char* name)
+369 -9
View File
@@ -34,6 +34,9 @@
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#include <wolfssl/openssl/x509v3.h>
#endif
#ifdef OPENSSL_EXTRA
#include <wolfssl/wolfio.h>
#endif
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
unsigned int wolfSSL_X509_get_extension_flags(WOLFSSL_X509* x509)
@@ -3053,8 +3056,31 @@ int wolfSSL_X509_add_altname(WOLFSSL_X509* x509, const char* name, int type)
return WOLFSSL_SUCCESS;
if (type == ASN_IP_TYPE) {
WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
#ifdef WOLFSSL_IP_ALT_NAME
byte ip4[4];
byte ip6[16];
int ptonRet;
/* Check if this is an ip4 address */
ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4);
if (ptonRet == 1) {
return wolfSSL_X509_add_altname_ex(x509, (const char*)ip4, 4,
type);
}
/* Check for ip6 */
ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6);
if (ptonRet == 1) {
return wolfSSL_X509_add_altname_ex(x509, (const char*)ip6, 16,
type);
}
WOLFSSL_MSG("IP address parse failed");
return WOLFSSL_FAILURE;
#else
WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled");
return WOLFSSL_FAILURE;
#endif
}
return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
@@ -9397,16 +9423,29 @@ int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
}
/* Set signature NID of CRL
* return OID on success
* return WOLFSSL_SUCCESS on success
* return negative value on failure
*/
int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl, int nid)
{
if (crl == NULL || crl->crlList == NULL || nid <= 0)
return BAD_FUNC_ARG;
int ret = WOLFSSL_SUCCESS;
word32 oid;
crl->crlList->signatureOID = nid2oid(nid, oidSigType);
return WOLFSSL_SUCCESS;
if (crl == NULL || crl->crlList == NULL || nid <= 0) {
ret = BAD_FUNC_ARG;
}
if (ret == WOLFSSL_SUCCESS) {
oid = nid2oid(nid, oidSigType);
if (oid == (word32)-1 || oid == (word32)WOLFSSL_FATAL_ERROR) {
ret = WOLFSSL_FATAL_ERROR;
}
else {
crl->crlList->signatureOID = oid;
}
}
return ret;
}
/* Retrieve signature from CRL
@@ -10004,7 +10043,7 @@ int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
*
* @param crl CRL to encode
* @param out Pointer to output buffer pointer
* @return Size of DER encoding on success, negative on failure
* @return Size of DER encoding on success, WOLFSSL_FAILURE on failure
*/
int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
{
@@ -10057,11 +10096,156 @@ int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
if (alloced) {
*out = der;
}
else {
*out += derSz;
}
return (int)derSz;
}
#endif /* HAVE_CRL && OPENSSL_EXTRA */
#if defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
/* Set CRL Distribution Points from pre-encoded DER.
*
* x509 - Certificate to modify
* der - Pre-encoded CRLDistributionPoints DER
* derSz - Size of DER in bytes
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
const unsigned char* der, int derSz)
{
WOLFSSL_ENTER("wolfSSL_X509_CRL_set_dist_points");
if (x509 == NULL || der == NULL || derSz <= 0) {
return WOLFSSL_FAILURE;
}
if (x509->rawCRLInfo != NULL) {
XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
}
x509->rawCRLInfo = (byte*)XMALLOC((word32)derSz, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->rawCRLInfo == NULL) {
return WOLFSSL_FAILURE;
}
XMEMCPY(x509->rawCRLInfo, der, (word32)derSz);
x509->rawCRLInfoSz = derSz;
x509->CRLdistSet = 1;
return WOLFSSL_SUCCESS;
}
/* Add CRL Distribution Point URI.
* Encodes URI into proper CRLDistributionPoints DER format.
*
* x509 - Certificate to modify
* uri - URI string (e.g., "http://crl.example.com/ca.crl")
* critical - Whether extension is critical
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
const char* uri, int critical)
{
word32 uriLen;
byte* derBuf = NULL;
word32 derSz;
word32 idx;
word32 uriTagLen; /* [6] tag + length + URI */
word32 genNamesLen; /* [0] IMPLICIT GeneralNames wrapper */
word32 distPtNmLen; /* [0] EXPLICIT distributionPoint wrapper */
word32 distPtSeqLen; /* SEQUENCE for DistributionPoint */
word32 outerSeqLen; /* SEQUENCE for CRLDistributionPoints */
int ret = WOLFSSL_SUCCESS;
WOLFSSL_ENTER("wolfSSL_X509_CRL_add_dist_point");
if (x509 == NULL || uri == NULL) {
return WOLFSSL_FAILURE;
}
uriLen = (word32)XSTRLEN(uri);
if (uriLen == 0) {
WOLFSSL_MSG("URI empty");
return WOLFSSL_FAILURE;
}
/*
* Encode CRL Distribution Points in DER format:
* CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
* DistributionPoint ::= SEQUENCE {
* distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL
* }
* DistributionPointName ::= CHOICE {
* fullName [0] IMPLICIT GeneralNames
* }
* GeneralNames ::= SEQUENCE OF GeneralName
* GeneralName ::= [6] IMPLICIT IA5String (uniformResourceIdentifier)
*/
/* Calculate sizes from innermost to outermost */
/* [6] tag (1 byte) + length encoding + URI data */
uriTagLen = ASN_TAG_SZ + SetLength(uriLen, NULL) + uriLen;
/* [0] CONSTRUCTED tag (1 byte) + length encoding + uriTagLen */
genNamesLen = ASN_TAG_SZ + SetLength(uriTagLen, NULL) + uriTagLen;
/* [0] CONSTRUCTED tag (1 byte) + length encoding + genNamesLen */
distPtNmLen = ASN_TAG_SZ + SetLength(genNamesLen, NULL) + genNamesLen;
/* SEQUENCE header + distPtNmLen */
distPtSeqLen = SetSequence(distPtNmLen, NULL) + distPtNmLen;
/* Outer SEQUENCE header + distPtSeqLen */
outerSeqLen = SetSequence(distPtSeqLen, NULL) + distPtSeqLen;
derSz = outerSeqLen;
/* Allocate buffer for DER encoding */
derBuf = (byte*)XMALLOC(derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
if (derBuf == NULL) {
return WOLFSSL_FAILURE;
}
/* Build forward using SetSequence/SetHeader/SetLength */
idx = 0;
/* SEQUENCE for CRLDistributionPoints (outer) */
idx += SetSequence(distPtSeqLen, derBuf + idx);
/* SEQUENCE for DistributionPoint */
idx += SetSequence(distPtNmLen, derBuf + idx);
/* [0] EXPLICIT wrapper for distributionPoint */
derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
idx += SetLength(genNamesLen, derBuf + idx);
/* [0] IMPLICIT wrapper for GeneralNames (constructed) */
derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
idx += SetLength(uriTagLen, derBuf + idx);
/* [6] IMPLICIT IA5String tag for URI (context-specific, primitive) */
derBuf[idx++] = (ASN_CONTEXT_SPECIFIC | 6); /* [6] tag */
idx += SetLength(uriLen, derBuf + idx);
/* Copy URI string */
XMEMCPY(derBuf + idx, uri, uriLen);
idx += uriLen;
/* Store the encoded CRL info in x509 */
{
ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf, (int)idx);
if (ret == WOLFSSL_SUCCESS && critical) {
x509->CRLdistCrit = 1;
}
}
XFREE(derBuf, x509->heap, DYNAMIC_TYPE_X509_EXT);
return ret;
}
#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
#ifdef OPENSSL_EXTRA
@@ -13106,9 +13290,8 @@ WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
CRL_TYPE);
}
/* Convert CRL to DER or PEM format.
/* Store CRL to file in DER or PEM format.
* Returns WOLFSSL_SUCCESS on success, negative on failure.
* The caller is responsible for freeing the buffer using XFREE.
*/
int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
{
@@ -15720,6 +15903,183 @@ int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
return WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_CERT_EXT
/* Set Subject Key Identifier from raw bytes.
*
* x509 - Certificate to modify
* skid - Raw SKID bytes
* skidSz - Size of SKID in bytes
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
const unsigned char* skid, int skidSz)
{
WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id");
if (x509 == NULL || skid == NULL || skidSz <= 0) {
return WOLFSSL_FAILURE;
}
/* Allocate/reallocate memory for subjKeyId */
if (x509->subjKeyId == NULL || (int)x509->subjKeyIdSz < skidSz) {
if (x509->subjKeyId != NULL) {
XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
}
x509->subjKeyId = (byte*)XMALLOC((word32)skidSz, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->subjKeyId == NULL) {
return WOLFSSL_FAILURE;
}
}
XMEMCPY(x509->subjKeyId, skid, (word32)skidSz);
x509->subjKeyIdSz = (word32)skidSz;
x509->subjKeyIdSet = 1;
return WOLFSSL_SUCCESS;
}
#ifndef NO_SHA
/* Set Subject Key Identifier by computing SHA-1 hash of the public key.
*
* x509 - Certificate to modify (must have public key set)
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
{
byte hash[WC_SHA_DIGEST_SIZE];
int ret;
WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id_ex");
if (x509 == NULL) {
return WOLFSSL_FAILURE;
}
/* Check if public key has been set */
if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
WOLFSSL_MSG("Public key not set");
return WOLFSSL_FAILURE;
}
/* Compute SHA-1 hash of the public key */
ret = wc_ShaHash(x509->pubKey.buffer, x509->pubKey.length, hash);
if (ret != 0) {
WOLFSSL_MSG("wc_ShaHash failed");
return WOLFSSL_FAILURE;
}
return wolfSSL_X509_set_subject_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
}
#endif /* !NO_SHA */
/* Set Authority Key Identifier from raw bytes.
*
* x509 - Certificate to modify
* akid - Raw AKID bytes
* akidSz - Size of AKID in bytes
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
const unsigned char* akid, int akidSz)
{
WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
if (x509 == NULL || akid == NULL || akidSz <= 0) {
return WOLFSSL_FAILURE;
}
/* Allocate/reallocate memory for authKeyIdSrc */
if (x509->authKeyIdSrc == NULL || (int)x509->authKeyIdSrcSz < akidSz) {
if (x509->authKeyIdSrc != NULL) {
XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
}
x509->authKeyIdSrc = (byte*)XMALLOC((word32)akidSz, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->authKeyIdSrc == NULL) {
return WOLFSSL_FAILURE;
}
}
XMEMCPY(x509->authKeyIdSrc, akid, (word32)akidSz);
x509->authKeyIdSrcSz = (word32)akidSz;
x509->authKeyId = x509->authKeyIdSrc;
x509->authKeyIdSz = (word32)akidSz;
x509->authKeyIdSet = 1;
return WOLFSSL_SUCCESS;
}
#ifndef NO_SHA
/* Set Authority Key Identifier from issuer certificate.
* Extracts SKID from issuer (or computes from issuer's public key).
*
* x509 - Certificate to modify
* issuer - Issuer certificate
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
WOLFSSL_X509* issuer)
{
byte hash[WC_SHA_DIGEST_SIZE];
int ret;
WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id_ex");
if (x509 == NULL || issuer == NULL) {
return WOLFSSL_FAILURE;
}
/* First try to use issuer's SKID if it's set */
if (issuer->subjKeyIdSet && issuer->subjKeyId != NULL &&
issuer->subjKeyIdSz > 0) {
return wolfSSL_X509_set_authority_key_id(x509, issuer->subjKeyId,
(int)issuer->subjKeyIdSz);
}
/* Otherwise compute from issuer's public key */
if (issuer->pubKey.buffer == NULL || issuer->pubKey.length == 0) {
WOLFSSL_MSG("Issuer public key not available");
return WOLFSSL_FAILURE;
}
ret = wc_ShaHash(issuer->pubKey.buffer, issuer->pubKey.length, hash);
if (ret != 0) {
WOLFSSL_MSG("wc_ShaHash failed");
return WOLFSSL_FAILURE;
}
return wolfSSL_X509_set_authority_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
}
#endif /* !NO_SHA */
#endif /* WOLFSSL_CERT_EXT */
#ifndef IGNORE_NETSCAPE_CERT_TYPE
/* Set Netscape Certificate Type extension.
*
* x509 - Certificate to modify
* nsCertType - Bitwise OR of NS_SSL_CLIENT, NS_SSL_SERVER, etc.
*
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType)
{
WOLFSSL_ENTER("wolfSSL_X509_set_ns_cert_type");
if (x509 == NULL) {
return WOLFSSL_FAILURE;
}
x509->nsCertType = (byte)nsCertType;
return WOLFSSL_SUCCESS;
}
#endif /* !IGNORE_NETSCAPE_CERT_TYPE */
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
+83
View File
@@ -18043,6 +18043,88 @@ static int test_wolfSSL_X509_SEP(void)
return EXPECT_RESULT();
}
/* Test wolfSSL_X509_set_* extension functions */
static int test_wolfSSL_X509_set_extensions(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
WOLFSSL_X509* x509 = NULL;
#ifdef WOLFSSL_CERT_EXT
byte skid[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
byte akid[20] = {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
#endif
#ifndef IGNORE_NETSCAPE_CERT_TYPE
int nsCertType = 0;
#endif
ExpectNotNull(x509 = wolfSSL_X509_new());
#ifdef WOLFSSL_CERT_EXT
/* Test wolfSSL_X509_set_subject_key_id */
ExpectIntEQ(wolfSSL_X509_set_subject_key_id(NULL, skid, sizeof(skid)),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_subject_key_id(x509, NULL, sizeof(skid)),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_subject_key_id(x509, skid, 0),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_subject_key_id(x509, skid, sizeof(skid)),
WOLFSSL_SUCCESS);
/* Test wolfSSL_X509_set_authority_key_id */
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(NULL, akid, sizeof(akid)),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(x509, NULL, sizeof(akid)),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(x509, akid, 0),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(x509, akid, sizeof(akid)),
WOLFSSL_SUCCESS);
/* Test wolfSSL_X509_CRL_add_dist_point */
ExpectIntEQ(wolfSSL_X509_CRL_add_dist_point(NULL,
"http://crl.example.com/ca.crl", 0), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_add_dist_point(x509, NULL, 0),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_add_dist_point(x509,
"http://crl.example.com/ca.crl", 0), WOLFSSL_SUCCESS);
/* Test wolfSSL_X509_CRL_set_dist_points with raw DER */
{
/* Simple CRL DP DER encoding for "http://example.com/crl" */
byte crlDer[] = {
0x30, 0x1d, /* SEQUENCE (outer) */
0x30, 0x1b, /* SEQUENCE (DistributionPoint) */
0xa0, 0x19, /* [0] EXPLICIT */
0xa0, 0x17, /* [0] IMPLICIT GeneralNames */
0x86, 0x15, /* [6] URI */
'h','t','t','p',':','/','/','e','x','a','m','p','l','e','.','c',
'o','m','/','c','r','l'
};
ExpectIntEQ(wolfSSL_X509_CRL_set_dist_points(NULL, crlDer,
sizeof(crlDer)), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_set_dist_points(x509, NULL,
sizeof(crlDer)), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_set_dist_points(x509, crlDer, 0),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_CRL_set_dist_points(x509, crlDer,
sizeof(crlDer)), WOLFSSL_SUCCESS);
}
#endif /* WOLFSSL_CERT_EXT */
#ifndef IGNORE_NETSCAPE_CERT_TYPE
/* Test wolfSSL_X509_set_ns_cert_type */
nsCertType = WC_NS_SSL_CLIENT | WC_NS_SSL_SERVER;
ExpectIntEQ(wolfSSL_X509_set_ns_cert_type(NULL, nsCertType),
WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_X509_set_ns_cert_type(x509, nsCertType),
WOLFSSL_SUCCESS);
#endif
wolfSSL_X509_free(x509);
#endif /* OPENSSL_EXTRA && !NO_CERTS */
return EXPECT_RESULT();
}
static int test_wolfSSL_OpenSSL_add_all_algorithms(void)
{
EXPECT_DECLS;
@@ -32391,6 +32473,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_X509_ALGOR_get0),
TEST_DECL(test_wolfSSL_X509_SEP),
TEST_DECL(test_wolfSSL_X509_set_extensions),
TEST_DECL(test_wolfSSL_X509_CRL),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_X509_print),
+6 -2
View File
@@ -976,9 +976,14 @@ int test_wolfSSL_CertManagerNameConstraint2(void)
WOLFSSL_SUCCESS);
ExpectIntEQ(wolfSSL_X509_add_altname(x509, "", ASN_DIR_TYPE),
WOLFSSL_SUCCESS);
/* IP not supported. */
/* IP not supported unless WOLFSSL_IP_ALT_NAME is enabled. */
#ifdef WOLFSSL_IP_ALT_NAME
ExpectIntEQ(wolfSSL_X509_add_altname(x509, "127.0.0.1", ASN_IP_TYPE),
WOLFSSL_SUCCESS);
#else
ExpectIntEQ(wolfSSL_X509_add_altname(x509, "127.0.0.1", ASN_IP_TYPE),
WOLFSSL_FAILURE);
#endif
/* add in matching DIR alt name and resign */
wolfSSL_X509_add_altname_ex(x509, altName, sizeof(altName), ASN_DIR_TYPE);
@@ -2397,4 +2402,3 @@ int test_various_pathlen_chains(void)
#endif
return EXPECT_RESULT();
}
+15 -1
View File
@@ -576,6 +576,21 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define X509_set1_notBefore wolfSSL_X509_set1_notBefore
#define X509_set_serialNumber wolfSSL_X509_set_serialNumber
#define X509_set_version wolfSSL_X509_set_version
#ifdef WOLFSSL_CERT_EXT
#define X509_set_subject_key_id wolfSSL_X509_set_subject_key_id
#ifndef NO_SHA
#define X509_set_subject_key_id_ex wolfSSL_X509_set_subject_key_id_ex
#endif
#define X509_set_authority_key_id wolfSSL_X509_set_authority_key_id
#ifndef NO_SHA
#define X509_set_authority_key_id_ex wolfSSL_X509_set_authority_key_id_ex
#endif
#define X509_CRL_set_dist_points wolfSSL_X509_CRL_set_dist_points
#define X509_CRL_add_dist_point wolfSSL_X509_CRL_add_dist_point
#endif
#ifndef IGNORE_NETSCAPE_CERT_TYPE
#define X509_set_ns_cert_type wolfSSL_X509_set_ns_cert_type
#endif
#define X509_REQ_set_version wolfSSL_X509_REQ_set_version
#define X509_REQ_get_version wolfSSL_X509_REQ_get_version
#define X509_sign wolfSSL_X509_sign
@@ -818,7 +833,6 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define X509_CRL_verify wolfSSL_X509_CRL_verify
#define X509_CRL_get_REVOKED wolfSSL_X509_CRL_get_REVOKED
#define X509_CRL_get_issuer wolfSSL_X509_CRL_get_issuer_name
#define X509_CRL_get_signature_nid wolfSSL_X509_CRL_get_signature_nid
#define X509_CRL_get_version wolfSSL_X509_CRL_version
#define X509_CRL_set_lastUpdate wolfSSL_X509_CRL_set_lastUpdate
#define X509_CRL_set1_lastUpdate wolfSSL_X509_CRL_set_lastUpdate
+25
View File
@@ -2307,6 +2307,24 @@ WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509* x50
WOLFSSL_API int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509,
WOLFSSL_ASN1_INTEGER* s);
WOLFSSL_API int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v);
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
#ifdef WOLFSSL_CERT_EXT
WOLFSSL_API int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
const unsigned char* skid, int skidSz);
#ifndef NO_SHA
WOLFSSL_API int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509);
#endif
WOLFSSL_API int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
const unsigned char* akid, int akidSz);
#ifndef NO_SHA
WOLFSSL_API int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
WOLFSSL_X509* issuer);
#endif
#endif /* WOLFSSL_CERT_EXT */
#ifndef IGNORE_NETSCAPE_CERT_TYPE
WOLFSSL_API int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType);
#endif
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
WOLFSSL_API int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
const WOLFSSL_EVP_MD* md);
WOLFSSL_API int wolfSSL_X509_sign_ctx(WOLFSSL_X509 *x509, WOLFSSL_EVP_MD_CTX *ctx);
@@ -3515,6 +3533,13 @@ WOLFSSL_API int wolfSSL_X509_CRL_sign(WOLFSSL_X509_CRL* crl,
WOLFSSL_API int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl,
unsigned char** out);
#endif /* HAVE_CRL && OPENSSL_EXTRA */
#if defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
WOLFSSL_API int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
const unsigned char* der, int derSz);
WOLFSSL_API int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
const char* uri, int critical);
#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
#if defined(WOLFSSL_ACERT) && \
(defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
+4
View File
@@ -1012,6 +1012,10 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags);
#define XINET_PTON(a,b,c,d) inet_pton((a),(b),(c),(d))
#elif defined(WOLFSSL_ZEPHYR)
#define XINET_PTON(a,b,c) zsock_inet_pton((a),(b),(c))
#elif defined(WOLFSSL_LINUXKM)
#define XINET_PTON(a,b,c) \
(((a) == WOLFSSL_IP4) ? in4_pton((b), -1, (u8*)(c), -1, NULL) : \
((a) == WOLFSSL_IP6) ? in6_pton((b), -1, (u8*)(c), -1, NULL) : 0)
#else
#define XINET_PTON(a,b,c) inet_pton((a),(b),(c))
#endif