1 /* 2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <string.h> 12 #include "apps.h" 13 #include "progs.h" 14 #include <openssl/pem.h> 15 #include <openssl/err.h> 16 17 typedef enum OPTION_choice { 18 OPT_COMMON, 19 OPT_TOSEQ, 20 OPT_IN, 21 OPT_OUT, 22 OPT_PROV_ENUM 23 } OPTION_CHOICE; 24 25 const OPTIONS nseq_options[] = { 26 OPT_SECTION("General"), 27 { "help", OPT_HELP, '-', "Display this summary" }, 28 29 OPT_SECTION("Input"), 30 { "in", OPT_IN, '<', "Input file" }, 31 32 OPT_SECTION("Output"), 33 { "toseq", OPT_TOSEQ, '-', "Output NS Sequence file" }, 34 { "out", OPT_OUT, '>', "Output file" }, 35 36 OPT_PROV_OPTIONS, 37 { NULL } 38 }; 39 40 int nseq_main(int argc, char **argv) 41 { 42 BIO *in = NULL, *out = NULL; 43 X509 *x509 = NULL; 44 NETSCAPE_CERT_SEQUENCE *seq = NULL; 45 OPTION_CHOICE o; 46 int toseq = 0, ret = 1, i; 47 char *infile = NULL, *outfile = NULL, *prog; 48 49 prog = opt_init(argc, argv, nseq_options); 50 while ((o = opt_next()) != OPT_EOF) { 51 switch (o) { 52 case OPT_EOF: 53 case OPT_ERR: 54 opthelp: 55 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 56 goto end; 57 case OPT_HELP: 58 ret = 0; 59 opt_help(nseq_options); 60 goto end; 61 case OPT_TOSEQ: 62 toseq = 1; 63 break; 64 case OPT_IN: 65 infile = opt_arg(); 66 break; 67 case OPT_OUT: 68 outfile = opt_arg(); 69 break; 70 case OPT_PROV_CASES: 71 if (!opt_provider(o)) 72 goto end; 73 break; 74 } 75 } 76 77 /* No extra arguments. */ 78 if (!opt_check_rest_arg(NULL)) 79 goto opthelp; 80 81 in = bio_open_default(infile, 'r', FORMAT_PEM); 82 if (in == NULL) 83 goto end; 84 out = bio_open_default(outfile, 'w', FORMAT_PEM); 85 if (out == NULL) 86 goto end; 87 88 if (toseq) { 89 seq = NETSCAPE_CERT_SEQUENCE_new(); 90 if (seq == NULL) 91 goto end; 92 seq->certs = sk_X509_new_null(); 93 if (seq->certs == NULL) 94 goto end; 95 while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 96 if (!sk_X509_push(seq->certs, x509)) 97 goto end; 98 } 99 100 if (!sk_X509_num(seq->certs)) { 101 BIO_printf(bio_err, "%s: Error reading certs file %s\n", 102 prog, infile); 103 ERR_print_errors(bio_err); 104 goto end; 105 } 106 PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); 107 ret = 0; 108 goto end; 109 } 110 111 seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL); 112 if (seq == NULL) { 113 BIO_printf(bio_err, "%s: Error reading sequence file %s\n", 114 prog, infile); 115 ERR_print_errors(bio_err); 116 goto end; 117 } 118 119 for (i = 0; i < sk_X509_num(seq->certs); i++) { 120 x509 = sk_X509_value(seq->certs, i); 121 dump_cert_text(out, x509); 122 PEM_write_bio_X509(out, x509); 123 } 124 ret = 0; 125 end: 126 BIO_free(in); 127 BIO_free_all(out); 128 NETSCAPE_CERT_SEQUENCE_free(seq); 129 130 return ret; 131 } 132