ba6f9196d2323985692468d90cef801c7e72c060
[openssl.git] / crypto / x509 / t_x509.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 "internal/cryptlib.h"
12 #include <openssl/buffer.h>
13 #include <openssl/bn.h>
14 #include <openssl/objects.h>
15 #include <openssl/x509.h>
16 #include <openssl/x509v3.h>
17 #include "internal/asn1_int.h"
18
19 #ifndef OPENSSL_NO_STDIO
20 int X509_print_fp(FILE *fp, X509 *x)
21 {
22     return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
23 }
24
25 int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
26                      unsigned long cflag)
27 {
28     BIO *b;
29     int ret;
30
31     if ((b = BIO_new(BIO_s_file())) == NULL) {
32         X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
33         return 0;
34     }
35     BIO_set_fp(b, fp, BIO_NOCLOSE);
36     ret = X509_print_ex(b, x, nmflag, cflag);
37     BIO_free(b);
38     return ret;
39 }
40 #endif
41
42 int X509_print(BIO *bp, X509 *x)
43 {
44     return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
45 }
46
47 int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
48                   unsigned long cflag)
49 {
50     long l;
51     int ret = 0, i;
52     char *m = NULL, mlch = ' ';
53     int nmindent = 0;
54     ASN1_INTEGER *bs;
55     EVP_PKEY *pkey = NULL;
56     const char *neg;
57
58     if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
59         mlch = '\n';
60         nmindent = 12;
61     }
62
63     if (nmflags == X509_FLAG_COMPAT)
64         nmindent = 16;
65
66     if (!(cflag & X509_FLAG_NO_HEADER)) {
67         if (BIO_write(bp, "Certificate:\n", 13) <= 0)
68             goto err;
69         if (BIO_write(bp, "    Data:\n", 10) <= 0)
70             goto err;
71     }
72     if (!(cflag & X509_FLAG_NO_VERSION)) {
73         l = X509_get_version(x);
74         if (l >= 0 && l <= 2) {
75             if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
76                 goto err;
77         } else {
78             if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
79                 goto err;
80         }
81     }
82     if (!(cflag & X509_FLAG_NO_SERIAL)) {
83
84         if (BIO_write(bp, "        Serial Number:", 22) <= 0)
85             goto err;
86
87         bs = X509_get_serialNumber(x);
88         if (bs->length <= (int)sizeof(long)) {
89                 ERR_set_mark();
90                 l = ASN1_INTEGER_get(bs);
91                 ERR_pop_to_mark();
92         } else {
93             l = -1;
94         }
95         if (l != -1) {
96             unsigned long ul;
97             if (bs->type == V_ASN1_NEG_INTEGER) {
98                 ul = 0 - (unsigned long)l;
99                 neg = "-";
100             } else {
101                 ul = l;
102                 neg = "";
103             }
104             if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0)
105                 goto err;
106         } else {
107             neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
108             if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
109                 goto err;
110
111             for (i = 0; i < bs->length; i++) {
112                 if (BIO_printf(bp, "%02x%c", bs->data[i],
113                                ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
114                     goto err;
115             }
116         }
117
118     }
119
120     if (!(cflag & X509_FLAG_NO_SIGNAME)) {
121         const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x);
122         if (X509_signature_print(bp, tsig_alg, NULL) <= 0)
123             goto err;
124     }
125
126     if (!(cflag & X509_FLAG_NO_ISSUER)) {
127         if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
128             goto err;
129         if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
130             < 0)
131             goto err;
132         if (BIO_write(bp, "\n", 1) <= 0)
133             goto err;
134     }
135     if (!(cflag & X509_FLAG_NO_VALIDITY)) {
136         if (BIO_write(bp, "        Validity\n", 17) <= 0)
137             goto err;
138         if (BIO_write(bp, "            Not Before: ", 24) <= 0)
139             goto err;
140         if (!ASN1_TIME_print(bp, X509_get0_notBefore(x)))
141             goto err;
142         if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
143             goto err;
144         if (!ASN1_TIME_print(bp, X509_get0_notAfter(x)))
145             goto err;
146         if (BIO_write(bp, "\n", 1) <= 0)
147             goto err;
148     }
149     if (!(cflag & X509_FLAG_NO_SUBJECT)) {
150         if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
151             goto err;
152         if (X509_NAME_print_ex
153             (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
154             goto err;
155         if (BIO_write(bp, "\n", 1) <= 0)
156             goto err;
157     }
158     if (!(cflag & X509_FLAG_NO_PUBKEY)) {
159         X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x);
160         ASN1_OBJECT *xpoid;
161         X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
162         if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
163             goto err;
164         if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
165             goto err;
166         if (i2a_ASN1_OBJECT(bp, xpoid) <= 0)
167             goto err;
168         if (BIO_puts(bp, "\n") <= 0)
169             goto err;
170
171         pkey = X509_get0_pubkey(x);
172         if (pkey == NULL) {
173             BIO_printf(bp, "%12sUnable to load Public Key\n", "");
174             ERR_print_errors(bp);
175         } else {
176             EVP_PKEY_print_public(bp, pkey, 16, NULL);
177         }
178     }
179
180     if (!(cflag & X509_FLAG_NO_IDS)) {
181         const ASN1_BIT_STRING *iuid, *suid;
182         X509_get0_uids(x, &iuid, &suid);
183         if (iuid != NULL) {
184             if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
185                 goto err;
186             if (!X509_signature_dump(bp, iuid, 12))
187                 goto err;
188         }
189         if (suid != NULL) {
190             if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
191                 goto err;
192             if (!X509_signature_dump(bp, suid, 12))
193                 goto err;
194         }
195     }
196
197     if (!(cflag & X509_FLAG_NO_EXTENSIONS))
198         X509V3_extensions_print(bp, "X509v3 extensions",
199                                 X509_get0_extensions(x), cflag, 8);
200
201     if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
202         const X509_ALGOR *sig_alg;
203         const ASN1_BIT_STRING *sig;
204         X509_get0_signature(&sig, &sig_alg, x);
205         if (X509_signature_print(bp, sig_alg, sig) <= 0)
206             goto err;
207     }
208     if (!(cflag & X509_FLAG_NO_AUX)) {
209         if (!X509_aux_print(bp, x, 0))
210             goto err;
211     }
212     ret = 1;
213  err:
214     OPENSSL_free(m);
215     return ret;
216 }
217
218 int X509_ocspid_print(BIO *bp, X509 *x)
219 {
220     unsigned char *der = NULL;
221     unsigned char *dertmp;
222     int derlen;
223     int i;
224     unsigned char SHA1md[SHA_DIGEST_LENGTH];
225     ASN1_BIT_STRING *keybstr;
226     X509_NAME *subj;
227
228     /*
229      * display the hash of the subject as it would appear in OCSP requests
230      */
231     if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
232         goto err;
233     subj = X509_get_subject_name(x);
234     derlen = i2d_X509_NAME(subj, NULL);
235     if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
236         goto err;
237     i2d_X509_NAME(subj, &dertmp);
238
239     if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
240         goto err;
241     for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
242         if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
243             goto err;
244     }
245     OPENSSL_free(der);
246     der = NULL;
247
248     /*
249      * display the hash of the public key as it would appear in OCSP requests
250      */
251     if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
252         goto err;
253
254     keybstr = X509_get0_pubkey_bitstr(x);
255
256     if (keybstr == NULL)
257         goto err;
258
259     if (!EVP_Digest(ASN1_STRING_get0_data(keybstr),
260                     ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(),
261                     NULL))
262         goto err;
263     for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
264         if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
265             goto err;
266     }
267     BIO_printf(bp, "\n");
268
269     return 1;
270  err:
271     OPENSSL_free(der);
272     return 0;
273 }
274
275 int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
276 {
277     const unsigned char *s;
278     int i, n;
279
280     n = sig->length;
281     s = sig->data;
282     for (i = 0; i < n; i++) {
283         if ((i % 18) == 0) {
284             if (BIO_write(bp, "\n", 1) <= 0)
285                 return 0;
286             if (BIO_indent(bp, indent, indent) <= 0)
287                 return 0;
288         }
289         if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
290             return 0;
291     }
292     if (BIO_write(bp, "\n", 1) != 1)
293         return 0;
294
295     return 1;
296 }
297
298 int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg,
299                          const ASN1_STRING *sig)
300 {
301     int sig_nid;
302     if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
303         return 0;
304     if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
305         return 0;
306
307     sig_nid = OBJ_obj2nid(sigalg->algorithm);
308     if (sig_nid != NID_undef) {
309         int pkey_nid, dig_nid;
310         const EVP_PKEY_ASN1_METHOD *ameth;
311         if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
312             ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
313             if (ameth && ameth->sig_print)
314                 return ameth->sig_print(bp, sigalg, sig, 9, 0);
315         }
316     }
317     if (sig)
318         return X509_signature_dump(bp, sig, 9);
319     else if (BIO_puts(bp, "\n") <= 0)
320         return 0;
321     return 1;
322 }
323
324 int X509_aux_print(BIO *out, X509 *x, int indent)
325 {
326     char oidstr[80], first;
327     STACK_OF(ASN1_OBJECT) *trust, *reject;
328     const unsigned char *alias, *keyid;
329     int keyidlen;
330     int i;
331     if (X509_trusted(x) == 0)
332         return 1;
333     trust = X509_get0_trust_objects(x);
334     reject = X509_get0_reject_objects(x);
335     if (trust) {
336         first = 1;
337         BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
338         for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
339             if (!first)
340                 BIO_puts(out, ", ");
341             else
342                 first = 0;
343             OBJ_obj2txt(oidstr, sizeof oidstr,
344                         sk_ASN1_OBJECT_value(trust, i), 0);
345             BIO_puts(out, oidstr);
346         }
347         BIO_puts(out, "\n");
348     } else
349         BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
350     if (reject) {
351         first = 1;
352         BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
353         for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
354             if (!first)
355                 BIO_puts(out, ", ");
356             else
357                 first = 0;
358             OBJ_obj2txt(oidstr, sizeof oidstr,
359                         sk_ASN1_OBJECT_value(reject, i), 0);
360             BIO_puts(out, oidstr);
361         }
362         BIO_puts(out, "\n");
363     } else
364         BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
365     alias = X509_alias_get0(x, NULL);
366     if (alias)
367         BIO_printf(out, "%*sAlias: %s\n", indent, "", alias);
368     keyid = X509_keyid_get0(x, &keyidlen);
369     if (keyid) {
370         BIO_printf(out, "%*sKey Id: ", indent, "");
371         for (i = 0; i < keyidlen; i++)
372             BIO_printf(out, "%s%02X", i ? ":" : "", keyid[i]);
373         BIO_write(out, "\n", 1);
374     }
375     return 1;
376 }