Skip to content

Commit eb909d5

Browse files
committed
Add cert/CRL capabilities: skid, akid, dist point, netscape
1 parent 8192c01 commit eb909d5

7 files changed

Lines changed: 481 additions & 4 deletions

File tree

src/ssl.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11504,7 +11504,6 @@ void wolfSSL_set_dynlock_destroy_callback(
1150411504
(void)f;
1150511505
}
1150611506

11507-
1150811507
/* Sets the DNS hostname to name.
1150911508
* Hostname is cleared if name is NULL or empty. */
1151011509
int wolfSSL_set1_host(WOLFSSL * ssl, const char* name)

src/x509.c

Lines changed: 354 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
3535
#include <wolfssl/openssl/x509v3.h>
3636
#endif
37+
#ifdef OPENSSL_EXTRA
38+
#include <wolfssl/wolfio.h>
39+
#endif
3740

3841
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
3942
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)
30533056
return WOLFSSL_SUCCESS;
30543057

30553058
if (type == ASN_IP_TYPE) {
3056-
WOLFSSL_MSG("Type not supported, use wolfSSL_X509_add_altname_ex");
3059+
#ifdef WOLFSSL_IP_ALT_NAME
3060+
byte ip4[4];
3061+
byte ip6[16];
3062+
int ptonRet;
3063+
3064+
/* Check if this is an ip4 address */
3065+
ptonRet = XINET_PTON(WOLFSSL_IP4, name, ip4);
3066+
if (ptonRet == 1) {
3067+
return wolfSSL_X509_add_altname_ex(x509, (const char*)ip4, 4,
3068+
type);
3069+
}
3070+
3071+
/* Check for ip6 */
3072+
ptonRet = XINET_PTON(WOLFSSL_IP6, name, ip6);
3073+
if (ptonRet == 1) {
3074+
return wolfSSL_X509_add_altname_ex(x509, (const char*)ip6, 16,
3075+
type);
3076+
}
3077+
3078+
WOLFSSL_MSG("IP address parse failed");
30573079
return WOLFSSL_FAILURE;
3080+
#else
3081+
WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled");
3082+
return WOLFSSL_FAILURE;
3083+
#endif
30583084
}
30593085

30603086
return wolfSSL_X509_add_altname_ex(x509, name, nameSz, type);
@@ -10049,6 +10075,156 @@ int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
1004910075
}
1005010076
#endif /* HAVE_CRL && OPENSSL_EXTRA */
1005110077

