1/*
2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include "ossl-config.h"
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <time.h>
30
31#include "ossl-objects.h"
32#include "ossl-evp.h"
33#include "ossl-engine.h"
34#include "ossl-buffer.h"
35#include "ossl-bio.h"
36#include "ossl-pem.h"
37#include "ossl-rsa.h"
38
39#define MIN_LENGTH    4
40
41int
42PEM_def_callback(char *buf, int num, int w, void *key)
43{
44	int i, j;
45	const char *prompt;
46
47	if (key) {
48		i = strlen(key);
49		i = (i > num) ? num : i;
50		memcpy(buf, key, i);
51		return (i);
52	}
53
54	prompt = EVP_get_pw_prompt();
55	if (NULL == prompt) {
56		prompt = "Enter PEM pass phrase:";
57	}
58
59	for ( ; ; ) {
60		i = EVP_read_pw_string(buf, num, prompt, w);
61		if (i != 0) {
62			/* PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); */
63			memset(buf, 0, (unsigned int)num);
64			return (-1);
65		}
66
67		j = strlen(buf);
68		if (j < MIN_LENGTH) {
69			fprintf(stderr, "phrase is too short, needs to be at least %d chars\n",
70			    MIN_LENGTH);
71		} else{
72			break;
73		}
74	}
75	return (j);
76}
77
78
79int
80PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
81    pem_password_cb *callback, void *u)
82{
83	int i, j, o, klen;
84	long len;
85	EVP_CIPHER_CTX ctx;
86	unsigned char key[EVP_MAX_KEY_LENGTH];
87	char buf[PEM_BUFSIZE];
88
89	len = *plen;
90
91	if (cipher->cipher == NULL) {
92		return (1);
93	}
94	if (callback == NULL) {
95		klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
96	} else{
97		klen = callback(buf, PEM_BUFSIZE, 0, u);
98	}
99	if (klen <= 0) {
100		/* PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ); */
101		return (0);
102	}
103
104	EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
105	    (unsigned char *)buf, klen, 1, key, NULL);
106
107	j = (int)len;
108	EVP_CIPHER_CTX_init(&ctx);
109	EVP_CipherInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0]), 0);
110	EVP_CipherUpdate(&ctx, data, &i, data, j);
111	o = EVP_CipherFinal_ex(&ctx, &(data[i]), &j);
112	EVP_CIPHER_CTX_cleanup(&ctx);
113	memset((char *)buf, 0, sizeof(buf));
114	memset((char *)key, 0, sizeof(key));
115	j += i;
116	if (!o) {
117		/* PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT); */
118		return (0);
119	}
120	*plen = j;
121
122	return (1);
123}
124
125
126static int
127load_iv(char **fromp, unsigned char *to, int num)
128{
129	int v, i;
130	char *from = *fromp;
131
132	for (i = 0; i < num; i++) {
133		to[i] = 0;
134	}
135	num *= 2;
136
137	for (i = 0; i < num; i++) {
138		if ((*from >= '0') && (*from <= '9')) {
139			v = *from - '0';
140		} else if ((*from >= 'A') && (*from <= 'F')) {
141			v = *from - 'A' +10;
142		} else if ((*from >= 'a') && (*from <= 'f')) {
143			v = *from - 'a' + 10;
144		} else{
145			/* PEMerr(PEM_F_LOAD_IV,PEM_R_BAD_IV_CHARS); */
146			return (0);
147		}
148		from++;
149		to[i/2] |= v << (long)((!(i & 1)) * 4);
150	}
151	*fromp = from;
152
153	return (1);
154}
155
156
157int
158PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
159{
160	const EVP_CIPHER *enc = NULL;
161	char *p, c;
162	char **header_pp = &header;
163
164	cipher->cipher = NULL;
165	if ((header == NULL) || (*header == '\0') || (*header == '\n')) {
166		return (1);
167	}
168	if (strncmp(header, "Proc-Type: ", 11) != 0) {
169		/* PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); */
170		return (0);
171	}
172	header += 11;
173	if (*header != '4') {
174		return (0);
175	}
176	header++;
177	if (*header != ',') {
178		return (0);
179	}
180	header++;
181	if (strncmp(header, "ENCRYPTED", 9) != 0) {
182		/* PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_ENCRYPTED); */
183		return (0);
184	}
185	for ( ; (*header != '\n') && (*header != '\0'); header++) {
186	}
187	if (*header == '\0') {
188		/* PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_SHORT_HEADER); */
189		return (0);
190	}
191	header++;
192	if (strncmp(header, "DEK-Info: ", 10) != 0) {
193		/* PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_DEK_INFO); */
194		return (0);
195	}
196	header += 10;
197
198	p = header;
199	for ( ; ; ) {
200		c = *header;
201		if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') ||
202		    ((c >= '0') && (c <= '9')))) {
203			break;
204		}
205		header++;
206	}
207	*header = '\0';
208	cipher->cipher = enc = EVP_get_cipherbyname(p);
209	*header = c;
210	header++;
211
212	if (enc == NULL) {
213		/* PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTION); */
214		return (0);
215	}
216	if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len)) {
217		return (0);
218	}
219
220	return (1);
221}
222
223
224int
225PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, long *len)
226{
227	EVP_ENCODE_CTX ctx;
228	int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
229	char buf[256];
230	BUF_MEM *nameB;
231	BUF_MEM *headerB;
232	BUF_MEM *dataB, *tmpB;
233
234	nameB = BUF_MEM_new();
235	headerB = BUF_MEM_new();
236	dataB = BUF_MEM_new();
237	if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
238		BUF_MEM_free(nameB);
239		BUF_MEM_free(headerB);
240		BUF_MEM_free(dataB);
241		return (0);
242	}
243
244	buf[254] = '\0';
245	for ( ; ; ) {
246		i = BIO_gets(bp, buf, 254);
247
248		if (i <= 0) {
249			goto err;
250		}
251
252		while ((i >= 0) && (buf[i] <= ' ')) {
253			i--;
254		}
255		buf[++i] = '\n';
256		buf[++i] = '\0';
257
258		if (strncmp(buf, "-----BEGIN ", 11) == 0) {
259			i = strlen(&(buf[11]));
260
261			if (strncmp(&(buf[11+i-6]), "-----\n", 6) != 0) {
262				continue;
263			}
264			if (!BUF_MEM_grow(nameB, i+9)) {
265				goto err;
266			}
267			memcpy(nameB->data, &(buf[11]), (i - 6));
268			nameB->data[i-6] = '\0';
269			break;
270		}
271	}
272	hl = 0;
273	if (!BUF_MEM_grow(headerB, 256)) {
274		goto err;
275	}
276	headerB->data[0] = '\0';
277	for ( ; ; ) {
278		i = BIO_gets(bp, buf, 254);
279		if (i <= 0) {
280			break;
281		}
282
283		while ((i >= 0) && (buf[i] <= ' ')) {
284			i--;
285		}
286		buf[++i] = '\n';
287		buf[++i] = '\0';
288
289		if (buf[0] == '\n') {
290			break;
291		}
292		if (!BUF_MEM_grow(headerB, hl+i+9)) {
293			goto err;
294		}
295		if (strncmp(buf, "-----END ", 9) == 0) {
296			nohead = 1;
297			break;
298		}
299		memcpy(&(headerB->data[hl]), buf, i);
300		headerB->data[hl + i] = '\0';
301		hl += i;
302	}
303
304	bl = 0;
305	if (!BUF_MEM_grow(dataB, 1024)) {
306		goto err;
307	}
308	dataB->data[0] = '\0';
309	if (!nohead) {
310		for ( ; ; ) {
311			i = BIO_gets(bp, buf, 254);
312			if (i <= 0) {
313				break;
314			}
315
316			while ((i >= 0) && (buf[i] <= ' ')) {
317				i--;
318			}
319			buf[++i] = '\n';
320			buf[++i] = '\0';
321
322			if (i != 65) {
323				end = 1;
324			}
325			if (strncmp(buf, "-----END ", 9) == 0) {
326				break;
327			}
328			if (i > 65) {
329				break;
330			}
331			if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
332				goto err;
333			}
334			memcpy(&(dataB->data[bl]), buf, i);
335			dataB->data[bl+i] = '\0';
336			bl += i;
337			if (end) {
338				buf[0] = '\0';
339				i = BIO_gets(bp, buf, 254);
340				if (i <= 0) {
341					break;
342				}
343
344				while ((i >= 0) && (buf[i] <= ' ')) {
345					i--;
346				}
347				buf[++i] = '\n';
348				buf[++i] = '\0';
349
350				break;
351			}
352		}
353	} else {
354		tmpB = headerB;
355		headerB = dataB;
356		dataB = tmpB;
357		bl = hl;
358	}
359	i = strlen(nameB->data);
360	if ((strncmp(buf, "-----END ", 9) != 0) || (strncmp(nameB->data, &(buf[9]), i) != 0) ||
361	    (strncmp(&(buf[9+i]), "-----\n", 6) != 0)) {
362		goto err;
363	}
364
365	EVP_DecodeInit(&ctx);
366	i = EVP_DecodeUpdate(&ctx, (unsigned char *)dataB->data, &bl,
367		(unsigned char *)dataB->data, bl);
368	if (i < 0) {
369		goto err;
370	}
371	i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
372	if (i < 0) {
373		goto err;
374	}
375	bl += k;
376
377	if (bl == 0) {
378		goto err;
379	}
380	*name = nameB->data;
381	*header = headerB->data;
382	*data = (unsigned char *)dataB->data;
383	*len = bl;
384	free(nameB);
385	free(headerB);
386	free(dataB);
387	return (1);
388
389err:
390	BUF_MEM_free(nameB);
391	BUF_MEM_free(headerB);
392	BUF_MEM_free(dataB);
393	return (0);
394}
395
396
397static int
398check_pem(const char *nm, const char *name)
399{
400	if (!strcmp(nm, name)) {
401		return (1);
402	}
403
404	if (!strcmp(nm, PEM_STRING_RSA) &&
405	    !strcmp(name, PEM_STRING_EVP_PKEY)) {
406		return (1);
407	}
408
409	if (!strcmp(nm, PEM_STRING_DSA) &&
410	    !strcmp(name, PEM_STRING_EVP_PKEY)) {
411		return (1);
412	}
413
414	return (0);
415}
416
417
418int
419PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
420    pem_password_cb *cb, void *u)
421{
422	EVP_CIPHER_INFO cipher;
423	char *nm = NULL, *header = NULL;
424	unsigned char *data = NULL;
425	long len;
426	int ret = 0;
427
428	for ( ; ; ) {
429		if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
430			return (0);
431		}
432		if (check_pem(nm, name)) {
433			break;
434		}
435		free(nm);
436		free(header);
437		free(data);
438	}
439	if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) {
440		goto err;
441	}
442	if (!PEM_do_header(&cipher, data, &len, cb, u)) {
443		goto err;
444	}
445
446	*pdata = data;
447	*plen = len;
448
449	if (pnm) {
450		*pnm = nm;
451	}
452
453	ret = 1;
454
455err:
456	if (!ret || !pnm) {
457		free(nm);
458	}
459	free(header);
460	if (!ret) {
461		free(data);
462	}
463
464	return (ret);
465}
466
467
468static EVP_PKEY *
469d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
470    long length)
471{
472	EVP_PKEY *ret;
473
474	if ((a == NULL) || (*a == NULL)) {
475		if ((ret = EVP_PKEY_new()) == NULL) {
476			return (NULL);
477		}
478	} else{
479		ret = *a;
480	}
481
482	ret->save_type = type;
483	ret->type = EVP_PKEY_type(type);
484	switch (ret->type) {
485	case EVP_PKEY_RSA:
486		if ((ret->pkey.rsa = d2i_RSAPrivateKey(NULL,
487		    (const unsigned char **)pp, length)) == NULL) {
488			goto err;
489		}
490		break;
491
492	case EVP_PKEY_DSA:
493		if ((ret->pkey.dsa = d2i_DSAPrivateKey(NULL,
494		    (const unsigned char **)pp, length)) == NULL) {
495			goto err;
496		}
497		break;
498
499	default:
500		goto err;
501		break;
502	}
503	if (NULL != a) {
504		(*a) = ret;
505	}
506	return (ret);
507
508err:
509	if ((NULL != ret) && ((NULL == a) || (ret != *a))) {
510		EVP_PKEY_free(ret);
511	}
512	return (NULL);
513}
514
515
516EVP_PKEY *
517PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
518{
519	char *nm = NULL;
520	const unsigned char *p = NULL;
521	unsigned char *data = NULL;
522	long len;
523	EVP_PKEY *ret = NULL;
524
525	if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) {
526		return (NULL);
527	}
528	p = data;
529
530	if (strcmp(nm, PEM_STRING_RSA) == 0) {
531		ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len);
532	} else if (strcmp(nm, PEM_STRING_DSA) == 0) {
533		ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len);
534	}
535
536	/*
537	 * if (NULL == ret)
538	 *      PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB);
539	 */
540
541	free(nm);
542	memset(data, 0, len);
543	free(data);
544
545	return (ret);
546}
547
548
549static const char *
550pkey_str(EVP_PKEY *x)
551{
552	switch (x->type) {
553	case EVP_PKEY_RSA:
554		return (PEM_STRING_RSA);
555
556	case EVP_PKEY_DSA:
557		return (PEM_STRING_DSA);
558
559	default:
560		return (NULL);
561	}
562}
563
564
565void
566PEM_proc_type(char *buf, int type)
567{
568	const char *str;
569
570	if (type == PEM_TYPE_ENCRYPTED) {
571		str = "ENCRYPTED";
572	} else if (type == PEM_TYPE_MIC_CLEAR) {
573		str = "MIC-CLEAR";
574	} else if (type == PEM_TYPE_MIC_ONLY) {
575		str = "MIC-ONLY";
576	} else{
577		str = "BAD-TYPE";
578	}
579
580	strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
581	strlcat(buf, str, PEM_BUFSIZE);
582	strlcat(buf, "\n", PEM_BUFSIZE);
583}
584
585
586void
587PEM_dek_info(char *buf, const char *type, int len, char *str)
588{
589	static const unsigned char map[17] = "0123456789ABCDEF";
590	long i;
591	int j;
592
593	BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
594	BUF_strlcat(buf, type, PEM_BUFSIZE);
595	BUF_strlcat(buf, ",", PEM_BUFSIZE);
596	j = strlen(buf);
597	if (j + (len * 2) + 1 > PEM_BUFSIZE) {
598		return;
599	}
600	for (i = 0; i < len; i++) {
601		buf[j+i*2] = map[(str[i]>>4)&0x0f];
602		buf[j+i*2+1] = map[(str[i])&0x0f];
603	}
604	buf[j + i * 2] = '\n';
605	buf[j + i * 2 + 1] = '\0';
606}
607
608
609int
610i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
611{
612	if (a->type == EVP_PKEY_RSA) {
613		return (i2d_RSAPrivateKey(a->pkey.rsa, pp));
614	} else if (a->type == EVP_PKEY_DSA) {
615		return (i2d_DSAPrivateKey(a->pkey.dsa, pp));
616
617		return (-1);
618	}
619
620	return (-1);
621}
622
623
624int
625PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data,
626    long len)
627{
628	int nlen, n, i, j, outl;
629	unsigned char *buf = NULL;
630	EVP_ENCODE_CTX ctx;
631
632	/* int reason = ERR_R_BUF_LIB; */
633
634	EVP_EncodeInit(&ctx);
635	nlen = strlen(name);
636
637	if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
638	    (BIO_write(bp, name, nlen) != nlen) ||
639	    (BIO_write(bp, "-----\n", 6) != 6)) {
640		goto err;
641	}
642
643	i = strlen(header);
644	if (i > 0) {
645		if ((BIO_write(bp, header, i) != i) ||
646		    (BIO_write(bp, "\n", 1) != 1)) {
647			goto err;
648		}
649	}
650
651	buf = malloc(PEM_BUFSIZE*8);
652	if (NULL == buf) {
653		/* reason = ERR_R_MALLOC_FAILURE; */
654		goto err;
655	}
656
657	i = j = 0;
658	while (len > 0) {
659		n = (int)((len > (PEM_BUFSIZE*5)) ? (PEM_BUFSIZE*5) : len);
660		EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
661		if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) {
662			goto err;
663		}
664		i += outl;
665		len -= n;
666		j += n;
667	}
668	EVP_EncodeFinal(&ctx, buf, &outl);
669	if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) {
670		goto err;
671	}
672	memset(buf, 0, PEM_BUFSIZE * 8);
673	free(buf);
674	buf = NULL;
675	if ((BIO_write(bp, "-----END ", 9) != 9) ||
676	    (BIO_write(bp, name, nlen) != nlen) ||
677	    (BIO_write(bp, "-----\n", 6) != 6)) {
678		goto err;
679	}
680	return (i + outl);
681
682err:
683	if (buf) {
684		memset(buf, 0, PEM_BUFSIZE*8);
685		free(buf);
686	}
687	/* PEMerr(PEM_F_PEM_WRITE_BIO,reason); */
688	return (0);
689}
690
691
692int
693PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
694    unsigned char *kstr, int klen, pem_password_cb *callback, void *u)
695{
696#if 0
697	return (PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
698	       pkey_str(x), bp, (char *)x, enc, kstr, klen, cb, u));
699#endif
700	EVP_CIPHER_CTX ctx;
701	int dsize = 0, i, j, ret = 0;
702	unsigned char *p, *data = NULL;
703	const char *objstr = NULL;
704	const char *name = pkey_str(x);
705	char buf[PEM_BUFSIZE];
706	unsigned char key[EVP_MAX_KEY_LENGTH];
707	unsigned char iv[EVP_MAX_IV_LENGTH];
708
709	if (enc != NULL) {
710		objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
711
712		if (objstr == NULL) {
713			/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); */
714			goto err;
715		}
716	}
717
718	if ((dsize = i2d_PrivateKey(x, NULL)) < 0) {
719		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
720		dsize = 0;
721		goto err;
722	}
723	/* dzise + 8 bytes are needed */
724	/* actually it needs the cipher block size extra... */
725	data = (unsigned char *)malloc((unsigned int)dsize + 20);
726	if (data == NULL) {
727		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
728		goto err;
729	}
730	p = data;
731	i = i2d_PrivateKey(x, &p);
732
733	if (enc != NULL) {
734		if (kstr == NULL) {
735			if (callback == NULL) {
736				klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
737			} else{
738				klen = (*callback)(buf, PEM_BUFSIZE, 1, u);
739			}
740			if (klen <= 0) {
741				/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); */
742				goto err;
743			}
744			kstr = (unsigned char *)buf;
745		}
746		RAND_add(data, i, 0); /* put in the RSA key. */
747		/* assert(enc->iv_len <= (int)sizeof(iv)); */
748		if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) { /* Generate a salt */
749			goto err;
750		}
751
752		/* The 'iv' is used as the iv and as a salt.  It is
753		 * NOT taken from the BytesToKey function */
754		EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL);
755
756		if (kstr == (unsigned char *)buf) {
757			memset(buf, 0, PEM_BUFSIZE);
758		}
759
760		/* assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); */
761
762		buf[0] = '\0';
763		PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
764		PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
765		/* k=strlen(buf); */
766
767		EVP_CIPHER_CTX_init(&ctx);
768		EVP_CipherInit_ex(&ctx, enc, NULL, key, iv, 1);
769		EVP_CipherUpdate(&ctx, data, &j, data, i);
770		EVP_CipherFinal_ex(&ctx, &(data[j]), &i);
771		EVP_CIPHER_CTX_cleanup(&ctx);
772		i += j;
773		ret = 1;
774	} else {
775		ret = 1;
776		buf[0] = '\0';
777	}
778	i = PEM_write_bio(bp, name, buf, data, i);
779	if (i <= 0) {
780		ret = 0;
781	}
782err:
783	memset(key, 0, sizeof(key));
784	memset(iv, 0, sizeof(iv));
785	memset(&ctx, 0, sizeof(ctx));
786	memset(buf, 0, PEM_BUFSIZE);
787	if (data != NULL) {
788		memset(data, 0, dsize);
789		free(data);
790	}
791
792	return (ret);
793}
794
795
796int
797PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
798    unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
799{
800	EVP_PKEY *k;
801	int ret;
802
803	k = EVP_PKEY_new();
804	if (!k) {
805		return (0);
806	}
807	EVP_PKEY_set1_RSA(k, x);
808
809	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
810	EVP_PKEY_free(k);
811
812	return (ret);
813}
814
815
816int
817PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
818    unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
819{
820	EVP_PKEY *k;
821	int ret;
822
823	k = EVP_PKEY_new();
824	if (!k) {
825		return (0);
826	}
827	EVP_PKEY_set1_DSA(k, x);
828
829	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
830	EVP_PKEY_free(k);
831	return (ret);
832}
833
834
835RSA *
836PEM_read_RSAPublicKey(FILE *fp, RSA *rsa, pem_password_cb *cb, void *u)
837{
838	BIO *b;
839	RSA *ret;
840	const unsigned char *p = NULL;
841	unsigned char *data = NULL;
842	long len;
843
844	if ((b = BIO_new(BIO_s_file())) == NULL) {
845		/* PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB); */
846		return (0);
847	}
848	BIO_set_fp(b, fp, BIO_NOCLOSE);
849
850	/* ret = PEM_ASN1_read_bio(d2i, name, b, x, cd, u); */
851	if (!PEM_bytes_read_bio(&data, &len, NULL, PEM_STRING_RSA_PUBLIC, b, cb, u)) {
852		return (NULL);
853	}
854
855	ret = d2i_RSAPublicKey(&rsa, &p, len);
856#if 0
857	if (NULL == ret) {
858		PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
859	}
860#endif
861	free(data);
862	BIO_free(b);
863
864	return (ret);
865}
866
867
868int
869PEM_write_RSAPrivateKey(FILE *fp, RSA *rsa, const EVP_CIPHER *enc, unsigned char *kstr,
870    int klen, pem_password_cb *callback, void *u)
871{
872	BIO *b;
873	EVP_CIPHER_CTX ctx;
874	int dsize = 0, i, j, ret = 0;
875	unsigned char *p, *data = NULL;
876	const char *objstr = NULL;
877	char buf[PEM_BUFSIZE];
878	unsigned char key[EVP_MAX_KEY_LENGTH];
879	unsigned char iv[EVP_MAX_IV_LENGTH];
880
881	if ((b = BIO_new(BIO_s_file())) == NULL) {
882		/* PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); */
883		return (0);
884	}
885	BIO_set_fp(b, fp, BIO_NOCLOSE);
886
887	/*
888	 * ret = PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey, PEM_STRING_RSA, b, x,
889	 *  enc, kstr, klen, callback, u);
890	 */
891	if (enc != NULL) {
892		objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
893
894		if (objstr == NULL) {
895			/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); */
896			goto err;
897		}
898	}
899
900	if ((dsize = i2d_RSAPrivateKey(rsa, NULL)) < 0) {
901		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
902		dsize = 0;
903		goto err;
904	}
905
906	data = (unsigned char *)malloc((unsigned int)dsize+20);
907	if (data == NULL) {
908		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
909		goto err;
910	}
911	p = data;
912	i = i2d_RSAPrivateKey(rsa, &p);
913
914	if (enc != NULL) {
915		if (kstr == NULL) {
916			if (callback == NULL) {
917				klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
918			} else{
919				klen = (*callback)(buf, PEM_BUFSIZE, 1, u);
920			}
921			if (klen <= 0) {
922				/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); */
923				goto err;
924			}
925			kstr = (unsigned char *)buf;
926		}
927		RAND_add(data, i, 0); /* put in the RSA key. */
928		/* assert(enc->iv_len <= (int)sizeof(iv)); */
929		if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) { /* Generate a salt */
930			goto err;
931		}
932		EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL);
933
934		if (kstr == (unsigned char *)buf) {
935			memset(buf, 0, PEM_BUFSIZE);
936		}
937
938		/* assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); */
939		buf[0] = '\0';
940		PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
941		PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
942
943		EVP_CIPHER_CTX_init(&ctx);
944		EVP_CipherInit_ex(&ctx, enc, NULL, key, iv, 1);
945		EVP_CipherUpdate(&ctx, data, &j, data, i);
946		EVP_CipherFinal_ex(&ctx, &(data[j]), &i);
947		EVP_CIPHER_CTX_cleanup(&ctx);
948		i += j;
949		ret = 1;
950	} else {
951		ret = 1;
952		buf[0] = '\0';
953	}
954
955	i = PEM_write_bio(b, PEM_STRING_RSA, buf, data, i);
956	if (i <= 0) {
957		ret = 0;
958	}
959err:
960	memset(key, 0, sizeof(key));
961	memset(iv, 0, sizeof(iv));
962	memset(&ctx, 0, sizeof(ctx));
963	memset(buf, 0, PEM_BUFSIZE);
964
965	if (data != NULL) {
966		memset(data, 0, (unsigned int)dsize);
967		free(data);
968	}
969
970	return (ret);
971}
972
973
974int
975PEM_write_DSAPrivateKey(FILE *fp, DSA *dsa, const EVP_CIPHER *enc, unsigned char *kstr,
976    int klen, pem_password_cb *callback, void *u)
977{
978	BIO *b;
979	EVP_CIPHER_CTX ctx;
980	int dsize = 0, i, j, ret = 0;
981	unsigned char *p, *data = NULL;
982	const char *objstr = NULL;
983	char buf[PEM_BUFSIZE];
984	unsigned char key[EVP_MAX_KEY_LENGTH];
985	unsigned char iv[EVP_MAX_IV_LENGTH];
986
987	if ((b = BIO_new(BIO_s_file())) == NULL) {
988		/* PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); */
989		return (0);
990	}
991	BIO_set_fp(b, fp, BIO_NOCLOSE);
992#if 0
993	ret = PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey, PEM_STRING_DSA, b, x,
994		enc, kstr, klen, callback, u);
995#endif
996	if (enc != NULL) {
997		objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
998
999		if (objstr == NULL) {
1000			/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); */
1001			goto err;
1002		}
1003	}
1004
1005	if ((dsize = i2d_DSAPrivateKey(dsa, NULL)) < 0) {
1006		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
1007		dsize = 0;
1008		goto err;
1009	}
1010
1011	data = (unsigned char *)malloc((unsigned int)dsize+20);
1012	if (data == NULL) {
1013		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
1014		goto err;
1015	}
1016	p = data;
1017	i = i2d_DSAPrivateKey(dsa, &p);
1018
1019	if (enc != NULL) {
1020		if (kstr == NULL) {
1021			if (callback == NULL) {
1022				klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
1023			} else{
1024				klen = (*callback)(buf, PEM_BUFSIZE, 1, u);
1025			}
1026			if (klen <= 0) {
1027				/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); */
1028				goto err;
1029			}
1030			kstr = (unsigned char *)buf;
1031		}
1032		RAND_add(data, i, 0); /* put in the DSA key. */
1033		/* assert(enc->iv_len <= (int)sizeof(iv)); */
1034		if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) { /* Generate a salt */
1035			goto err;
1036		}
1037		EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL);
1038
1039		if (kstr == (unsigned char *)buf) {
1040			memset(buf, 0, PEM_BUFSIZE);
1041		}
1042
1043		/* assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); */
1044		buf[0] = '\0';
1045		PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
1046		PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
1047
1048		EVP_CIPHER_CTX_init(&ctx);
1049		EVP_CipherInit_ex(&ctx, enc, NULL, key, iv, 1);
1050		EVP_CipherUpdate(&ctx, data, &j, data, i);
1051		EVP_CipherFinal_ex(&ctx, &(data[j]), &i);
1052		EVP_CIPHER_CTX_cleanup(&ctx);
1053		i += j;
1054		ret = 1;
1055	} else {
1056		ret = 1;
1057		buf[0] = '\0';
1058	}
1059
1060	i = PEM_write_bio(b, PEM_STRING_DSA, buf, data, i);
1061	if (i <= 0) {
1062		ret = 0;
1063	}
1064err:
1065	memset(key, 0, sizeof(key));
1066	memset(iv, 0, sizeof(iv));
1067	memset(&ctx, 0, sizeof(ctx));
1068	memset(buf, 0, PEM_BUFSIZE);
1069
1070	if (data != NULL) {
1071		memset(data, 0, (unsigned int)dsize);
1072		free(data);
1073	}
1074
1075	return (ret);
1076}
1077
1078
1079int
1080PEM_write_RSAPublicKey(FILE *fp, RSA *rsa)
1081{
1082	BIO *b;
1083	int dsize = 0, i, ret = 0;
1084	unsigned char *p, *data = NULL;
1085	char buf[PEM_BUFSIZE];
1086
1087	if ((b = BIO_new(BIO_s_file())) == NULL) {
1088		/* PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); */
1089		return (0);
1090	}
1091	BIO_set_fp(b, fp, BIO_NOCLOSE);
1092
1093	if ((dsize = i2d_RSAPrivateKey(rsa, NULL)) < 0) {
1094		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
1095		dsize = 0;
1096		goto err;
1097	}
1098	/* dzise + 8 bytes are needed */
1099	/* actually it needs the cipher block size extra... */
1100	data = (unsigned char *)malloc((unsigned int)dsize + 20);
1101	if (data == NULL) {
1102		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
1103		goto err;
1104	}
1105	p = data;
1106	i = i2d_RSAPrivateKey(rsa, &p);
1107
1108	ret = 1;
1109	buf[0] = '\0';
1110	i = PEM_write_bio(b, PEM_STRING_RSA_PUBLIC, buf, data, i);
1111	if (i <= 0) {
1112		ret = 0;
1113	}
1114err:
1115	memset(buf, 0, PEM_BUFSIZE);
1116	if (data != NULL) {
1117		memset(data, 0, dsize);
1118		free(data);
1119	}
1120
1121	BIO_free(b);
1122	return (ret);
1123}
1124
1125
1126/* ------------------ */
1127#include <stdint.h>
1128#include <errno.h>
1129#include <rfc2459_asn1.h>
1130#include "ossl-common.h"
1131
1132static heim_octet_string null_entry_oid = { 2, "\x05\x00" };
1133
1134static unsigned rsaEncryption_oid_tree[] = { 1, 2, 840, 113549, 1, 1, 1 };
1135static const AlgorithmIdentifier _x509_rsaEncryption =
1136{
1137	{ 7, rsaEncryption_oid_tree }, &null_entry_oid
1138};
1139
1140static unsigned dsaEncryption_oid_tree[] = { 1, 2, 840, 10040, 4, 1 };
1141static const AlgorithmIdentifier _x509_dsaEncryption =
1142{
1143	{ 6, dsaEncryption_oid_tree }, &null_entry_oid
1144};
1145
1146static int
1147i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
1148{
1149	switch (a->type) {
1150	case EVP_PKEY_RSA:
1151		return (i2d_RSAPublicKey(a->pkey.rsa, pp));
1152
1153	case EVP_PKEY_DSA:
1154		return (i2d_DSAPublicKey(a->pkey.dsa, pp));
1155
1156	default:
1157		/* ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); */
1158		return (-1);
1159	}
1160}
1161
1162
1163static EVP_PKEY *
1164d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
1165{
1166	EVP_PKEY *ret;
1167
1168	if ((a == NULL) || (*a == NULL)) {
1169		/* ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB); */
1170		return (NULL);
1171	} else{
1172		ret = *a;
1173	}
1174
1175	ret->save_type = type;
1176	ret->type = EVP_PKEY_type(type);
1177	switch (ret->type) {
1178	case EVP_PKEY_RSA:
1179		if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL,
1180		    (const unsigned char **)pp, length)) == NULL) {
1181			/* ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB); */
1182			goto err;
1183		}
1184		break;
1185
1186	case EVP_PKEY_DSA:
1187		if ((ret->pkey.dsa = d2i_DSAPublicKey(&(ret->pkey.dsa),
1188		    (const unsigned char **)pp, length)) == NULL) {
1189			/* ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB); */
1190			goto err;
1191		}
1192		break;
1193
1194	default:
1195		/* ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); */
1196		goto err;
1197	}
1198	if (a != NULL) {
1199		(*a) = ret;
1200	}
1201	return (ret);
1202
1203err:
1204	if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
1205		EVP_PKEY_free(ret);
1206	}
1207
1208	return (NULL);
1209}
1210
1211
1212static void
1213X509_PUBKEY_free(SubjectPublicKeyInfo *pk)
1214{
1215	if (NULL == pk) {
1216		return;
1217	}
1218
1219	/*  algorithm */
1220	if (pk->algorithm.parameters != NULL) {
1221		/* free the parameter list */
1222		if (pk->algorithm.parameters->data) {
1223			memset(pk->algorithm.parameters->data, 0,
1224			    pk->algorithm.parameters->length);
1225			free(pk->algorithm.parameters->data);
1226		}
1227	}
1228
1229	/* subjectPublicKey */
1230	if (pk->subjectPublicKey.data != NULL) {
1231		memset(pk->subjectPublicKey.data, 0,
1232		    pk->subjectPublicKey.length);
1233		free(pk->subjectPublicKey.data);
1234	}
1235
1236	free(pk);
1237}
1238
1239
1240static int
1241X509_PUBKEY_set(SubjectPublicKeyInfo **x, EVP_PKEY *pkey)
1242{
1243	SubjectPublicKeyInfo *pk;
1244	unsigned char *s, *p = NULL;
1245	size_t i, len;
1246
1247	if (x == NULL) {
1248		return (0);
1249	}
1250
1251	pk = (SubjectPublicKeyInfo *)calloc(1, sizeof(*pk));
1252	if (NULL == pk) {
1253		/* X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); */
1254		return (0);
1255	}
1256
1257	switch (pkey->type) {
1258	case EVP_PKEY_RSA:
1259		pk->algorithm = _x509_rsaEncryption;
1260		break;
1261
1262	case EVP_PKEY_DSA:
1263		pk->algorithm = _x509_dsaEncryption;
1264		break;
1265
1266	default:
1267		return (0);
1268	}
1269
1270
1271	/* Set the parameter list */
1272	if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA)) {
1273		heim_any *params;
1274
1275		params = (heim_any *)calloc(1, sizeof(*params));
1276		if (NULL == params) {
1277			/* X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); */
1278			free(pk);
1279			return (0);
1280		}
1281		p = (unsigned char *)calloc(1, 2);
1282		if (NULL == p) {
1283			free(params);
1284			free(pk);
1285			return (0);
1286		}
1287		p[0] = 0x05;
1288		p[1] = 0x00;               /* ASN1_NULL */
1289
1290		params->length = 2;
1291		params->data = p;
1292
1293		pk->algorithm.parameters = params;
1294	} else if (pkey->type == EVP_PKEY_DSA) {
1295		DSA *dsa;
1296		int ret = 0;
1297		DSAParams dsaparams;
1298		heim_any *params;
1299
1300		dsa = pkey->pkey.dsa;
1301		dsa->write_params = 0;
1302
1303		ret = _cs_BN_to_integer(dsa->p, &dsaparams.p);
1304		ret |= _cs_BN_to_integer(dsa->q, &dsaparams.q);
1305		ret |= _cs_BN_to_integer(dsa->g, &dsaparams.g);
1306		if (ret) {
1307			free_DSAParams(&dsaparams);
1308			return (0);
1309		}
1310
1311		i = length_DSAParams(&dsaparams);
1312
1313		if ((p = (unsigned char *)malloc(i)) != NULL) {
1314			/* X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); */
1315			free_DSAParams(&dsaparams);
1316			return (0);
1317		}
1318
1319		ASN1_MALLOC_ENCODE(DSAParams, p, len, &dsaparams, &i, ret);
1320		free_DSAParams(&dsaparams);
1321		if (ret) {
1322			return (0);
1323		}
1324
1325		params = (heim_any *)calloc(1, sizeof(*params));
1326		if (NULL == params) {
1327			/* X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); */
1328			return (0);
1329		}
1330
1331		params->length = i;
1332		params->data = p;
1333
1334		pk->algorithm.parameters = params;
1335	} else {
1336		/* X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); */
1337		goto err;
1338	}
1339
1340	if ((i = i2d_PublicKey(pkey, NULL)) <= 0) {
1341		goto err;
1342	}
1343	if ((s = (unsigned char *)malloc(i+1)) == NULL) {
1344		/* X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); */
1345		goto err;
1346	}
1347	p = s;
1348	i2d_PublicKey(pkey, &p);
1349
1350
1351	pk->subjectPublicKey.data = s;
1352	pk->subjectPublicKey.length = i;
1353
1354	if (*x != NULL) {
1355		X509_PUBKEY_free(*x);
1356	}
1357
1358	*x = pk;
1359
1360	return (1);
1361
1362err:
1363	if (pk != NULL) {
1364		X509_PUBKEY_free(pk);
1365	}
1366	return (0);
1367}
1368
1369
1370static int
1371obj2type(AlgorithmIdentifier *a)
1372{
1373	switch (a->algorithm.length) {
1374	case 6:
1375		if (!memcmp(a->algorithm.components, dsaEncryption_oid_tree, 6)) {
1376			return (NID_dsa);
1377		} else{
1378			return (NID_undef);
1379		}
1380
1381	case 7:
1382		if (!memcmp(a->algorithm.components, rsaEncryption_oid_tree, 7)) {
1383			return (NID_rsaEncryption);
1384		} else{
1385			return (NID_undef);
1386		}
1387
1388	default:
1389		return (NID_undef);
1390	}
1391}
1392
1393
1394static DSA *
1395d2i_DSAParams(DSA **dsa, const unsigned char **pp, long len)
1396{
1397	DSAParams data;
1398	DSA *k = NULL;
1399	size_t size;
1400	int ret;
1401
1402	if (dsa != NULL) {
1403		k = *dsa;
1404	}
1405
1406	ret = decode_DSAParams(*pp, len, &data, &size);
1407	if (ret) {
1408		return (NULL);
1409	}
1410
1411	*pp += size;
1412
1413	if (k == NULL) {
1414		k = DSA_new();
1415		if (k == NULL) {
1416			free_DSAParams(&data);
1417			return (NULL);
1418		}
1419	}
1420
1421	k->p = _cs_integer_to_BN(&data.p, NULL);
1422	k->q = _cs_integer_to_BN(&data.q, NULL);
1423	k->g = _cs_integer_to_BN(&data.g, NULL);
1424
1425	if ((k->p == NULL) || (k->q == NULL) || (k->g == NULL)) {
1426		DSA_free(k);
1427		return (NULL);
1428	}
1429
1430	if (dsa != NULL) {
1431		*dsa = k;
1432	}
1433
1434	return (k);
1435}
1436
1437
1438static EVP_PKEY *
1439X509_PUBKEY_get(SubjectPublicKeyInfo *key)
1440{
1441	EVP_PKEY *ret = NULL;
1442	long j;
1443	int type;
1444	const unsigned char *p;
1445	const unsigned char *cp;
1446	AlgorithmIdentifier *a;
1447
1448	if (key == NULL) {
1449		goto err;
1450	}
1451
1452	if (key->subjectPublicKey.data == NULL) {
1453		goto err;
1454	}
1455
1456	type = obj2type(&key->algorithm);
1457	if ((ret = EVP_PKEY_new()) == NULL) {
1458		/* X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); */
1459		goto err;
1460	}
1461	ret->type = EVP_PKEY_type(type);
1462
1463	/* the parameters must be extracted before the public key (ECDSA!) */
1464	a = &key->algorithm;
1465
1466	if (ret->type == EVP_PKEY_DSA) {
1467		if (a->parameters) {
1468			if ((ret->pkey.dsa = DSA_new()) == NULL) {
1469				/* X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); */
1470				goto err;
1471			}
1472			ret->pkey.dsa->write_params = 0;
1473			cp = p = a->parameters->data;
1474			j = a->parameters->length;
1475			if (!d2i_DSAParams(&ret->pkey.dsa, &cp, (long)j)) {
1476				goto err;
1477			}
1478		}
1479		ret->save_parameters = 1;
1480	}
1481
1482	p = key->subjectPublicKey.data;
1483	j = key->subjectPublicKey.length;
1484	if (!d2i_PublicKey(type, &ret, &p, (long)j)) {
1485		/* X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); */
1486		goto err;
1487	}
1488
1489	/* key->pkey = ret; */
1490
1491	/* XXX atomic op:  CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); */
1492	ret->references++;
1493
1494	return (ret);
1495
1496err:
1497	if (ret != NULL) {
1498		EVP_PKEY_free(ret);
1499	}
1500	return (NULL);
1501}
1502
1503
1504static EVP_PKEY *
1505d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
1506{
1507	SubjectPublicKeyInfo xpk;
1508	EVP_PKEY *pktmp;
1509	size_t size;
1510	int ret;
1511
1512	ret = decode_SubjectPublicKeyInfo(*pp, length, &xpk, &size);
1513	if (ret) {
1514		return (NULL);
1515	}
1516	pktmp = X509_PUBKEY_get(&xpk);
1517	/* X509_PUBKEY_free(xpk); */
1518	free_SubjectPublicKeyInfo(&xpk);
1519	if (!pktmp) {
1520		return (NULL);
1521	}
1522
1523	if (a) {
1524		EVP_PKEY_free(*a);
1525		*a = pktmp;
1526	}
1527	return (pktmp);
1528}
1529
1530
1531static int
1532i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
1533{
1534	SubjectPublicKeyInfo *xpk = NULL;
1535	void *p;
1536	size_t len, size;
1537	int ret;
1538
1539	if (!a) {
1540		return (0);
1541	}
1542	if (!X509_PUBKEY_set(&xpk, a)) {
1543		return (0);
1544	}
1545
1546	/* ret = i2d_X509_PUBKEY(xpk, pp); */
1547	size = length_SubjectPublicKeyInfo(xpk);
1548	if (pp == NULL) {
1549		X509_PUBKEY_free(xpk);
1550		return (size);
1551	}
1552
1553	ASN1_MALLOC_ENCODE(SubjectPublicKeyInfo, p, len, xpk, &size, ret);
1554	X509_PUBKEY_free(xpk);
1555	memcpy(*pp, p, size);
1556	free(p);
1557
1558	return (ret);
1559}
1560
1561
1562/* The following are equivalents but which return RSA and DSA
1563 * keys
1564 */
1565static RSA *
1566d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
1567{
1568	EVP_PKEY *pkey;
1569	RSA *key;
1570	const unsigned char *q;
1571
1572	q = *pp;
1573	pkey = d2i_PUBKEY(NULL, &q, length);
1574	if (!pkey) {
1575		return (NULL);
1576	}
1577	key = EVP_PKEY_get1_RSA(pkey);
1578	EVP_PKEY_free(pkey);
1579	if (!key) {
1580		return (NULL);
1581	}
1582	*pp = q;
1583	if (a) {
1584		RSA_free(*a);
1585		*a = key;
1586	}
1587	return (key);
1588}
1589
1590
1591static int
1592i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
1593{
1594	EVP_PKEY *pktmp;
1595	int ret;
1596
1597	if (!a) {
1598		return (0);
1599	}
1600	pktmp = EVP_PKEY_new();
1601	if (!pktmp) {
1602		/* ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); */
1603		return (0);
1604	}
1605	EVP_PKEY_set1_RSA(pktmp, a);
1606	ret = i2d_PUBKEY(pktmp, pp);
1607	EVP_PKEY_free(pktmp);
1608	return (ret);
1609}
1610
1611
1612static DSA *
1613d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
1614{
1615	EVP_PKEY *pkey;
1616	DSA *key;
1617	const unsigned char *q;
1618
1619	q = *pp;
1620	pkey = d2i_PUBKEY(NULL, &q, length);
1621	if (!pkey) {
1622		return (NULL);
1623	}
1624	key = EVP_PKEY_get1_DSA(pkey);
1625	EVP_PKEY_free(pkey);
1626	if (!key) {
1627		return (NULL);
1628	}
1629	*pp = q;
1630	if (a) {
1631		DSA_free(*a);
1632		*a = key;
1633	}
1634	return (key);
1635}
1636
1637
1638static int
1639i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
1640{
1641	EVP_PKEY *pktmp;
1642	int ret;
1643
1644	if (!a) {
1645		return (0);
1646	}
1647	pktmp = EVP_PKEY_new();
1648	if (!pktmp) {
1649		/* ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); */
1650		return (0);
1651	}
1652	EVP_PKEY_set1_DSA(pktmp, a);
1653	ret = i2d_PUBKEY(pktmp, pp);
1654	EVP_PKEY_free(pktmp);
1655	return (ret);
1656}
1657
1658
1659int
1660PEM_write_RSA_PUBKEY(FILE *fp, RSA *rsa)
1661{
1662	/*
1663	 * return PEM_ASN1_write((const RSA *)i2d_RSA_PUBKEY, PEM_STRING_PUBLIC, fp,
1664	 *  (const RSA *) x, NULL, NULL, 0, NULL, NULL);
1665	 */
1666
1667	BIO *bp = NULL;
1668	const char *name = PEM_STRING_PUBLIC;
1669	int dsize = 0, ret = 0;
1670	unsigned char *p, *data = NULL;
1671	char buf[PEM_BUFSIZE];
1672	int i;
1673
1674	if ((bp = BIO_new(BIO_s_file())) == NULL) {
1675		/* PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); */
1676		return (0);
1677	}
1678	BIO_set_fp(bp, fp, BIO_NOCLOSE);
1679
1680
1681	if ((dsize = i2d_RSA_PUBKEY(rsa, NULL)) < 0) {
1682		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
1683		dsize = 0;
1684		goto err;
1685	}
1686	/* dzise + 8 bytes are needed */
1687	/* actually it needs the cipher block size extra... */
1688	data = (unsigned char *)malloc((unsigned int)dsize + 20);
1689	if (NULL == data) {
1690		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
1691		goto err;
1692	}
1693	p = data;
1694	i = i2d_RSA_PUBKEY(rsa, &p);
1695
1696	ret = 1;
1697	buf[0] = '\0';
1698
1699	i = PEM_write_bio(bp, name, buf, data, i);
1700	if (i <= 0) {
1701		ret = 0;
1702	}
1703
1704err:
1705	if (bp != NULL) {
1706		BIO_free(bp);
1707	}
1708	if (data != NULL) {
1709		memset(data, 0, (unsigned int)dsize);
1710		free(data);
1711	}
1712	return (ret);
1713}
1714
1715
1716int
1717PEM_write_DSA_PUBKEY(FILE *fp, DSA *dsa)
1718{
1719	/*
1720	 * return PEM_ASN1_write((const DSA *)i2d_DSA_PUBKEY, PEM_STRING_PUBLIC, fp,
1721	 *  (const DSA *) x, NULL, NULL, 0, NULL, NULL);
1722	 */
1723
1724	BIO *bp = NULL;
1725	const char *name = PEM_STRING_PUBLIC;
1726	int dsize = 0, ret = 0;
1727	unsigned char *p, *data = NULL;
1728	char buf[PEM_BUFSIZE];
1729	int i;
1730
1731	if ((bp = BIO_new(BIO_s_file())) == NULL) {
1732		/* PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); */
1733		return (0);
1734	}
1735	BIO_set_fp(bp, fp, BIO_NOCLOSE);
1736
1737
1738	if ((dsize = i2d_DSA_PUBKEY(dsa, NULL)) < 0) {
1739		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); */
1740		dsize = 0;
1741		goto err;
1742	}
1743	/* dzise + 8 bytes are needed */
1744	/* actually it needs the cipher block size extra... */
1745	data = (unsigned char *)malloc((unsigned int)dsize + 20);
1746	if (NULL == data) {
1747		/* PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); */
1748		goto err;
1749	}
1750	p = data;
1751	i = i2d_DSA_PUBKEY(dsa, &p);
1752
1753	ret = 1;
1754	buf[0] = '\0';
1755
1756	i = PEM_write_bio(bp, name, buf, data, i);
1757	if (i <= 0) {
1758		ret = 0;
1759	}
1760
1761err:
1762	if (bp != NULL) {
1763		BIO_free(bp);
1764	}
1765	if (data != NULL) {
1766		memset(data, 0, (unsigned int)dsize);
1767		free(data);
1768	}
1769	return (ret);
1770}
1771
1772
1773EVP_PKEY *
1774PEM_read_PUBKEY(FILE *fp, EVP_PKEY **pkey, pem_password_cb *cb, void *u)
1775{
1776	/*
1777	 * return (EVP_PKEY *)PEM_ASN1_read(d2i_PUBKEY,
1778	 *  PEM_STRING_PUBLIC, fp, CHECKED_PPTR_OF(type, x), cb, u);
1779	 */
1780
1781	BIO *b;
1782	EVP_PKEY *ret;
1783	const unsigned char *p = NULL;
1784	unsigned char *data = NULL;
1785	long len;
1786
1787	if ((b = BIO_new(BIO_s_file())) == NULL) {
1788		/* PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB); */
1789		return (0);
1790	}
1791	BIO_set_fp(b, fp, BIO_NOCLOSE);
1792
1793	/* ret = PEM_ASN1_read_bio(d2i, name, b, x, cd, u); */
1794	if (!PEM_bytes_read_bio(&data, &len, NULL, PEM_STRING_RSA_PUBLIC, b, cb, u)) {
1795		return (NULL);
1796	}
1797
1798	ret = d2i_PUBKEY(pkey, &p, len);
1799#if 0
1800	if (NULL == ret) {
1801		PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
1802	}
1803#endif
1804	free(data);
1805	BIO_free(b);
1806
1807	return (ret);
1808}
1809