From 95b9fae605ec46d72220f84b716db5db314b526d Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Wed, 29 Sep 2021 16:27:39 -0600 Subject: [PATCH] Add DIST_POINT compatibility functions (#4351) * add DIST_POINT compatibility functions * switch X509_LU_* from enum to define, prevent compiler type warnings * refactoring, adding in comments, and formating * refactoring and a memory leak fix * cast return value for g++ warning * refactor wolfSSL_sk_DIST_POINT_pop_free and remove NULL assign after free * fix get next DIST_POINT node for free function Co-authored-by: Jacob Barthelmeh --- certs/client-crl-dist.der | Bin 0 -> 1011 bytes certs/client-crl-dist.pem | 80 ++++++++++ certs/include.am | 2 + certs/renewcerts.sh | 22 +++ certs/renewcerts/wolfssl.cnf | 4 + src/ssl.c | 299 ++++++++++++++++++++++++++++++++--- tests/api.c | 54 +++++++ wolfssl/internal.h | 2 + wolfssl/openssl/ssl.h | 17 ++ wolfssl/ssl.h | 37 ++++- 10 files changed, 492 insertions(+), 25 deletions(-) create mode 100644 certs/client-crl-dist.der create mode 100644 certs/client-crl-dist.pem diff --git a/certs/client-crl-dist.der b/certs/client-crl-dist.der new file mode 100644 index 0000000000000000000000000000000000000000..60553fe4c72b760298b0aaf7d7dcc5b5f75ba158 GIT binary patch literal 1011 zcmXqLVt#MX#B_ZDGZP~dlZf9|m#A;YUz>^es+>0ycih+hG3cfNFB_*;n@8JsUPeZ4 zRtAH{X@=YeoNUaYENsF|p}~d%27Dk62M@b%eqKppULs6{orm2izbZ91G0#xcKp3Qk zi-)H?KPN3X*eBk|z{J8((10H#%+15$9OM)4;u#!bC}AK55@P1zFE20G1F0@9&e2QG z&oz`ckcB&hlTl0{GcPUQ0ZD;@oH(zMp@D^gsgZ%9p|N3R~kM3>SiqJPT#$-^n{s?*Cpxi-Mh~7{(S%DW20R4Y-aaa`%}-bNw zdm+*p{lw(^(G4P#zou7PRaHD>3=5mMOxUUSl8wV0pZ6Er?wbcn^DMOf`f;(B>63@& zrrnpW+wV91g20Ov90rZ+6}X*6j+UfvF>1>1Z9CNAFw?Agmz+b9lKAzYRF&cl=iW=6 zUH88tr}}^p^A*1$-hf=|#ny{w#?3u(lc#m_&90jvYPWNLt=auw)#u2?$}feN+Z-f> zHzaQ@@-sLxy`@bzO#iy*_xc0tzW#}R`g`H7%S_CS42+A74GazR*_cCR zC@oNElglV6DX`MlM@uaF$wfJO1*y5n!O9H|Rz?O+@rwfIYS-nzIUgr$A=hs0SYxoU zx#35CuJ_4_A7ai3Mx0-Lw#DGk<1)r}cdK_drNh46t@7)+y>h+VjIf5r@JG7Od3P_d z+p_t}+`nho!i0SfNN9cV*{Qc)ZJCumQ~BiDN%sz9PP=kARW9#G&9T`+?Thcu310rB z|AyS@9DWnkrCtSJZ`^aad-G%PTbtN&UgmX6vu7L%zEo6S|L*@|odse04lZ9THn)$< zCR5&Yqag$Tm!id7&+^-6Kiu?eZ}{I!Ei*mtu$v!QcyeuM-i+HRcS@QSjpnRanf8n= uK~|})ATdi={djf2X7e+fPFw!n#*}a{=w9H*-$`ytUFK^(i2rk{JPQE(LVP^{ literal 0 HcmV?d00001 diff --git a/certs/client-crl-dist.pem b/certs/client-crl-dist.pem new file mode 100644 index 000000000..df53d1c09 --- /dev/null +++ b/certs/client-crl-dist.pem @@ -0,0 +1,80 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4e:b5:44:5a:f6:c7:eb:36:14:4d:24:cf:36:17:41:be:87:f1:52:d9 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = CRL_DIST, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Aug 5 20:11:31 2021 GMT + Not After : May 1 20:11:31 2024 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = CRL_DIST, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:c3:03:d1:2b:fe:39:a4:32:45:3b:53:c8:84:2b: + 2a:7c:74:9a:bd:aa:2a:52:07:47:d6:a6:36:b2:07: + 32:8e:d0:ba:69:7b:c6:c3:44:9e:d4:81:48:fd:2d: + 68:a2:8b:67:bb:a1:75:c8:36:2c:4a:d2:1b:f7:8b: + ba:cf:0d:f9:ef:ec:f1:81:1e:7b:9b:03:47:9a:bf: + 65:cc:7f:65:24:69:a6:e8:14:89:5b:e4:34:f7:c5: + b0:14:93:f5:67:7b:3a:7a:78:e1:01:56:56:91:a6: + 13:42:8d:d2:3c:40:9c:4c:ef:d1:86:df:37:51:1b: + 0c:a1:3b:f5:f1:a3:4a:35:e4:e1:ce:96:df:1b:7e: + bf:4e:97:d0:10:e8:a8:08:30:81:af:20:0b:43:14: + c5:74:67:b4:32:82:6f:8d:86:c2:88:40:99:36:83: + ba:1e:40:72:22:17:d7:52:65:24:73:b0:ce:ef:19: + cd:ae:ff:78:6c:7b:c0:12:03:d4:4e:72:0d:50:6d: + 3b:a3:3b:a3:99:5e:9d:c8:d9:0c:85:b3:d9:8a:d9: + 54:26:db:6d:fa:ac:bb:ff:25:4c:c4:d1:79:f4:71: + d3:86:40:18:13:b0:63:b5:72:4e:30:c4:97:84:86: + 2d:56:2f:d7:15:f7:7f:c0:ae:f5:fc:5b:e5:fb:a1: + ba:d3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.wolfssl.com/crl.pem + + Signature Algorithm: sha256WithRSAEncryption + 09:17:d1:10:ce:7d:ae:6f:ec:cf:5e:1d:38:1e:87:3b:41:7c: + 30:b1:83:80:f8:6f:6d:4b:c9:91:f0:5c:cc:11:58:cf:ab:cd: + 84:30:c2:e3:76:01:87:47:3a:ee:d9:1b:56:f6:dd:7a:4e:8c: + db:a9:af:46:98:56:80:81:57:e2:2d:e7:0d:bb:a4:3e:b4:b3: + d4:9d:fd:cc:06:56:13:4d:c0:18:2a:f0:4c:b9:2e:af:26:a6: + 3a:2f:02:77:93:7d:92:de:c0:69:96:d4:c3:65:1e:6e:f8:7c: + c6:9b:12:87:a3:dd:9c:53:a7:e4:8f:d8:1e:cb:6c:0f:34:25: + a5:4a:70:f5:d8:de:44:dd:d9:f1:53:ed:3c:5d:77:0d:03:ae: + a5:6b:98:c2:53:d2:72:7f:7f:ee:ff:e3:2c:a0:56:be:c1:a7: + a3:16:9d:8e:0a:3c:69:1f:35:b1:31:00:0f:f4:72:a3:0a:e6: + 6f:87:9b:e1:b2:e6:bd:57:fd:d2:84:99:48:dc:07:37:c4:a1: + c9:ad:55:6e:98:db:64:dc:74:83:21:32:9c:a8:a9:66:e6:06: + 60:1d:22:86:70:61:6a:13:27:c7:7b:50:b3:37:cc:b2:cb:39: + fd:b6:02:60:c1:52:de:51:f1:fb:62:46:22:8a:37:ac:f0:17: + fe:42:79:cd +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIUTrVEWvbH6zYUTSTPNhdBvofxUtkwDQYJKoZIhvcNAQEL +BQAwgZYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC +b3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxETAPBgNVBAsMCENSTF9ESVNU +MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9A +d29sZnNzbC5jb20wHhcNMjEwODA1MjAxMTMxWhcNMjQwNTAxMjAxMTMxWjCBljEL +MAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4x +FTATBgNVBAoMDHdvbGZTU0xfMjA0ODERMA8GA1UECwwIQ1JMX0RJU1QxGDAWBgNV +BAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3Ns +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMMD0Sv+OaQyRTtT +yIQrKnx0mr2qKlIHR9amNrIHMo7Quml7xsNEntSBSP0taKKLZ7uhdcg2LErSG/eL +us8N+e/s8YEee5sDR5q/Zcx/ZSRppugUiVvkNPfFsBST9Wd7Onp44QFWVpGmE0KN +0jxAnEzv0YbfN1EbDKE79fGjSjXk4c6W3xt+v06X0BDoqAgwga8gC0MUxXRntDKC +b42GwohAmTaDuh5AciIX11JlJHOwzu8Zza7/eGx7wBID1E5yDVBtO6M7o5lencjZ +DIWz2YrZVCbbbfqsu/8lTMTRefRx04ZAGBOwY7VyTjDEl4SGLVYv1xX3f8Cu9fxb +5fuhutMCAwEAAaMzMDEwLwYDVR0fBCgwJjAkoCKgIIYeaHR0cDovL3d3dy53b2xm +c3NsLmNvbS9jcmwucGVtMA0GCSqGSIb3DQEBCwUAA4IBAQAJF9EQzn2ub+zPXh04 +Hoc7QXwwsYOA+G9tS8mR8FzMEVjPq82EMMLjdgGHRzru2RtW9t16Tozbqa9GmFaA +gVfiLecNu6Q+tLPUnf3MBlYTTcAYKvBMuS6vJqY6LwJ3k32S3sBpltTDZR5u+HzG +mxKHo92cU6fkj9gey2wPNCWlSnD12N5E3dnxU+08XXcNA66la5jCU9Jyf3/u/+Ms +oFa+waejFp2OCjxpHzWxMQAP9HKjCuZvh5vhsua9V/3ShJlI3Ac3xKHJrVVumNtk +3HSDITKcqKlm5gZgHSKGcGFqEyfHe1CzN8yyyzn9tgJgwVLeUfH7YkYiijes8Bf+ +QnnN +-----END CERTIFICATE----- diff --git a/certs/include.am b/certs/include.am index 9625b5d32..b9c7ce9d3 100644 --- a/certs/include.am +++ b/certs/include.am @@ -11,6 +11,8 @@ EXTRA_DIST += \ certs/client-key.pem \ certs/client-uri-cert.pem \ certs/client-relative-uri.pem \ + certs/client-crl-dist.pem \ + certs/client-crl-dist.der \ certs/ecc-key.pem \ certs/ecc-privkey.pem \ certs/ecc-privkeyPkcs8.der \ diff --git a/certs/renewcerts.sh b/certs/renewcerts.sh index 1d60d0404..126583060 100755 --- a/certs/renewcerts.sh +++ b/certs/renewcerts.sh @@ -25,6 +25,7 @@ # ecc-privOnlyCert.pem # client-uri-cert.pem # client-relative-uri.pem +# client-crl-dist.pem # entity-no-ca-bool-cert.pem # updates the following crls: # crl/cliCrl.pem @@ -105,6 +106,27 @@ run_renewcerts(){ echo "End of section" echo "---------------------------------------------------------------------" ############################################################ + #### update the self-signed (2048-bit) client-crl-dist.pem + ############################################################ + echo "Updating 2048-bit client-crl-dist.pem" + echo "" + #pipe the following arguments to openssl req... + echo -e "US\\nMontana\\nBozeman\\nwolfSSL_2048\\nCRL_DIST\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | openssl req -new -key client-key.pem -config ./wolfssl.cnf -nodes -out client-cert.csr + check_result $? "Step 1" + + + openssl x509 -req -in client-cert.csr -days 1000 -extfile wolfssl.cnf -extensions crl_dist_points -signkey client-key.pem -out client-crl-dist.pem + check_result $? "Step 2" + rm client-cert.csr + + openssl x509 -in client-crl-dist.pem -text > tmp.pem + check_result $? "Step 3" + mv tmp.pem client-crl-dist.pem + + openssl x509 -in client-crl-dist.pem -outform der -out client-crl-dist.der + echo "End of section" + echo "---------------------------------------------------------------------" + ############################################################ #### update the self-signed (2048-bit) client-cert.pem ##### ############################################################ echo "Updating 2048-bit client-cert.pem" diff --git a/certs/renewcerts/wolfssl.cnf b/certs/renewcerts/wolfssl.cnf index db1edbc21..8a735f690 100644 --- a/certs/renewcerts/wolfssl.cnf +++ b/certs/renewcerts/wolfssl.cnf @@ -300,6 +300,10 @@ authorityKeyIdentifier=keyid:always,issuer:always basicConstraints=CA:false subjectAltName=URI:../relative/page.html +# test CRL distribution points +[ crl_dist_points ] +crlDistributionPoints=URI:http://www.wolfssl.com/crl.pem + #tsa default [ tsa ] default_tsa = tsa_config1 diff --git a/src/ssl.c b/src/ssl.c index 21b6c3000..6f9e06ad2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -10062,9 +10062,7 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) } /* Allocate memory for GENERAL NAME */ - ad->location = (WOLFSSL_GENERAL_NAME*) - XMALLOC(sizeof(WOLFSSL_GENERAL_NAME), NULL, - DYNAMIC_TYPE_OPENSSL); + ad->location = wolfSSL_GENERAL_NAME_new(); if (ad->location == NULL) { WOLFSSL_MSG("Failed to malloc GENERAL_NAME"); wolfSSL_ASN1_OBJECT_free(ad->method); @@ -10072,20 +10070,25 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); return NULL; } - XMEMSET(ad->location, 0, sizeof(WOLFSSL_GENERAL_NAME)); - ad->location->type = GEN_URI; - ad->location->d.uniformResourceIdentifier = - wolfSSL_ASN1_STRING_new(); + + ret = wolfSSL_GENERAL_NAME_set_type(ad->location, GEN_URI); + if (ret != WOLFSSL_SUCCESS) { + wolfSSL_ASN1_OBJECT_free(ad->method); + XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT); + wolfSSL_GENERAL_NAME_free(ad->location); + XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); + return NULL; + } + /* Set the URI in GENERAL_NAME */ ret = wolfSSL_ASN1_STRING_set( ad->location->d.uniformResourceIdentifier, aiaEntry->obj, aiaEntry->objSz); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("ASN1_STRING_set() failed"); - wolfSSL_ASN1_STRING_free(ad->location->d.uniformResourceIdentifier); wolfSSL_ASN1_OBJECT_free(ad->method); XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT); - XFREE(ad->location, NULL, DYNAMIC_TYPE_OPENSSL); + wolfSSL_GENERAL_NAME_free(ad->location); XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); return NULL; } @@ -10095,6 +10098,7 @@ void* wolfSSL_X509V3_EXT_d2i(WOLFSSL_X509_EXTENSION* ext) WOLFSSL_MSG("Error pushing ASN1 AD onto stack"); wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(aia, NULL); wolfSSL_ASN1_OBJECT_free(ad->method); + wolfSSL_GENERAL_NAME_free(ad->location); XFREE(aia, NULL, DYNAMIC_TYPE_X509_EXT); XFREE(ad, NULL, DYNAMIC_TYPE_X509_EXT); return NULL; @@ -10238,7 +10242,6 @@ int wolfSSL_X509_get_ext_by_NID(const WOLFSSL_X509* x509, int nid, int lastPos) #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) - WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void) { WOLFSSL_ASN1_BIT_STRING* str; @@ -10294,6 +10297,7 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, WOLFSSL_STACK* sk = NULL; WOLFSSL_ASN1_OBJECT* obj = NULL; WOLFSSL_GENERAL_NAME* gn = NULL; + WOLFSSL_DIST_POINT* dp = NULL; WOLFSSL_BASIC_CONSTRAINTS* bc = NULL; WOLFSSL_ENTER("wolfSSL_X509_get_ext_d2i"); @@ -10402,19 +10406,59 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, if (c != NULL) { *c = x509->CRLdistCrit; } - obj = wolfSSL_ASN1_OBJECT_new(); - if (obj == NULL) { - WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct"); + + sk = wolfSSL_sk_new_null(); + if (sk == NULL) { return NULL; } - obj->type = CRL_DIST_OID; - obj->grp = oidCertExtType; - obj->obj = x509->CRLInfo; - obj->objSz = x509->CRLInfoSz; + sk->type = STACK_TYPE_DIST_POINT; + + gn = wolfSSL_GENERAL_NAME_new(); + if (gn == NULL) { + WOLFSSL_MSG("Error creating GENERAL_NAME"); + goto err; + } + + if (wolfSSL_GENERAL_NAME_set_type(gn, GEN_URI) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error setting GENERAL_NAME type"); + goto err; + } + + if (wolfSSL_ASN1_STRING_set(gn->d.uniformResourceIdentifier, + x509->CRLInfo, x509->CRLInfoSz) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("ASN1_STRING_set failed"); + goto err; + } + + /* wolfSSL only decodes one dist point */ + dp = wolfSSL_DIST_POINT_new(); + if (dp == NULL) { + WOLFSSL_MSG("Error creating DIST_POINT"); + goto err; + } + + /* push GENERAL_NAME onto fullname stack */ + if (wolfSSL_sk_GENERAL_NAME_push(dp->distpoint->name.fullname, + gn) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_sk_GENERAL_NAME_push error"); + goto err; + } + + /* push DIST_POINT onto stack */ + if (wolfSSL_sk_DIST_POINT_push(sk, dp) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error pushing DIST_POINT onto stack"); + goto err; + } + + gn = NULL; + dp = NULL; + } else { WOLFSSL_MSG("No CRL dist set"); } + break; case AUTH_INFO_OID: @@ -10678,6 +10722,9 @@ err: if (gn) { wolfSSL_GENERAL_NAME_free(gn); } + if (dp) { + wolfSSL_DIST_POINT_free(dp); + } if (sk) { wolfSSL_sk_free(sk); } @@ -20848,6 +20895,169 @@ void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk) #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #ifdef OPENSSL_EXTRA + +static void wolfSSL_DIST_POINT_NAME_free(WOLFSSL_DIST_POINT_NAME* dpn) +{ + if (dpn != NULL) { + if (dpn->name.fullname != NULL) { + wolfSSL_GENERAL_NAMES_free(dpn->name.fullname); + } + XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + + +/* returns new pointer on success and NULL on fail */ +static WOLFSSL_DIST_POINT_NAME* wolfSSL_DIST_POINT_NAME_new(void) +{ + WOLFSSL_DIST_POINT_NAME* dpn = NULL; + WOLFSSL_GENERAL_NAMES* gns = NULL; + + dpn = (WOLFSSL_DIST_POINT_NAME*)XMALLOC(sizeof(WOLFSSL_DIST_POINT_NAME), + NULL, DYNAMIC_TYPE_OPENSSL); + if (dpn == NULL) { + return NULL; + } + XMEMSET(dpn, 0, sizeof(WOLFSSL_DIST_POINT_NAME)); + + gns = wolfSSL_sk_new_null(); + if (gns == NULL) { + WOLFSSL_MSG("wolfSSL_sk_new_null error"); + XFREE(dpn, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + gns->type = STACK_TYPE_GEN_NAME; + + dpn->name.fullname = gns; + dpn->type = CRL_DIST_OID; + + return dpn; +} + + +/* Creates and returns new DIST_POINT structure */ +WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void) +{ + WOLFSSL_DIST_POINT* dp = NULL; + WOLFSSL_DIST_POINT_NAME* dpn = NULL; + + WOLFSSL_ENTER("DIST_POINT_new"); + + dp = (WOLFSSL_DIST_POINT*)XMALLOC(sizeof(WOLFSSL_DIST_POINT), NULL, + DYNAMIC_TYPE_OPENSSL); + if (dp == NULL) { + return NULL; + } + XMEMSET(dp, 0, sizeof(WOLFSSL_DIST_POINT)); + + dpn = wolfSSL_DIST_POINT_NAME_new(); + if (dpn == NULL) { + XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + dp->distpoint = dpn; + + return dp; +} + + +/* Frees DIST_POINT objects. +*/ +void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp) +{ + WOLFSSL_ENTER("wolfSSL_DIST_POINT_free"); + if (dp != NULL) { + wolfSSL_DIST_POINT_NAME_free(dp->distpoint); + XFREE(dp, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + +void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS *dps) +{ + WOLFSSL_ENTER("wolfSSL_DIST_POINTS_free"); + + if (dps == NULL) { + return; + } + + wolfSSL_sk_free(dps); +} + +/* return 1 on success 0 on fail */ +int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, WOLFSSL_DIST_POINT* dp) +{ + WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_push"); + + if (sk == NULL || dp == NULL) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_sk_push(sk, dp); +} + +/* Returns the CRL dist point at index i from the stack + * + * sk stack to get general name from + * idx index to get + * + * return a pointer to the internal node of the stack + */ +WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value(WOLFSSL_STACK* sk, int idx) +{ + if (sk == NULL) { + return NULL; + } + + return (WOLFSSL_DIST_POINT*)wolfSSL_sk_value(sk, idx); +} + +/* Gets the number of nodes in the stack + * + * sk stack to get the number of nodes from + * + * returns the number of nodes, -1 if no nodes + */ +int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_num"); + + if (sk == NULL) { + return -1; + } + + return wolfSSL_sk_num(sk); +} + +/* Frees all nodes in a DIST_POINT stack + * + * sk stack of nodes to free + * f free function to use, not called with wolfSSL + */ +void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk, + void (*f) (WOLFSSL_DIST_POINT*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_DIST_POINT_pop_free"); + + node = sk; + while (node != NULL) { + WOLFSSL_STACK* tmp = node; + if (f) + f(tmp->data.dp); + else + wolfSSL_DIST_POINT_free(tmp->data.dp); + node = tmp->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); + } +} + +void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk) +{ + WOLFSSL_ENTER("sk_DIST_POINT_free"); + wolfSSL_sk_DIST_POINT_pop_free(sk, NULL); +} + /* returns the number of nodes in stack on success and WOLFSSL_FATAL_ERROR * on fail */ int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk) @@ -20897,12 +21107,10 @@ WOLFSSL_ACCESS_DESCRIPTION* wolfSSL_sk_ACCESS_DESCRIPTION_value( #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) -/* Frees GENERAL_NAME objects. -*/ -void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) +/* free's the internal type for the general name */ +static void wolfSSL_GENERAL_NAME_type_free(WOLFSSL_GENERAL_NAME* name) { - WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free"); - if(name != NULL) { + if (name != NULL) { if (name->d.dNSName != NULL) { wolfSSL_ASN1_STRING_free(name->d.dNSName); name->d.dNSName = NULL; @@ -20923,6 +21131,48 @@ void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) wolfSSL_ASN1_STRING_free(name->d.ia5); name->d.ia5 = NULL; } + } +} + + +/* sets the general name type and free's the existing one + * can fail with a memory error if malloc fails or bad arg error + * otherwise return WOLFSSL_SUCCESS */ +int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, int typ) +{ + int ret = WOLFSSL_SUCCESS; + + if (name != NULL) { + wolfSSL_GENERAL_NAME_type_free(name); + name->type = typ; + + switch (typ) { + case GEN_URI: + name->d.uniformResourceIdentifier = wolfSSL_ASN1_STRING_new(); + if (name->d.uniformResourceIdentifier == NULL) + ret = MEMORY_E; + break; + default: + name->d.ia5 = wolfSSL_ASN1_STRING_new(); + if (name->d.ia5 == NULL) + ret = MEMORY_E; + } + } + else { + ret = BAD_FUNC_ARG; + } + + return ret; +} + + +/* Frees GENERAL_NAME objects. +*/ +void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) +{ + WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free"); + if (name != NULL) { + wolfSSL_GENERAL_NAME_type_free(name); XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL); } } @@ -29730,6 +29980,8 @@ void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i) return (void*)sk->data.ext; case STACK_TYPE_X509_OBJ: return (void*)sk->data.x509_obj; + case STACK_TYPE_DIST_POINT: + return (void*)sk->data.dp; #ifdef OPENSSL_EXTRA case STACK_TYPE_CONF_VALUE: return (void*)sk->data.conf; @@ -29859,6 +30111,9 @@ void wolfSSL_sk_free(WOLFSSL_STACK* sk) wolfSSL_sk_ACCESS_DESCRIPTION_free(sk); break; #endif + case STACK_TYPE_DIST_POINT: + wolfSSL_sk_DIST_POINT_free(sk); + break; case STACK_TYPE_OBJ: wolfSSL_sk_ASN1_OBJECT_free(sk); break; diff --git a/tests/api.c b/tests/api.c index 3f14e74ba..6167bf9c9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -37851,6 +37851,59 @@ static void test_wolfSSL_GENERAL_NAME_print(void) #endif /* OPENSSL_ALL */ } +static void test_wolfSSL_sk_DIST_POINT(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) + X509* x509; + unsigned char buf[4096]; + const unsigned char* bufPt; + int bytes, i, j; + XFILE f; + DIST_POINT* dp; + GENERAL_NAME* gn; + ASN1_IA5STRING* uri; + STACK_OF(DIST_POINT)* dps; + STACK_OF(GENERAL_NAME)* gns; + const char cliCertDerCrlDistPoint[] = "./certs/client-crl-dist.der"; + + printf(testingFmt, "wolfSSL_sk_DIST_POINT()"); + + f = XFOPEN(cliCertDerCrlDistPoint, "rb"); + AssertTrue((f != XBADFILE)); + AssertIntGT((bytes = (int)XFREAD(buf, 1, sizeof(buf), f)), 0); + XFCLOSE(f); + + bufPt = buf; + AssertNotNull(x509 = d2i_X509(NULL, &bufPt, bytes)); + + AssertNotNull(dps = (STACK_OF(DIST_POINT)*)X509_get_ext_d2i(x509, + NID_crl_distribution_points, NULL, NULL)); + + AssertIntEQ(sk_DIST_POINT_num(dps), 1); + for (i = 0; i < sk_DIST_POINT_num(dps); i++) { + AssertNotNull(dp = sk_DIST_POINT_value(dps, i)); + + gns = dp->distpoint->name.fullname; + AssertNotNull(gns); + AssertIntEQ(sk_GENERAL_NAME_num(gns), 1); + + for (j = 0; j < sk_GENERAL_NAME_num(gns); j++) { + gn = sk_GENERAL_NAME_value(gns, j); + AssertIntEQ(gn->type, GEN_URI); + AssertNotNull(uri = gn->d.uniformResourceIdentifier); + AssertNotNull(uri->data); + AssertIntGT(uri->length, 0); + } + } + + X509_free(x509); + CRL_DIST_POINTS_free(dps); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_MD4(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_MD4) @@ -49416,6 +49469,7 @@ void ApiTest(void) test_wolfSSL_DES_ecb_encrypt(); test_wolfSSL_sk_GENERAL_NAME(); test_wolfSSL_GENERAL_NAME_print(); + test_wolfSSL_sk_DIST_POINT(); test_wolfSSL_MD4(); test_wolfSSL_RSA(); test_wolfSSL_RSA_DER(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 720ffe148..dcdb0cf9e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3726,6 +3726,7 @@ typedef struct Arrays { #define STACK_TYPE_BY_DIR_entry 12 #define STACK_TYPE_BY_DIR_hash 13 #define STACK_TYPE_X509_OBJ 14 +#define STACK_TYPE_DIST_POINT 15 struct WOLFSSL_STACK { unsigned long num; /* number of nodes in stack @@ -3754,6 +3755,7 @@ struct WOLFSSL_STACK { WOLFSSL_BY_DIR_entry* dir_entry; WOLFSSL_BY_DIR_HASH* dir_hash; WOLFSSL_X509_OBJECT* x509_obj; + WOLFSSL_DIST_POINT* dp; } data; void* heap; /* memory heap hint */ WOLFSSL_STACK* next; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 91421cd03..46e8446fe 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -112,6 +112,8 @@ typedef WOLFSSL_BUF_MEM BUF_MEM; typedef WOLFSSL_GENERAL_NAMES GENERAL_NAMES; typedef WOLFSSL_GENERAL_NAME GENERAL_NAME; typedef WOLFSSL_OBJ_NAME OBJ_NAME; +typedef WOLFSSL_DIST_POINT_NAME DIST_POINT_NAME; +typedef WOLFSSL_DIST_POINT DIST_POINT; #define X509_L_FILE_LOAD WOLFSSL_X509_L_FILE_LOAD #define X509_L_ADD_DIR WOLFSSL_X509_L_ADD_DIR @@ -1273,6 +1275,17 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define GENERAL_NAME_print wolfSSL_GENERAL_NAME_print #define sk_GENERAL_NAME_push wolfSSL_sk_GENERAL_NAME_push #define sk_GENERAL_NAME_value wolfSSL_sk_GENERAL_NAME_value + +#define DIST_POINT_new wolfSSL_DIST_POINT_new +#define DIST_POINT_free wolfSSL_DIST_POINT_free +#define DIST_POINTS_free wolfSSL_DIST_POINTS_free +#define CRL_DIST_POINTS_free wolfSSL_sk_DIST_POINT_free +#define sk_DIST_POINT_push wolfSSL_sk_DIST_POINT_push +#define sk_DIST_POINT_value wolfSSL_sk_DIST_POINT_value +#define sk_DIST_POINT_num wolfSSL_sk_DIST_POINT_num +#define sk_DIST_POINT_pop_free wolfSSL_sk_DIST_POINT_pop_free +#define sk_DIST_POINT_free wolfSSL_sk_DIST_POINT_free + #define SSL_SESSION_get_ex_data wolfSSL_SESSION_get_ex_data #define SSL_SESSION_set_ex_data wolfSSL_SESSION_set_ex_data #define SSL_SESSION_get_ex_new_index wolfSSL_SESSION_get_ex_new_index @@ -1476,6 +1489,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) #define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) +#define X509_LU_NONE WOLFSSL_X509_LU_NONE +#define X509_LU_X509 WOLFSSL_X509_LU_X509 +#define X509_LU_CRL WOLFSSL_X509_LU_CRL + #define X509_STORE_get0_objects wolfSSL_X509_STORE_get0_objects #define sk_X509_OBJECT_num wolfSSL_sk_X509_OBJECT_num #define sk_X509_OBJECT_value wolfSSL_sk_X509_OBJECT_value diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 44572de4c..0d175fd04 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -221,6 +221,8 @@ typedef struct WOLFSSL_GENERAL_NAME WOLFSSL_GENERAL_NAME; typedef struct WOLFSSL_AUTHORITY_KEYID WOLFSSL_AUTHORITY_KEYID; typedef struct WOLFSSL_BASIC_CONSTRAINTS WOLFSSL_BASIC_CONSTRAINTS; typedef struct WOLFSSL_ACCESS_DESCRIPTION WOLFSSL_ACCESS_DESCRIPTION; +typedef struct WOLFSSL_DIST_POINT_NAME WOLFSSL_DIST_POINT_NAME; +typedef struct WOLFSSL_DIST_POINT WOLFSSL_DIST_POINT; typedef struct WOLFSSL_CONF_CTX WOLFSSL_CONF_CTX; @@ -287,6 +289,22 @@ struct WOLFSSL_GENERAL_NAME { } d; /* dereference */ }; +struct WOLFSSL_DIST_POINT_NAME { + int type; + + /* name 'name.fullname' needs to remain the same, in some ports the elements + * of the structure are accessed directly */ + union { + WOLF_STACK_OF(WOLFSSL_GENERAL_NAME)* fullname; + } name; +}; + +struct WOLFSSL_DIST_POINT { + /* name 'distpoint' needs to remain the same, in some ports the elements of + * the structure are accessed directly */ + WOLFSSL_DIST_POINT_NAME* distpoint; +}; + struct WOLFSSL_ACCESS_DESCRIPTION { WOLFSSL_ASN1_OBJECT* method; WOLFSSL_GENERAL_NAME* location; @@ -1327,6 +1345,7 @@ WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push( #endif /* defined(OPENSSL_ALL) || defined(WOLFSSL_QT) */ typedef WOLF_STACK_OF(WOLFSSL_GENERAL_NAME) WOLFSSL_GENERAL_NAMES; +typedef WOLF_STACK_OF(WOLFSSL_DIST_POINT) WOLFSSL_DIST_POINTS; WOLFSSL_API int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509); @@ -1334,6 +1353,8 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); WOLFSSL_API WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_new(void); WOLFSSL_API void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* gn); +WOLFSSL_API int wolfSSL_GENERAL_NAME_set_type(WOLFSSL_GENERAL_NAME* name, + int typ); WOLFSSL_API WOLFSSL_GENERAL_NAMES* wolfSSL_GENERAL_NAMES_dup( WOLFSSL_GENERAL_NAMES* gns); WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk, @@ -1347,6 +1368,19 @@ WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_free(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_GENERAL_NAMES_free(WOLFSSL_GENERAL_NAMES* name); WOLFSSL_API int wolfSSL_GENERAL_NAME_print(WOLFSSL_BIO* out, WOLFSSL_GENERAL_NAME* name); + +WOLFSSL_API WOLFSSL_DIST_POINT* wolfSSL_DIST_POINT_new(void); +WOLFSSL_API void wolfSSL_DIST_POINT_free(WOLFSSL_DIST_POINT* dp); +WOLFSSL_API int wolfSSL_sk_DIST_POINT_push(WOLFSSL_DIST_POINTS* sk, + WOLFSSL_DIST_POINT* dp); +WOLFSSL_API WOLFSSL_DIST_POINT* wolfSSL_sk_DIST_POINT_value( + WOLFSSL_STACK* sk, int i); +WOLFSSL_API int wolfSSL_sk_DIST_POINT_num(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_sk_DIST_POINT_pop_free(WOLFSSL_STACK* sk, + void (*f) (WOLFSSL_DIST_POINT*)); +WOLFSSL_API void wolfSSL_sk_DIST_POINT_free(WOLFSSL_STACK* sk); +WOLFSSL_API void wolfSSL_DIST_POINTS_free(WOLFSSL_DIST_POINTS* dp); + WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_num(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_AUTHORITY_INFO_ACCESS_free( WOLF_STACK_OF(WOLFSSL_ACCESS_DESCRIPTION)* sk); @@ -2098,9 +2132,6 @@ enum { BIO_NOCLOSE = 0, X509_FILETYPE_PEM = 8, - X509_LU_NONE = WOLFSSL_X509_LU_NONE, - X509_LU_X509 = WOLFSSL_X509_LU_X509, - X509_LU_CRL = WOLFSSL_X509_LU_CRL, X509_V_OK = 0, X509_V_ERR_CRL_SIGNATURE_FAILURE = 8,