10078+
#if defined(WOLFSSL_CERT_EXT) && \
10079+
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
10080+
/* Set CRL Distribution Points from pre-encoded DER.
10081+
*
10082+
* x509 - Certificate to modify
10083+
* der - Pre-encoded CRLDistributionPoints DER
10084+
* derSz - Size of DER in bytes
10085+
*
10086+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
10087+
*/
10088+
int wolfSSL_X509_CRL_set_dist_points(WOLFSSL_X509* x509,
10089+
const unsigned char* der, int derSz)
10090+
{
10091+
WOLFSSL_ENTER("wolfSSL_X509_CRL_set_dist_points");
10092+
10093+
if (x509 == NULL || der == NULL || derSz <= 0) {
10094+
return WOLFSSL_FAILURE;
10095+
}
10096+
10097+
if (x509->rawCRLInfo != NULL) {
10098+
XFREE(x509->rawCRLInfo, x509->heap, DYNAMIC_TYPE_X509_EXT);
10099+
}
10100+
x509->rawCRLInfo = (byte*)XMALLOC((word32)derSz, x509->heap,
10101+
DYNAMIC_TYPE_X509_EXT);
10102+
if (x509->rawCRLInfo == NULL) {
10103+
return WOLFSSL_FAILURE;
10104+
}
10105+
10106+
XMEMCPY(x509->rawCRLInfo, der, (word32)derSz);
10107+
x509->rawCRLInfoSz = derSz;
10108+
x509->CRLdistSet = 1;
10109+
10110+
return WOLFSSL_SUCCESS;
10111+
}
10112+
10113+
/* Add CRL Distribution Point URI.
10114+
* Encodes URI into proper CRLDistributionPoints DER format.
10115+
*
10116+
* x509 - Certificate to modify
10117+
* uri - URI string (e.g., "http://crl.example.com/ca.crl")
10118+
* critical - Whether extension is critical
10119+
*
10120+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
10121+
*/
10122+
int wolfSSL_X509_CRL_add_dist_point(WOLFSSL_X509* x509,
10123+
const char* uri, int critical)
10124+
{
10125+
int uriLen;
10126+
byte* derBuf = NULL;
10127+
int derSz;
10128+
int idx;
10129+
int ret = WOLFSSL_SUCCESS;
10130+
10131+
WOLFSSL_ENTER("wolfSSL_X509_CRL_add_dist_point");
10132+
10133+
if (x509 == NULL || uri == NULL) {
10134+
return WOLFSSL_FAILURE;
10135+
}
10136+
10137+
uriLen = (int)XSTRLEN(uri);
10138+
if (uriLen == 0 || uriLen >= 128) {
10139+
/* Current implementation limited to URIs < 128 bytes */
10140+
WOLFSSL_MSG("URI too long or empty");
10141+
return WOLFSSL_FAILURE;
10142+
}
10143+
10144+
/*
10145+
* Encode CRL Distribution Points in DER format:
10146+
* CRLDistributionPoints ::= SEQUENCE OF DistributionPoint
10147+
* DistributionPoint ::= SEQUENCE {
10148+
* distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL
10149+
* }
10150+
* DistributionPointName ::= CHOICE {
10151+
* fullName [0] IMPLICIT GeneralNames
10152+
* }
10153+
* GeneralNames ::= SEQUENCE OF GeneralName
10154+
* GeneralName ::= [6] IMPLICIT IA5String (uniformResourceIdentifier)
10155+
*/
10156+
10157+
/* Allocate buffer for DER encoding */
10158+
derSz = uriLen + 20; /* URI + tags + length bytes */
10159+
derBuf = (byte*)XMALLOC((word32)derSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
10160+
if (derBuf == NULL) {
10161+
return WOLFSSL_FAILURE;
10162+
}
10163+
10164+
/* Build from inside out, starting from end of buffer */
10165+
idx = derSz;
10166+
10167+
/* Copy URI string */
10168+
idx -= uriLen;
10169+
XMEMCPY(derBuf + idx, uri, (word32)uriLen);
10170+
10171+
/* [6] IMPLICIT IA5String tag for URI (context-specific, primitive) */
10172+
idx--;
10173+
derBuf[idx] = (byte)uriLen;
10174+
idx--;
10175+
derBuf[idx] = (ASN_CONTEXT_SPECIFIC | 6); /* [6] tag */
10176+
10177+
/* [0] IMPLICIT wrapper for GeneralNames (constructed) */
10178+
{
10179+
int innerLen = derSz - idx;
10180+
idx--;
10181+
derBuf[idx] = (byte)innerLen;
10182+
idx--;
10183+
derBuf[idx] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
10184+
}
10185+
10186+
/* [0] EXPLICIT wrapper for distributionPoint */
10187+
{
10188+
int innerLen = derSz - idx;
10189+
idx--;
10190+
derBuf[idx] = (byte)innerLen;
10191+
idx--;
10192+
derBuf[idx] = (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED);
10193+
}
10194+
10195+
/* SEQUENCE for DistributionPoint */
10196+
{
10197+
int innerLen = derSz - idx;
10198+
idx--;
10199+
derBuf[idx] = (byte)innerLen;
10200+
idx--;
10201+
derBuf[idx] = (ASN_SEQUENCE | ASN_CONSTRUCTED);
10202+
}
10203+
10204+
/* SEQUENCE for CRLDistributionPoints (outer) */
10205+
{
10206+
int innerLen = derSz - idx;
10207+
idx--;
10208+
derBuf[idx] = (byte)innerLen;
10209+
idx--;
10210+
derBuf[idx] = (ASN_SEQUENCE | ASN_CONSTRUCTED);
10211+
}
10212+
10213+
/* Store the encoded CRL info in x509 */
10214+
{
10215+
int finalSz = derSz - idx;
10216+
ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf + idx, finalSz);
10217+
if (ret == WOLFSSL_SUCCESS && critical) {
10218+
x509->CRLdistCrit = 1;
10219+
}
10220+
}
10221+
10222+
XFREE(derBuf, x509->heap, DYNAMIC_TYPE_X509_EXT);
10223+
10224+
return ret;
10225+
}
10226+
#endif /* WOLFSSL_CERT_EXT && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
10227+
1005210228
#ifdef OPENSSL_EXTRA
1005310229

