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, ©k->u.rsa.modulus, &pubk->u.rsa.modulus); if (rv == SECSuccess) { rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, &pubk->u.rsa.publicExponent); if (rv == SECSuccess) return copyk; } break; case dsaKey: rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, &pubk->u.dsa.publicValue); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, &pubk->u.dsa.params.prime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, &pubk->u.dsa.params.subPrime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, &pubk->u.dsa.params.base); break; case keaKey: rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, &pubk->u.kea.publicValue); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->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, ©k->u.fortezza.clearance, &pubk->u.fortezza.clearance); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, &pubk->u.fortezza.KEApriviledge); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, &pubk->u.fortezza.DSSpriviledge); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, &pubk->u.fortezza.KEAKey); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, &pubk->u.fortezza.DSSKey); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, &pubk->u.fortezza.params.prime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, &pubk->u.fortezza.params.subPrime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, &pubk->u.fortezza.params.base); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, &pubk->u.fortezza.keaParams.prime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, &pubk->u.fortezza.keaParams.subPrime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, &pubk->u.fortezza.keaParams.base); break; case dhKey: rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); if (rv != SECSuccess) break; rv = SECITEM_CopyItem(arena, ©k->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 + -
显示快捷键?