|
34 | 34 | #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) |
35 | 35 | #include <wolfssl/openssl/x509v3.h> |
36 | 36 | #endif |
| 37 | +#ifdef OPENSSL_EXTRA |
| 38 | + #include <wolfssl/wolfio.h> |
| 39 | +#endif |
37 | 40 |
|
38 | 41 | #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) |
39 | 42 | 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) |
3053 | 3056 | return WOLFSSL_SUCCESS; |
3054 | 3057 |
|
3055 | 3058 | 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"); |
3057 | 3079 | return WOLFSSL_FAILURE; |
| 3080 | +#else |
| 3081 | + WOLFSSL_MSG("WOLFSSL_IP_ALT_NAME not enabled"); |
| 3082 | + return WOLFSSL_FAILURE; |
| 3083 | +#endif |
3058 | 3084 | } |
3059 | 3085 |
|
3060 | 3086 | 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) |
10049 | 10075 | } |
10050 | 10076 | #endif /* HAVE_CRL && OPENSSL_EXTRA */ |
10051 | 10077 |
|
| 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 | + |
10052 | 10228 | #ifdef OPENSSL_EXTRA |
10053 | 10229 |
|
10054 | 10230 |
|
@@ -15707,6 +15883,183 @@ int wolfSSL_X509_set_version(WOLFSSL_X509* x509, long v) |
15707 | 15883 | return WOLFSSL_SUCCESS; |
15708 | 15884 | } |
15709 | 15885 |
|
| 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 | + |
15710 | 16063 | #endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && WOLFSSL_CERT_GEN */ |
15711 | 16064 |
|
15712 | 16065 | #if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \ |
|
0 commit comments