rpms/curl/devel curl-7.19.5-cc.patch, NONE, 1.1 curl-7.19.5-cc_refcnt-2.patch, 1.2, 1.3 curl.spec, 1.105, 1.106

Kamil Dudka kdudka at fedoraproject.org
Wed Jul 22 08:48:26 UTC 2009


Author: kdudka

Update of /cvs/extras/rpms/curl/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv11354

Modified Files:
	curl-7.19.5-cc_refcnt-2.patch curl.spec 
Added Files:
	curl-7.19.5-cc.patch 
Log Message:
try to select client certificate automatically when not specified

curl-7.19.5-cc.patch:
 nss.c     |  210 +++++++++++++++++++++++++++++---------------------------------
 urldata.h |    1 
 2 files changed, 101 insertions(+), 110 deletions(-)

--- NEW FILE curl-7.19.5-cc.patch ---
diff -ruNp curl-7.19.5.orig/lib/nss.c curl-7.19.5/lib/nss.c
--- curl-7.19.5.orig/lib/nss.c	2009-07-22 10:30:03.010106586 +0200
+++ curl-7.19.5/lib/nss.c	2009-07-22 10:30:54.069293169 +0200
@@ -585,48 +585,6 @@ static char * nss_get_password(PK11SlotI
     return (char *)PORT_Strdup((char *)arg);
 }
 
