Ejemplo n.º 1
0
SECStatus
JSSL_GetClientAuthData( void * arg,
                        PRFileDesc *        fd,
                        CERTDistNames *     caNames,
                        CERTCertificate **  pRetCert,
                        SECKEYPrivateKey ** pRetKey)
{
    SECKEYPrivateKey * privkey;
    JSSL_SocketData *  sock;
    SECStatus          rv         = SECFailure;

    PR_ASSERT(arg != NULL);
    sock = (JSSL_SocketData*) arg;

    if (sock->clientCert) {
        privkey = PK11_FindPrivateKeyFromCert(sock->clientCertSlot,
            sock->clientCert, NULL /*pinarg*/);
        if ( privkey ) {
            rv = SECSuccess;
            *pRetCert = CERT_DupCertificate(sock->clientCert); 
            *pRetKey  = privkey;
        }
    }
    
    return rv;
}
Ejemplo n.º 2
0
int sign_value(pkcs11_handle_t *h, cert_object_t *cert, CK_BYTE *data,
	      CK_ULONG length, CK_BYTE **signature, CK_ULONG *signature_length)
{
  SECOidTag algtag;
  SECKEYPrivateKey *key;
  SECItem result;
  SECStatus rv;

  if (h->slot == NULL) {
    return -1;
  }

  /* get the key */
  key = PK11_FindPrivateKeyFromCert(h->slot, (CERTCertificate *)cert, NULL);
  if (key == NULL) {
    DBG1("Couldn't Find key for Cert: %s", SECU_Strerror(PR_GetError()));
    return -1;
  }

  /* get the oid */
  algtag = SEC_GetSignatureAlgorithmOidTag(key->keyType, SEC_OID_SHA1);

  /* sign the data */
  rv = SEC_SignData(&result, data, length, key, algtag);
  SECKEY_DestroyPrivateKey(key);
  if (rv != SECSuccess) {
    DBG1("Signature failed: %s", SECU_Strerror(PR_GetError()));
    return -1;
  }

  *signature = (CK_BYTE *)result.data;
  *signature_length = result.len;
  return 0;
}
Ejemplo n.º 3
0
/*
 * grab the nss key from a VCardKey. If it doesn't exist, try to look it up
 */
static SECKEYPrivateKey *
vcard_emul_get_nss_key(VCardKey *key)
{
    if (key->key) {
        return key->key;
    }
    /* NOTE: if we aren't logged into the token, this could return NULL */
    key->key = PK11_FindPrivateKeyFromCert(key->slot, key->cert, NULL);
    return key->key;
}
Ejemplo n.º 4
0
/**
 *
 * Callback to pick the SSL client certificate.
 */
static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
                                  struct CERTDistNamesStr *caNames,
                                  struct CERTCertificateStr **pRetCert,
                                  struct SECKEYPrivateKeyStr **pRetKey)
{
  SECKEYPrivateKey *privKey;
  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;

  proto_win = SSL_RevealPinArg(sock);

  if(!nickname)
    return secStatus;

  connssl->client_cert = PK11_FindCertFromNickname(nickname, proto_win);
  if(connssl->client_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, connssl->client_cert, NULL);
      PK11_FreeSlot(slot);
      if(privKey) {
        secStatus = SECSuccess;
      }
    }
    else {
      privKey = PK11_FindKeyByAnyCert(connssl->client_cert, proto_win);
      if(privKey)
        secStatus = SECSuccess;
    }
  }

  if(secStatus == SECSuccess) {
    *pRetCert = connssl->client_cert;
    *pRetKey = privKey;
  }
  else {
    if(connssl->client_cert)
      CERT_DestroyCertificate(connssl->client_cert);
    connssl->client_cert = NULL;
  }

  return secStatus;
}
Ejemplo n.º 5
0
/**
 *
 * Callback to pick the SSL client certificate.
 */
