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 |