-static SECStatus nss_Init_Tokens(struct connectdata * conn)
-{
-  PK11SlotList *slotList;
-  PK11SlotListElement *listEntry;
-  SECStatus ret, status = SECSuccess;
-
-  PK11_SetPasswordFunc(nss_get_password);
-
-  slotList =
-    PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL);
-
-  for(listEntry = PK11_GetFirstSafe(slotList);
-      listEntry; listEntry = listEntry->next) {
-    PK11SlotInfo *slot = listEntry->slot;
-
-    if(PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) {
-      if(slot == PK11_GetInternalKeySlot()) {
-        failf(conn->data, "The NSS database has not been initialized");
-      }
-      else {
-        failf(conn->data, "The token %s has not been initialized",
-              PK11_GetTokenName(slot));
-      }
-      PK11_FreeSlot(slot);
-      continue;
-    }
-
-    ret = PK11_Authenticate(slot, PR_TRUE,
-                            conn->data->set.str[STRING_KEY_PASSWD]);
-    if(SECSuccess != ret) {
-      if(PR_GetError() == SEC_ERROR_BAD_PASSWORD)
-        infof(conn->data, "The password for token '%s' is incorrect\n",
-              PK11_GetTokenName(slot));
-      status = SECFailure;
-      break;
-    }
-    PK11_FreeSlot(slot);
-  }
-
-  return status;
-}
-
 static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
 {
   SECStatus success = SECSuccess;
@@ -692,15 +650,37 @@ static SECStatus HandshakeCallback(PRFil
   return SECSuccess;
 }
 
+static void display_cert_info(struct SessionHandle *data, CERTCertificate *cert) {
+    char *subject, *issuer, *common_name;
+    PRExplodedTime printableTime;
+    char timeString[256];
+    PRTime notBefore, notAfter;
+
+    subject = CERT_NameToAscii(&cert->subject);
+    issuer = CERT_NameToAscii(&cert->issuer);
+    common_name = CERT_GetCommonName(&cert->subject);
+    infof(data, "\tsubject: %s\n", subject);
+
+    CERT_GetCertTimes(cert, &notBefore, &notAfter);
+    PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
+    PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+    infof(data, "\tstart date: %s\n", timeString);
+    PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
+    PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+    infof(data, "\texpire date: %s\n", timeString);
+    infof(data, "\tcommon name: %s\n", common_name);
+    infof(data, "\tissuer: %s\n", issuer);
+
+    PR_Free(subject);
+    PR_Free(issuer);
+    PR_Free(common_name);
+}
+
 static void display_conn_info(struct connectdata *conn, PRFileDesc *sock)
 {
   SSLChannelInfo channel;
   SSLCipherSuiteInfo suite;
   CERTCertificate *cert;
-  char *subject, *issuer, *common_name;
-  PRExplodedTime printableTime;
-  char timeString[256];
-  PRTime notBefore, notAfter;
 
   if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
      SECSuccess && channel.length == sizeof channel &&
@@ -714,25 +694,7 @@ static void display_conn_info(struct con
   infof(conn->data, "Server certificate:\n");
 
   cert = SSL_PeerCertificate(sock);
-  subject = CERT_NameToAscii(&cert->subject);
-  issuer = CERT_NameToAscii(&cert->issuer);
-  common_name = CERT_GetCommonName(&cert->subject);
-  infof(conn->data, "\tsubject: %s\n", subject);
-
-  CERT_GetCertTimes(cert, &notBefore, &notAfter);
-  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
-  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
-  infof(conn->data, "\tstart date: %s\n", timeString);
-  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
-  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
-  infof(conn->data, "\texpire date: %s\n", timeString);
-  infof(conn->data, "\tcommon name: %s\n", common_name);
-  infof(conn->data, "\tissuer: %s\n", issuer);
-
-  PR_Free(subject);
-  PR_Free(issuer);
-  PR_Free(common_name);
-
+  display_cert_info(conn->data, cert);
   CERT_DestroyCertificate(cert);
 
   return;
@@ -786,48 +748,71 @@ static SECStatus SelectClientCert(void *
                                   struct CERTCertificateStr **pRetCert,
                                   struct SECKEYPrivateKeyStr **pRetKey)
 {
-  SECKEYPrivateKey *privKey = NULL;
-  CERTCertificate *cert;
-  struct ssl_connect_data *connssl = (struct ssl_connect_data *) arg;
-  char *nickname = connssl->client_nickname;
-  void *proto_win = NULL;
-  SECStatus secStatus = SECFailure;
-  PK11SlotInfo *slot;
-  (void)caNames;
+  static const char pem_nickname[] = "PEM Token #1";
+  const char *pem_slotname = pem_nickname;
 
-  proto_win = SSL_RevealPinArg(sock);
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
+  struct SessionHandle *data = connssl->data;
+  const char *nickname = connssl->client_nickname;
 
-  if(!nickname)
-    return secStatus;
+  if (mod && nickname &&
+      0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {
 
-  cert = PK11_FindCertFromNickname(nickname, proto_win);
-  if(cert) {
-    if(!strncmp(nickname, "PEM Token", 9)) {
-      CK_SLOT_ID slotID = 1; /* hardcoded for now */
-      char slotname[SLOTSIZE];
-      snprintf(slotname, SLOTSIZE, "PEM Token #%ld", slotID);
-      slot = PK11_FindSlotByName(slotname);
-      privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
-      PK11_FreeSlot(slot);
-      if(privKey) {
-        secStatus = SECSuccess;
-      }
+    /* use the cert/key provided by PEM reader */
+    PK11SlotInfo *slot;
+    void *proto_win = SSL_RevealPinArg(sock);
+    *pRetKey = NULL;
+
+    *pRetCert = PK11_FindCertFromNickname(nickname, proto_win);
+    if (NULL == *pRetCert) {
+      failf(data, "NSS: client certificate not found: %s", nickname);
+      return SECFailure;
     }
-    else {
-      privKey = PK11_FindKeyByAnyCert(cert, proto_win);
-      if(privKey)
-        secStatus = SECSuccess;
+
+    slot = PK11_FindSlotByName(pem_slotname);
+    if (NULL == slot) {
+      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
+      return SECFailure;
+    }
+
+    *pRetKey = PK11_FindPrivateKeyFromCert(slot, *pRetCert, NULL);
+    PK11_FreeSlot(slot);
+    if (NULL == *pRetKey) {
+      failf(data, "NSS: private key not found for certificate: %s", nickname);
+      return SECFailure;
     }
+
+    infof(data, "NSS: Client client certificate: %s\n", nickname);
+    display_cert_info(data, *pRetCert);
+    return SECSuccess;
   }
 
-  *pRetCert = cert;
-  *pRetKey = privKey;
-  
-  /* There's no need to destroy either cert or privKey as 
-   * NSS will do that for us even if returning SECFailure
-   */
+  /* use the default NSS hook */
+  if (SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
+                                          pRetCert, pRetKey)
+      || NULL == *pRetCert) {
 
-  return secStatus;
+    if (NULL == nickname)
+      failf(data, "NSS: client certificate not found (nickname not specified)");
+    else
+      failf(data, "NSS: client certificate not found: %s", nickname);
+
+    return SECFailure;
+  }
+
+  /* get certificate nickname if any */
+  nickname = (*pRetCert)->nickname;
+  if (NULL == nickname)
+    nickname = "[unknown]";
+
+  if (NULL == *pRetKey) {
+    failf(data, "NSS: private key not found for certificate: %s", nickname);
+    return SECFailure;
+  }
+
+  infof(data, "NSS: using client certificate: %s\n", nickname);
+  display_cert_info(data, *pRetCert);
+  return SECSuccess;
 }
 
 /**
@@ -955,6 +940,8 @@ CURLcode Curl_nss_connect(struct connect
   if (connssl->state == ssl_connection_complete)
     return CURLE_OK;
 
+  connssl->data = data;
+
 #ifdef HAVE_PK11_CREATEGENERICOBJECT  
   connssl->cacert[0] = NULL;
   connssl->cacert[1] = NULL;
@@ -1017,6 +1004,9 @@ CURLcode Curl_nss_connect(struct connect
       }
     }
 #endif
+
+    PK11_SetPasswordFunc(nss_get_password);
+
   }
   PR_Unlock(nss_initlock);
 
@@ -1164,11 +1154,7 @@ CURLcode Curl_nss_connect(struct connect
     else {
       nickname = data->set.str[STRING_CERT];
     }
-    if(nss_Init_Tokens(conn) != SECSuccess) {
-      if(nickname_alloc)
-        free(nickname);
-      goto error;
-    }
+
     if(!cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
                     data->set.str[STRING_KEY])) {
       /* failf() is already done in cert_stuff() */
@@ -1183,16 +1169,15 @@ CURLcode Curl_nss_connect(struct connect
     if(!connssl->client_nickname)
       return CURLE_OUT_OF_MEMORY;
 
-    if(SSL_GetClientAuthDataHook(model,
-                                 (SSLGetClientAuthData) SelectClientCert,
-                                 (void *)connssl) != SECSuccess) {
-      curlerr = CURLE_SSL_CERTPROBLEM;
-      goto error;
-    }
   }
   else
     connssl->client_nickname = NULL;
 
+  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
+                               (void *)connssl) != SECSuccess) {
+    curlerr = CURLE_SSL_CERTPROBLEM;
+    goto error;
+  }
 
   /* Import our model socket  onto the existing file descriptor */
   connssl->handle = PR_ImportTCPSocket(sockfd);
@@ -1201,6 +1186,11 @@ CURLcode Curl_nss_connect(struct connect
     goto error;
   PR_Close(model); /* We don't need this any more */
 
+  /* This is the password associated with the cert that we're using */
+  if (data->set.str[STRING_KEY_PASSWD]) {
+      SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
+  }
+
   /* Force handshake on next I/O */
   SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);
 
diff -ruNp curl-7.19.5.orig/lib/urldata.h curl-7.19.5/lib/urldata.h
--- curl-7.19.5.orig/lib/urldata.h	2009-07-22 10:30:03.007106061 +0200
+++ curl-7.19.5/lib/urldata.h	2009-07-22 10:30:54.070293354 +0200
@@ -211,6 +211,7 @@ struct ssl_connect_data {
 #ifdef USE_NSS
   PRFileDesc *handle;
   char *client_nickname;
+  struct SessionHandle *data;
 #ifdef HAVE_PK11_CREATEGENERICOBJECT
   PK11GenericObject *key;
   PK11GenericObject *cacert[2];

curl-7.19.5-cc_refcnt-2.patch:
 nss.c |   41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

Index: curl-7.19.5-cc_refcnt-2.patch
===================================================================
RCS file: /cvs/extras/rpms/curl/devel/curl-7.19.5-cc_refcnt-2.patch,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -p -r1.2 -r1.3
--- curl-7.19.5-cc_refcnt-2.patch	10 Jul 2009 12:45:41 -0000	1.2
+++ curl-7.19.5-cc_refcnt-2.patch	22 Jul 2009 08:48:25 -0000	1.3
@@ -1,7 +1,7 @@
 diff -ruNp curl-7.19.5.orig/lib/nss.c curl-7.19.5/lib/nss.c
---- curl-7.19.5.orig/lib/nss.c	2009-07-10 14:41:55.890168660 +0200
-+++ curl-7.19.5/lib/nss.c	2009-07-10 14:42:18.966293110 +0200
-@@ -857,8 +857,15 @@ void Curl_nss_cleanup(void)
+--- curl-7.19.5.orig/lib/nss.c	2009-07-22 10:28:01.254355601 +0200
++++ curl-7.19.5/lib/nss.c	2009-07-22 10:29:02.437231090 +0200
+@@ -857,9 +857,15 @@ void Curl_nss_cleanup(void)
     */
    PR_Lock(nss_initlock);
    if (initialized) {
@@ -11,10 +11,58 @@ diff -ruNp curl-7.19.5.orig/lib/nss.c cu
 +     * the certificates. */
 +    SSL_ClearSessionCache();
 +
-+    if(mod) {
-+      SECMOD_UnloadUserModule(mod);
++    if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) {
        SECMOD_DestroyModule(mod);
+-    mod = NULL;
++      mod = NULL;
 +    }
-     mod = NULL;
      NSS_Shutdown();
    }
+   PR_Unlock(nss_initlock);
+@@ -940,9 +946,6 @@ CURLcode Curl_nss_connect(struct connect
+   curl_socket_t sockfd = conn->sock[sockindex];
+   struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+   SECStatus rv;
+-#ifdef HAVE_PK11_CREATEGENERICOBJECT
+-  char *configstring = NULL;
+-#endif
+   char *certDir = NULL;
+   int curlerr;
+   const int *cipher_to_enable;
+@@ -995,21 +998,23 @@ CURLcode Curl_nss_connect(struct connect
+       NSS_SetDomesticPolicy();
+ 
+ #ifdef HAVE_PK11_CREATEGENERICOBJECT
+-    configstring = aprintf("library=%s name=PEM", pem_library);
+-    if(!configstring) {
+-      PR_Unlock(nss_initlock);
+-      goto error;
+-    }
+-    mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
+-    free(configstring);
++    if(!mod) {
++      char *configstring = aprintf("library=%s name=PEM", pem_library);
++      if(!configstring) {
++        PR_Unlock(nss_initlock);
++        goto error;
++      }
++      mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
++      free(configstring);
+ 
+-    if(!mod || !mod->loaded) {
+-      if(mod) {
+-        SECMOD_DestroyModule(mod);
+-        mod = NULL;
++      if(!mod || !mod->loaded) {
++        if(mod) {
++          SECMOD_DestroyModule(mod);
++          mod = NULL;
++        }
++        infof(data, "WARNING: failed to load NSS PEM library %s. Using OpenSSL "
++              "PEM certificates will not work.\n", pem_library);
+       }
+-      infof(data, "WARNING: failed to load NSS PEM library %s. Using OpenSSL "
+-            "PEM certificates will not work.\n", pem_library);
+     }
+ #endif
+   }


Index: curl.spec
===================================================================
RCS file: /cvs/extras/rpms/curl/devel/curl.spec,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -p -r1.105 -r1.106
--- curl.spec	10 Jul 2009 12:27:52 -0000	1.105
+++ curl.spec	22 Jul 2009 08:48:25 -0000	1.106
@@ -1,7 +1,7 @@
 Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
 Name: curl
 Version: 7.19.5
-Release: 7%{?dist}
+Release: 8%{?dist}
 License: MIT
 Group: Applications/Internet
 Source: http://curl.haxx.se/download/%{name}-%{version}.tar.bz2
@@ -12,6 +12,7 @@ Patch3: curl-7.17.1-badsocket.patch
 Patch4: curl-7.19.4-debug.patch
 Patch5: curl-7.19.5-cc_refcnt-1.patch
 Patch6: curl-7.19.5-cc_refcnt-2.patch
+Patch7: curl-7.19.5-cc.patch
 Provides: webclient
 URL: http://curl.haxx.se/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -58,6 +59,7 @@ use cURL's capabilities internally.
 %patch4 -p1
 %patch5 -p1
 %patch6 -p1
+%patch7 -p1
 
 # Convert docs to UTF-8
 for f in CHANGES README; do
@@ -140,6 +142,11 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/aclocal/libcurl.m4
 
 %changelog
+* Wed Jul 22 2009 Kamil Dudka <kdudka at redhat.com> 7.19.5-8
+- do not pre-login to all PKCS11 slots, it causes problems with HW tokens
+- try to select client certificate automatically when not specified, thanks
+  to Claes Jakobsson
+
 * Fri Jul 10 2009 Kamil Dudka <kdudka at redhat.com> 7.19.5-7
 - fix SIGSEGV when using NSS client certificates, thanks to Claes Jakobsson
 




More information about the fedora-extras-commits mailing list