pk11skey.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,251 行 · 第 1/5 页

C
2,251
字号
					privKey->pkcs11ID, CKA_DECRYPT );    /* If the encryption attribute is set; attempt to encrypt */    /* with the public key and decrypt with the private key.  */    if( isEncryptable ) {	/* Find a module to encrypt against */	slot = PK11_GetBestSlot(pk11_mapWrapKeyType(privKey->keyType),wincx);	if (slot == NULL) {	    PORT_SetError( SEC_ERROR_NO_MODULE );	    return SECFailure;	}	id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);	if (id == CK_INVALID_KEY) {	    PK11_FreeSlot(slot);	    return SECFailure;	}        /* Compute max bytes encrypted from modulus length of private key. */	max_bytes_encrypted = PK11_GetPrivateModulusLen( privKey );	/* Prepare for encryption using the public key. */        PK11_EnterSlotMonitor(slot);	crv = PK11_GETTAB( slot )->C_EncryptInit( slot->session,						  mech, id );        if( crv != CKR_OK ) {	    PK11_ExitSlotMonitor(slot);	    PORT_SetError( PK11_MapError( crv ) );	    PK11_FreeSlot(slot);	    return SECFailure;	}	/* Allocate space for ciphertext. */	ciphertext = (unsigned char *) PORT_Alloc( max_bytes_encrypted );	if( ciphertext == NULL ) {	    PK11_ExitSlotMonitor(slot);	    PORT_SetError( SEC_ERROR_NO_MEMORY );	    PK11_FreeSlot(slot);	    return SECFailure;	}	/* Initialize bytes encrypted to max bytes encrypted. */	bytes_encrypted = max_bytes_encrypted;	/* Encrypt using the public key. */	crv = PK11_GETTAB( slot )->C_Encrypt( slot->session,					      known_message,					      PAIRWISE_MESSAGE_LENGTH,					      ciphertext,					      &bytes_encrypted );	PK11_ExitSlotMonitor(slot);	PK11_FreeSlot(slot);	if( crv != CKR_OK ) {	    PORT_SetError( PK11_MapError( crv ) );	    PORT_Free( ciphertext );	    return SECFailure;	}	/* Always use the smaller of these two values . . . */	bytes_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH )			 ? PAIRWISE_MESSAGE_LENGTH			 : bytes_encrypted;	/* If there was a failure, the plaintext */	/* goes at the end, therefore . . .      */	text_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH )			? (ciphertext + bytes_encrypted -			  PAIRWISE_MESSAGE_LENGTH )			: ciphertext;	/* Check to ensure that ciphertext does */	/* NOT EQUAL known input message text   */	/* per FIPS PUB 140-1 directive.        */	if( ( bytes_encrypted != max_bytes_encrypted ) ||	    ( PORT_Memcmp( text_compared, known_message,			   bytes_compared ) == 0 ) ) {	    /* Set error to Invalid PRIVATE Key. */	    PORT_SetError( SEC_ERROR_INVALID_KEY );	    PORT_Free( ciphertext );	    return SECFailure;	}	slot = privKey->pkcs11Slot;	/* Prepare for decryption using the private key. */        PK11_EnterSlotMonitor(slot);	crv = PK11_GETTAB( slot )->C_DecryptInit( slot->session,						  mech,						  privKey->pkcs11ID );	if( crv != CKR_OK ) {	    PK11_ExitSlotMonitor(slot);	    PORT_SetError( PK11_MapError(crv) );	    PORT_Free( ciphertext );	    PK11_FreeSlot(slot);	    return SECFailure;	}	/* Initialize bytes decrypted to be the */	/* expected PAIRWISE_MESSAGE_LENGTH.    */	bytes_decrypted = PAIRWISE_MESSAGE_LENGTH;	/* Decrypt using the private key.   */	/* NOTE:  No need to reset the      */	/*        value of bytes_encrypted. */	crv = PK11_GETTAB( slot )->C_Decrypt( slot->session,					      ciphertext,					      bytes_encrypted,					      plaintext,					      &bytes_decrypted );	PK11_ExitSlotMonitor(slot);	/* Finished with ciphertext; free it. */	PORT_Free( ciphertext );	if( crv != CKR_OK ) {	   PORT_SetError( PK11_MapError(crv) );	    PK11_FreeSlot(slot);	   return SECFailure;	}	/* Check to ensure that the output plaintext */	/* does EQUAL known input message text.      */	if( ( bytes_decrypted != PAIRWISE_MESSAGE_LENGTH ) ||	    ( PORT_Memcmp( plaintext, known_message,			   PAIRWISE_MESSAGE_LENGTH ) != 0 ) ) {	    /* Set error to Bad PUBLIC Key. */	    PORT_SetError( SEC_ERROR_BAD_KEY );	    PK11_FreeSlot(slot);	    return SECFailure;	}      }    /**********************************************/    /* Pairwise Consistency Check of Sign/Verify. */    /**********************************************/    canSignVerify = PK11_HasAttributeSet ( privKey->pkcs11Slot, 					  privKey->pkcs11ID, CKA_VERIFY);        if (canSignVerify)      {	/* Initialize signature and digest data. */	signature.data = NULL;	digest.data = NULL;		/* Determine length of signature. */	signature_length = PK11_SignatureLen( privKey );	if( signature_length == 0 )	  goto failure;		/* Allocate space for signature data. */	signature.data = (unsigned char *) PORT_Alloc( signature_length );	if( signature.data == NULL ) {	  PORT_SetError( SEC_ERROR_NO_MEMORY );	  goto failure;	}		/* Allocate space for known digest data. */	digest.data = (unsigned char *) PORT_Alloc( PAIRWISE_DIGEST_LENGTH );	if( digest.data == NULL ) {	  PORT_SetError( SEC_ERROR_NO_MEMORY );	  goto failure;	}		/* "Fill" signature type and length. */	signature.type = PAIRWISE_SECITEM_TYPE;	signature.len  = signature_length;		/* "Fill" digest with known SHA-1 digest parameters. */	digest.type = PAIRWISE_SECITEM_TYPE;	PORT_Memcpy( digest.data, known_digest, PAIRWISE_DIGEST_LENGTH );	digest.len = PAIRWISE_DIGEST_LENGTH;		/* Sign the known hash using the private key. */	rv = PK11_Sign( privKey, &signature, &digest );	if( rv != SECSuccess )	  goto failure;		/* Verify the known hash using the public key. */	rv = PK11_Verify( pubKey, &signature, &digest, wincx );    if( rv != SECSuccess )      goto failure;		/* Free signature and digest data. */	PORT_Free( signature.data );	PORT_Free( digest.data );      }    /**********************************************/    /* Pairwise Consistency Check for Derivation  */    /**********************************************/    isDerivable = PK11_HasAttributeSet ( privKey->pkcs11Slot, 					  privKey->pkcs11ID, CKA_DERIVE);        if (isDerivable)      {   	/* 	 * We are not doing consistency check for Diffie-Hellman Key - 	 * otherwise it would be here	 */      }    return SECSuccess;failure:    if( signature.data != NULL )	PORT_Free( signature.data );    if( digest.data != NULL )	PORT_Free( digest.data );    return SECFailure;}/* * take a private key in one pkcs11 module and load it into another: *  NOTE: the source private key is a rare animal... it can't be sensitive. *  This is used to do a key gen using one pkcs11 module and storing the *  result into another. */SECKEYPrivateKey *pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, 		SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) {    CK_ATTRIBUTE privTemplate[] = {        /* class must be first */	{ CKA_CLASS, NULL, 0 },	{ CKA_KEY_TYPE, NULL, 0 },	/* these three must be next */	{ CKA_TOKEN, NULL, 0 },	{ CKA_PRIVATE, NULL, 0 },	{ CKA_SENSITIVE, NULL, 0 },	{ CKA_ID, NULL, 0 },#ifdef notdef	{ CKA_LABEL, NULL, 0 },	{ CKA_SUBJECT, NULL, 0 },#endif	/* RSA */	{ CKA_MODULUS, NULL, 0 },	{ CKA_PRIVATE_EXPONENT, NULL, 0 },	{ CKA_PUBLIC_EXPONENT, NULL, 0 },	{ CKA_PRIME_1, NULL, 0 },	{ CKA_PRIME_2, NULL, 0 },	{ CKA_EXPONENT_1, NULL, 0 },	{ CKA_EXPONENT_2, NULL, 0 },	{ CKA_COEFFICIENT, NULL, 0 },    };    CK_ATTRIBUTE *attrs = NULL, *ap;    int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);    PRArenaPool *arena;    CK_OBJECT_HANDLE objectID;    int i, count = 0;    int extra_count = 0;    CK_RV crv;    SECStatus rv;    for (i=0; i < templateSize; i++) {	if (privTemplate[i].type == CKA_MODULUS) {	    attrs= &privTemplate[i];	    count = i;	    break;	}    }    PORT_Assert(attrs != NULL);    if (attrs == NULL) {	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);	return NULL;    }    ap = attrs;    switch (privKey->keyType) {    case rsaKey:	count = templateSize;	extra_count = templateSize - (attrs - privTemplate);	break;    case dsaKey:	ap->type = CKA_PRIME; ap++; count++; extra_count++;	ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;	ap->type = CKA_BASE; ap++; count++; extra_count++;	ap->type = CKA_VALUE; ap++; count++; extra_count++;	break;    case dhKey:	ap->type = CKA_PRIME; ap++; count++; extra_count++;	ap->type = CKA_BASE; ap++; count++; extra_count++;	ap->type = CKA_VALUE; ap++; count++; extra_count++;	break;     default:	count = 0;	extra_count = 0;	break;     }     if (count == 0) {	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);	return NULL;     }     arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);     if (arena == NULL) return NULL;     /*      * read out the old attributes.      */     crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,		privTemplate,count);     if (crv != CKR_OK) {	PORT_SetError( PK11_MapError(crv) );	PORT_FreeArena(arena, PR_TRUE);	return NULL;     }     /* Reset sensitive, token, and private */     *(CK_BBOOL *)(privTemplate[2].pValue) = token ? CK_TRUE : CK_FALSE;     *(CK_BBOOL *)(privTemplate[3].pValue) = token ? CK_TRUE : CK_FALSE;     *(CK_BBOOL *)(privTemplate[4].pValue) = sensitive ? CK_TRUE : CK_FALSE;     /* Not everyone can handle zero padded key values, give      * them the raw data as unsigned */     for (ap=attrs; extra_count; ap++, extra_count--) {	pk11_SignedToUnsigned(ap);     }     /* now Store the puppies */     rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate, 						count, token, &objectID);     PORT_FreeArena(arena, PR_TRUE);     if (rv != SECSuccess) {	return NULL;     }     /* try loading the public key as a token object */     if (pubKey) {	PK11_ImportPublicKey(slot, pubKey, PR_TRUE);	if (pubKey->pkcs11Slot) {	    PK11_FreeSlot(pubKey->pkcs11Slot);	    pubKey->pkcs11Slot = NULL;	    pubKey->pkcs11ID = CK_INVALID_KEY;	}     }     /* build new key structure */     return PK11_MakePrivKey(slot, privKey->keyType, (PRBool)!token, 						objectID, privKey->wincx);}/* * Use the token to Generate a key. keySize must be 'zero' for fixed key * length algorithms. NOTE: this means we can never generate a DES2 key * from this interface! */SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,    void *param, SECKEYPublicKey **pubKey, PRBool token, 					PRBool sensitive, void *wincx){    /* we have to use these native types because when we call PKCS 11 modules     * we have to make sure that we are using the correct sizes for all the     * parameters. */    CK_BBOOL ckfalse = CK_FALSE;    CK_BBOOL cktrue = CK_TRUE;    CK_ULONG modulusBits;    CK_BYTE publicExponent[4];    CK_ATTRIBUTE privTemplate[] = {	{ CKA_SENSITIVE, NULL, 0},	{ CKA_TOKEN,  NULL, 0},	{ CKA_PRIVATE,  NULL, 0},	{ CKA_DERIVE,  NULL, 0},	{ CKA_UNWRAP,  NULL, 0},	{ CKA_SIGN,  NULL, 0},	{ CKA_DECRYPT,  NULL, 0},    };    CK_ATTRIBUTE rsaPubTemplate[] = {	{ CKA_MODULUS_BITS, NULL, 0},	{ CKA_PUBLIC_EXPONENT, NULL, 0},	{ CKA_TOKEN,  NULL, 0},	{ CKA_DERIVE,  NULL, 0},	{ CKA_WRAP,  NULL, 0},	{ CKA_VERIFY,  NULL, 0},	{ CKA_VERIFY_RECOVER,  NULL, 0},	{ CKA_ENCRYPT,  NULL, 0},    };    CK_ATTRIBUTE dsaPubTemplate[] = {	{ CKA_PRIME, NULL, 0 },	{ CKA_SUBPRIME, NULL, 0 },	{ CKA_BASE, NULL, 0 },	{ CKA_TOKEN,  NULL, 0},	{ CKA_DERIVE,  NULL, 0},	{ CKA_WRAP,  NULL, 0},	{ CKA_VERIFY,  NULL, 0},	{ CKA_VERIFY_RECOVER,  NULL, 0},	{ CKA_ENCRYPT,  NULL, 0},    };    CK_ATTRIBUTE dhPubTemplate[] = {      { CKA_PRIME, NULL, 0 },       { CKA_BASE, NULL, 0 },       { CKA_TOKEN,  NULL, 0},      { CKA_DERIVE,  NULL, 0},      { CKA_WRAP,  NULL, 0},      { CKA_VERIFY,  NULL, 0},      { CKA_VERIFY_RECOVER,  NULL, 0},      { CKA_ENCRYPT,  NULL, 0},    };    int dsaPubCount = sizeof(dsaPubTemplate)/sizeof(dsaPubTemplate[0]);    /*CK_ULONG key_size = 0;*/    CK_ATTRIBUTE *pubTemplate;    int privCount = sizeof(privTemplate)/sizeof(privTemplate[0]);    int rsaPubCount = sizeof(rsaPubTemplate)/sizeof(rsaPubTemplate[0]);    int dhPubCount = sizeof(dhPubTemplate)/sizeof(dhPubTemplate[0]);    int pubCount = 0;    PK11RSAGenParams *rsaParams;    PQGParams *dsaParams;    DHParams * dhParams;    CK_MECHANISM mechanism;    CK_MECHANISM test_mech;    CK_SESSION_HANDLE session_handle;    CK_RV crv;    CK_OBJECT_HANDLE privID,pubID;    SECKEYPrivateKey *privKey;    KeyType keyType;    PRBool restore;    int peCount,i;    CK_ATTRIBUTE *attrs;    CK_ATTRIBUTE *privattrs;    SECItem *pubKeyIndex;    CK_ATTRIBUTE setTemplate;    SECStatus rv;    CK_MECHANISM_INFO mechanism_info;    CK_OBJECT_CLASS keyClass;    SECItem *cka_id;    PRBool haslock = PR_FALSE;    PRBool pubIsToken = PR_FALSE;    PORT_Assert(slot != NULL);    if (slot == NULL) {	PORT_SetError( SEC_ERROR_NO_MODULE);	return NULL;    }    /* if our slot really doesn't do this mechanism, Generate the key     * in our internal token and write it out */    if (!PK11_DoesMechanism(slot,type)) {	PK11SlotInfo *int_slot = PK11_GetInternalSlot();	/* don't loop forever looking for a slot */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?