/ tools / chain.c
chain.c
  1  /*
  2   * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
  3   *
  4   * Permission is hereby granted, free of charge, to any person obtaining 
  5   * a copy of this software and associated documentation files (the
  6   * "Software"), to deal in the Software without restriction, including
  7   * without limitation the rights to use, copy, modify, merge, publish,
  8   * distribute, sublicense, and/or sell copies of the Software, and to
  9   * permit persons to whom the Software is furnished to do so, subject to
 10   * the following conditions:
 11   *
 12   * The above copyright notice and this permission notice shall be 
 13   * included in all copies or substantial portions of the Software.
 14   *
 15   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 16   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 17   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 18   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 19   * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 20   * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 21   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22   * SOFTWARE.
 23   */
 24  
 25  #include <stdio.h>
 26  #include <stdlib.h>
 27  #include <string.h>
 28  #include <stdint.h>
 29  #include <errno.h>
 30  
 31  #include "brssl.h"
 32  #include "bearssl.h"
 33  
 34  static void
 35  print_blob(const char *name, const unsigned char *buf, size_t len)
 36  {
 37  	size_t u;
 38  
 39  	printf("\nstatic const unsigned char %s[] = {", name);
 40  	for (u = 0; u < len; u ++) {
 41  		if (u != 0) {
 42  			printf(",");
 43  		}
 44  		if (u % 12 == 0) {
 45  			printf("\n\t");
 46  		} else {
 47  			printf(" ");
 48  		}
 49  		printf("0x%02X", buf[u]);
 50  	}
 51  	printf("\n};\n");
 52  }
 53  
 54  static void
 55  usage_chain(void)
 56  {
 57  	fprintf(stderr,
 58  "usage: brssl chain [ options ] file...\n");
 59  	fprintf(stderr,
 60  "options:\n");
 61  	fprintf(stderr,
 62  "   -q            suppress verbose messages\n");
 63  }
 64  
 65  /* see brssl.h */
 66  int
 67  do_chain(int argc, char *argv[])
 68  {
 69  	int retcode;
 70  	int verbose;
 71  	int i, num_files;
 72  	long k, ctr;
 73  
 74  	retcode = 0;
 75  	verbose = 1;
 76  	num_files = 0;
 77  	for (i = 0; i < argc; i ++) {
 78  		const char *arg;
 79  
 80  		arg = argv[i];
 81  		if (arg[0] != '-') {
 82  			num_files ++;
 83  			continue;
 84  		}
 85  		argv[i] = NULL;
 86  		if (eqstr(arg, "-v") || eqstr(arg, "-verbose")) {
 87  			verbose = 1;
 88  		} else if (eqstr(arg, "-q") || eqstr(arg, "-quiet")) {
 89  			verbose = 0;
 90  		} else {
 91  			fprintf(stderr, "ERROR: unknown option: '%s'\n", arg);
 92  			usage_chain();
 93  			goto chain_exit_error;
 94  		}
 95  	}
 96  	if (num_files == 0) {
 97  		fprintf(stderr, "ERROR: no certificate file provided\n");
 98  		usage_chain();
 99  		goto chain_exit_error;
100  	}
101  
102  	ctr = 0;
103  	for (i = 0; i < argc; i ++) {
104  		const char *fname;
105  		br_x509_certificate *xcs;
106  		size_t u, num;
107  
108  		fname = argv[i];
109  		if (fname == NULL) {
110  			continue;
111  		}
112  		if (verbose) {
113  			fprintf(stderr, "Reading file '%s': ", fname);
114  			fflush(stderr);
115  		}
116  		xcs = read_certificates(fname, &num);
117  		if (xcs == NULL) {
118  			goto chain_exit_error;
119  		}
120  		if (verbose) {
121  			fprintf(stderr, "%lu certificate%s\n",
122  				(unsigned long)num, num > 1 ? "s" : "");
123  		}
124  		for (u = 0; u < num; u ++) {
125  			char tmp[50];
126  
127  			sprintf(tmp, "CERT%ld", ctr ++);
128  			print_blob(tmp, xcs[u].data, xcs[u].data_len);
129  			xfree(xcs[u].data);
130  		}
131  		xfree(xcs);
132  	}
133  
134  	printf("\nstatic const br_x509_certificate CHAIN[] = {");
135  	for (k = 0; k < ctr; k ++) {
136  		if (k != 0) {
137  			printf(",");
138  		}
139  		printf("\n\t{ (unsigned char *)CERT%ld, sizeof CERT%ld }",
140  			k, k);
141  	}
142  	printf("\n};\n");
143  	printf("\n#define CHAIN_LEN   %ld\n", ctr);
144  
145  	/*
146  	 * Release allocated structures.
147  	 */
148  chain_exit:
149  	return retcode;
150  
151  chain_exit_error:
152  	retcode = -1;
153  	goto chain_exit;
154  }