60 #include <private/pprio.h> 62 #define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH) 64 #if NSSVERNUM >= 0x030f00 76 #define SSL_DIR "/etc/pki/nssdb" 81 struct ssl_backend_data {
83 char *client_nickname;
86 PK11GenericObject *obj_clicert;
89 #define BACKEND connssl->backend 91 static PRLock *nss_initlock = NULL;
92 static PRLock *nss_crllock = NULL;
93 static PRLock *nss_findslot_lock = NULL;
94 static PRLock *nss_trustload_lock = NULL;
96 static NSSInitContext *nss_context = NULL;
100 struct ptr_list_wrap {
110 #define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \ 111 CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \ 112 ptr->type = (_type); \ 113 ptr->pValue = (_val); \ 114 ptr->ulValueLen = (_len); \ 117 #define CERT_NewTempCertificate __CERT_NewTempCertificate 119 #define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0]) 120 static const cipher_s cipherlist[] = {
122 {
"rc4", SSL_EN_RC4_128_WITH_MD5},
123 {
"rc4-md5", SSL_EN_RC4_128_WITH_MD5},
124 {
"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5},
125 {
"rc2", SSL_EN_RC2_128_CBC_WITH_MD5},
126 {
"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
127 {
"des", SSL_EN_DES_64_CBC_WITH_MD5},
128 {
"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
130 {
"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5},
131 {
"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA},
132 {
"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA},
133 {
"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA},
134 {
"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5},
135 {
"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
136 {
"rsa_null_md5", SSL_RSA_WITH_NULL_MD5},
137 {
"rsa_null_sha", SSL_RSA_WITH_NULL_SHA},
138 {
"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
139 {
"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA},
140 {
"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
141 {
"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
142 {
"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
144 {
"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
145 {
"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
147 {
"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
148 {
"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
149 {
"dhe_rsa_aes_128_cbc_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
150 {
"dhe_rsa_aes_256_cbc_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
151 {
"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA},
152 {
"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA},
154 {
"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA},
155 {
"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
156 {
"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
157 {
"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
158 {
"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
159 {
"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA},
160 {
"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
161 {
"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
162 {
"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
163 {
"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
164 {
"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA},
165 {
"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA},
166 {
"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
167 {
"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
168 {
"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
169 {
"ecdhe_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA},
170 {
"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
171 {
"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
172 {
"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
173 {
"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
174 {
"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA},
175 {
"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA},
176 {
"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
177 {
"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
178 {
"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
179 #ifdef TLS_RSA_WITH_NULL_SHA256 181 {
"rsa_null_sha_256", TLS_RSA_WITH_NULL_SHA256},
182 {
"rsa_aes_128_cbc_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256},
183 {
"rsa_aes_256_cbc_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256},
184 {
"dhe_rsa_aes_128_cbc_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
185 {
"dhe_rsa_aes_256_cbc_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
186 {
"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
187 {
"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
189 #ifdef TLS_RSA_WITH_AES_128_GCM_SHA256 191 {
"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256},
192 {
"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
193 {
"dhe_dss_aes_128_gcm_sha_256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
194 {
"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
195 {
"ecdh_ecdsa_aes_128_gcm_sha_256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
196 {
"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
197 {
"ecdh_rsa_aes_128_gcm_sha_256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
199 #ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 201 {
"rsa_aes_256_gcm_sha_384", TLS_RSA_WITH_AES_256_GCM_SHA384},
202 {
"dhe_rsa_aes_256_gcm_sha_384", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
203 {
"dhe_dss_aes_256_gcm_sha_384", TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
204 {
"ecdhe_ecdsa_aes_256_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
205 {
"ecdhe_rsa_aes_256_sha_384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
206 {
"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
207 {
"ecdhe_rsa_aes_256_gcm_sha_384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
209 #ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 211 {
"ecdhe_rsa_chacha20_poly1305_sha_256",
212 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
213 {
"ecdhe_ecdsa_chacha20_poly1305_sha_256",
214 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
215 {
"dhe_rsa_chacha20_poly1305_sha_256",
216 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
220 static const char *pem_library =
"libnsspem.so";
221 static SECMODModule *pem_module = NULL;
223 static const char *trust_library =
"libnssckbi.so";
224 static SECMODModule *trust_module = NULL;
227 static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
228 static PRIOMethods nspr_io_methods;
230 static const char *nss_error_to_name(PRErrorCode code)
232 const char *
name = PR_ErrorToName(code);
236 return "unknown error";
239 static void nss_print_error_message(
struct Curl_easy *
data, PRUint32 err)
241 failf(data,
"%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
244 static SECStatus set_ciphers(
struct Curl_easy *data, PRFileDesc * model,
248 PRBool cipher_state[NUM_OF_CIPHERS];
253 const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
254 const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers();
255 if(!implemented_ciphers)
262 for(i = 0; i < num_implemented_ciphers; i++) {
263 SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
267 for(i = 0; i < NUM_OF_CIPHERS; i++) {
268 cipher_state[
i] = PR_FALSE;
271 cipher = cipher_list;
273 while(cipher_list && (cipher_list[0])) {
274 while((*cipher) && (
ISSPACE(*cipher)))
277 cipher_list = strchr(cipher,
',');
279 *cipher_list++ =
'\0';
284 for(i = 0; i<NUM_OF_CIPHERS; i++) {
286 cipher_state[
i] = PR_TRUE;
292 if(found == PR_FALSE) {
293 failf(data,
"Unknown cipher in list: %s", cipher);
298 cipher = cipher_list;
303 for(i = 0; i<NUM_OF_CIPHERS; i++) {
307 if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
308 failf(data,
"cipher-suite not supported by NSS: %s", cipherlist[i].name);
320 static bool any_cipher_enabled(
void)
324 for(i = 0; i<NUM_OF_CIPHERS; i++) {
326 SSL_CipherPolicyGet(cipherlist[i].num, &policy);
341 static int is_file(
const char *filename)
348 if(
stat(filename, &st) == 0)
349 if(S_ISREG(st.st_mode))
361 static char *dup_nickname(
struct Curl_easy *data,
const char *
str)
370 n = strchr(str,
'/');
372 infof(data,
"warning: certificate file name \"%s\" handled as nickname; " 373 "please use \"./%s\" to force file name\n", str, str);
385 static PK11SlotInfo* nss_find_slot_by_name(
const char *slot_name)
388 PR_Lock(nss_findslot_lock);
389 slot = PK11_FindSlotByName(slot_name);
390 PR_Unlock(nss_findslot_lock);
397 struct ptr_list_wrap *wrap =
malloc(
sizeof *wrap);
410 CK_OBJECT_CLASS obj_class,
411 const char *filename,
bool cacert)
414 PK11GenericObject *obj;
415 CK_BBOOL cktrue = CK_TRUE;
416 CK_BBOOL ckfalse = CK_FALSE;
417 CK_ATTRIBUTE attrs[ 4];
423 const int slot_id = (cacert) ? 0 : 1;
424 char *slot_name =
aprintf(
"PEM Token #%d", slot_id);
428 slot = nss_find_slot_by_name(slot_name);
433 PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class,
sizeof(obj_class));
434 PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue,
sizeof(CK_BBOOL));
435 PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (
unsigned char *)filename,
436 (CK_ULONG)strlen(filename) + 1);
438 if(CKO_CERTIFICATE == obj_class) {
439 CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
440 PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval,
sizeof(*pval));
443 obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
448 if(insert_wrapped_ptr(&BACKEND->obj_list, obj) !=
CURLE_OK) {
449 PK11_DestroyGenericObject(obj);
453 if(!cacert && CKO_CERTIFICATE == obj_class)
455 BACKEND->obj_clicert = obj;
463 static void nss_destroy_object(
void *user,
void *ptr)
465 struct ptr_list_wrap *wrap = (
struct ptr_list_wrap *) ptr;
466 PK11GenericObject *obj = (PK11GenericObject *) wrap->ptr;
468 PK11_DestroyGenericObject(obj);
473 static void nss_destroy_crl_item(
void *user,
void *ptr)
475 struct ptr_list_wrap *wrap = (
struct ptr_list_wrap *) ptr;
476 SECItem *crl_der = (SECItem *) wrap->ptr;
478 SECITEM_FreeItem(crl_der, PR_TRUE);
483 const char *filename, PRBool cacert)
491 if(is_file(filename))
492 result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
494 if(!result && !cacert) {
496 CERTCertificate *cert;
497 char *nickname = NULL;
498 char *n = strrchr(filename,
'/');
506 nickname =
aprintf(
"PEM Token #1:%s", n);
508 cert = PK11_FindCertFromNickname(nickname, NULL);
510 CERT_DestroyCertificate(cert);
520 static CURLcode nss_cache_crl(SECItem *crl_der)
522 CERTCertDBHandle *db = CERT_GetDefaultCertDB();
523 CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
527 SECITEM_FreeItem(crl_der, PR_TRUE);
532 PR_Lock(nss_crllock);
535 if(insert_wrapped_ptr(&nss_crl_list, crl_der) !=
CURLE_OK) {
536 SECITEM_FreeItem(crl_der, PR_TRUE);
537 PR_Unlock(nss_crllock);
541 if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
543 PR_Unlock(nss_crllock);
548 SSL_ClearSessionCache();
549 PR_Unlock(nss_crllock);
553 static CURLcode nss_load_crl(
const char *crlfilename)
557 SECItem filedata = { 0, NULL, 0 };
558 SECItem *crl_der = NULL;
561 infile = PR_Open(crlfilename, PR_RDONLY, 0);
565 if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
568 if(!SECITEM_AllocItem(NULL, &filedata, info.size + 1))
571 if(info.size != PR_Read(infile, filedata.data, info.size))
574 crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
579 body = (
char *)filedata.data;
580 body[--filedata.len] =
'\0';
582 body = strstr(body,
"-----BEGIN");
586 char *begin = PORT_Strchr(body,
'\n');
588 begin = PORT_Strchr(body,
'\r');
592 trailer = strstr(++begin,
"-----END");
598 if(ATOB_ConvertAsciiToItem(crl_der, begin))
601 SECITEM_FreeItem(&filedata, PR_FALSE);
608 return nss_cache_crl(crl_der);
612 SECITEM_FreeItem(crl_der, PR_TRUE);
613 SECITEM_FreeItem(&filedata, PR_FALSE);
620 PK11SlotInfo *slot, *tmp;
628 result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file,
FALSE);
630 PR_SetError(SEC_ERROR_BAD_KEY, 0);
634 slot = nss_find_slot_by_name(
"PEM Token #1");
639 tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0);
642 PK11_IsPresent(slot);
644 status = PK11_Authenticate(slot, PR_TRUE,
SSL_SET_OPTION(key_passwd));
650 static int display_error(
struct connectdata *conn, PRInt32 err,
651 const char *filename)
654 case SEC_ERROR_BAD_PASSWORD:
655 failf(conn->
data,
"Unable to load client key: Incorrect password");
657 case SEC_ERROR_UNKNOWN_CERT:
658 failf(conn->
data,
"Unable to load certificate %s", filename);
667 char *cert_file,
char *key_file)
673 result = nss_load_cert(&conn->
ssl[sockindex], cert_file, PR_FALSE);
675 const PRErrorCode err = PR_GetError();
676 if(!display_error(conn, err, cert_file)) {
677 const char *err_name = nss_error_to_name(err);
678 failf(data,
"unable to load client cert: %d (%s)", err, err_name);
685 if(key_file || (is_file(cert_file))) {
687 result = nss_load_key(conn, sockindex, key_file);
690 result = nss_load_key(conn, sockindex, cert_file);
692 const PRErrorCode err = PR_GetError();
693 if(!display_error(conn, err, key_file)) {
694 const char *err_name = nss_error_to_name(err);
695 failf(data,
"unable to load client key: %d (%s)", err, err_name);
705 static char *nss_get_password(PK11SlotInfo *slot, PRBool retry,
void *arg)
709 if(retry || NULL == arg)
712 return (
char *)PORT_Strdup((
char *)arg);
717 static SECStatus nss_auth_cert_hook(
void *arg, PRFileDesc *fd, PRBool checksig,
722 #ifdef SSL_ENABLE_OCSP_STAPLING 724 SECStatus cacheResult;
726 const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
728 failf(conn->
data,
"Invalid OCSP response");
733 failf(conn->
data,
"No OCSP response received");
737 cacheResult = CERT_CacheOCSPResponseFromSideChannel(
738 CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
739 PR_Now(), &csa->items[0], arg
742 if(cacheResult != SECSuccess) {
743 failf(conn->
data,
"Invalid OCSP response");
750 infof(conn->
data,
"skipping SSL peer certificate verification\n");
754 return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
760 static void HandshakeCallback(PRFileDesc *
sock,
void *arg)
763 unsigned int buflenmax = 50;
764 unsigned char buf[50];
766 SSLNextProtoState
state;
772 if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
775 #if NSSVERNUM >= 0x031a00 777 case SSL_NEXT_PROTO_EARLY_VALUE:
780 case SSL_NEXT_PROTO_NO_SUPPORT:
781 case SSL_NEXT_PROTO_NO_OVERLAP:
782 infof(conn->
data,
"ALPN/NPN, server did not agree to a protocol\n");
784 #ifdef SSL_ENABLE_ALPN 785 case SSL_NEXT_PROTO_SELECTED:
786 infof(conn->
data,
"ALPN, server accepted to use %.*s\n", buflen, buf);
789 case SSL_NEXT_PROTO_NEGOTIATED:
790 infof(conn->
data,
"NPN, server accepted to use %.*s\n", buflen, buf);
795 if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
796 !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
808 #if NSSVERNUM >= 0x030f04 809 static SECStatus CanFalseStartCallback(PRFileDesc *sock,
void *client_data,
810 PRBool *canFalseStart)
815 SSLChannelInfo channelInfo;
816 SSLCipherSuiteInfo cipherInfo;
819 PRBool negotiatedExtension;
821 *canFalseStart = PR_FALSE;
823 if(SSL_GetChannelInfo(sock, &channelInfo,
sizeof(channelInfo)) != SECSuccess)
826 if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
827 sizeof(cipherInfo)) != SECSuccess)
833 if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
838 if(cipherInfo.keaType != ssl_kea_ecdh)
844 if(cipherInfo.symCipher != ssl_calg_aes_gcm)
849 rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
850 &negotiatedExtension);
851 if(rv != SECSuccess || !negotiatedExtension) {
852 rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
853 &negotiatedExtension);
856 if(rv != SECSuccess || !negotiatedExtension)
859 *canFalseStart = PR_TRUE;
861 infof(data,
"Trying TLS False Start\n");
868 static void display_cert_info(
struct Curl_easy *data,
869 CERTCertificate *cert)
871 char *subject, *issuer, *common_name;
872 PRExplodedTime printableTime;
873 char timeString[256];
874 PRTime notBefore, notAfter;
876 subject = CERT_NameToAscii(&cert->subject);
877 issuer = CERT_NameToAscii(&cert->issuer);
878 common_name = CERT_GetCommonName(&cert->subject);
879 infof(data,
"\tsubject: %s\n", subject);
881 CERT_GetCertTimes(cert, ¬Before, ¬After);
882 PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
883 PR_FormatTime(timeString, 256,
"%b %d %H:%M:%S %Y GMT", &printableTime);
884 infof(data,
"\tstart date: %s\n", timeString);
885 PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
886 PR_FormatTime(timeString, 256,
"%b %d %H:%M:%S %Y GMT", &printableTime);
887 infof(data,
"\texpire date: %s\n", timeString);
888 infof(data,
"\tcommon name: %s\n", common_name);
889 infof(data,
"\tissuer: %s\n", issuer);
893 PR_Free(common_name);
899 SSLChannelInfo channel;
900 SSLCipherSuiteInfo suite;
901 CERTCertificate *cert;
902 CERTCertificate *cert2;
903 CERTCertificate *cert3;
907 if(SSL_GetChannelInfo(sock, &channel,
sizeof channel) ==
908 SECSuccess && channel.length ==
sizeof channel &&
909 channel.cipherSuite) {
910 if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
911 &suite,
sizeof suite) == SECSuccess) {
912 infof(conn->
data,
"SSL connection using %s\n", suite.cipherSuiteName);
916 cert = SSL_PeerCertificate(sock);
918 infof(conn->
data,
"Server certificate:\n");
921 display_cert_info(conn->
data, cert);
922 CERT_DestroyCertificate(cert);
929 cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
933 CERT_DestroyCertificate(cert2);
936 cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
937 CERT_DestroyCertificate(cert2);
942 result = Curl_ssl_init_certinfo(conn->
data, i);
944 for(i = 0; cert; cert = cert2) {
945 result = Curl_extract_certinfo(conn, i++, (
char *)cert->derCert.
data,
946 (
char *)cert->derCert.data +
952 CERT_DestroyCertificate(cert);
956 cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
957 CERT_DestroyCertificate(cert);
966 static SECStatus BadCertHandler(
void *arg, PRFileDesc *sock)
970 PRErrorCode err = PR_GetError();
971 CERTCertificate *cert;
984 cert = SSL_PeerCertificate(sock);
986 infof(data,
"Server certificate:\n");
987 display_cert_info(data, cert);
988 CERT_DestroyCertificate(cert);
1001 static SECStatus check_issuer_cert(PRFileDesc *sock,
1002 char *issuer_nickname)
1004 CERTCertificate *cert, *cert_issuer, *issuer;
1005 SECStatus
res = SECSuccess;
1006 void *proto_win = NULL;
1008 cert = SSL_PeerCertificate(sock);
1009 cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
1011 proto_win = SSL_RevealPinArg(sock);
1012 issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
1014 if((!cert_issuer) || (!issuer))
1016 else if(SECITEM_CompareItem(&cert_issuer->derCert,
1017 &issuer->derCert) != SECEqual)
1020 CERT_DestroyCertificate(cert);
1021 CERT_DestroyCertificate(issuer);
1022 CERT_DestroyCertificate(cert_issuer);
1027 const char *pinnedpubkey)
1031 CERTCertificate *cert;
1038 cert = SSL_PeerCertificate(BACKEND->handle);
1041 SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
1044 SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
1047 result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
1049 SECITEM_FreeItem(cert_der, PR_TRUE);
1051 SECKEY_DestroyPublicKey(pubkey);
1053 CERT_DestroyCertificate(cert);
1059 infof(data,
"pinned public key verified successfully!\n");
1062 failf(data,
"failed to verify pinned public key");
1076 static SECStatus SelectClientCert(
void *arg, PRFileDesc *sock,
1077 struct CERTDistNamesStr *caNames,
1078 struct CERTCertificateStr **pRetCert,
1079 struct SECKEYPrivateKeyStr **pRetKey)
1083 const char *nickname = BACKEND->client_nickname;
1084 static const char pem_slotname[] =
"PEM Token #1";
1086 if(BACKEND->obj_clicert) {
1088 SECItem cert_der = { 0, NULL, 0 };
1089 void *proto_win = SSL_RevealPinArg(sock);
1090 struct CERTCertificateStr *cert;
1091 struct SECKEYPrivateKeyStr *
key;
1093 PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
1095 failf(data,
"NSS: PK11 slot not found: %s", pem_slotname);
1099 if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
1100 &cert_der) != SECSuccess) {
1101 failf(data,
"NSS: CKA_VALUE not found in PK11 generic object");
1102 PK11_FreeSlot(slot);
1106 cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
1107 SECITEM_FreeItem(&cert_der, PR_FALSE);
1109 failf(data,
"NSS: client certificate from file not found");
1110 PK11_FreeSlot(slot);
1114 key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
1115 PK11_FreeSlot(slot);
1117 failf(data,
"NSS: private key from file not found");
1118 CERT_DestroyCertificate(cert);
1122 infof(data,
"NSS: client certificate from file\n");
1123 display_cert_info(data, cert);
1131 if(SECSuccess != NSS_GetClientAuthData((
void *)nickname, sock, caNames,
1133 || NULL == *pRetCert) {
1135 if(NULL == nickname)
1136 failf(data,
"NSS: client certificate not found (nickname not " 1139 failf(data,
"NSS: client certificate not found: %s", nickname);
1145 nickname = (*pRetCert)->nickname;
1146 if(NULL == nickname)
1147 nickname =
"[unknown]";
1149 if(!strncmp(nickname, pem_slotname,
sizeof(pem_slotname) - 1U)) {
1150 failf(data,
"NSS: refusing previously loaded certificate from file: %s",
1155 if(NULL == *pRetKey) {
1156 failf(data,
"NSS: private key not found for certificate: %s", nickname);
1160 infof(data,
"NSS: using client certificate: %s\n", nickname);
1161 display_cert_info(data, *pRetCert);
1169 if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
1188 static PRInt32 nspr_io_recv(PRFileDesc *fd,
void *buf, PRInt32 amount,
1189 PRIntn flags, PRIntervalTime
timeout)
1191 const PRRecvFN recv_fn = fd->lower->methods->recv;
1192 const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
1200 static PRInt32 nspr_io_send(PRFileDesc *fd,
const void *buf, PRInt32 amount,
1201 PRIntn flags, PRIntervalTime timeout)
1203 const PRSendFN send_fn = fd->lower->methods->send;
1204 const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
1212 static PRStatus nspr_io_close(PRFileDesc *fd)
1214 const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
1216 return close_fn(fd);
1220 static CURLcode nss_load_module(SECMODModule **pmod,
const char *
library,
1223 char *config_string;
1224 SECMODModule *module = *pmod;
1229 config_string =
aprintf(
"library=%s name=%s", library, name);
1233 module = SECMOD_LoadUserModule(config_string, NULL, PR_FALSE);
1234 free(config_string);
1236 if(module && module->loaded) {
1243 SECMOD_DestroyModule(module);
1248 static void nss_unload_module(SECMODModule **pmod)
1250 SECMODModule *module = *pmod;
1255 if(SECMOD_UnloadUserModule(module) != SECSuccess)
1259 SECMOD_DestroyModule(module);
1266 NSSInitParameters initparams;
1268 if(nss_context != NULL)
1271 memset((
void *) &initparams,
'\0',
sizeof(initparams));
1272 initparams.length =
sizeof(initparams);
1275 char *certpath =
aprintf(
"sql:%s", cert_dir);
1279 infof(data,
"Initializing NSS with certpath: %s\n", certpath);
1280 nss_context = NSS_InitContext(certpath,
"",
"",
"", &initparams,
1281 NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
1284 if(nss_context != NULL)
1287 infof(data,
"Unable to initialize NSS database\n");
1290 infof(data,
"Initializing NSS with certpath: none\n");
1291 nss_context = NSS_InitContext(
"",
"",
"",
"", &initparams, NSS_INIT_READONLY
1292 | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
1293 | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
1294 if(nss_context != NULL)
1297 infof(data,
"Unable to initialize NSS\n");
1315 cert_dir =
getenv(
"SSL_DIR");
1317 if((
stat(cert_dir, &st) != 0) ||
1318 (!S_ISDIR(st.st_mode))) {
1325 if((
stat(SSL_DIR, &st) == 0) &&
1326 (S_ISDIR(st.st_mode))) {
1327 cert_dir = (
char *)SSL_DIR;
1331 if(nspr_io_identity == PR_INVALID_IO_LAYER) {
1333 nspr_io_identity = PR_GetUniqueIdentity(
"libcurl");
1334 if(nspr_io_identity == PR_INVALID_IO_LAYER)
1338 memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(),
sizeof nspr_io_methods);
1341 nspr_io_methods.recv = nspr_io_recv;
1342 nspr_io_methods.send = nspr_io_send;
1343 nspr_io_methods.close = nspr_io_close;
1346 result = nss_init_core(data, cert_dir);
1350 if(!any_cipher_enabled())
1351 NSS_SetDomesticPolicy();
1364 static int Curl_nss_init(
void)
1367 if(nss_initlock == NULL) {
1368 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
1369 nss_initlock = PR_NewLock();
1370 nss_crllock = PR_NewLock();
1371 nss_findslot_lock = PR_NewLock();
1372 nss_trustload_lock = PR_NewLock();
1386 failf(data,
"unable to initialize NSS, curl_global_init() should have " 1387 "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
1391 PR_Lock(nss_initlock);
1392 result = nss_init(data);
1393 PR_Unlock(nss_initlock);
1399 static void Curl_nss_cleanup(
void)
1404 PR_Lock(nss_initlock);
1409 SSL_ClearSessionCache();
1411 nss_unload_module(&pem_module);
1412 nss_unload_module(&trust_module);
1413 NSS_ShutdownContext(nss_context);
1420 PR_Unlock(nss_initlock);
1422 PR_DestroyLock(nss_initlock);
1423 PR_DestroyLock(nss_crllock);
1424 PR_DestroyLock(nss_findslot_lock);
1425 PR_DestroyLock(nss_trustload_lock);
1426 nss_initlock = NULL;
1439 static int Curl_nss_check_cxn(
struct connectdata *conn)
1446 PR_Recv(BACKEND->handle, (
void *)&buf, 1, PR_MSG_PEEK,
1447 PR_SecondsToInterval(1));
1460 const bool client_cert = (BACKEND->client_nickname != NULL)
1461 || (BACKEND->obj_clicert != NULL);
1463 free(BACKEND->client_nickname);
1464 BACKEND->client_nickname = NULL;
1468 BACKEND->obj_clicert = NULL;
1470 if(BACKEND->handle) {
1476 SSL_InvalidateSession(BACKEND->handle);
1478 PR_Close(BACKEND->handle);
1479 BACKEND->handle = NULL;
1486 static void Curl_nss_close(
struct connectdata *conn,
int sockindex)
1491 if(BACKEND->handle || connssl_proxy->backend->handle) {
1502 connssl_proxy->backend->handle = NULL;
1505 nss_close(connssl_proxy);
1510 static bool is_nss_error(
CURLcode err)
1526 static bool is_cc_error(PRInt32 err)
1529 case SSL_ERROR_BAD_CERT_ALERT:
1530 case SSL_ERROR_EXPIRED_CERT_ALERT:
1531 case SSL_ERROR_REVOKED_CERT_ALERT:
1548 bool use_trust_module;
1552 if(cafile && !cafile[0])
1554 if(capath && !capath[0])
1557 infof(data,
" CAfile: %s\n CApath: %s\n",
1558 cafile ? cafile :
"none",
1559 capath ? capath :
"none");
1562 use_trust_module = !cafile && !capath;
1564 PR_Lock(nss_trustload_lock);
1565 if(use_trust_module && !trust_module) {
1567 result = nss_load_module(&trust_module, trust_library,
"trust");
1568 infof(data,
"%s %s\n", (result) ?
"failed to load" :
"loaded",
1574 else if(!use_trust_module && trust_module) {
1576 infof(data,
"unloading %s\n", trust_library);
1577 nss_unload_module(&trust_module);
1579 PR_Unlock(nss_trustload_lock);
1582 result = nss_load_cert(&conn->
ssl[sockindex], cafile, PR_TRUE);
1589 if(
stat(capath, &st) == -1)
1592 if(S_ISDIR(st.st_mode)) {
1594 PRDir *dir = PR_OpenDir(capath);
1598 while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
1599 char *fullpath =
aprintf(
"%s/%s", capath, entry->name);
1605 if(
CURLE_OK != nss_load_cert(&conn->
ssl[sockindex], fullpath, PR_TRUE))
1608 infof(data,
"failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
1616 infof(data,
"warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
1622 static CURLcode nss_sslver_from_curl(PRUint16 *nssver,
long version)
1627 #ifdef SSL_LIBRARY_VERSION_TLS_1_2 1628 *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
1629 #elif defined SSL_LIBRARY_VERSION_TLS_1_1 1630 *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
1632 *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
1637 *nssver = SSL_LIBRARY_VERSION_2;
1641 *nssver = SSL_LIBRARY_VERSION_3_0;
1645 *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
1649 #ifdef SSL_LIBRARY_VERSION_TLS_1_1 1650 *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
1657 #ifdef SSL_LIBRARY_VERSION_TLS_1_2 1658 *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
1665 #ifdef SSL_LIBRARY_VERSION_TLS_1_3 1666 *nssver = SSL_LIBRARY_VERSION_TLS_1_3;
1677 static CURLcode nss_init_sslver(SSLVersionRange *sslver,
1688 if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
1691 if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
1692 sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
1699 sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
1702 result = nss_sslver_from_curl(&sslver->min, min);
1704 failf(data,
"unsupported min version passed via CURLOPT_SSLVERSION");
1708 sslver->max = sslver->min;
1716 result = nss_sslver_from_curl(&sslver->max, max >> 16);
1718 failf(data,
"unsupported max version passed via CURLOPT_SSLVERSION");
1730 PRErrorCode err = 0;
1732 if(is_nss_error(curlerr)) {
1734 err = PR_GetError();
1735 if(is_cc_error(err))
1739 infof(data,
"NSS error %d (%s)\n", err, nss_error_to_name(err));
1742 nss_print_error_message(data, err);
1756 static PRSocketOptionData sock_opt;
1757 sock_opt.option = PR_SockOpt_Nonblocking;
1758 sock_opt.value.non_blocking = !blocking;
1760 if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
1768 PRFileDesc *model = NULL;
1769 PRFileDesc *nspr_io = NULL;
1770 PRFileDesc *nspr_io_stub = NULL;
1771 PRBool ssl_no_cache;
1772 PRBool ssl_cbc_random_iv;
1777 bool second_layer =
FALSE;
1779 SSLVersionRange sslver = {
1780 SSL_LIBRARY_VERSION_TLS_1_0,
1781 SSL_LIBRARY_VERSION_TLS_1_0
1784 BACKEND->data =
data;
1790 PR_Lock(nss_initlock);
1791 result = nss_init(conn->
data);
1793 PR_Unlock(nss_initlock);
1797 PK11_SetPasswordFunc(nss_get_password);
1799 result = nss_load_module(&pem_module, pem_library,
"PEM");
1800 PR_Unlock(nss_initlock);
1802 infof(data,
"WARNING: failed to load NSS PEM library %s. Using " 1803 "OpenSSL PEM certificates will not work.\n", pem_library);
1809 model = PR_NewTCPSocket();
1812 model = SSL_ImportFD(NULL, model);
1814 if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
1816 if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
1818 if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
1824 if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
1828 if(nss_init_sslver(&sslver, data, conn) !=
CURLE_OK)
1830 if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
1834 #ifdef SSL_CBC_RANDOM_IV 1837 if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
1838 infof(data,
"warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
1841 if(ssl_cbc_random_iv)
1842 infof(data,
"warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
1846 if(set_ciphers(data, model,
SSL_CONN_CONFIG(cipher_list)) != SECSuccess) {
1853 infof(data,
"warning: ignoring value of ssl.verifyhost\n");
1857 if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
1866 if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
1869 if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
1873 const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
1876 infof(data,
"warning: CA certificates failed to load\n");
1896 BACKEND->obj_clicert = NULL;
1909 BACKEND->client_nickname = nickname;
1912 BACKEND->client_nickname = NULL;
1914 if(SSL_GetClientAuthDataHook(model, SelectClientCert,
1915 (
void *)connssl) != SECSuccess) {
1923 nspr_io = conn->
proxy_ssl[sockindex].backend->handle;
1924 second_layer =
TRUE;
1928 nspr_io = PR_ImportTCPSocket(sockfd);
1934 nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
1942 nspr_io_stub->secret = (
void *)connssl;
1945 if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
1948 PR_Close(nspr_io_stub);
1953 BACKEND->handle = SSL_ImportFD(model, nspr_io);
1954 if(!BACKEND->handle) {
1965 SSL_SetPKCS11PinArg(BACKEND->handle,
SSL_SET_OPTION(key_passwd));
1968 #ifdef SSL_ENABLE_OCSP_STAPLING 1970 if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
1976 #ifdef SSL_ENABLE_NPN 1978 ? PR_TRUE : PR_FALSE) != SECSuccess)
1982 #ifdef SSL_ENABLE_ALPN 1984 ? PR_TRUE : PR_FALSE) != SECSuccess)
1988 #if NSSVERNUM >= 0x030f04 1990 if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
1994 if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
1995 conn) != SECSuccess)
2000 #if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN) 2008 protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
2009 memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
2010 NGHTTP2_PROTO_VERSION_ID_LEN);
2011 cur += NGHTTP2_PROTO_VERSION_ID_LEN;
2018 if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
2025 if(SSL_ResetHandshake(BACKEND->handle, PR_FALSE)
2046 return nss_fail_connect(connssl, data, result);
2065 failf(data,
"timed out before SSL handshake");
2071 timeout = PR_MillisecondsToInterval((PRUint32) time_left);
2072 if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
2073 if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
2076 else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
2078 else if(*certverifyresult != 0)
2083 result = display_conn_info(conn, BACKEND->handle);
2088 SECStatus ret = SECFailure;
2092 ret = check_issuer_cert(BACKEND->handle, nickname);
2096 if(SECFailure == ret) {
2097 infof(data,
"SSL certificate issuer check failed\n");
2102 infof(data,
"SSL certificate issuer check ok\n");
2106 result = cmp_peer_pubkey(connssl, pinnedpubkey);
2114 return nss_fail_connect(connssl, data, result);
2122 const bool blocking = (done == NULL);
2132 result = nss_setup_connect(conn, sockindex);
2141 result = nss_set_blocking(connssl, data, blocking);
2145 result = nss_do_connect(conn, sockindex);
2160 result = nss_set_blocking(connssl, data,
FALSE);
2169 conn->
recv[sockindex] = nss_recv;
2170 conn->
send[sockindex] = nss_send;
2180 return nss_connect_common(conn, sockindex, NULL);
2184 int sockindex,
bool *done)
2186 return nss_connect_common(conn, sockindex, done);
2200 BACKEND->data = conn->
data;
2202 rc = PR_Send(BACKEND->handle, mem, (
int)len, 0, PR_INTERVAL_NO_WAIT);
2204 PRInt32 err = PR_GetError();
2205 if(err == PR_WOULD_BLOCK_ERROR)
2209 const char *err_name = nss_error_to_name(err);
2210 infof(conn->
data,
"SSL write: error %d (%s)\n", err, err_name);
2213 nss_print_error_message(conn->
data, err);
2215 *curlcode = (is_cc_error(err))
2237 BACKEND->data = conn->
data;
2239 nread = PR_Recv(BACKEND->handle, buf, (
int)buffersize, 0,
2240 PR_INTERVAL_NO_WAIT);
2243 PRInt32 err = PR_GetError();
2245 if(err == PR_WOULD_BLOCK_ERROR)
2249 const char *err_name = nss_error_to_name(err);
2250 infof(conn->
data,
"SSL read: errno %d (%s)\n", err, err_name);
2253 nss_print_error_message(conn->
data, err);
2255 *curlcode = (is_cc_error(err))
2266 static size_t Curl_nss_version(
char *
buffer,
size_t size)
2268 return snprintf(buffer, size,
"NSS/%s", NSS_VERSION);
2272 static int Curl_nss_seed(
struct Curl_easy *data)
2275 return !!Curl_nss_force_init(data);
2280 unsigned char *entropy,
2283 Curl_nss_seed(data);
2285 if(SECSuccess != PK11_GenerateRandom(entropy,
curlx_uztosi(length)))
2292 static CURLcode Curl_nss_md5sum(
unsigned char *tmp,
2294 unsigned char *md5sum,
2297 PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
2298 unsigned int MD5out;
2301 PK11_DigestFinal(MD5pw, md5sum, &MD5out,
curlx_uztoui(md5len));
2302 PK11_DestroyContext(MD5pw, PR_TRUE);
2307 static void Curl_nss_sha256sum(
const unsigned char *tmp,
2309 unsigned char *sha256sum,
2312 PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
2313 unsigned int SHA256out;
2316 PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out,
curlx_uztoui(sha256len));
2317 PK11_DestroyContext(SHA256pw, PR_TRUE);
2320 static bool Curl_nss_cert_status_request(
void)
2322 #ifdef SSL_ENABLE_OCSP_STAPLING 2329 static bool Curl_nss_false_start(
void)
2331 #if NSSVERNUM >= 0x030f04 2342 return BACKEND->handle;
2345 const struct Curl_ssl Curl_ssl_nss = {
2354 sizeof(
struct ssl_backend_data),
2364 Curl_nss_cert_status_request,
2366 Curl_nss_connect_nonblocking,
2367 Curl_nss_get_internals,
2375 Curl_nss_false_start,
struct ssl_connect_data ssl[2]
ssize_t( Curl_recv)(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err)
#define SSL_CONN_CONFIG(var)
int stat(const char *path, struct stat *buffer)
void Curl_none_session_free(void *ptr)
struct ssl_config_data proxy_ssl
#define SSL_SET_OPTION(var)
ssl_connect_state connecting_state
struct curl_llist_element * tail
UNITTEST_START char * ptr
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
static const struct Curl_handler *const protocols[]
int Curl_none_shutdown(struct connectdata *conn, int sockindex)
void Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
static unsigned int initialized
bool Curl_none_data_pending(const struct connectdata *conn, int connindex)
#define strcasecompare(a, b)
int curlx_uztosi(size_t uznum)
UNITTEST_START int result
struct ssl_config_data ssl
struct proxy_info http_proxy
ssl_connection_state state
memcpy(filename, filename1, strlen(filename1))
#define ALPN_HTTP_1_1_LENGTH
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
UNITTEST_START struct Curl_easy data
double min(double a, double b)
unsigned int curlx_uztoui(size_t uznum)
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
void Curl_llist_destroy(struct curl_llist *list, void *user)
struct ssl_connect_data proxy_ssl[2]
#define CURL_HTTP_VERSION_2
void Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e, const void *p, struct curl_llist_element *ne)
double max(double a, double b)
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
void Curl_none_close_all(struct Curl_easy *data)