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 if (!opt_check_rest_arg(NULL)) 77 goto opthelp; 78 79 in = bio_open_default(infile, 'r', FORMAT_PEM); 80 if (in == NULL) 81 goto end; 82 out = bio_open_default(outfile, 'w', FORMAT_PEM); 83 if (out == NULL) 84 goto end; 85 86 if (toseq) { 87 seq = NETSCAPE_CERT_SEQUENCE_new(); 88 if (seq == NULL) 89 goto end; 90 seq->certs = sk_X509_new_null(); 91 if (seq->certs == NULL) 92 goto end; 93 while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) { 94 if (!sk_X509_push(seq->certs, x509)) 95 goto end; 96 } 97 98 if (!sk_X509_num(seq->certs)) { 99 BIO_printf(bio_err, "%s: Error reading certs file %s\n", 100 prog, infile); 101 ERR_print_errors(bio_err); 102 goto end; 103 } 104 PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq); 105 ret = 0; 106 goto end; 107 } 108 109 seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL); 110 if (seq == NULL) { 111 BIO_printf(bio_err, "%s: Error reading sequence file %s\n", 112 prog, infile); 113 ERR_print_errors(bio_err); 114 goto end; 115 } 116 117 for (i = 0; i < sk_X509_num(seq->certs); i++) { 118 x509 = sk_X509_value(seq->certs, i); 119 dump_cert_text(out, x509); 120 PEM_write_bio_X509(out, x509); 121 } 122 ret = 0; 123 end: 124 BIO_free(in); 125 BIO_free_all(out); 126 NETSCAPE_CERT_SEQUENCE_free(seq); 127 128 return ret; 129 } 130