summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pem/pem_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pem/pem_info.c')
-rw-r--r--src/lib/libcrypto/pem/pem_info.c177
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
80STACK_OF(X509_INFO) * 80X509_PKEY *
81PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, 81X509_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
93void
94X509_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
103X509_INFO *
104X509_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}
116LCRYPTO_ALIAS(X509_INFO_new);
117
118void
119X509_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}
96LCRYPTO_ALIAS(PEM_X509_INFO_read); 134LCRYPTO_ALIAS(X509_INFO_free);
97 135
98STACK_OF(X509_INFO) * 136STACK_OF(X509_INFO) *
99PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, 137PEM_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}
292LCRYPTO_ALIAS(PEM_X509_INFO_read_bio); 330LCRYPTO_ALIAS(PEM_X509_INFO_read_bio);
293
294
295/* A TJH addition */
296int
297PEM_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
382err:
383 explicit_bzero((char *)&ctx, sizeof(ctx));
384 explicit_bzero(buf, PEM_BUFSIZE);
385 return (ret);
386}
387LCRYPTO_ALIAS(PEM_X509_INFO_write_bio);