diff options
Diffstat (limited to 'src/lib/libcrypto/pem/pem_info.c')
-rw-r--r-- | src/lib/libcrypto/pem/pem_info.c | 177 |
1 files changed, 60 insertions, 117 deletions
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c index b979c79b33..26061f6f08 100644 --- a/src/lib/libcrypto/pem/pem_info.c +++ b/src/lib/libcrypto/pem/pem_info.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: pem_info.c,v 1.27 2023/07/07 13:40:44 beck Exp $ */ | 1 | /* $OpenBSD: pem_info.c,v 1.33 2025/07/16 15:59:26 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -57,43 +57,81 @@ | |||
57 | */ | 57 | */ |
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include <stdlib.h> | ||
60 | #include <string.h> | 61 | #include <string.h> |
61 | 62 | ||
62 | #include <openssl/opensslconf.h> | 63 | #include <openssl/opensslconf.h> |
63 | 64 | ||
64 | #include <openssl/buffer.h> | 65 | #include <openssl/asn1.h> |
66 | #include <openssl/bio.h> | ||
67 | #include <openssl/crypto.h> | ||
68 | #include <openssl/dsa.h> | ||
69 | #include <openssl/ec.h> | ||
65 | #include <openssl/err.h> | 70 | #include <openssl/err.h> |
66 | #include <openssl/evp.h> | 71 | #include <openssl/evp.h> |
67 | #include <openssl/objects.h> | 72 | #include <openssl/objects.h> |
68 | #include <openssl/pem.h> | 73 | #include <openssl/pem.h> |
69 | #include <openssl/x509.h> | ||
70 | |||
71 | #ifndef OPENSSL_NO_DSA | ||
72 | #include <openssl/dsa.h> | ||
73 | #endif | ||
74 | #ifndef OPENSSL_NO_RSA | ||
75 | #include <openssl/rsa.h> | 74 | #include <openssl/rsa.h> |
76 | #endif | 75 | #include <openssl/x509.h> |
77 | 76 | ||
77 | #include "err_local.h" | ||
78 | #include "evp_local.h" | 78 | #include "evp_local.h" |
79 | 79 | ||
80 | STACK_OF(X509_INFO) * | 80 | X509_PKEY * |
81 | PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, | 81 | X509_PKEY_new(void) |
82 | void *u) | 82 | { |
83 | X509_PKEY *x_pkey; | ||
84 | |||
85 | if ((x_pkey = calloc(1, sizeof(*x_pkey))) == NULL) { | ||
86 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | return x_pkey; | ||
91 | } | ||
92 | |||
93 | void | ||
94 | X509_PKEY_free(X509_PKEY *x_pkey) | ||
95 | { | ||
96 | if (x_pkey == NULL) | ||
97 | return; | ||
98 | |||
99 | EVP_PKEY_free(x_pkey->dec_pkey); | ||
100 | free(x_pkey); | ||
101 | } | ||
102 | |||
103 | X509_INFO * | ||
104 | X509_INFO_new(void) | ||
83 | { | 105 | { |
84 | BIO *b; | 106 | X509_INFO *ret; |
85 | STACK_OF(X509_INFO) *ret; | ||
86 | 107 | ||
87 | if ((b = BIO_new(BIO_s_file())) == NULL) { | 108 | if ((ret = calloc(1, sizeof(X509_INFO))) == NULL) { |
88 | PEMerror(ERR_R_BUF_LIB); | 109 | ASN1error(ERR_R_MALLOC_FAILURE); |
89 | return (0); | 110 | return NULL; |
90 | } | 111 | } |
91 | BIO_set_fp(b, fp, BIO_NOCLOSE); | 112 | ret->references = 1; |
92 | ret = PEM_X509_INFO_read_bio(b, sk, cb, u); | 113 | |
93 | BIO_free(b); | 114 | return ret; |
94 | return (ret); | 115 | } |
116 | LCRYPTO_ALIAS(X509_INFO_new); | ||
117 | |||
118 | void | ||
119 | X509_INFO_free(X509_INFO *x) | ||
120 | { | ||
121 | if (x == NULL) | ||
122 | return; | ||
123 | |||
124 | if (CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO) > 0) | ||
125 | return; | ||
126 | |||
127 | X509_free(x->x509); | ||
128 | X509_CRL_free(x->crl); | ||
129 | X509_PKEY_free(x->x_pkey); | ||
130 | free(x->enc_data); | ||
131 | |||
132 | free(x); | ||
95 | } | 133 | } |
96 | LCRYPTO_ALIAS(PEM_X509_INFO_read); | 134 | LCRYPTO_ALIAS(X509_INFO_free); |
97 | 135 | ||
98 | STACK_OF(X509_INFO) * | 136 | STACK_OF(X509_INFO) * |
99 | PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, | 137 | PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, |
@@ -290,98 +328,3 @@ err: | |||
290 | return ret; | 328 | return ret; |
291 | } | 329 | } |
292 | LCRYPTO_ALIAS(PEM_X509_INFO_read_bio); | 330 | LCRYPTO_ALIAS(PEM_X509_INFO_read_bio); |
293 | |||
294 | |||
295 | /* A TJH addition */ | ||
296 | int | ||
297 | PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, | ||
298 | unsigned char *kstr, int klen, pem_password_cb *cb, void *u) | ||
299 | { | ||
300 | EVP_CIPHER_CTX ctx; | ||
301 | int i, ret = 0; | ||
302 | unsigned char *data = NULL; | ||
303 | const char *objstr = NULL; | ||
304 | char buf[PEM_BUFSIZE]; | ||
305 | unsigned char *iv = NULL; | ||
306 | |||
307 | if (enc != NULL) { | ||
308 | objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); | ||
309 | if (objstr == NULL) { | ||
310 | PEMerror(PEM_R_UNSUPPORTED_CIPHER); | ||
311 | goto err; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /* now for the fun part ... if we have a private key then | ||
316 | * we have to be able to handle a not-yet-decrypted key | ||
317 | * being written out correctly ... if it is decrypted or | ||
318 | * it is non-encrypted then we use the base code | ||
319 | */ | ||
320 | if (xi->x_pkey != NULL) { | ||
321 | if ((xi->enc_data != NULL) && (xi->enc_len > 0) ) { | ||
322 | if (enc == NULL) { | ||
323 | PEMerror(PEM_R_CIPHER_IS_NULL); | ||
324 | goto err; | ||
325 | } | ||
326 | |||
327 | /* copy from weirdo names into more normal things */ | ||
328 | iv = xi->enc_cipher.iv; | ||
329 | data = (unsigned char *)xi->enc_data; | ||
330 | i = xi->enc_len; | ||
331 | |||
332 | /* we take the encryption data from the | ||
333 | * internal stuff rather than what the | ||
334 | * user has passed us ... as we have to | ||
335 | * match exactly for some strange reason | ||
336 | */ | ||
337 | objstr = OBJ_nid2sn( | ||
338 | EVP_CIPHER_nid(xi->enc_cipher.cipher)); | ||
339 | if (objstr == NULL) { | ||
340 | PEMerror(PEM_R_UNSUPPORTED_CIPHER); | ||
341 | goto err; | ||
342 | } | ||
343 | |||
344 | /* create the right magic header stuff */ | ||
345 | if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 > | ||
346 | sizeof buf) { | ||
347 | PEMerror(ASN1_R_BUFFER_TOO_SMALL); | ||
348 | goto err; | ||
349 | } | ||
350 | buf[0] = '\0'; | ||
351 | PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); | ||
352 | PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); | ||
353 | |||
354 | /* use the normal code to write things out */ | ||
355 | i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); | ||
356 | if (i <= 0) | ||
357 | goto err; | ||
358 | } else { | ||
359 | /* Add DSA/DH */ | ||
360 | #ifndef OPENSSL_NO_RSA | ||
361 | /* normal optionally encrypted stuff */ | ||
362 | if (PEM_write_bio_RSAPrivateKey(bp, | ||
363 | xi->x_pkey->dec_pkey->pkey.rsa, | ||
364 | enc, kstr, klen, cb, u) <= 0) | ||
365 | goto err; | ||
366 | #endif | ||
367 | } | ||
368 | } | ||
369 | |||
370 | /* if we have a certificate then write it out now */ | ||
371 | if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) | ||
372 | goto err; | ||
373 | |||
374 | /* we are ignoring anything else that is loaded into the X509_INFO | ||
375 | * structure for the moment ... as I don't need it so I'm not | ||
376 | * coding it here and Eric can do it when this makes it into the | ||
377 | * base library --tjh | ||
378 | */ | ||
379 | |||
380 | ret = 1; | ||
381 | |||
382 | err: | ||
383 | explicit_bzero((char *)&ctx, sizeof(ctx)); | ||
384 | explicit_bzero(buf, PEM_BUFSIZE); | ||
385 | return (ret); | ||
386 | } | ||
387 | LCRYPTO_ALIAS(PEM_X509_INFO_write_bio); | ||