seckey.c

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

C
1,652
字号
    if (arena == NULL)	return NULL;    pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));    if (pubk == NULL) {	PORT_FreeArena (arena, PR_FALSE);	return NULL;    }    pubk->arena = arena;    pubk->pkcs11Slot = 0;    pubk->pkcs11ID = CK_INVALID_KEY;    /* Convert bit string length from bits to bytes */    os = spki->subjectPublicKey;    DER_ConvertBitString (&os);    tag = SECOID_GetAlgorithmTag(&spki->algorithm);    switch ( tag ) {      case SEC_OID_X500_RSA_ENCRYPTION:      case SEC_OID_PKCS1_RSA_ENCRYPTION:	pubk->keyType = rsaKey;	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os);	if (rv == SECSuccess)	    return pubk;	break;      case SEC_OID_ANSIX9_DSA_SIGNATURE:	pubk->keyType = dsaKey;	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os);	if (rv != SECSuccess) break;        rv = SECKEY_DSADecodePQG(arena, pubk,                                 &spki->algorithm.parameters); 	if (rv == SECSuccess) return pubk;	break;      case SEC_OID_X942_DIFFIE_HELMAN_KEY:	pubk->keyType = dhKey;	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os);	if (rv != SECSuccess) break;        rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate,                                 &spki->algorithm.parameters); 	if (rv == SECSuccess) return pubk;	break;      case SEC_OID_MISSI_KEA_DSS_OLD:      case SEC_OID_MISSI_KEA_DSS:      case SEC_OID_MISSI_DSS_OLD:      case SEC_OID_MISSI_DSS:	pubk->keyType = fortezzaKey;	rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &os,				          &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;	break;      case SEC_OID_MISSI_KEA:	pubk->keyType = keaKey;        rv = SEC_ASN1DecodeItem(arena, pubk,                                SECKEY_KEAPublicKeyTemplate, &os);        if (rv != SECSuccess) break;        rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,                        &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;      break;      case SEC_OID_MISSI_ALT_KEA:	pubk->keyType = keaKey;        rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&os);        if (rv != SECSuccess) break;         rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,                        &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;      break;      default:	rv = SECFailure;	break;    }    SECKEY_DestroyPublicKey (pubk);    return NULL;}SECKEYPublicKey *CERT_ExtractPublicKey(CERTCertificate *cert){    SECStatus rv;    rv = SECKEY_UpdateCertPQG(cert);    if (rv != SECSuccess) return NULL;    return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);}/* * Get the public key for the fortezza KMID. NOTE this requires the * PQG paramters to be set. We probably should have a fortezza call that  * just extracts the kmid for us directly so this function can work * without having the whole cert chain */SECKEYPublicKey *CERT_KMIDPublicKey(CERTCertificate *cert){    return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo);}/* returns key strength in bytes (not bits) */unsignedSECKEY_PublicKeyStrength(SECKEYPublicKey *pubk){    unsigned char b0;    /* interpret modulus length as key strength... in     * fortezza that's the public key length */    switch (pubk->keyType) {    case rsaKey:    	b0 = pubk->u.rsa.modulus.data[0];    	return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;    case dsaKey:    	b0 = pubk->u.dsa.publicValue.data[0];    	return b0 ? pubk->u.dsa.publicValue.len :	    pubk->u.dsa.publicValue.len - 1;    case dhKey:    	b0 = pubk->u.dh.publicValue.data[0];    	return b0 ? pubk->u.dh.publicValue.len :	    pubk->u.dh.publicValue.len - 1;    case fortezzaKey:	return PR_MAX(pubk->u.fortezza.KEAKey.len, pubk->u.fortezza.DSSKey.len);    default:	break;    }    return 0;}SECKEYPrivateKey *SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk){    SECKEYPrivateKey *copyk;    PRArenaPool *arena;        if (privk == NULL) {	return NULL;    }        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError (SEC_ERROR_NO_MEMORY);	return NULL;    }    copyk = (SECKEYPrivateKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPrivateKey));    if (copyk) {	copyk->arena = arena;	copyk->keyType = privk->keyType;	/* copy the PKCS #11 parameters */	copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);	/* if the key we're referencing was a temparary key we have just	 * created, that we want to go away when we're through, we need	 * to make a copy of it */	if (privk->pkcs11IsTemp) {	    copyk->pkcs11ID = 			PK11_CopyKey(privk->pkcs11Slot,privk->pkcs11ID);	    if (copyk->pkcs11ID == CK_INVALID_KEY) goto fail;	} else {	    copyk->pkcs11ID = privk->pkcs11ID;	}	copyk->pkcs11IsTemp = privk->pkcs11IsTemp;	copyk->wincx = privk->wincx;	return copyk;    } else {	PORT_SetError (SEC_ERROR_NO_MEMORY);    }fail:    PORT_FreeArena (arena, PR_FALSE);    return NULL;}SECKEYPublicKey *SECKEY_CopyPublicKey(SECKEYPublicKey *pubk){    SECKEYPublicKey *copyk;    PRArenaPool *arena;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError (SEC_ERROR_NO_MEMORY);	return NULL;    }    copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));    if (copyk != NULL) {	SECStatus rv = SECSuccess;	copyk->arena = arena;	copyk->keyType = pubk->keyType;	copyk->pkcs11Slot = NULL;	/* go get own reference */	copyk->pkcs11ID = CK_INVALID_KEY;	switch (pubk->keyType) {	  case rsaKey:	    rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,				  &pubk->u.rsa.modulus);	    if (rv == SECSuccess) {		rv = SECITEM_CopyItem (arena, &copyk->u.rsa.publicExponent,				       &pubk->u.rsa.publicExponent);		if (rv == SECSuccess)		    return copyk;	    }	    break;	  case dsaKey:	    rv = SECITEM_CopyItem(arena, &copyk->u.dsa.publicValue,				  &pubk->u.dsa.publicValue);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.prime,				  &pubk->u.dsa.params.prime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.subPrime,				  &pubk->u.dsa.params.subPrime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.dsa.params.base,				  &pubk->u.dsa.params.base);	    break;          case keaKey:            rv = SECITEM_CopyItem(arena, &copyk->u.kea.publicValue,                                  &pubk->u.kea.publicValue);            if (rv != SECSuccess) break;            rv = SECITEM_CopyItem(arena, &copyk->u.kea.params.hash,                                  &pubk->u.kea.params.hash);            break;	  case fortezzaKey:	    copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion;	    copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion;	    PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID,			sizeof(pubk->u.fortezza.KMID));	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.clearance, 				  &pubk->u.fortezza.clearance);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEApriviledge, 				&pubk->u.fortezza.KEApriviledge);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSpriviledge, 				&pubk->u.fortezza.DSSpriviledge);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.KEAKey, 				&pubk->u.fortezza.KEAKey);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.DSSKey, 				&pubk->u.fortezza.DSSKey);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.prime, 				  &pubk->u.fortezza.params.prime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.subPrime, 				&pubk->u.fortezza.params.subPrime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.params.base, 				&pubk->u.fortezza.params.base);            if (rv != SECSuccess) break;            rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.prime, 				  &pubk->u.fortezza.keaParams.prime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.subPrime, 				&pubk->u.fortezza.keaParams.subPrime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.fortezza.keaParams.base, 				&pubk->u.fortezza.keaParams.base);	    break;	  case dhKey:            rv = SECITEM_CopyItem(arena,&copyk->u.dh.prime,&pubk->u.dh.prime);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena,&copyk->u.dh.base,&pubk->u.dh.base);	    if (rv != SECSuccess) break;	    rv = SECITEM_CopyItem(arena, &copyk->u.dh.publicValue, 				&pubk->u.dh.publicValue);	    break;	  case nullKey:	    return copyk;	  default:	    rv = SECFailure;	    break;	}	if (rv == SECSuccess)	    return copyk;	SECKEY_DestroyPublicKey (copyk);    } else {	PORT_SetError (SEC_ERROR_NO_MEMORY);    }    PORT_FreeArena (arena, PR_FALSE);    return NULL;}SECKEYPublicKey *SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk){    SECKEYPublicKey *pubk;    PRArenaPool *arena;    CERTCertificate *cert;    SECStatus rv;    /*     * First try to look up the cert.     */    cert = PK11_GetCertFromPrivateKey(privk);    if (cert) {	pubk = CERT_ExtractPublicKey(cert);	CERT_DestroyCertificate(cert);	return pubk;    }    /* couldn't find the cert, build pub key by hand */    arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError (SEC_ERROR_NO_MEMORY);	return NULL;    }    pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena,						   sizeof (SECKEYPublicKey));    if (pubk == NULL) {	PORT_FreeArena(arena,PR_FALSE);	return NULL;    }    pubk->keyType = privk->keyType;    pubk->pkcs11Slot = NULL;    pubk->pkcs11ID = CK_INVALID_KEY;    pubk->arena = arena;    /*     * fortezza is at the head of this switch, since we don't want to     * allocate an arena... CERT_ExtractPublicKey will to that for us.     */    switch(privk->keyType) {      case fortezzaKey:      case nullKey:      case dhKey:      case dsaKey:	/* Nothing to query, if the cert isn't there, we're done -- no way	 * to get the public key */	break;      case rsaKey:	rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID,				CKA_MODULUS,arena,&pubk->u.rsa.modulus);	if (rv != SECSuccess)  break;	rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID,			CKA_PUBLIC_EXPONENT,arena,&pubk->u.rsa.publicExponent);	if (rv != SECSuccess)  break;	return pubk;	break;    default:	break;    }    PORT_FreeArena (arena, PR_FALSE);    return NULL;}CERTSubjectPublicKeyInfo *SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk){    CERTSubjectPublicKeyInfo *spki;    PRArenaPool *arena;    SECItem params = { siBuffer, NULL, 0 };    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return NULL;    }    spki = (CERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(arena, sizeof (*spki));    if (spki != NULL) {	SECStatus rv;	SECItem *rv_item;		spki->arena = arena;	switch(pubk->keyType) {	  case rsaKey:	    rv = SECOID_SetAlgorithmID(arena, &spki->algorithm,				     SEC_OID_PKCS1_RSA_ENCRYPTION, 0);	    if (rv == SECSuccess) {		/*		 * DER encode the public key into the subjectPublicKeyInfo.		 */		rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey,					     pubk, SECKEY_RSAPublicKeyTemplate);		if (rv_item != NULL) {		    /*		     * The stored value is supposed to be a BIT_STRING,		     * so convert the length.		     */		    spki->subjectPublicKey.len <<= 3;		    /*		     * We got a good one; return it.		     */

⌨️ 快捷键说明

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