| OLD | NEW |
| (Empty) |
| 1 diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c | |
| 2 --- a/lib/pk11wrap/pk11akey.c | |
| 3 +++ b/lib/pk11wrap/pk11akey.c | |
| 4 @@ -1708,17 +1708,23 @@ done: | |
| 5 } | |
| 6 | |
| 7 return rv; | |
| 8 } | |
| 9 | |
| 10 SECKEYPrivateKeyInfo * | |
| 11 PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) | |
| 12 { | |
| 13 - return NULL; | |
| 14 + SECKEYPrivateKeyInfo *pki = NULL; | |
| 15 + SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx); | |
| 16 + if (pk != NULL) { | |
| 17 + pki = PK11_ExportPrivKeyInfo(pk, wincx); | |
| 18 + SECKEY_DestroyPrivateKey(pk); | |
| 19 + } | |
| 20 + return pki; | |
| 21 } | |
| 22 | |
| 23 SECKEYEncryptedPrivateKeyInfo * | |
| 24 PK11_ExportEncryptedPrivKeyInfo( | |
| 25 PK11SlotInfo *slot, /* optional, encrypt key in this slot */ | |
| 26 SECOidTag algTag, /* encrypt key with this algorithm */ | |
| 27 SECItem *pwitem, /* password for PBE encryption */ | |
| 28 SECKEYPrivateKey *pk, /* encrypt this private key */ | |
| 29 diff --git a/lib/pk11wrap/pk11obj.c b/lib/pk11wrap/pk11obj.c | |
| 30 --- a/lib/pk11wrap/pk11obj.c | |
| 31 +++ b/lib/pk11wrap/pk11obj.c | |
| 32 @@ -76,16 +76,19 @@ PK11_DestroyTokenObject(PK11SlotInfo *sl | |
| 33 PK11_RestoreROSession(slot,rwsession); | |
| 34 return rv; | |
| 35 } | |
| 36 | |
| 37 /* | |
| 38 * Read in a single attribute into a SECItem. Allocate space for it with | |
| 39 * PORT_Alloc unless an arena is supplied. In the latter case use the arena | |
| 40 * to allocate the space. | |
| 41 + * | |
| 42 + * PK11_ReadAttribute sets the 'data' and 'len' fields of the SECItem but | |
| 43 + * does not modify its 'type' field. | |
| 44 */ | |
| 45 SECStatus | |
| 46 PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, | |
| 47 CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result) { | |
| 48 CK_ATTRIBUTE attr = { 0, NULL, 0 }; | |
| 49 CK_RV crv; | |
| 50 | |
| 51 attr.type = type; | |
| 52 diff --git a/lib/pk11wrap/pk11pk12.c b/lib/pk11wrap/pk11pk12.c | |
| 53 --- a/lib/pk11wrap/pk11pk12.c | |
| 54 +++ b/lib/pk11wrap/pk11pk12.c | |
| 55 @@ -13,16 +13,17 @@ | |
| 56 #include "secmodi.h" | |
| 57 #include "pkcs11.h" | |
| 58 #include "pk11func.h" | |
| 59 #include "secitem.h" | |
| 60 #include "key.h" | |
| 61 #include "secoid.h" | |
| 62 #include "secasn1.h" | |
| 63 #include "secerr.h" | |
| 64 +#include "prerror.h" | |
| 65 | |
| 66 | |
| 67 | |
| 68 /* These data structures should move to a common .h file shared between the | |
| 69 * wrappers and the pkcs 12 code. */ | |
| 70 | |
| 71 /* | |
| 72 ** RSA Raw Private Key structures | |
| 73 @@ -511,8 +512,117 @@ PK11_ImportPrivateKeyInfo(PK11SlotInfo * | |
| 74 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 75 PRBool isPrivate, unsigned int keyUsage, void *wincx) | |
| 76 { | |
| 77 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, | |
| 78 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); | |
| 79 | |
| 80 } | |
| 81 | |
| 82 +SECItem * | |
| 83 +PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx) | |
| 84 +{ | |
| 85 + SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx); | |
| 86 + SECItem *derPKI; | |
| 87 + | |
| 88 + if (!pki) { | |
| 89 + return NULL; | |
| 90 + } | |
| 91 + derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki, | |
| 92 + SECKEY_PrivateKeyInfoTemplate); | |
| 93 + SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE); | |
| 94 + return derPKI; | |
| 95 +} | |
| 96 + | |
| 97 +static PRBool | |
| 98 +ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, | |
| 99 + PLArenaPool *arena, SECItem *output) | |
| 100 +{ | |
| 101 + SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type, | |
| 102 + arena, output); | |
| 103 + return rv == SECSuccess; | |
| 104 +} | |
| 105 + | |
| 106 +/* | |
| 107 + * The caller is responsible for freeing the return value by passing it to | |
| 108 + * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE). | |
| 109 + */ | |
| 110 +SECKEYPrivateKeyInfo * | |
| 111 +PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx) | |
| 112 +{ | |
| 113 + /* PrivateKeyInfo version (always zero) */ | |
| 114 + const unsigned char pkiVersion = 0; | |
| 115 + /* RSAPrivateKey version (always zero) */ | |
| 116 + const unsigned char rsaVersion = 0; | |
| 117 + PLArenaPool *arena = NULL; | |
| 118 + SECKEYRawPrivateKey rawKey; | |
| 119 + SECKEYPrivateKeyInfo *pki; | |
| 120 + SECItem *encoded; | |
| 121 + SECStatus rv; | |
| 122 + | |
| 123 + if (pk->keyType != rsaKey) { | |
| 124 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 125 + goto loser; | |
| 126 + } | |
| 127 + | |
| 128 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
| 129 + if (!arena) { | |
| 130 + goto loser; | |
| 131 + } | |
| 132 + memset(&rawKey, 0, sizeof(rawKey)); | |
| 133 + rawKey.keyType = pk->keyType; | |
| 134 + rawKey.u.rsa.version.type = siUnsignedInteger; | |
| 135 + rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); | |
| 136 + if (!rawKey.u.rsa.version.data) { | |
| 137 + goto loser; | |
| 138 + } | |
| 139 + rawKey.u.rsa.version.data[0] = rsaVersion; | |
| 140 + rawKey.u.rsa.version.len = 1; | |
| 141 + | |
| 142 + /* Read the component attributes of the private key */ | |
| 143 + prepare_rsa_priv_key_export_for_asn1(&rawKey); | |
| 144 + if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) || | |
| 145 + !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena, | |
| 146 + &rawKey.u.rsa.publicExponent) || | |
| 147 + !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena, | |
| 148 + &rawKey.u.rsa.privateExponent) || | |
| 149 + !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) || | |
| 150 + !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) || | |
| 151 + !ReadAttribute(pk, CKA_EXPONENT_1, arena, | |
| 152 + &rawKey.u.rsa.exponent1) || | |
| 153 + !ReadAttribute(pk, CKA_EXPONENT_2, arena, | |
| 154 + &rawKey.u.rsa.exponent2) || | |
| 155 + !ReadAttribute(pk, CKA_COEFFICIENT, arena, | |
| 156 + &rawKey.u.rsa.coefficient)) { | |
| 157 + goto loser; | |
| 158 + } | |
| 159 + | |
| 160 + pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo); | |
| 161 + if (!pki) { | |
| 162 + goto loser; | |
| 163 + } | |
| 164 + encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, | |
| 165 + SECKEY_RSAPrivateKeyExportTemplate); | |
| 166 + if (!encoded) { | |
| 167 + goto loser; | |
| 168 + } | |
| 169 + rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, | |
| 170 + SEC_OID_PKCS1_RSA_ENCRYPTION, NULL); | |
| 171 + if (rv != SECSuccess) { | |
| 172 + goto loser; | |
| 173 + } | |
| 174 + pki->version.type = siUnsignedInteger; | |
| 175 + pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); | |
| 176 + if (!pki->version.data) { | |
| 177 + goto loser; | |
| 178 + } | |
| 179 + pki->version.data[0] = pkiVersion; | |
| 180 + pki->version.len = 1; | |
| 181 + pki->arena = arena; | |
| 182 + | |
| 183 + return pki; | |
| 184 + | |
| 185 +loser: | |
| 186 + if (arena) { | |
| 187 + PORT_FreeArena(arena, PR_TRUE); | |
| 188 + } | |
| 189 + return NULL; | |
| 190 +} | |
| 191 diff --git a/lib/pk11wrap/pk11pub.h b/lib/pk11wrap/pk11pub.h | |
| 192 --- a/lib/pk11wrap/pk11pub.h | |
| 193 +++ b/lib/pk11wrap/pk11pub.h | |
| 194 @@ -554,16 +554,19 @@ SECStatus PK11_ImportEncryptedPrivateKey | |
| 195 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 196 PRBool isPrivate, KeyType type, | |
| 197 unsigned int usage, void *wincx); | |
| 198 SECStatus PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, | |
| 199 SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem, | |
| 200 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
| 201 PRBool isPrivate, KeyType type, | |
| 202 unsigned int usage, SECKEYPrivateKey** privk, void *wincx); | |
| 203 +SECItem *PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx); | |
| 204 +SECKEYPrivateKeyInfo *PK11_ExportPrivKeyInfo( | |
| 205 + SECKEYPrivateKey *pk, void *wincx); | |
| 206 SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo( | |
| 207 CERTCertificate *cert, void *wincx); | |
| 208 SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfo( | |
| 209 PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem, | |
| 210 SECKEYPrivateKey *pk, int iteration, void *wincx); | |
| 211 SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfo( | |
| 212 PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem, | |
| 213 CERTCertificate *cert, int iteration, void *wincx); | |
| OLD | NEW |