static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
                                  struct CERTDistNamesStr *caNames,
                                  struct CERTCertificateStr **pRetCert,
                                  struct SECKEYPrivateKeyStr **pRetKey)
{
  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
  struct SessionHandle *data = connssl->data;
  const char *nickname = connssl->client_nickname;

  if(connssl->obj_clicert) {
    /* use the cert/key provided by PEM reader */
    static const char pem_slotname[] = "PEM Token #1";
    SECItem cert_der = { 0, NULL, 0 };
    void *proto_win = SSL_RevealPinArg(sock);
    struct CERTCertificateStr *cert;
    struct SECKEYPrivateKeyStr *key;

    PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname);
    if(NULL == slot) {
      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
      return SECFailure;
    }

    if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE,
                             &cert_der) != SECSuccess) {
      failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
      PK11_FreeSlot(slot);
      return SECFailure;
    }

    cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
    SECITEM_FreeItem(&cert_der, PR_FALSE);
    if(NULL == cert) {
      failf(data, "NSS: client certificate from file not found");
      PK11_FreeSlot(slot);
      return SECFailure;
    }

    key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
    PK11_FreeSlot(slot);
    if(NULL == key) {
      failf(data, "NSS: private key from file not found");
      CERT_DestroyCertificate(cert);
      return SECFailure;
    }

    infof(data, "NSS: client certificate from file\n");
    display_cert_info(data, cert);

    *pRetCert = cert;
    *pRetKey = key;
    return SECSuccess;
  }

  /* use the default NSS hook */
  if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
                                          pRetCert, pRetKey)
      || NULL == *pRetCert) {

    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;
}
Ejemplo n.º 6
0
SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
                                             CERTCertificate** retcert,
                                             SECKEYPrivateKey** retkey)
{
    CERTCertificate* cert = NULL;
    NSSCMSRecipient** recipients = NULL;
    NSSCMSRecipientInfo* recipientInfos[2];
    SECStatus rv = SECSuccess;
    SECKEYPrivateKey* key = NULL;

    if (!ri)
        return SECFailure;
    
    if (!retcert && !retkey) {
        /* nothing requested, nothing found, success */
        return SECSuccess;
    }

    if (retcert) {
        *retcert = NULL;
    }
    if (retkey) {
        *retkey = NULL;
    }

    if (ri->cert) {
        cert = CERT_DupCertificate(ri->cert);
        if (!cert) {
            rv = SECFailure;
        }
    }
    if (SECSuccess == rv && !cert) {
        /* we don't have the cert, we have to look for it */
        /* first build an NSS_CMSRecipient */
        recipientInfos[0] = ri;
        recipientInfos[1] = NULL;

        recipients = nss_cms_recipient_list_create(recipientInfos);
        if (recipients) {
            /* now look for the cert and key */
            if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients,
                ri->cmsg->pwfn_arg)) {
                cert = CERT_DupCertificate(recipients[0]->cert);
                key = SECKEY_CopyPrivateKey(recipients[0]->privkey);
            } else {
                rv = SECFailure;
            }

            nss_cms_recipient_list_destroy(recipients);
        }
        else {
            rv = SECFailure;
        }            
    } else if (SECSuccess == rv && cert && retkey) {
        /* we have the cert, we just need the key now */
        key = PK11_FindPrivateKeyFromCert(cert->slot, cert, ri->cmsg->pwfn_arg);
    }
    if (retcert) {
        *retcert = cert;
    } else {
        if (cert) {
            CERT_DestroyCertificate(cert);
        }
    }
    if (retkey) {
        *retkey = key;
    } else {
        if (key) {
            SECKEY_DestroyPrivateKey(key);
        }
    }

    return rv;
}
Ejemplo n.º 7
0
// Based on nsPKCS12Blob::ImportFromFileHelper.
int
nsPKCS12Blob_ImportHelper(const char* pkcs12_data,
                          size_t pkcs12_len,
                          const base::string16& password,
                          bool is_extractable,
                          bool try_zero_length_secitem,
                          PK11SlotInfo *slot,
                          net::CertificateList* imported_certs)
{
    DCHECK(pkcs12_data);
    DCHECK(slot);
    int import_result = net::ERR_PKCS12_IMPORT_FAILED;
    SECStatus srv = SECSuccess;
    SEC_PKCS12DecoderContext *dcx = NULL;
    SECItem unicodePw;
    SECItem attribute_value;
    CK_BBOOL attribute_data = CK_FALSE;
    const SEC_PKCS12DecoderItem* decoder_item = NULL;

    unicodePw.type = siBuffer;
    unicodePw.len = 0;
    unicodePw.data = NULL;
    if (!try_zero_length_secitem) {
        unicodeToItem(password.c_str(), &unicodePw);
    }

    // Initialize the decoder
    dcx = SEC_PKCS12DecoderStart(&unicodePw, slot,
                                 // wincx
                                 NULL,
                                 // dOpen, dClose, dRead, dWrite, dArg: NULL
                                 // specifies default impl using memory buffer.
                                 NULL, NULL, NULL, NULL, NULL);
    if (!dcx) {
        srv = SECFailure;
        goto finish;
    }
    // feed input to the decoder
    srv = SEC_PKCS12DecoderUpdate(dcx,
                                  (unsigned char*)pkcs12_data,
                                  pkcs12_len);
    if (srv) goto finish;
    // verify the blob
    srv = SEC_PKCS12DecoderVerify(dcx);
    if (srv) goto finish;
    // validate bags
    srv = SEC_PKCS12DecoderValidateBags(dcx, nickname_collision);
    if (srv) goto finish;
    // import certificate and key
    srv = SEC_PKCS12DecoderImportBags(dcx);
    if (srv) goto finish;

    attribute_value.data = &attribute_data;
    attribute_value.len = sizeof(attribute_data);

    srv = SEC_PKCS12DecoderIterateInit(dcx);
    if (srv) goto finish;

    if (imported_certs)
        imported_certs->clear();

    // Collect the list of decoded certificates, and mark private keys
    // non-extractable if needed.
    while (SEC_PKCS12DecoderIterateNext(dcx, &decoder_item) == SECSuccess) {
        if (decoder_item->type != SEC_OID_PKCS12_V1_CERT_BAG_ID)
            continue;

        CERTCertificate* cert = PK11_FindCertFromDERCertItem(
                                    slot, decoder_item->der,
                                    NULL);  // wincx
        if (!cert) {
            LOG(ERROR) << "Could not grab a handle to the certificate in the slot "
                       << "from the corresponding PKCS#12 DER certificate.";
            continue;
        }

        // Add the cert to the list
        if (imported_certs) {
            // Empty list of intermediates.
            net::X509Certificate::OSCertHandles intermediates;
            imported_certs->push_back(
                net::X509Certificate::CreateFromHandle(cert, intermediates));
        }

        // Once we have determined that the imported certificate has an
        // associated private key too, only then can we mark the key as
        // non-extractable.
        if (!decoder_item->hasKey) {
            CERT_DestroyCertificate(cert);
            continue;
        }

        // Iterate through all the imported PKCS12 items and mark any accompanying
        // private keys as non-extractable.
        if (!is_extractable) {
            SECKEYPrivateKey* privKey = PK11_FindPrivateKeyFromCert(slot, cert,
                                        NULL);  // wincx
            if (privKey) {
                // Mark the private key as non-extractable.
                srv = PK11_WriteRawAttribute(PK11_TypePrivKey, privKey, CKA_EXTRACTABLE,
                                             &attribute_value);
                SECKEY_DestroyPrivateKey(privKey);
                if (srv) {
                    LOG(ERROR) << "Could not set CKA_EXTRACTABLE attribute on private "
                               << "key.";
                    CERT_DestroyCertificate(cert);
                    break;
                }
            }
        }
        CERT_DestroyCertificate(cert);
        if (srv) goto finish;
    }
    import_result = net::OK;
finish:
    // If srv != SECSuccess, NSS probably set a specific error code.
    // We should use that error code instead of inventing a new one
    // for every error possible.
    if (srv != SECSuccess) {
        int error = PORT_GetError();
        LOG(ERROR) << "PKCS#12 import failed with error " << error;
        switch (error) {
        case SEC_ERROR_BAD_PASSWORD:
        case SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT:
            import_result = net::ERR_PKCS12_IMPORT_BAD_PASSWORD;
            break;
        case SEC_ERROR_PKCS12_INVALID_MAC:
            import_result = net::ERR_PKCS12_IMPORT_INVALID_MAC;
            break;
        case SEC_ERROR_BAD_DER:
        case SEC_ERROR_PKCS12_DECODING_PFX:
        case SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE:
            import_result = net::ERR_PKCS12_IMPORT_INVALID_FILE;
            break;
        case SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM:
        case SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE:
        case SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM:
        case SEC_ERROR_PKCS12_UNSUPPORTED_VERSION:
            import_result = net::ERR_PKCS12_IMPORT_UNSUPPORTED;
            break;
        default:
            import_result = net::ERR_PKCS12_IMPORT_FAILED;
            break;
        }
    }
    // Finish the decoder
    if (dcx)
        SEC_PKCS12DecoderFinish(dcx);
    SECITEM_ZfreeItem(&unicodePw, PR_FALSE);
    return import_result;
}
Ejemplo n.º 8
0
Archivo: nss.c Proyecto: 0w/moai-dev
/**
 *
 * Callback to pick the SSL client certificate.
 */
