Пример #1
0
bool
CryptoKey::PublicKeyValid(SECKEYPublicKey* aPubKey)
{
  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
  if (!slot.get()) {
    return false;
  }

  // This assumes that NSS checks the validity of a public key when
  // it is imported into a PKCS#11 module, and returns CK_INVALID_HANDLE
  // if it is invalid.
  CK_OBJECT_HANDLE id = PK11_ImportPublicKey(slot, aPubKey, PR_FALSE);
  if (id == CK_INVALID_HANDLE) {
    return false;
  }

  SECStatus rv = PK11_DestroyObject(slot, id);
  return (rv == SECSuccess);
}
Пример #2
0
static int
cmmf_create_witness_and_challenge(PRArenaPool     *poolp,
                                  CMMFChallenge   *challenge,
                                  long             inRandom,
                                  SECItem         *senderDER,
                                  SECKEYPublicKey *inPubKey,
                                  void            *passwdArg)
{
    SECItem       *encodedRandNum;
    SECItem        encodedRandStr = {siBuffer, NULL, 0};
    SECItem       *dummy;
    unsigned char *randHash, *senderHash, *encChal=NULL;
    unsigned       modulusLen = 0;
    SECStatus      rv = SECFailure;
    CMMFRand       randStr= { {siBuffer, NULL, 0}, {siBuffer, NULL, 0}};
    PK11SlotInfo  *slot;
    PK11SymKey    *symKey = NULL;
    CK_OBJECT_HANDLE id;
    CERTSubjectPublicKeyInfo *spki = NULL;


    encodedRandNum = SEC_ASN1EncodeInteger(poolp, &challenge->randomNumber,
                                           inRandom);
    encodedRandNum = &challenge->randomNumber;
    randHash   = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
    senderHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
    if (randHash == NULL) {
        goto loser;
    }
    rv = PK11_HashBuf(SEC_OID_SHA1, randHash, encodedRandNum->data,
                      (PRUint32)encodedRandNum->len);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = PK11_HashBuf(SEC_OID_SHA1, senderHash, senderDER->data,
                      (PRUint32)senderDER->len);
    if (rv != SECSuccess) {
        goto loser;
    }
    challenge->witness.data = randHash;
    challenge->witness.len  = SHA1_LENGTH;

    randStr.integer    = *encodedRandNum;
    randStr.senderHash.data = senderHash;
    randStr.senderHash.len  = SHA1_LENGTH;
    dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr,
                               CMMFRandTemplate);
    if (dummy != &encodedRandStr) {
        rv = SECFailure;
        goto loser;
    }
    /* XXXX Now I have to encrypt encodedRandStr and stash it away. */
    modulusLen = SECKEY_PublicKeyStrength(inPubKey);
    encChal = PORT_ArenaNewArray(poolp, unsigned char, modulusLen);
    if (encChal == NULL) {
        rv = SECFailure;
        goto loser;
    }
    slot =PK11_GetBestSlotWithAttributes(CKM_RSA_PKCS, CKF_WRAP, 0, passwdArg);
    if (slot == NULL) {
        rv = SECFailure;
        goto loser;
    }
    id = PK11_ImportPublicKey(slot, inPubKey, PR_FALSE);
    /* In order to properly encrypt the data, we import as a symmetric
     * key, and then wrap that key.  That in essence encrypts the data.
     * This is the method recommended in the PK11 world in order
     * to prevent threading issues as well as breaking any other semantics
     * the PK11 libraries depend on.
     */
    symKey = PK11_ImportSymKey(slot, CKM_RSA_PKCS, PK11_OriginGenerated,
                               CKA_VALUE, &encodedRandStr, passwdArg);
    if (symKey == NULL) {
        rv = SECFailure;
        goto loser;
    }
    challenge->challenge.data = encChal;
    challenge->challenge.len  = modulusLen;
    rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey,
                            &challenge->challenge);
    PK11_FreeSlot(slot);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = SECITEM_CopyItem(poolp, &challenge->senderDER, senderDER);
    crmf_get_public_value(inPubKey, &challenge->key);
    /* Fall through */
loser:
    if (spki != NULL) {
        SECKEY_DestroySubjectPublicKeyInfo(spki);
    }
    if (encodedRandStr.data != NULL) {
        PORT_Free(encodedRandStr.data);
    }
    if (encodedRandNum != NULL) {
        SECITEM_FreeItem(encodedRandNum, PR_TRUE);
    }
    if (symKey != NULL) {
        PK11_FreeSymKey(symKey);
    }
    return rv;
}