1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-10 11:35:07 -05:00

nss: select client certificates by DER

... instead of nicknames, which are not unique.
This commit is contained in:
Kamil Dudka 2011-08-26 14:38:18 +02:00
parent d47d95ac3b
commit f6980bbf24
3 changed files with 31 additions and 16 deletions

View File

@ -24,6 +24,7 @@ This release includes the following bugfixes:
o lots of MinGW build tweaks o lots of MinGW build tweaks
o Curl_gethostname: return un-qualified machine name o Curl_gethostname: return un-qualified machine name
o fixed the openssl version number configure check o fixed the openssl version number configure check
o nss: certificates from files are no longer looked up by file base names
This release includes the following known bugs: This release includes the following known bugs:

View File

@ -354,6 +354,10 @@ static CURLcode nss_create_object(struct ssl_connect_data *ssl,
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
if(!cacert && CKO_CERTIFICATE == obj_class)
/* store reference to a client certificate */
ssl->obj_clicert = obj;
return CURLE_OK; return CURLE_OK;
} }
@ -398,6 +402,7 @@ static int nss_load_cert(struct ssl_connect_data *ssl,
nickname = strdup(filename); nickname = strdup(filename);
if(!nickname) if(!nickname)
return 0; return 0;
goto done; goto done;
} }
@ -797,44 +802,51 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
struct CERTCertificateStr **pRetCert, struct CERTCertificateStr **pRetCert,
struct SECKEYPrivateKeyStr **pRetKey) struct SECKEYPrivateKeyStr **pRetKey)
{ {
static const char pem_nickname[] = "PEM Token #1";
const char *pem_slotname = pem_nickname;
struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg; struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
struct SessionHandle *data = connssl->data; struct SessionHandle *data = connssl->data;
const char *nickname = connssl->client_nickname; const char *nickname = connssl->client_nickname;
if(mod && nickname && #ifdef HAVE_PK11_CREATEGENERICOBJECT
0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) { if(connssl->obj_clicert) {
/* use the cert/key provided by PEM reader */ /* use the cert/key provided by PEM reader */
PK11SlotInfo *slot; static const char pem_slotname[] = "PEM Token #1";
SECItem cert_der = { 0, NULL, 0 };
void *proto_win = SSL_RevealPinArg(sock); void *proto_win = SSL_RevealPinArg(sock);
*pRetKey = NULL;
*pRetCert = PK11_FindCertFromNickname(nickname, proto_win); PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
if(NULL == *pRetCert) { if(NULL == slot) {
failf(data, "NSS: client certificate not found: %s", nickname); failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
return SECFailure; return SECFailure;
} }
slot = PK11_FindSlotByName(pem_slotname); if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
if(NULL == slot) { &cert_der) != SECSuccess) {
failf(data, "NSS: PK11 slot not found: %s", pem_slotname); failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
PK11_FreeSlot(slot);
return SECFailure;
}
*pRetCert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
SECITEM_FreeItem(&cert_der, PR_FALSE);
if(NULL == *pRetCert) {
failf(data, "NSS: client certificate from file not found");
PK11_FreeSlot(slot);
return SECFailure; return SECFailure;
} }
*pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL); *pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
PK11_FreeSlot(slot); PK11_FreeSlot(slot);
if(NULL == *pRetKey) { if(NULL == *pRetKey) {
failf(data, "NSS: private key not found for certificate: %s", nickname); failf(data, "NSS: private key from file not found");
CERT_DestroyCertificate(*pRetCert);
return SECFailure; return SECFailure;
} }
infof(data, "NSS: client certificate: %s\n", nickname); infof(data, "NSS: client certificate from file\n");
display_cert_info(data, *pRetCert); display_cert_info(data, *pRetCert);
return SECSuccess; return SECSuccess;
} }
#endif
/* use the default NSS hook */ /* use the default NSS hook */
if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames, if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
@ -1076,6 +1088,7 @@ void Curl_nss_close(struct connectdata *conn, int sockindex)
/* destroy all NSS objects in order to avoid failure of NSS shutdown */ /* destroy all NSS objects in order to avoid failure of NSS shutdown */
Curl_llist_destroy(connssl->obj_list, NULL); Curl_llist_destroy(connssl->obj_list, NULL);
connssl->obj_list = NULL; connssl->obj_list = NULL;
connssl->obj_clicert = NULL;
#endif #endif
PR_Close(connssl->handle); PR_Close(connssl->handle);
connssl->handle = NULL; connssl->handle = NULL;

View File

@ -273,6 +273,7 @@ struct ssl_connect_data {
struct SessionHandle *data; struct SessionHandle *data;
#ifdef HAVE_PK11_CREATEGENERICOBJECT #ifdef HAVE_PK11_CREATEGENERICOBJECT
struct curl_llist *obj_list; struct curl_llist *obj_list;
PK11GenericObject *obj_clicert;
#endif #endif
#endif /* USE_NSS */ #endif /* USE_NSS */
#ifdef USE_QSOSSL #ifdef USE_QSOSSL