static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
                                  struct CERTDistNamesStr *caNames,
                                  struct CERTCertificateStr **pRetCert,
                                  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 SessionHandle *data = connssl->data;
  const char *nickname = connssl->client_nickname;

  if (mod && nickname &&
      0 == strncmp(nickname, pem_nickname, /* length of "PEM Token" */ 9)) {

    /* 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;
    }

    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 certificate: %s\n", nickname);
    display_cert_info(data, *pRetCert);
    return SECSuccess;
  }

  /* use the default NSS hook */
  if (SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
                                          pRetCert, pRetKey)
      || NULL == *pRetCert) {

    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;
}
Ejemplo n.º 9
0
/* 
 * This callback is called when the peer has request you to send you
 * client-auth certificate. You get to pick which one you want
 * to send.
 *
 * Expected return values:
 *    0        SECSuccess
 *    -1        SECFailure - No suitable certificate found.
 *    -2         SECWouldBlock (we're waiting while we ask the user).
 */
SECStatus
JSSL_CallCertSelectionCallback(    void * arg,
            PRFileDesc *        fd,
            CERTDistNames *     caNames,
            CERTCertificate **  pRetCert,
            SECKEYPrivateKey ** pRetKey)
{
    CERTCertificate *  cert;
    PK11SlotInfo *  slot;
    SECKEYPrivateKey * privkey;
    jobject             nicknamecallback = (jobject)arg;
    SECStatus          rv         = SECFailure;
    CERTCertNicknames * names;
    int                 i;
    int count           =0;
    jclass    vectorclass;
    jmethodID vectorcons;
    jobject vector;
    jmethodID vector_add;
    jstring nickname_string;
    jstring chosen_nickname;
    char *chosen_nickname_for_c;
    jboolean chosen_nickname_cleanup;
    jclass clientcertselectionclass;
    jmethodID clientcertselectionclass_select;
    JNIEnv *env;
    int debug_cc=0;

    if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){
        PR_ASSERT(PR_FALSE);
        goto loser;
    }
    PR_ASSERT(env != NULL);
    

    clientcertselectionclass = (*env)->GetObjectClass(env,nicknamecallback);

    clientcertselectionclass_select = (*env)->GetMethodID(
            env,
            clientcertselectionclass,
            "select",
            "(Ljava/util/Vector;)Ljava/lang/String;" );

    /* get java bits and piece ready to create a new vector */

    vectorclass = (*env)->FindClass(
            env, "java/util/Vector");

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  got vectorclass: %lx\n",vectorclass); }

    vectorcons = (*env)->GetMethodID(
            env,
            vectorclass,"<init>","()V");

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  got vectorcons: %lx\n",vectorcons); }

    vector_add = (*env)->GetMethodID(
            env,
            vectorclass,
            "addElement",
            "(Ljava/lang/Object;)V");

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  got vectoradd: %lx\n",vector_add); }

    /* create new vector */
    vector = (*env)->NewObject( env, vectorclass, vectorcons); 

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  got new vector: %lx\n",vector); }

