summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/n_pkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/n_pkey.c')
-rw-r--r--src/lib/libcrypto/asn1/n_pkey.c434
1 files changed, 0 insertions, 434 deletions
diff --git a/src/lib/libcrypto/asn1/n_pkey.c b/src/lib/libcrypto/asn1/n_pkey.c
deleted file mode 100644
index 1e73c82d09..0000000000
--- a/src/lib/libcrypto/asn1/n_pkey.c
+++ /dev/null
@@ -1,434 +0,0 @@
1/* $OpenBSD: n_pkey.c,v 1.30 2015/10/16 15:15:39 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/opensslconf.h>
63
64#ifndef OPENSSL_NO_RSA
65#include <openssl/asn1t.h>
66#include <openssl/err.h>
67#include <openssl/evp.h>
68#include <openssl/objects.h>
69#include <openssl/rsa.h>
70#include <openssl/x509.h>
71
72#ifndef OPENSSL_NO_RC4
73
74typedef struct netscape_pkey_st {
75 long version;
76 X509_ALGOR *algor;
77 ASN1_OCTET_STRING *private_key;
78} NETSCAPE_PKEY;
79
80typedef struct netscape_encrypted_pkey_st {
81 ASN1_OCTET_STRING *os;
82 /* This is the same structure as DigestInfo so use it:
83 * although this isn't really anything to do with
84 * digests.
85 */
86 X509_SIG *enckey;
87} NETSCAPE_ENCRYPTED_PKEY;
88
89
90static const ASN1_AUX NETSCAPE_ENCRYPTED_PKEY_aux = {
91 .flags = ASN1_AFLG_BROKEN,
92};
93static const ASN1_TEMPLATE NETSCAPE_ENCRYPTED_PKEY_seq_tt[] = {
94 {
95 .offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, os),
96 .field_name = "os",
97 .item = &ASN1_OCTET_STRING_it,
98 },
99 {
100 .offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, enckey),
101 .field_name = "enckey",
102 .item = &X509_SIG_it,
103 },
104};
105
106const ASN1_ITEM NETSCAPE_ENCRYPTED_PKEY_it = {
107 .itype = ASN1_ITYPE_SEQUENCE,
108 .utype = V_ASN1_SEQUENCE,
109 .templates = NETSCAPE_ENCRYPTED_PKEY_seq_tt,
110 .tcount = sizeof(NETSCAPE_ENCRYPTED_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
111 .funcs = &NETSCAPE_ENCRYPTED_PKEY_aux,
112 .size = sizeof(NETSCAPE_ENCRYPTED_PKEY),
113 .sname = "NETSCAPE_ENCRYPTED_PKEY",
114};
115
116NETSCAPE_ENCRYPTED_PKEY *NETSCAPE_ENCRYPTED_PKEY_new(void);
117void NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a);
118NETSCAPE_ENCRYPTED_PKEY *d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len);
119int i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out);
120
121NETSCAPE_ENCRYPTED_PKEY *
122d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len)
123{
124 return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
125 &NETSCAPE_ENCRYPTED_PKEY_it);
126}
127
128int
129i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out)
130{
131 return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_ENCRYPTED_PKEY_it);
132}
133
134NETSCAPE_ENCRYPTED_PKEY *
135NETSCAPE_ENCRYPTED_PKEY_new(void)
136{
137 return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_new(&NETSCAPE_ENCRYPTED_PKEY_it);
138}
139
140void
141NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a)
142{
143 ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_ENCRYPTED_PKEY_it);
144}
145
146static const ASN1_TEMPLATE NETSCAPE_PKEY_seq_tt[] = {
147 {
148 .offset = offsetof(NETSCAPE_PKEY, version),
149 .field_name = "version",
150 .item = &LONG_it,
151 },
152 {
153 .offset = offsetof(NETSCAPE_PKEY, algor),
154 .field_name = "algor",
155 .item = &X509_ALGOR_it,
156 },
157 {
158 .offset = offsetof(NETSCAPE_PKEY, private_key),
159 .field_name = "private_key",
160 .item = &ASN1_OCTET_STRING_it,
161 },
162};
163
164const ASN1_ITEM NETSCAPE_PKEY_it = {
165 .itype = ASN1_ITYPE_SEQUENCE,
166 .utype = V_ASN1_SEQUENCE,
167 .templates = NETSCAPE_PKEY_seq_tt,
168 .tcount = sizeof(NETSCAPE_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
169 .size = sizeof(NETSCAPE_PKEY),
170 .sname = "NETSCAPE_PKEY",
171};
172
173NETSCAPE_PKEY *NETSCAPE_PKEY_new(void);
174void NETSCAPE_PKEY_free(NETSCAPE_PKEY *a);
175NETSCAPE_PKEY *d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len);
176int i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out);
177
178NETSCAPE_PKEY *
179d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len)
180{
181 return (NETSCAPE_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
182 &NETSCAPE_PKEY_it);
183}
184
185int
186i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out)
187{
188 return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_PKEY_it);
189}
190
191NETSCAPE_PKEY *
192NETSCAPE_PKEY_new(void)
193{
194 return (NETSCAPE_PKEY *)ASN1_item_new(&NETSCAPE_PKEY_it);
195}
196
197void
198NETSCAPE_PKEY_free(NETSCAPE_PKEY *a)
199{
200 ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_PKEY_it);
201}
202
203static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
204 int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey);
205
206int
207i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
208 int (*cb)(char *buf, int len, const char *prompt, int verify))
209{
210 return i2d_RSA_NET(a, pp, cb, 0);
211}
212
213int
214i2d_RSA_NET(const RSA *a, unsigned char **pp,
215 int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
216{
217 int i, j, ret = 0;
218 int rsalen, pkeylen, olen;
219 NETSCAPE_PKEY *pkey = NULL;
220 NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
221 unsigned char buf[256], *zz;
222 unsigned char key[EVP_MAX_KEY_LENGTH];
223 EVP_CIPHER_CTX ctx;
224 EVP_CIPHER_CTX_init(&ctx);
225
226 if (a == NULL)
227 return (0);
228
229 if ((pkey = NETSCAPE_PKEY_new()) == NULL)
230 goto err;
231 if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
232 goto err;
233 pkey->version = 0;
234
235 pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
236 if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
237 goto err;
238 pkey->algor->parameter->type = V_ASN1_NULL;
239
240 rsalen = i2d_RSAPrivateKey(a, NULL);
241
242 /* Fake some octet strings just for the initial length
243 * calculation.
244 */
245 pkey->private_key->length = rsalen;
246 pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);
247 enckey->enckey->digest->length = pkeylen;
248 enckey->os->length = 11; /* "private-key" */
249 enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
250 if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
251 goto err;
252 enckey->enckey->algor->parameter->type = V_ASN1_NULL;
253
254 if (pp == NULL) {
255 olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
256 NETSCAPE_PKEY_free(pkey);
257 NETSCAPE_ENCRYPTED_PKEY_free(enckey);
258 return olen;
259 }
260
261 /* Since its RC4 encrypted length is actual length */
262 if ((zz = malloc(rsalen)) == NULL) {
263 ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
264 goto err;
265 }
266
267 pkey->private_key->data = zz;
268 /* Write out private key encoding */
269 i2d_RSAPrivateKey(a, &zz);
270
271 if ((zz = malloc(pkeylen)) == NULL) {
272 ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
273 goto err;
274 }
275
276 if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
277 ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
278 goto err;
279 }
280 enckey->enckey->digest->data = zz;
281 i2d_NETSCAPE_PKEY(pkey, &zz);
282
283 /* Wipe the private key encoding */
284 explicit_bzero(pkey->private_key->data, rsalen);
285
286 if (cb == NULL)
287 cb = EVP_read_pw_string;
288 i = cb((char *)buf, sizeof(buf), "Enter Private Key password:", 1);
289 if (i != 0) {
290 ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ);
291 goto err;
292 }
293 i = strlen((char *)buf);
294 /* If the key is used for SGC the algorithm is modified a little. */
295 if (sgckey) {
296 if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
297 goto err;
298 memcpy(buf + 16, "SGCKEYSALT", 10);
299 i = 26;
300 }
301
302 if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
303 goto err;
304 explicit_bzero(buf, sizeof(buf));
305
306 /* Encrypt private key in place */
307 zz = enckey->enckey->digest->data;
308 if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
309 goto err;
310 if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
311 goto err;
312 if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
313 goto err;
314
315 ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
316err:
317 EVP_CIPHER_CTX_cleanup(&ctx);
318 NETSCAPE_ENCRYPTED_PKEY_free(enckey);
319 NETSCAPE_PKEY_free(pkey);
320 return (ret);
321}
322
323
324RSA *
325d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
326 int (*cb)(char *buf, int len, const char *prompt, int verify))
327{
328 return d2i_RSA_NET(a, pp, length, cb, 0);
329}
330
331RSA *
332d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
333 int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
334{
335 RSA *ret = NULL;
336 const unsigned char *p;
337 NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
338
339 p = *pp;
340
341 enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
342 if (!enckey) {
343 ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR);
344 return NULL;
345 }
346
347 /* XXX 11 == strlen("private-key") */
348 if (enckey->os->length != 11 ||
349 memcmp("private-key", enckey->os->data, 11) != 0) {
350 ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
351 goto err;
352 }
353 if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
354 ASN1err(ASN1_F_D2I_RSA_NET,
355 ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
356 goto err;
357 }
358 if (cb == NULL)
359 cb = EVP_read_pw_string;
360 if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb,
361 sgckey)) == NULL)
362 goto err;
363
364 *pp = p;
365
366err:
367 NETSCAPE_ENCRYPTED_PKEY_free(enckey);
368 return ret;
369
370}
371
372static RSA *
373d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
374 int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
375{
376 NETSCAPE_PKEY *pkey = NULL;
377 RSA *ret = NULL;
378 int i, j;
379 unsigned char buf[256];
380 const unsigned char *zz;
381 unsigned char key[EVP_MAX_KEY_LENGTH];
382 EVP_CIPHER_CTX ctx;
383 EVP_CIPHER_CTX_init(&ctx);
384
385 i=cb((char *)buf, sizeof(buf), "Enter Private Key password:",0);
386 if (i != 0) {
387 ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ);
388 goto err;
389 }
390
391 i = strlen((char *)buf);
392 if (sgckey){
393 if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
394 goto err;
395 memcpy(buf + 16, "SGCKEYSALT", 10);
396 i = 26;
397 }
398
399 if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
400 goto err;
401 explicit_bzero(buf, sizeof(buf));
402
403 if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
404 goto err;
405 if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
406 goto err;
407 if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
408 goto err;
409 os->length = i + j;
410
411 zz = os->data;
412
413 if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
414 ASN1err(ASN1_F_D2I_RSA_NET_2,
415 ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
416 goto err;
417 }
418
419 zz = pkey->private_key->data;
420 if ((ret = d2i_RSAPrivateKey(a, &zz,
421 pkey->private_key->length)) == NULL) {
422 ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
423 goto err;
424 }
425
426err:
427 EVP_CIPHER_CTX_cleanup(&ctx);
428 NETSCAPE_PKEY_free(pkey);
429 return (ret);
430}
431
432#endif /* OPENSSL_NO_RC4 */
433
434#endif