summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pem/pem_info.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libcrypto/pem/pem_info.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/pem/pem_info.c')
-rw-r--r--src/lib/libcrypto/pem/pem_info.c365
1 files changed, 365 insertions, 0 deletions
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c
new file mode 100644
index 0000000000..4b69833b62
--- /dev/null
+++ b/src/lib/libcrypto/pem/pem_info.c
@@ -0,0 +1,365 @@
1/* crypto/pem/pem_info.c */
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 "cryptlib.h"
61#include "buffer.h"
62#include "objects.h"
63#include "evp.h"
64#include "x509.h"
65#include "pem.h"
66
67#ifndef NO_FP_API
68STACK *PEM_X509_INFO_read(fp,sk,cb)
69FILE *fp;
70STACK *sk;
71int (*cb)();
72 {
73 BIO *b;
74 STACK *ret;
75
76 if ((b=BIO_new(BIO_s_file())) == NULL)
77 {
78 PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB);
79 return(0);
80 }
81 BIO_set_fp(b,fp,BIO_NOCLOSE);
82 ret=PEM_X509_INFO_read_bio(b,sk,cb);
83 BIO_free(b);
84 return(ret);
85 }
86#endif
87
88STACK *PEM_X509_INFO_read_bio(bp,sk,cb)
89BIO *bp;
90STACK *sk;
91int (*cb)();
92 {
93 X509_INFO *xi=NULL;
94 char *name=NULL,*header=NULL,**pp;
95 unsigned char *data=NULL,*p;
96 long len,error=0;
97 int ok=0;
98 STACK *ret=NULL;
99 unsigned int i,raw;
100 char *(*d2i)();
101
102 if (sk == NULL)
103 {
104 if ((ret=sk_new_null()) == NULL)
105 {
106 PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE);
107 goto err;
108 }
109 }
110 else
111 ret=sk;
112
113 if ((xi=X509_INFO_new()) == NULL) goto err;
114 for (;;)
115 {
116 raw=0;
117 i=PEM_read_bio(bp,&name,&header,&data,&len);
118 if (i == 0)
119 {
120 error=ERR_GET_REASON(ERR_peek_error());
121 if (error == PEM_R_NO_START_LINE)
122 {
123 ERR_clear_error();
124 break;
125 }
126 goto err;
127 }
128start:
129 if ( (strcmp(name,PEM_STRING_X509) == 0) ||
130 (strcmp(name,PEM_STRING_X509_OLD) == 0))
131 {
132 d2i=(char *(*)())d2i_X509;
133 if (xi->x509 != NULL)
134 {
135 if (!sk_push(ret,(char *)xi)) goto err;
136 if ((xi=X509_INFO_new()) == NULL) goto err;
137 goto start;
138 }
139 pp=(char **)&(xi->x509);
140 }
141 else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
142 {
143 d2i=(char *(*)())d2i_X509_CRL;
144 if (xi->crl != NULL)
145 {
146 if (!sk_push(ret,(char *)xi)) goto err;
147 if ((xi=X509_INFO_new()) == NULL) goto err;
148 goto start;
149 }
150 pp=(char **)&(xi->crl);
151 }
152 else
153#ifndef NO_RSA
154 if (strcmp(name,PEM_STRING_RSA) == 0)
155 {
156 d2i=(char *(*)())d2i_RSAPrivateKey;
157 if (xi->x_pkey != NULL)
158 {
159 if (!sk_push(ret,(char *)xi)) goto err;
160 if ((xi=X509_INFO_new()) == NULL) goto err;
161 goto start;
162 }
163
164 xi->enc_data=NULL;
165 xi->enc_len=0;
166
167 xi->x_pkey=X509_PKEY_new();
168 if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
169 goto err;
170 xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA;
171 pp=(char **)&(xi->x_pkey->dec_pkey->pkey.rsa);
172 if ((int)strlen(header) > 10) /* assume encrypted */
173 raw=1;
174 }
175 else
176#endif
177#ifndef NO_DSA
178 if (strcmp(name,PEM_STRING_DSA) == 0)
179 {
180 d2i=(char *(*)())d2i_DSAPrivateKey;
181 if (xi->x_pkey != NULL)
182 {
183 if (!sk_push(ret,(char *)xi)) goto err;
184 if ((xi=X509_INFO_new()) == NULL) goto err;
185 goto start;
186 }
187
188 xi->enc_data=NULL;
189 xi->enc_len=0;
190
191 xi->x_pkey=X509_PKEY_new();
192 if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
193 goto err;
194 xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA;
195 pp=(char **)&(xi->x_pkey->dec_pkey->pkey.dsa);
196 if ((int)strlen(header) > 10) /* assume encrypted */
197 raw=1;
198 }
199 else
200#endif
201 {
202 d2i=NULL;
203 pp=NULL;
204 }
205
206 if (d2i != NULL)
207 {
208 if (!raw)
209 {
210 EVP_CIPHER_INFO cipher;
211
212 if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
213 goto err;
214 if (!PEM_do_header(&cipher,data,&len,cb))
215 goto err;
216 p=data;
217 if (d2i(pp,&p,len) == NULL)
218 {
219 PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
220 goto err;
221 }
222 }
223 else
224 { /* encrypted RSA data */
225 if (!PEM_get_EVP_CIPHER_INFO(header,
226 &xi->enc_cipher)) goto err;
227 xi->enc_data=(char *)data;
228 xi->enc_len=(int)len;
229 data=NULL;
230 }
231 }
232 else {
233 /* unknown */
234 }
235 if (name != NULL) Free(name);
236 if (header != NULL) Free(header);
237 if (data != NULL) Free(data);
238 name=NULL;
239 header=NULL;
240 data=NULL;
241 }
242
243 /* if the last one hasn't been pushed yet and there is anything
244 * in it then add it to the stack ...
245 */
246 if ((xi->x509 != NULL) || (xi->crl != NULL) ||
247 (xi->x_pkey != NULL) || (xi->enc_data != NULL))
248 {
249 if (!sk_push(ret,(char *)xi)) goto err;
250 xi=NULL;
251 }
252 ok=1;
253err:
254 if (xi != NULL) X509_INFO_free(xi);
255 if (!ok)
256 {
257 for (i=0; ((int)i)<sk_num(ret); i++)
258 {
259 xi=(X509_INFO *)sk_value(ret,i);
260 X509_INFO_free(xi);
261 }
262 if (ret != sk) sk_free(ret);
263 ret=NULL;
264 }
265
266 if (name != NULL) Free(name);
267 if (header != NULL) Free(header);
268 if (data != NULL) Free(data);
269 return(ret);
270 }
271
272
273/* A TJH addition */
274int PEM_X509_INFO_write_bio(bp,xi,enc,kstr,klen,cb)
275BIO *bp;
276X509_INFO *xi;
277EVP_CIPHER *enc;
278unsigned char *kstr;
279int klen;
280int (*cb)();
281 {
282 EVP_CIPHER_CTX ctx;
283 int i,ret=0;
284 unsigned char *data=NULL;
285 char *objstr=NULL;
286#define PEM_BUFSIZE 1024
287 char buf[PEM_BUFSIZE];
288 unsigned char *iv=NULL;
289
290 if (enc != NULL)
291 {
292 objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
293 if (objstr == NULL)
294 {
295 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
296 goto err;
297 }
298 }
299
300 /* now for the fun part ... if we have a private key then
301 * we have to be able to handle a not-yet-decrypted key
302 * being written out correctly ... if it is decrypted or
303 * it is non-encrypted then we use the base code
304 */
305 if (xi->x_pkey!=NULL)
306 {
307 if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
308 {
309 /* copy from wierdo names into more normal things */
310 iv=xi->enc_cipher.iv;
311 data=(unsigned char *)xi->enc_data;
312 i=xi->enc_len;
313
314 /* we take the encryption data from the
315 * internal stuff rather than what the
316 * user has passed us ... as we have to
317 * match exactly for some strange reason
318 */
319 objstr=OBJ_nid2sn(
320 EVP_CIPHER_nid(xi->enc_cipher.cipher));
321 if (objstr == NULL)
322 {
323 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
324 goto err;
325 }
326
327 /* create the right magic header stuff */
328 buf[0]='\0';
329 PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
330 PEM_dek_info(buf,objstr,8,(char *)iv);
331
332 /* use the normal code to write things out */
333 i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
334 if (i <= 0) goto err;
335 }
336 else
337 {
338 /* Add DSA/DH */
339#ifndef NO_RSA
340 /* normal optionally encrypted stuff */
341 if (PEM_write_bio_RSAPrivateKey(bp,
342 xi->x_pkey->dec_pkey->pkey.rsa,
343 enc,kstr,klen,cb)<=0)
344 goto err;
345#endif
346 }
347 }
348
349 /* if we have a certificate then write it out now */
350 if ((xi->x509 != NULL) || (PEM_write_bio_X509(bp,xi->x509) <= 0))
351 goto err;
352
353 /* we are ignoring anything else that is loaded into the X509_INFO
354 * structure for the moment ... as I don't need it so I'm not
355 * coding it here and Eric can do it when this makes it into the
356 * base library --tjh
357 */
358
359 ret=1;
360
361err:
362 memset((char *)&ctx,0,sizeof(ctx));
363 memset(buf,0,PEM_BUFSIZE);
364 return(ret);
365 }