/* next, get a list of all the valid nicknames */
    names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
                      SEC_CERT_NICKNAMES_USER, NULL /*pinarg*/);
    if (names != NULL) {
        for (i = 0; i < names->numnicknames; i++) {
        if (debug_cc) { PR_fprintf(PR_STDOUT,"checking nn: %s\n",names->nicknames[i]); }
        cert = JSS_PK11_findCertAndSlotFromNickname(
                names->nicknames[i],
                NULL /*pinarg*/,
                &slot);
        if ( !cert )
            continue;

        /* Only check unexpired certs */
        if ( CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE /*allowOverride*/)
                 != secCertTimeValid ) {
        if (debug_cc) { PR_fprintf(PR_STDOUT,"  not valid\n"); }
            CERT_DestroyCertificate(cert);
            PK11_FreeSlot(slot);
            continue;
        }
        rv = secCmpCertChainWCANames(cert, caNames);
        if ( rv == SECSuccess ) {
            if (debug_cc) { PR_fprintf(PR_STDOUT,"  matches ca name\n"); }

            privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/);

            /* just test if we have the private key */
            if ( privkey )  {

            count++;
            if (debug_cc) { PR_fprintf(PR_STDOUT,"  found privkey\n"); }
            SECKEY_DestroyPrivateKey(privkey);

            /* if we have, then this nickname has passed all the
                 tests necessary to put it in the list */

            nickname_string = (*env)->NewStringUTF(env,
                        names->nicknames[i]);

            if (debug_cc) { PR_fprintf(PR_STDOUT,"  calling vector_add\n"); }
            (*env)->CallVoidMethod(env,vector,vector_add,
                nickname_string
                );
                        
            if (debug_cc) { PR_fprintf(PR_STDOUT,"  back from vector_add\n"); }
                }
            
        }
        CERT_DestroyCertificate(cert);
        PK11_FreeSlot(slot);
        }
        CERT_FreeNicknames(names);
    }

    /* okay - so we made a vector of the certs - now call the java 
       class to figure out which one to send */

    chosen_nickname = (*env)->CallObjectMethod(env,nicknamecallback,
            clientcertselectionclass_select,
            vector
            );

    if (chosen_nickname == NULL) {
        rv = SECFailure;
        goto loser;
    }

    chosen_nickname_for_c = (char*)(*env)->GetStringUTFChars(env,
        chosen_nickname,
        &chosen_nickname_cleanup);

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  chosen nickname: %s\n",chosen_nickname_for_c); }
    cert = JSS_PK11_findCertAndSlotFromNickname(chosen_nickname_for_c,
        NULL /*pinarg*/,
        &slot);

    if (debug_cc) { PR_fprintf(PR_STDOUT,"  found certificate\n"); }

    if (chosen_nickname_cleanup == JNI_TRUE) {
        (*env)->ReleaseStringUTFChars(env,
            chosen_nickname,
            chosen_nickname_for_c);
    }
            

    if (cert == NULL) {
        rv = SECFailure;
        goto loser;
    }

        privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/);
        PK11_FreeSlot(slot);
        if ( privkey == NULL )  {
        CERT_DestroyCertificate(cert);
        rv = SECFailure;
        goto loser;
    }
    if (debug_cc) { PR_fprintf(PR_STDOUT,"  found privkey. returning\n"); }

    *pRetCert = cert;
    *pRetKey  = privkey;
    rv = SECSuccess;

loser:
    return rv;
}