1 /**
2 * Tool to generate an index file for the OpenSSL OCSP responder
3 *
4 * NOTE: This is a tool for setting up the test environment. At the
5 * moment, all certificates are marked as valid.
6 *
7 * Copyright 2016 Fiona Klute
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you
10 * may not use this file except in compliance with the License. You
11 * may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
18 * implied. See the License for the specific language governing
19 * permissions and limitations under the License.
20 */
21 #include <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <gnutls/gnutls.h>
26 #include <gnutls/x509.h>
27
28 #include "cert_helper.h"
29
30
31
index_line(const char * filename)32 static int index_line(const char* filename)
33 {
34 gnutls_datum_t rawcert;
35 /* read_cert reports errors to STDERR, just return if there were any */
36 if (read_cert(filename, &rawcert))
37 return GNUTLS_E_FILE_ERROR;
38
39 gnutls_x509_crt_t cert;
40 gnutls_x509_crt_init(&cert);
41 int ret = gnutls_x509_crt_import(cert, &rawcert, GNUTLS_X509_FMT_PEM);
42 if (ret != GNUTLS_E_SUCCESS)
43 goto cleanup;
44
45 /* For each certificate the index file contains a line with the
46 * tab separated fields declared below (in that order). */
47 /* status, one of: V (valid), R (revoked), E (expired) */
48 char* flag = "V";
49 /* expiration time (YYMMDDHHMMSSZ) */
50 char expires[14];
51 /* revocation time & optional reason (YYMMDDHHMMSSZ[,reason]), if
52 * any */
53 char* revocation = "";
54 /* serial number (hex), allocated when the length is known */
55 char* serial = NULL;
56 /* certificate filename, or "unknown" */
57 char* fname = "unknown";
58 /* certificate DN */
59 char dn[512];
60
61 time_t etime = gnutls_x509_crt_get_expiration_time(cert);
62 struct tm etmp;
63 memset(&etmp, 0, sizeof(etmp));
64 gmtime_r(&etime, &etmp);
65 strftime(expires, sizeof(expires), "%y%m%d%H%M%SZ", &etmp);
66
67 /* determine size of the serial number (in bytes) */
68 size_t serial_size = 0;
69 gnutls_x509_crt_get_serial(cert, NULL, &serial_size);
70 /* allocate memory for serial number and its string representation */
71 uint8_t* sno = calloc(serial_size, sizeof(uint8_t));
72 serial = calloc(serial_size * 2 + 1, sizeof(char));
73 /* actually get the serial */
74 gnutls_x509_crt_get_serial(cert, sno, &serial_size);
75 /* print serial into the buffer byte for byte */
76 for (int i = 0; i < serial_size; i++)
77 snprintf(serial + (2 * i), 3, "%.2X", sno[i]);
78 /* free binary serial */
79 free(sno);
80
81 size_t dn_size = sizeof(dn);
82 gnutls_x509_crt_get_dn(cert, dn, &dn_size);
83
84 fprintf(stdout, "%s\t%s\t%s\t%s\t%s\t%s\n",
85 flag, expires, revocation, serial, fname, dn);
86
87 /* free hex serial */
88 free(serial);
89
90 cleanup:
91 gnutls_x509_crt_deinit(cert);
92 free(rawcert.data);
93 return ret;
94 }
95
96
97
main(int argc,char * argv[])98 int main(int argc, char *argv[])
99 {
100 if (argc < 2)
101 {
102 fprintf(stderr, "Usage:\t%s CERTIFICATE ...\n", argv[0]);
103 return 1;
104 }
105
106 int ret = 0;
107 for (int i = 1; i < argc; i++)
108 {
109 int rv = index_line(argv[i]);
110 if (rv != GNUTLS_E_SUCCESS)
111 {
112 fprintf(stderr, "Error parsing %s: %s\n",
113 argv[i], gnutls_strerror(rv));
114 ret = 1;
115 }
116 }
117 return ret;
118 }
119