1005410230

@@ -15707,6 +15883,183 @@ int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v)
1570715883
return WOLFSSL_SUCCESS;
1570815884
}
1570915885

15886+
#ifdef WOLFSSL_CERT_EXT
15887+
/* Set Subject Key Identifier from raw bytes.
15888+
*
15889+
* x509 - Certificate to modify
15890+
* skid - Raw SKID bytes
15891+
* skidSz - Size of SKID in bytes
15892+
*
15893+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
15894+
*/
15895+
int wolfSSL_X509_set_subject_key_id(WOLFSSL_X509* x509,
15896+
const unsigned char* skid, int skidSz)
15897+
{
15898+
WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id");
15899+
15900+
if (x509 == NULL || skid == NULL || skidSz <= 0) {
15901+
return WOLFSSL_FAILURE;
15902+
}
15903+
15904+
/* Allocate/reallocate memory for subjKeyId */
15905+
if (x509->subjKeyId == NULL || (int)x509->subjKeyIdSz < skidSz) {
15906+
if (x509->subjKeyId != NULL) {
15907+
XFREE(x509->subjKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
15908+
}
15909+
x509->subjKeyId = (byte*)XMALLOC((word32)skidSz, x509->heap,
15910+
DYNAMIC_TYPE_X509_EXT);
15911+
if (x509->subjKeyId == NULL) {
15912+
return WOLFSSL_FAILURE;
15913+
}
15914+
}
15915+
15916+
XMEMCPY(x509->subjKeyId, skid, (word32)skidSz);
15917+
x509->subjKeyIdSz = (word32)skidSz;
15918+
x509->subjKeyIdSet = 1;
15919+
15920+
return WOLFSSL_SUCCESS;
15921+
}
15922+
15923+
#ifndef NO_SHA
15924+
/* Set Subject Key Identifier by computing SHA-1 hash of the public key.
15925+
*
15926+
* x509 - Certificate to modify (must have public key set)
15927+
*
15928+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
15929+
*/
15930+
int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
15931+
{
15932+
byte hash[WC_SHA_DIGEST_SIZE];
15933+
int ret;
15934+
15935+
WOLFSSL_ENTER("wolfSSL_X509_set_subject_key_id_ex");
15936+
15937+
if (x509 == NULL) {
15938+
return WOLFSSL_FAILURE;
15939+
}
15940+
15941+
/* Check if public key has been set */
15942+
if (x509->pubKey.buffer == NULL || x509->pubKey.length == 0) {
15943+
WOLFSSL_MSG("Public key not set");
15944+
return WOLFSSL_FAILURE;
15945+
}
15946+
15947+
/* Compute SHA-1 hash of the public key */
15948+
ret = wc_ShaHash(x509->pubKey.buffer, x509->pubKey.length, hash);
15949+
if (ret != 0) {
15950+
WOLFSSL_MSG("wc_ShaHash failed");
15951+
return WOLFSSL_FAILURE;
15952+
}
15953+
15954+
return wolfSSL_X509_set_subject_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
15955+
}
15956+
#endif /* !NO_SHA */
15957+
15958+
/* Set Authority Key Identifier from raw bytes.
15959+
*
15960+
* x509 - Certificate to modify
15961+
* akid - Raw AKID bytes
15962+
* akidSz - Size of AKID in bytes
15963+
*
15964+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
15965+
*/
15966+
int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
15967+
const unsigned char* akid, int akidSz)
15968+
{
15969+
WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
15970+
15971+
if (x509 == NULL || akid == NULL || akidSz <= 0) {
15972+
return WOLFSSL_FAILURE;
15973+
}
15974+
15975+
/* Allocate/reallocate memory for authKeyIdSrc */
15976+
if (x509->authKeyIdSrc == NULL || (int)x509->authKeyIdSrcSz < akidSz) {
15977+
if (x509->authKeyIdSrc != NULL) {
15978+
XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
15979+
}
15980+
x509->authKeyIdSrc = (byte*)XMALLOC((word32)akidSz, x509->heap,
15981+
DYNAMIC_TYPE_X509_EXT);
15982+
if (x509->authKeyIdSrc == NULL) {
15983+
return WOLFSSL_FAILURE;
15984+
}
15985+
}
15986+
15987+
XMEMCPY(x509->authKeyIdSrc, akid, (word32)akidSz);
15988+
x509->authKeyIdSrcSz = (word32)akidSz;
15989+
x509->authKeyId = x509->authKeyIdSrc;
15990+
x509->authKeyIdSz = (word32)akidSz;
15991+
x509->authKeyIdSet = 1;
15992+
15993+
return WOLFSSL_SUCCESS;
15994+
}
15995+
15996+
#ifndef NO_SHA
15997+
/* Set Authority Key Identifier from issuer certificate.
15998+
* Extracts SKID from issuer (or computes from issuer's public key).
15999+
*
16000+
* x509 - Certificate to modify
16001+
* issuer - Issuer certificate
16002+
*
16003+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16004+
*/
16005+
int wolfSSL_X509_set_authority_key_id_ex(WOLFSSL_X509* x509,
16006+
WOLFSSL_X509* issuer)
16007+
{
16008+
byte hash[WC_SHA_DIGEST_SIZE];
16009+
int ret;
16010+
16011+
WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id_ex");
16012+
16013+
if (x509 == NULL || issuer == NULL) {
16014+
return WOLFSSL_FAILURE;
16015+
}
16016+
16017+
/* First try to use issuer's SKID if it's set */
16018+
if (issuer->subjKeyIdSet && issuer->subjKeyId != NULL &&
16019+
issuer->subjKeyIdSz > 0) {
16020+
return wolfSSL_X509_set_authority_key_id(x509, issuer->subjKeyId,
16021+
(int)issuer->subjKeyIdSz);
16022+
}
16023+
16024+
/* Otherwise compute from issuer's public key */
16025+
if (issuer->pubKey.buffer == NULL || issuer->pubKey.length == 0) {
16026+
WOLFSSL_MSG("Issuer public key not available");
16027+
return WOLFSSL_FAILURE;
16028+
}
16029+
16030+
ret = wc_ShaHash(issuer->pubKey.buffer, issuer->pubKey.length, hash);
16031+
if (ret != 0) {
16032+
WOLFSSL_MSG("wc_ShaHash failed");
16033+
return WOLFSSL_FAILURE;
16034+
}
16035+
16036+
return wolfSSL_X509_set_authority_key_id(x509, hash, WC_SHA_DIGEST_SIZE);
16037+
}
16038+
#endif /* !NO_SHA */
16039+
#endif /* WOLFSSL_CERT_EXT */
16040+
16041+
#ifndef IGNORE_NETSCAPE_CERT_TYPE
16042+
/* Set Netscape Certificate Type extension.
16043+
*
16044+
* x509 - Certificate to modify
16045+
* nsCertType - Bitwise OR of NS_SSL_CLIENT, NS_SSL_SERVER, etc.
16046+
*
16047+
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
16048+
*/
16049+
int wolfSSL_X509_set_ns_cert_type(WOLFSSL_X509* x509, int nsCertType)
16050+
{
16051+
WOLFSSL_ENTER("wolfSSL_X509_set_ns_cert_type");
16052+
16053+
if (x509 == NULL) {
16054+
return WOLFSSL_FAILURE;
16055+
}
16056+
16057+
x509->nsCertType = (byte)nsCertType;
16058+
16059+
return WOLFSSL_SUCCESS;
16060+
}
16061+
#endif /* !IGNORE_NETSCAPE_CERT_TYPE */
16062+
1571016063
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */
1571116064

1571216065
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \

0 commit comments

Comments
 (0)