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, OPT_IN, OPT_OUT, 20 OPT_PROV_ENUM 21 } OPTION_CHOICE; 22 23 const OPTIONS nseq_options[] = { 24 OPT_SECTION("General"), 25 {"help", OPT_HELP, '-', "Display this summary"}, 26 27 OPT_SECTION("Input"), 28 {"in", OPT_IN, '<', "Input file"}, 29 30 OPT_SECTION("Output"), 31 {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"}, 32 {"out", OPT_OUT, '>', "Output file"}, 33 34 OPT_PROV_OPTIONS, 35 {NULL} 36 }; 37 38 int nseq_main(int argc, char **argv) 39 { 40 BIO *in = NULL, *out = NULL; 41 X509 *x509 = NULL; 42 NETSCAPE_CERT_SEQUENCE *seq = NULL; 43 OPTION_CHOICE o; 44 int toseq = 0, ret = 1, i; 45 char *infile = NULL, *outfile = NULL, *prog; 46 47 prog = opt_init(argc, argv, nseq_options); 48 while ((o = opt_next()) != OPT_EOF) { 49 switch (o) { 50 case OPT_EOF: 51 case OPT_ERR: 52 opthelp: 53 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 54 goto end; 55 case OPT_HELP: 56 ret = 0; 57 opt_help(nseq_options); 58 goto end; 59 case OPT_TOSEQ: 60 toseq = 1; 61 break; 62 case OPT_IN: 63 infile = opt_arg(); 64 break; 65 case OPT_OUT: 66 outfile = opt_arg(); 67 break; 68 case OPT_PROV_CASES: 69 if (!opt_provider(o)) 70 goto end; 71 break; 72 } 73 } 74 75 /* No extra arguments. */ 76 argc = opt_num_rest(); 77 if (argc != 0) 78 goto opthelp; 79 80 in = bio_open_default(infile, 'r', FORMAT_PEM); 81 if (in == NULL) 82 goto end; 83 out = bio_open_default(outfile, 'w', FORMAT_PEM); 84 if (out == NULL) 85 goto end; 86 87 if (toseq) { 88 seq = NETSCAPE_CERT_SEQUENCE_new(); 89 if (seq == NULL) 90 goto end; 91 seq->certs = sk_X509_new_null(); 92 if (seq->certs == NULL) 93 goto end; 94 while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 95 if (!sk_X509_push(seq->certs, x509)) 96 goto end; 97 } 98 99 if (!sk_X509_num(seq->certs)) { 100 BIO_printf(bio_err, "%s: Error reading certs file %s\n", 101 prog, infile); 102 ERR_print_errors(bio_err); 103 goto end; 104 } 105 PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); 106 ret = 0; 107 goto end; 108 } 109 110 seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL); 111 if (seq == NULL) { 112 BIO_printf(bio_err, "%s: Error reading sequence file %s\n", 113 prog, infile); 114 ERR_print_errors(bio_err); 115 goto end; 116 } 117 118 for (i = 0; i < sk_X509_num(seq->certs); i++) { 119 x509 = sk_X509_value(seq->certs, i); 120 dump_cert_text(out, x509); 121 PEM_write_bio_X509(out, x509); 122 } 123 ret = 0; 124 end: 125 BIO_free(in); 126 BIO_free_all(out); 127 NETSCAPE_CERT_SEQUENCE_free(seq); 128 129 return ret; 130 } 131