Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/output.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2007-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2017 Red Hat, Inc.
4
 *
5
 * Author: Simon Josefsson, Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* Functions for printing X.509 Certificate structures
25
 */
26
27
#include "gnutls_int.h"
28
#include <common.h>
29
#include <x509.h>
30
#include <x509_int.h>
31
#include <num.h>
32
#include "errors.h"
33
#include "hello_ext.h"
34
#include "ip.h"
35
36
0
#define addf _gnutls_buffer_append_printf
37
0
#define adds _gnutls_buffer_append_str
38
39
0
#define NON_NULL(x) (((x)!=NULL)?((char*)(x)):"")
40
0
#define ERROR_STR (char*) "(error)"
41
42
static void print_idn_name(gnutls_buffer_st * str, const char *prefix,
43
         const char *type, gnutls_datum_t * name)
44
0
{
45
0
  unsigned printable = 1;
46
0
  unsigned is_printed = 0;
47
0
  gnutls_datum_t out = { NULL, 0 };
48
0
  int ret;
49
50
0
  if (!_gnutls_str_is_print((char *)name->data, name->size))
51
0
    printable = 0;
52
53
0
  is_printed = 0;
54
0
  if (!printable) {
55
0
    addf(str, _("%s%s: %.*s (contains illegal chars)\n"), prefix,
56
0
         type, name->size, NON_NULL(name->data));
57
0
    is_printed = 1;
58
0
  } else if (name->data != NULL) {
59
0
    if (strstr((char *)name->data, "xn--") != NULL) {
60
0
      ret =
61
0
          gnutls_idna_reverse_map((char *)name->data,
62
0
                name->size, &out, 0);
63
0
      if (ret >= 0) {
64
0
        addf(str, _("%s%s: %.*s (%s)\n"), prefix, type,
65
0
             name->size, NON_NULL(name->data),
66
0
             out.data);
67
0
        is_printed = 1;
68
0
        gnutls_free(out.data);
69
0
      }
70
0
    }
71
0
  }
72
73
0
  if (is_printed == 0) {
74
0
    addf(str, _("%s%s: %.*s\n"), prefix, type, name->size,
75
0
         NON_NULL(name->data));
76
0
  }
77
0
}
78
79
static void print_idn_email(gnutls_buffer_st * str, const char *prefix,
80
          const char *type, gnutls_datum_t * name)
81
0
{
82
0
  unsigned printable = 1;
83
0
  unsigned is_printed = 0;
84
0
  gnutls_datum_t out = { NULL, 0 };
85
0
  int ret;
86
87
0
  if (!_gnutls_str_is_print((char *)name->data, name->size))
88
0
    printable = 0;
89
90
0
  is_printed = 0;
91
0
  if (!printable) {
92
0
    addf(str, _("%s%s: %.*s (contains illegal chars)\n"), prefix,
93
0
         type, name->size, NON_NULL(name->data));
94
0
    is_printed = 1;
95
0
  } else if (name->data != NULL) {
96
0
    if (strstr((char *)name->data, "xn--") != NULL) {
97
0
      ret =
98
0
          _gnutls_idna_email_reverse_map((char *)name->data,
99
0
                 name->size, &out);
100
0
      if (ret >= 0) {
101
0
        addf(str, _("%s%s: %.*s (%s)\n"), prefix, type,
102
0
             name->size, NON_NULL(name->data),
103
0
             out.data);
104
0
        is_printed = 1;
105
0
        gnutls_free(out.data);
106
0
      }
107
0
    }
108
0
  }
109
110
0
  if (is_printed == 0) {
111
0
    addf(str, _("%s%s: %.*s\n"), prefix, type, name->size,
112
0
         NON_NULL(name->data));
113
0
  }
114
0
}
115
116
static void
117
print_name(gnutls_buffer_st * str, const char *prefix, unsigned type,
118
     gnutls_datum_t * name, unsigned ip_is_cidr)
119
0
{
120
0
  char *sname = (char *)name->data;
121
0
  char str_ip[64];
122
0
  const char *p;
123
124
0
  if ((type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_OTHERNAME_XMPP
125
0
       || type == GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL
126
0
       || type == GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL
127
0
       || type == GNUTLS_SAN_RFC822NAME
128
0
       || type == GNUTLS_SAN_URI) && sname != NULL
129
0
      && strlen(sname) != name->size) {
130
0
    adds(str,
131
0
         _("warning: SAN contains an embedded NUL, "
132
0
           "replacing with '!'\n"));
133
0
    while (strlen(sname) < name->size)
134
0
      name->data[strlen(sname)] = '!';
135
0
  }
136
137
0
  switch (type) {
138
0
  case GNUTLS_SAN_DNSNAME:
139
0
    print_idn_name(str, prefix, "DNSname", name);
140
0
    break;
141
142
0
  case GNUTLS_SAN_RFC822NAME:
143
0
    print_idn_email(str, prefix, "RFC822Name", name);
144
0
    break;
145
146
0
  case GNUTLS_SAN_URI:
147
0
    addf(str, _("%sURI: %.*s\n"), prefix, name->size,
148
0
         NON_NULL(name->data));
149
0
    break;
150
151
0
  case GNUTLS_SAN_IPADDRESS:
152
0
    if (!ip_is_cidr)
153
0
      p = _gnutls_ip_to_string(name->data, name->size, str_ip,
154
0
             sizeof(str_ip));
155
0
    else
156
0
      p = _gnutls_cidr_to_string(name->data, name->size,
157
0
               str_ip, sizeof(str_ip));
158
0
    if (p == NULL)
159
0
      p = ERROR_STR;
160
0
    addf(str, "%sIPAddress: %s\n", prefix, p);
161
0
    break;
162
163
0
  case GNUTLS_SAN_DN:
164
0
    addf(str, _("%sdirectoryName: %.*s\n"), prefix, name->size,
165
0
         NON_NULL(name->data));
166
0
    break;
167
168
0
  case GNUTLS_SAN_REGISTERED_ID:
169
0
    addf(str, _("%sRegistered ID: %.*s\n"), prefix, name->size,
170
0
         NON_NULL(name->data));
171
0
    break;
172
173
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
174
0
    addf(str, _("%sXMPP Address: %.*s\n"), prefix, name->size,
175
0
         NON_NULL(name->data));
176
0
    break;
177
178
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
179
0
    addf(str, _("%sKRB5Principal: %.*s\n"), prefix, name->size,
180
0
         NON_NULL(name->data));
181
0
    break;
182
183
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
184
0
    addf(str, _("%sUser Principal Name: %.*s\n"), prefix,
185
0
         name->size, NON_NULL(name->data));
186
0
    break;
187
188
0
  default:
189
0
    addf(str, _("%sUnknown name: "), prefix);
190
0
    _gnutls_buffer_hexprint(str, name->data, name->size);
191
0
    adds(str, "\n");
192
0
    break;
193
0
  }
194
0
}
195
196
static char *get_pk_name(gnutls_x509_crt_t cert, unsigned *bits)
197
0
{
198
0
  char oid[MAX_OID_SIZE];
199
0
  size_t oid_size;
200
0
  oid_size = sizeof(oid);
201
0
  int ret;
202
203
0
  ret = gnutls_x509_crt_get_pk_algorithm(cert, bits);
204
0
  if (ret > 0) {
205
0
    const char *name = gnutls_pk_algorithm_get_name(ret);
206
207
0
    if (name != NULL)
208
0
      return gnutls_strdup(name);
209
0
  }
210
211
0
  ret = gnutls_x509_crt_get_pk_oid(cert, oid, &oid_size);
212
0
  if (ret < 0)
213
0
    return NULL;
214
215
0
  return gnutls_strdup(oid);
216
0
}
217
218
static char *crq_get_pk_name(gnutls_x509_crq_t crq)
219
0
{
220
0
  char oid[MAX_OID_SIZE];
221
0
  size_t oid_size;
222
0
  oid_size = sizeof(oid);
223
0
  int ret;
224
225
0
  ret = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
226
0
  if (ret > 0) {
227
0
    const char *name = gnutls_pk_algorithm_get_name(ret);
228
229
0
    if (name != NULL)
230
0
      return gnutls_strdup(name);
231
0
  }
232
233
0
  ret = gnutls_x509_crq_get_pk_oid(crq, oid, &oid_size);
234
0
  if (ret < 0)
235
0
    return NULL;
236
237
0
  return gnutls_strdup(oid);
238
0
}
239
240
static char *get_sign_name(gnutls_x509_crt_t cert, int *algo)
241
0
{
242
0
  char oid[MAX_OID_SIZE];
243
0
  size_t oid_size;
244
0
  oid_size = sizeof(oid);
245
0
  int ret;
246
247
0
  *algo = 0;
248
249
0
  ret = gnutls_x509_crt_get_signature_algorithm(cert);
250
0
  if (ret > 0) {
251
0
    const char *name = gnutls_sign_get_name(ret);
252
253
0
    *algo = ret;
254
255
0
    if (name != NULL)
256
0
      return gnutls_strdup(name);
257
0
  }
258
259
0
  ret = gnutls_x509_crt_get_signature_oid(cert, oid, &oid_size);
260
0
  if (ret < 0)
261
0
    return NULL;
262
263
0
  return gnutls_strdup(oid);
264
0
}
265
266
static char *crq_get_sign_name(gnutls_x509_crq_t crq)
267
0
{
268
0
  char oid[MAX_OID_SIZE];
269
0
  size_t oid_size;
270
0
  oid_size = sizeof(oid);
271
0
  int ret;
272
273
0
  ret = gnutls_x509_crq_get_signature_algorithm(crq);
274
0
  if (ret > 0) {
275
0
    const char *name = gnutls_sign_get_name(ret);
276
277
0
    if (name != NULL)
278
0
      return gnutls_strdup(name);
279
0
  }
280
281
0
  ret = gnutls_x509_crq_get_signature_oid(crq, oid, &oid_size);
282
0
  if (ret < 0)
283
0
    return NULL;
284
285
0
  return gnutls_strdup(oid);
286
0
}
287
288
static char *crl_get_sign_name(gnutls_x509_crl_t crl, int *algo)
289
0
{
290
0
  char oid[MAX_OID_SIZE];
291
0
  size_t oid_size;
292
0
  oid_size = sizeof(oid);
293
0
  int ret;
294
295
0
  *algo = 0;
296
297
0
  ret = gnutls_x509_crl_get_signature_algorithm(crl);
298
0
  if (ret > 0) {
299
0
    const char *name = gnutls_sign_get_name(ret);
300
301
0
    *algo = ret;
302
303
0
    if (name != NULL)
304
0
      return gnutls_strdup(name);
305
0
  }
306
307
0
  ret = gnutls_x509_crl_get_signature_oid(crl, oid, &oid_size);
308
0
  if (ret < 0)
309
0
    return NULL;
310
311
0
  return gnutls_strdup(oid);
312
0
}
313
314
static void print_proxy(gnutls_buffer_st * str, gnutls_datum_t * der)
315
0
{
316
0
  int pathlen;
317
0
  char *policyLanguage;
318
0
  char *policy;
319
0
  size_t npolicy;
320
0
  int err;
321
322
0
  err = gnutls_x509_ext_import_proxy(der, &pathlen, &policyLanguage,
323
0
             &policy, &npolicy);
324
0
  if (err < 0) {
325
0
    addf(str, "error: get_proxy: %s\n", gnutls_strerror(err));
326
0
    return;
327
0
  }
328
329
0
  if (pathlen >= 0)
330
0
    addf(str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
331
0
  addf(str, _("\t\t\tPolicy Language: %s"), policyLanguage);
332
0
  if (strcmp(policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
333
0
    adds(str, " (id-ppl-inheritALL)\n");
334
0
  else if (strcmp(policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
335
0
    adds(str, " (id-ppl-independent)\n");
336
0
  else
337
0
    adds(str, "\n");
338
0
  if (npolicy) {
339
0
    adds(str, _("\t\t\tPolicy:\n\t\t\t\tASCII: "));
340
0
    _gnutls_buffer_asciiprint(str, policy, npolicy);
341
0
    adds(str, _("\n\t\t\t\tHexdump: "));
342
0
    _gnutls_buffer_hexprint(str, policy, npolicy);
343
0
    adds(str, "\n");
344
0
  }
345
0
  gnutls_free(policy);
346
0
  gnutls_free(policyLanguage);
347
0
}
348
349
static void print_nc(gnutls_buffer_st * str, const char *prefix,
350
         gnutls_datum_t * der)
351
0
{
352
0
  gnutls_x509_name_constraints_t nc;
353
0
  int ret;
354
0
  unsigned idx = 0;
355
0
  gnutls_datum_t name;
356
0
  unsigned type;
357
0
  char new_prefix[16];
358
359
0
  ret = gnutls_x509_name_constraints_init(&nc);
360
0
  if (ret < 0)
361
0
    return;
362
363
0
  ret = gnutls_x509_ext_import_name_constraints(der, nc, 0);
364
0
  if (ret < 0)
365
0
    goto cleanup;
366
367
0
  snprintf(new_prefix, sizeof(new_prefix), "%s\t\t\t\t", prefix);
368
369
0
  do {
370
0
    ret =
371
0
        gnutls_x509_name_constraints_get_permitted(nc, idx++, &type,
372
0
                     &name);
373
374
0
    if (ret >= 0) {
375
0
      if (idx == 1)
376
0
        addf(str, _("%s\t\t\tPermitted:\n"), prefix);
377
378
0
      print_name(str, new_prefix, type, &name, 1);
379
0
    }
380
0
  } while (ret == 0);
381
382
0
  idx = 0;
383
0
  do {
384
0
    ret =
385
0
        gnutls_x509_name_constraints_get_excluded(nc, idx++, &type,
386
0
                    &name);
387
388
0
    if (ret >= 0) {
389
0
      if (idx == 1)
390
0
        addf(str, _("%s\t\t\tExcluded:\n"), prefix);
391
392
0
      print_name(str, new_prefix, type, &name, 1);
393
0
    }
394
0
  } while (ret == 0);
395
396
0
 cleanup:
397
0
  gnutls_x509_name_constraints_deinit(nc);
398
0
}
399
400
static void print_aia(gnutls_buffer_st * str, const gnutls_datum_t * der)
401
0
{
402
0
  int err;
403
0
  int seq;
404
0
  gnutls_datum_t san = { NULL, 0 }, oid = { NULL, 0 };
405
0
  gnutls_x509_aia_t aia;
406
0
  unsigned int san_type;
407
408
0
  err = gnutls_x509_aia_init(&aia);
409
0
  if (err < 0)
410
0
    return;
411
412
0
  err = gnutls_x509_ext_import_aia(der, aia, 0);
413
0
  if (err < 0) {
414
0
    addf(str, "error: get_aia: %s\n", gnutls_strerror(err));
415
0
    goto cleanup;
416
0
  }
417
418
0
  for (seq = 0;; seq++) {
419
0
    err = gnutls_x509_aia_get(aia, seq, &oid, &san_type, &san);
420
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
421
0
      goto cleanup;
422
0
    if (err < 0) {
423
0
      addf(str, "error: aia_get: %s\n", gnutls_strerror(err));
424
0
      goto cleanup;
425
0
    }
426
427
0
    if (strcmp((char *)oid.data, GNUTLS_OID_AD_OCSP) == 0)
428
0
      addf(str, _("\t\t\tAccess Method: %s (%s)\n"),
429
0
           GNUTLS_OID_AD_OCSP, "id-ad-ocsp");
430
0
    else if (strcmp((char *)oid.data, GNUTLS_OID_AD_CAISSUERS) == 0)
431
0
      addf(str, _("\t\t\tAccess Method: %s (%s)\n"),
432
0
           GNUTLS_OID_AD_CAISSUERS, "id-ad-caIssuers");
433
0
    else {
434
0
      addf(str, _("\t\t\tAccess Method: %s (%s)\n"),
435
0
           (char *)oid.data, "UNKNOWN");
436
0
    }
437
438
0
    adds(str, "\t\t\tAccess Location ");
439
0
    print_name(str, "", san_type, &san, 0);
440
0
  }
441
442
0
 cleanup:
443
0
  gnutls_x509_aia_deinit(aia);
444
0
}
445
446
static void print_ski(gnutls_buffer_st * str, gnutls_datum_t * der)
447
0
{
448
0
  gnutls_datum_t id = { NULL, 0 };
449
0
  int err;
450
451
0
  err = gnutls_x509_ext_import_subject_key_id(der, &id);
452
0
  if (err < 0) {
453
0
    addf(str, "error: get_subject_key_id: %s\n",
454
0
         gnutls_strerror(err));
455
0
    return;
456
0
  }
457
458
0
  adds(str, "\t\t\t");
459
0
  _gnutls_buffer_hexprint(str, id.data, id.size);
460
0
  adds(str, "\n");
461
462
0
  gnutls_free(id.data);
463
0
}
464
465
static void print_time(gnutls_buffer_st * str, time_t timestamp)
466
0
{
467
0
  char s[42];
468
0
  size_t max = sizeof(s);
469
0
  struct tm t;
470
471
0
  if (gmtime_r(&timestamp, &t) == NULL) {
472
0
    addf(str, "error: gmtime_r (%lu)\n", timestamp);
473
0
    return;
474
0
  }
475
476
0
  if (strftime(s, max, "%a, %b %d %H:%M:%S UTC %Y", &t) == 0)
477
0
    addf(str, "error: strftime (%lu)\n", timestamp);
478
0
  else
479
0
    addf(str, "%s\n", s);
480
0
}
481
482
static void print_scts(gnutls_buffer_st * str, const gnutls_datum_t * der,
483
           const char *prefix)
484
0
{
485
0
  int retval;
486
0
  unsigned int version;
487
0
  time_t timestamp;
488
0
  gnutls_datum_t logid = { NULL, 0 }, sig = { NULL, 0 };
489
0
  gnutls_sign_algorithm_t sigalg;
490
0
  gnutls_x509_ct_scts_t scts;
491
492
0
  retval = gnutls_x509_ext_ct_scts_init(&scts);
493
0
  if (retval < 0) {
494
0
    addf(str, "error: gnutls_x509_ext_ct_scts_init(): %s\n",
495
0
         gnutls_strerror(retval));
496
0
    return;
497
0
  }
498
499
0
  retval = gnutls_x509_ext_ct_import_scts(der, scts, 0);
500
0
  if (retval < 0) {
501
0
    addf(str, "error: gnutls_x509_ext_ct_import_scts(): %s\n",
502
0
         gnutls_strerror(retval));
503
0
    goto cleanup;
504
0
  }
505
506
0
  for (int i = 0;; i++) {
507
0
    retval = gnutls_x509_ct_sct_get_version(scts, i, &version);
508
0
    if (retval == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
509
0
      break;
510
511
0
    addf(str, _("%s\t\t\tSigned Certificate Timestamp %d:\n"),
512
0
         prefix, (i + 1));
513
514
0
    if (version != 1) {
515
0
      addf(str,
516
0
           _("%s\t\t\t\tVersion: %d (unknown SCT version)\n"),
517
0
           prefix, version);
518
0
      continue;
519
0
    }
520
521
0
    retval = gnutls_x509_ct_sct_get(scts, i,
522
0
            &timestamp,
523
0
            &logid, &sigalg, &sig);
524
0
    if (retval < 0) {
525
0
      addf(str, "error: could not get SCT info: %s\n",
526
0
           gnutls_strerror(retval));
527
0
      break;
528
0
    }
529
530
0
    addf(str, _("%s\t\t\t\tVersion: %d\n"), prefix, version);
531
0
    addf(str, _("%s\t\t\t\tLog ID: "), prefix);
532
0
    _gnutls_buffer_hexprint(str, logid.data, logid.size);
533
0
    addf(str, "\n");
534
0
    addf(str, _("%s\t\t\t\tTime: "), prefix);
535
0
    print_time(str, timestamp);
536
0
    addf(str, _("%s\t\t\t\tExtensions: none\n"), /* there are no extensions defined for v1 */
537
0
         prefix);
538
0
    addf(str, _("%s\t\t\t\tSignature algorithm: %s\n"),
539
0
         prefix, gnutls_sign_get_name(sigalg));
540
0
    addf(str, _("%s\t\t\t\tSignature: "), prefix);
541
0
    _gnutls_buffer_hexprint(str, sig.data, sig.size);
542
0
    addf(str, "\n");
543
544
0
    _gnutls_free_datum(&sig);
545
0
    _gnutls_free_datum(&logid);
546
0
    sig.data = NULL;
547
0
    logid.data = NULL;
548
0
  }
549
550
0
 cleanup:
551
0
  _gnutls_free_datum(&sig);
552
0
  _gnutls_free_datum(&logid);
553
0
  gnutls_x509_ext_ct_scts_deinit(scts);
554
0
}
555
556
0
#define TYPE_CRT 2
557
0
#define TYPE_CRQ 3
558
559
typedef union {
560
  gnutls_x509_crt_t crt;
561
  gnutls_x509_crq_t crq;
562
} cert_type_t;
563
564
static void print_aki_gn_serial(gnutls_buffer_st * str, gnutls_x509_aki_t aki)
565
0
{
566
0
  gnutls_datum_t san, other_oid, serial;
567
0
  unsigned int alt_type;
568
0
  int err;
569
570
0
  err =
571
0
      gnutls_x509_aki_get_cert_issuer(aki,
572
0
              0, &alt_type, &san, &other_oid,
573
0
              &serial);
574
0
  if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
575
0
    return;
576
0
  } else if (err < 0) {
577
0
    addf(str, "error: gnutls_x509_aki_get_cert_issuer: %s\n",
578
0
         gnutls_strerror(err));
579
0
    return;
580
0
  }
581
582
0
  print_name(str, "\t\t\t", alt_type, &san, 0);
583
584
0
  adds(str, "\t\t\tserial: ");
585
0
  _gnutls_buffer_hexprint(str, serial.data, serial.size);
586
0
  adds(str, "\n");
587
0
}
588
589
static void print_aki(gnutls_buffer_st * str, gnutls_datum_t * der)
590
0
{
591
0
  int err;
592
0
  gnutls_x509_aki_t aki;
593
0
  gnutls_datum_t id;
594
595
0
  err = gnutls_x509_aki_init(&aki);
596
0
  if (err < 0) {
597
0
    addf(str, "error: gnutls_x509_aki_init: %s\n",
598
0
         gnutls_strerror(err));
599
0
    return;
600
0
  }
601
602
0
  err = gnutls_x509_ext_import_authority_key_id(der, aki, 0);
603
0
  if (err < 0) {
604
0
    addf(str,
605
0
         "error: gnutls_x509_ext_import_authority_key_id: %s\n",
606
0
         gnutls_strerror(err));
607
0
    goto cleanup;
608
0
  }
609
610
  /* Check if an alternative name is there */
611
0
  print_aki_gn_serial(str, aki);
612
613
0
  err = gnutls_x509_aki_get_id(aki, &id);
614
0
  if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
615
0
    goto cleanup;
616
0
  } else if (err < 0) {
617
0
    addf(str, "error: gnutls_x509_aki_get_id: %s\n",
618
0
         gnutls_strerror(err));
619
0
    goto cleanup;
620
0
  }
621
622
0
  adds(str, "\t\t\t");
623
0
  _gnutls_buffer_hexprint(str, id.data, id.size);
624
0
  adds(str, "\n");
625
626
0
 cleanup:
627
0
  gnutls_x509_aki_deinit(aki);
628
0
}
629
630
static void
631
print_key_usage2(gnutls_buffer_st * str, const char *prefix,
632
     unsigned int key_usage)
633
0
{
634
0
  if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
635
0
    addf(str, _("%sDigital signature.\n"), prefix);
636
0
  if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
637
0
    addf(str, _("%sNon repudiation.\n"), prefix);
638
0
  if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
639
0
    addf(str, _("%sKey encipherment.\n"), prefix);
640
0
  if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
641
0
    addf(str, _("%sData encipherment.\n"), prefix);
642
0
  if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
643
0
    addf(str, _("%sKey agreement.\n"), prefix);
644
0
  if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
645
0
    addf(str, _("%sCertificate signing.\n"), prefix);
646
0
  if (key_usage & GNUTLS_KEY_CRL_SIGN)
647
0
    addf(str, _("%sCRL signing.\n"), prefix);
648
0
  if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
649
0
    addf(str, _("%sKey encipher only.\n"), prefix);
650
0
  if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
651
0
    addf(str, _("%sKey decipher only.\n"), prefix);
652
0
}
653
654
static void
655
print_key_usage(gnutls_buffer_st * str, const char *prefix,
656
    gnutls_datum_t * der)
657
0
{
658
0
  unsigned int key_usage;
659
0
  int err;
660
661
0
  err = gnutls_x509_ext_import_key_usage(der, &key_usage);
662
0
  if (err < 0) {
663
0
    addf(str, "error: get_key_usage: %s\n", gnutls_strerror(err));
664
0
    return;
665
0
  }
666
667
0
  print_key_usage2(str, prefix, key_usage);
668
0
}
669
670
static void
671
print_private_key_usage_period(gnutls_buffer_st * str, const char *prefix,
672
             gnutls_datum_t * der)
673
0
{
674
0
  time_t activation, expiration;
675
0
  int err;
676
0
  char s[42];
677
0
  struct tm t;
678
0
  size_t max;
679
680
0
  err =
681
0
      gnutls_x509_ext_import_private_key_usage_period(der, &activation,
682
0
                  &expiration);
683
0
  if (err < 0) {
684
0
    addf(str, "error: get_private_key_usage_period: %s\n",
685
0
         gnutls_strerror(err));
686
0
    return;
687
0
  }
688
689
0
  max = sizeof(s);
690
691
0
  if (gmtime_r(&activation, &t) == NULL)
692
0
    addf(str, "error: gmtime_r (%ld)\n", (unsigned long)activation);
693
0
  else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
694
0
    addf(str, "error: strftime (%ld)\n", (unsigned long)activation);
695
0
  else
696
0
    addf(str, _("\t\t\tNot Before: %s\n"), s);
697
698
0
  if (gmtime_r(&expiration, &t) == NULL)
699
0
    addf(str, "error: gmtime_r (%ld)\n", (unsigned long)expiration);
700
0
  else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
701
0
    addf(str, "error: strftime (%ld)\n", (unsigned long)expiration);
702
0
  else
703
0
    addf(str, _("\t\t\tNot After: %s\n"), s);
704
705
0
}
706
707
static void print_crldist(gnutls_buffer_st * str, gnutls_datum_t * der)
708
0
{
709
0
  int err;
710
0
  int indx;
711
0
  gnutls_x509_crl_dist_points_t dp;
712
0
  unsigned int flags, type;
713
0
  gnutls_datum_t dist;
714
715
0
  err = gnutls_x509_crl_dist_points_init(&dp);
716
0
  if (err < 0) {
717
0
    addf(str, "error: gnutls_x509_crl_dist_points_init: %s\n",
718
0
         gnutls_strerror(err));
719
0
    return;
720
0
  }
721
722
0
  err = gnutls_x509_ext_import_crl_dist_points(der, dp, 0);
723
0
  if (err < 0) {
724
0
    addf(str, "error: gnutls_x509_ext_import_crl_dist_points: %s\n",
725
0
         gnutls_strerror(err));
726
0
    goto cleanup;
727
0
  }
728
729
0
  for (indx = 0;; indx++) {
730
0
    err =
731
0
        gnutls_x509_crl_dist_points_get(dp, indx, &type, &dist,
732
0
                &flags);
733
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
734
0
      goto cleanup;
735
0
    else if (err < 0) {
736
0
      addf(str, "error: get_crl_dist_points: %s\n",
737
0
           gnutls_strerror(err));
738
0
      return;
739
0
    }
740
741
0
    print_name(str, "\t\t\t", type, &dist, 0);
742
0
  }
743
0
 cleanup:
744
0
  gnutls_x509_crl_dist_points_deinit(dp);
745
0
}
746
747
static void
748
print_key_purpose(gnutls_buffer_st * str, const char *prefix,
749
      gnutls_datum_t * der)
750
0
{
751
0
  int indx;
752
0
  gnutls_datum_t oid;
753
0
  char *p;
754
0
  int err;
755
0
  gnutls_x509_key_purposes_t purposes;
756
757
0
  err = gnutls_x509_key_purpose_init(&purposes);
758
0
  if (err < 0) {
759
0
    addf(str, "error: gnutls_x509_key_purpose_init: %s\n",
760
0
         gnutls_strerror(err));
761
0
    return;
762
0
  }
763
764
0
  err = gnutls_x509_ext_import_key_purposes(der, purposes, 0);
765
0
  if (err < 0) {
766
0
    addf(str, "error: gnutls_x509_ext_import_key_purposes: %s\n",
767
0
         gnutls_strerror(err));
768
0
    goto cleanup;
769
0
  }
770
771
0
  for (indx = 0;; indx++) {
772
0
    err = gnutls_x509_key_purpose_get(purposes, indx, &oid);
773
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
774
0
      goto cleanup;
775
0
    else if (err < 0) {
776
0
      addf(str, "error: gnutls_x509_key_purpose_get: %s\n",
777
0
           gnutls_strerror(err));
778
0
      goto cleanup;
779
0
    }
780
781
0
    p = (void *)oid.data;
782
0
    if (strcmp(p, GNUTLS_KP_TLS_WWW_SERVER) == 0)
783
0
      addf(str, _("%s\t\t\tTLS WWW Server.\n"), prefix);
784
0
    else if (strcmp(p, GNUTLS_KP_TLS_WWW_CLIENT) == 0)
785
0
      addf(str, _("%s\t\t\tTLS WWW Client.\n"), prefix);
786
0
    else if (strcmp(p, GNUTLS_KP_CODE_SIGNING) == 0)
787
0
      addf(str, _("%s\t\t\tCode signing.\n"), prefix);
788
0
    else if (strcmp(p, GNUTLS_KP_EMAIL_PROTECTION) == 0)
789
0
      addf(str, _("%s\t\t\tEmail protection.\n"), prefix);
790
0
    else if (strcmp(p, GNUTLS_KP_TIME_STAMPING) == 0)
791
0
      addf(str, _("%s\t\t\tTime stamping.\n"), prefix);
792
0
    else if (strcmp(p, GNUTLS_KP_OCSP_SIGNING) == 0)
793
0
      addf(str, _("%s\t\t\tOCSP signing.\n"), prefix);
794
0
    else if (strcmp(p, GNUTLS_KP_IPSEC_IKE) == 0)
795
0
      addf(str, _("%s\t\t\tIpsec IKE.\n"), prefix);
796
0
    else if (strcmp(p, GNUTLS_KP_MS_SMART_CARD_LOGON) == 0)
797
0
      addf(str, _("%s\t\t\tSmart Card Logon.\n"), prefix);
798
0
    else if (strcmp(p, GNUTLS_KP_ANY) == 0)
799
0
      addf(str, _("%s\t\t\tAny purpose.\n"), prefix);
800
0
    else
801
0
      addf(str, "%s\t\t\t%s\n", prefix, p);
802
0
  }
803
0
 cleanup:
804
0
  gnutls_x509_key_purpose_deinit(purposes);
805
0
}
806
807
static void
808
print_basic(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t * der)
809
0
{
810
0
  int pathlen;
811
0
  unsigned ca;
812
0
  int err;
813
814
0
  err = gnutls_x509_ext_import_basic_constraints(der, &ca, &pathlen);
815
0
  if (err < 0) {
816
0
    addf(str, "error: get_basic_constraints: %s\n",
817
0
         gnutls_strerror(err));
818
0
    return;
819
0
  }
820
821
0
  if (ca == 0)
822
0
    addf(str, _("%s\t\t\tCertificate Authority (CA): FALSE\n"),
823
0
         prefix);
824
0
  else
825
0
    addf(str, _("%s\t\t\tCertificate Authority (CA): TRUE\n"),
826
0
         prefix);
827
828
0
  if (pathlen >= 0)
829
0
    addf(str, _("%s\t\t\tPath Length Constraint: %d\n"),
830
0
         prefix, pathlen);
831
0
}
832
833
static void
834
print_altname(gnutls_buffer_st * str, const char *prefix, gnutls_datum_t * der)
835
0
{
836
0
  unsigned int altname_idx;
837
0
  gnutls_subject_alt_names_t names;
838
0
  unsigned int type;
839
0
  gnutls_datum_t san;
840
0
  gnutls_datum_t othername;
841
0
  char pfx[16];
842
0
  int err;
843
844
0
  err = gnutls_subject_alt_names_init(&names);
845
0
  if (err < 0) {
846
0
    addf(str, "error: gnutls_subject_alt_names_init: %s\n",
847
0
         gnutls_strerror(err));
848
0
    return;
849
0
  }
850
851
0
  err = gnutls_x509_ext_import_subject_alt_names(der, names, 0);
852
0
  if (err < 0) {
853
0
    addf(str,
854
0
         "error: gnutls_x509_ext_import_subject_alt_names: %s\n",
855
0
         gnutls_strerror(err));
856
0
    goto cleanup;
857
0
  }
858
859
0
  for (altname_idx = 0;; altname_idx++) {
860
0
    err = gnutls_subject_alt_names_get(names, altname_idx,
861
0
               &type, &san, &othername);
862
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
863
0
      break;
864
0
    else if (err < 0) {
865
0
      addf(str,
866
0
           "error: gnutls_subject_alt_names_get: %s\n",
867
0
           gnutls_strerror(err));
868
0
      break;
869
0
    }
870
871
0
    if (type == GNUTLS_SAN_OTHERNAME) {
872
0
      unsigned vtype;
873
0
      gnutls_datum_t virt;
874
875
0
      err = gnutls_x509_othername_to_virtual((char *)
876
0
                     othername.data,
877
0
                     &san, &vtype,
878
0
                     &virt);
879
0
      if (err >= 0) {
880
0
        snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
881
0
        print_name(str, pfx, vtype, &virt, 0);
882
0
        gnutls_free(virt.data);
883
0
        continue;
884
0
      }
885
886
0
      addf(str,
887
0
           _("%s\t\t\totherName OID: %.*s\n"),
888
0
           prefix, (int)othername.size,
889
0
           (char *)othername.data);
890
0
      addf(str, _("%s\t\t\totherName DER: "), prefix);
891
0
      _gnutls_buffer_hexprint(str, san.data, san.size);
892
0
      addf(str, _("\n%s\t\t\totherName ASCII: "), prefix);
893
0
      _gnutls_buffer_asciiprint(str, (char *)san.data,
894
0
              san.size);
895
0
      addf(str, "\n");
896
0
    } else {
897
898
0
      snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
899
0
      print_name(str, pfx, type, &san, 0);
900
0
    }
901
0
  }
902
903
0
 cleanup:
904
0
  gnutls_subject_alt_names_deinit(names);
905
0
}
906
907
static void
908
guiddump(gnutls_buffer_st * str, const char *data, size_t len, const char *spc)
909
0
{
910
0
  size_t j;
911
912
0
  if (spc)
913
0
    adds(str, spc);
914
0
  addf(str, "{");
915
0
  addf(str, "%.2X", (unsigned char)data[3]);
916
0
  addf(str, "%.2X", (unsigned char)data[2]);
917
0
  addf(str, "%.2X", (unsigned char)data[1]);
918
0
  addf(str, "%.2X", (unsigned char)data[0]);
919
0
  addf(str, "-");
920
0
  addf(str, "%.2X", (unsigned char)data[5]);
921
0
  addf(str, "%.2X", (unsigned char)data[4]);
922
0
  addf(str, "-");
923
0
  addf(str, "%.2X", (unsigned char)data[7]);
924
0
  addf(str, "%.2X", (unsigned char)data[6]);
925
0
  addf(str, "-");
926
0
  addf(str, "%.2X", (unsigned char)data[8]);
927
0
  addf(str, "%.2X", (unsigned char)data[9]);
928
0
  addf(str, "-");
929
0
  for (j = 10; j < 16; j++) {
930
0
    addf(str, "%.2X", (unsigned char)data[j]);
931
0
  }
932
0
  addf(str, "}\n");
933
0
}
934
935
static void
936
print_unique_ids(gnutls_buffer_st * str, const gnutls_x509_crt_t cert)
937
0
{
938
0
  int result;
939
0
  char buf[256];    /* if its longer, we won't bother to print it */
940
0
  size_t buf_size = 256;
941
942
0
  result = gnutls_x509_crt_get_issuer_unique_id(cert, buf, &buf_size);
943
0
  if (result >= 0) {
944
0
    addf(str, ("\tIssuer Unique ID:\n"));
945
0
    _gnutls_buffer_hexdump(str, buf, buf_size, "\t\t\t");
946
0
    if (buf_size == 16) { /* this could be a GUID */
947
0
      guiddump(str, buf, buf_size, "\t\t\t");
948
0
    }
949
0
  }
950
951
0
  buf_size = 256;
952
0
  result = gnutls_x509_crt_get_subject_unique_id(cert, buf, &buf_size);
953
0
  if (result >= 0) {
954
0
    addf(str, ("\tSubject Unique ID:\n"));
955
0
    _gnutls_buffer_hexdump(str, buf, buf_size, "\t\t\t");
956
0
    if (buf_size == 16) { /* this could be a GUID */
957
0
      guiddump(str, buf, buf_size, "\t\t\t");
958
0
    }
959
0
  }
960
0
}
961
962
static void print_tlsfeatures(gnutls_buffer_st * str, const char *prefix,
963
            const gnutls_datum_t * der)
964
0
{
965
0
  int err;
966
0
  int seq;
967
0
  gnutls_x509_tlsfeatures_t features;
968
0
  const char *name;
969
0
  unsigned int feature;
970
971
0
  err = gnutls_x509_tlsfeatures_init(&features);
972
0
  if (err < 0)
973
0
    return;
974
975
0
  err = gnutls_x509_ext_import_tlsfeatures(der, features, 0);
976
0
  if (err < 0) {
977
0
    addf(str, "error: get_tlsfeatures: %s\n", gnutls_strerror(err));
978
0
    goto cleanup;
979
0
  }
980
981
0
  for (seq = 0;; seq++) {
982
0
    err = gnutls_x509_tlsfeatures_get(features, seq, &feature);
983
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
984
0
      goto cleanup;
985
0
    if (err < 0) {
986
0
      addf(str, "error: get_tlsfeatures: %s\n",
987
0
           gnutls_strerror(err));
988
0
      goto cleanup;
989
0
    }
990
991
0
    name = gnutls_ext_get_name(feature);
992
0
    if (name == NULL)
993
0
      addf(str, "%s\t\t\t%u\n", prefix, feature);
994
0
    else
995
0
      addf(str, "%s\t\t\t%s(%u)\n", prefix, name, feature);
996
0
  }
997
998
0
 cleanup:
999
0
  gnutls_x509_tlsfeatures_deinit(features);
1000
0
}
1001
1002
static void print_subject_sign_tool(gnutls_buffer_st * str, const char *prefix,
1003
            const gnutls_datum_t * der)
1004
0
{
1005
0
  int ret;
1006
0
  gnutls_datum_t tmp = { NULL, 0 };
1007
1008
0
  ret =
1009
0
      _gnutls_x509_decode_string(ASN1_ETYPE_UTF8_STRING, der->data,
1010
0
               der->size, &tmp, 0);
1011
0
  if (ret < 0) {
1012
0
    addf(str, _("%s\t\t\tASCII: "), prefix);
1013
0
    _gnutls_buffer_asciiprint(str, (char *)der->data, der->size);
1014
1015
0
    addf(str, "\n");
1016
0
    addf(str, _("%s\t\t\tHexdump: "), prefix);
1017
0
    _gnutls_buffer_hexprint(str, (char *)der->data, der->size);
1018
0
    adds(str, "\n");
1019
1020
0
    return;
1021
0
  }
1022
1023
0
  addf(str, _("%s\t\t\t%.*s\n"), prefix, tmp.size, NON_NULL(tmp.data));
1024
0
  _gnutls_free_datum(&tmp);
1025
0
}
1026
1027
static void print_issuer_sign_tool(gnutls_buffer_st * str, const char *prefix,
1028
           const gnutls_datum_t * der)
1029
0
{
1030
0
  int ret;
1031
0
  asn1_node tmpasn = NULL;
1032
0
  char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
1033
0
  gnutls_datum_t tmp;
1034
1035
0
  if (asn1_create_element
1036
0
      (_gnutls_get_gnutls_asn(), "GNUTLS.IssuerSignTool",
1037
0
       &tmpasn) != ASN1_SUCCESS) {
1038
0
    gnutls_assert();
1039
0
    goto hexdump;
1040
0
  }
1041
1042
0
  if (_asn1_strict_der_decode(&tmpasn, der->data, der->size, asn1_err) !=
1043
0
      ASN1_SUCCESS) {
1044
0
    gnutls_assert();
1045
0
    _gnutls_debug_log("_asn1_strict_der_decode: %s\n", asn1_err);
1046
0
    goto hexdump;
1047
0
  }
1048
1049
0
  ret = _gnutls_x509_read_value(tmpasn, "signTool", &tmp);
1050
0
  if (ret < 0) {
1051
0
    gnutls_assert();
1052
0
    goto hexdump;
1053
0
  }
1054
0
  addf(str, _("%s\t\t\tSignTool: %.*s\n"), prefix, tmp.size,
1055
0
       NON_NULL(tmp.data));
1056
0
  _gnutls_free_datum(&tmp);
1057
1058
0
  ret = _gnutls_x509_read_value(tmpasn, "cATool", &tmp);
1059
0
  if (ret < 0) {
1060
0
    gnutls_assert();
1061
0
    goto hexdump;
1062
0
  }
1063
0
  addf(str, _("%s\t\t\tCATool: %.*s\n"), prefix, tmp.size,
1064
0
       NON_NULL(tmp.data));
1065
0
  _gnutls_free_datum(&tmp);
1066
1067
0
  ret = _gnutls_x509_read_value(tmpasn, "signToolCert", &tmp);
1068
0
  if (ret < 0) {
1069
0
    gnutls_assert();
1070
0
    goto hexdump;
1071
0
  }
1072
0
  addf(str, _("%s\t\t\tSignToolCert: %.*s\n"), prefix, tmp.size,
1073
0
       NON_NULL(tmp.data));
1074
0
  _gnutls_free_datum(&tmp);
1075
1076
0
  ret = _gnutls_x509_read_value(tmpasn, "cAToolCert", &tmp);
1077
0
  if (ret < 0) {
1078
0
    gnutls_assert();
1079
0
    goto hexdump;
1080
0
  }
1081
0
  addf(str, _("%s\t\t\tCAToolCert: %.*s\n"), prefix, tmp.size,
1082
0
       NON_NULL(tmp.data));
1083
0
  _gnutls_free_datum(&tmp);
1084
1085
0
  asn1_delete_structure(&tmpasn);
1086
1087
0
  return;
1088
1089
0
 hexdump:
1090
0
  asn1_delete_structure(&tmpasn);
1091
1092
0
  addf(str, _("%s\t\t\tASCII: "), prefix);
1093
0
  _gnutls_buffer_asciiprint(str, (char *)der->data, der->size);
1094
1095
0
  addf(str, "\n");
1096
0
  addf(str, _("%s\t\t\tHexdump: "), prefix);
1097
0
  _gnutls_buffer_hexprint(str, (char *)der->data, der->size);
1098
0
  adds(str, "\n");
1099
0
}
1100
1101
#define ENTRY(oid, name) {oid, sizeof(oid)-1, name, sizeof(name)-1, NULL, 0}
1102
1103
static const struct oid_to_string cp_oid2str[] = {
1104
  ENTRY("2.5.29.32.0", "anyPolicy"),
1105
1106
  ENTRY("2.23.140.1.2.1", "CA/B Domain Validated"),
1107
  ENTRY("2.23.140.1.2.2", "CA/B Organization Validated"),
1108
  ENTRY("2.23.140.1.2.3", "CA/B Individual Validated"),
1109
  ENTRY("2.23.140.1.1", "CA/B Extended Validation"),
1110
1111
  /* draft-deremin-rfc4491-bis */
1112
  ENTRY("1.2.643.100.113.1", "Russian security class KC1"),
1113
  ENTRY("1.2.643.100.113.2", "Russian security class KC2"),
1114
  ENTRY("1.2.643.100.113.3", "Russian security class KC3"),
1115
  ENTRY("1.2.643.100.113.4", "Russian security class KB1"),
1116
  ENTRY("1.2.643.100.113.5", "Russian security class KB2"),
1117
  ENTRY("1.2.643.100.113.6", "Russian security class KA1"),
1118
1119
  {NULL, 0, NULL, 0},
1120
};
1121
1122
struct ext_indexes_st {
1123
  int san;
1124
  int ian;
1125
  int proxy;
1126
  int basic;
1127
  int keyusage;
1128
  int keypurpose;
1129
  int ski;
1130
  int aki, nc;
1131
  int crldist, pkey_usage_period;
1132
  int tlsfeatures;
1133
};
1134
1135
static void print_extension(gnutls_buffer_st * str, const char *prefix,
1136
          struct ext_indexes_st *idx, const char *oid,
1137
          unsigned critical, gnutls_datum_t * der)
1138
0
{
1139
0
  int err;
1140
0
  unsigned j;
1141
0
  char pfx[16];
1142
1143
0
  if (strcmp(oid, "2.5.29.19") == 0) {
1144
0
    if (idx->basic) {
1145
0
      addf(str, "warning: more than one basic constraint\n");
1146
0
    }
1147
1148
0
    addf(str, _("%s\t\tBasic Constraints (%s):\n"),
1149
0
         prefix, critical ? _("critical") : _("not critical"));
1150
1151
0
    print_basic(str, prefix, der);
1152
0
    idx->basic++;
1153
1154
0
  } else if (strcmp(oid, "2.5.29.14") == 0) {
1155
0
    if (idx->ski) {
1156
0
      addf(str, "warning: more than one SKI extension\n");
1157
0
    }
1158
1159
0
    addf(str,
1160
0
         _("%s\t\tSubject Key Identifier (%s):\n"),
1161
0
         prefix, critical ? _("critical") : _("not critical"));
1162
1163
0
    print_ski(str, der);
1164
1165
0
    idx->ski++;
1166
0
  } else if (strcmp(oid, "2.5.29.32") == 0) {
1167
0
    struct gnutls_x509_policy_st policy;
1168
0
    gnutls_x509_policies_t policies;
1169
0
    const char *name;
1170
0
    const struct oid_to_string *entry;
1171
0
    int x;
1172
1173
0
    err = gnutls_x509_policies_init(&policies);
1174
0
    if (err < 0) {
1175
0
      addf(str,
1176
0
           "error: certificate policies: %s\n",
1177
0
           gnutls_strerror(err));
1178
0
      return;
1179
0
    }
1180
1181
0
    err = gnutls_x509_ext_import_policies(der, policies, 0);
1182
0
    if (err < 0) {
1183
0
      addf(str,
1184
0
           "error: certificate policies import: %s\n",
1185
0
           gnutls_strerror(err));
1186
0
      gnutls_x509_policies_deinit(policies);
1187
0
      return;
1188
0
    }
1189
1190
0
    for (x = 0;; x++) {
1191
0
      err = gnutls_x509_policies_get(policies, x, &policy);
1192
0
      if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1193
0
        break;
1194
1195
0
      if (err < 0) {
1196
0
        addf(str,
1197
0
             "error: certificate policy: %s\n",
1198
0
             gnutls_strerror(err));
1199
0
        break;
1200
0
      }
1201
1202
0
      if (x == 0)
1203
0
        addf(str,
1204
0
             "%s\t\tCertificate Policies (%s):\n",
1205
0
             prefix,
1206
0
             critical ? _("critical") :
1207
0
             _("not critical"));
1208
1209
0
      entry = _gnutls_oid_get_entry(cp_oid2str, policy.oid);
1210
0
      if (entry != NULL && entry->name_desc != NULL)
1211
0
        addf(str, "%s\t\t\t%s (%s)\n", prefix,
1212
0
             policy.oid, entry->name_desc);
1213
0
      else
1214
0
        addf(str, "%s\t\t\t%s\n", prefix, policy.oid);
1215
0
      for (j = 0; j < policy.qualifiers; j++) {
1216
0
        if (policy.qualifier[j].type ==
1217
0
            GNUTLS_X509_QUALIFIER_URI)
1218
0
          name = "URI";
1219
0
        else if (policy.qualifier[j].type ==
1220
0
           GNUTLS_X509_QUALIFIER_NOTICE)
1221
0
          name = "Note";
1222
0
        else
1223
0
          name = "Unknown qualifier";
1224
0
        addf(str, "%s\t\t\t\t%s: %s\n",
1225
0
             prefix, name, policy.qualifier[j].data);
1226
0
      }
1227
0
    }
1228
0
    gnutls_x509_policies_deinit(policies);
1229
0
  } else if (strcmp(oid, "2.5.29.54") == 0) {
1230
0
    unsigned int skipcerts;
1231
1232
0
    err = gnutls_x509_ext_import_inhibit_anypolicy(der, &skipcerts);
1233
0
    if (err < 0) {
1234
0
      addf(str,
1235
0
           "error: certificate inhibit any policy import: %s\n",
1236
0
           gnutls_strerror(err));
1237
0
      return;
1238
0
    }
1239
1240
0
    addf(str,
1241
0
         "%s\t\tInhibit anyPolicy skip certs: %u (%s)\n",
1242
0
         prefix, skipcerts,
1243
0
         critical ? _("critical") : _("not critical"));
1244
1245
0
  } else if (strcmp(oid, "2.5.29.35") == 0) {
1246
1247
0
    if (idx->aki) {
1248
0
      addf(str, "warning: more than one AKI extension\n");
1249
0
    }
1250
1251
0
    addf(str,
1252
0
         _("%s\t\tAuthority Key Identifier (%s):\n"),
1253
0
         prefix, critical ? _("critical") : _("not critical"));
1254
1255
0
    print_aki(str, der);
1256
1257
0
    idx->aki++;
1258
0
  } else if (strcmp(oid, "2.5.29.15") == 0) {
1259
0
    if (idx->keyusage) {
1260
0
      addf(str,
1261
0
           "warning: more than one key usage extension\n");
1262
0
    }
1263
1264
0
    addf(str, _("%s\t\tKey Usage (%s):\n"), prefix,
1265
0
         critical ? _("critical") : _("not critical"));
1266
1267
0
    snprintf(pfx, sizeof(pfx), "%s\t\t\t", prefix);
1268
0
    print_key_usage(str, pfx, der);
1269
1270
0
    idx->keyusage++;
1271
0
  } else if (strcmp(oid, "2.5.29.16") == 0) {
1272
0
    if (idx->pkey_usage_period) {
1273
0
      addf(str,
1274
0
           "warning: more than one private key usage period extension\n");
1275
0
    }
1276
1277
0
    addf(str,
1278
0
         _("%s\t\tPrivate Key Usage Period (%s):\n"),
1279
0
         prefix, critical ? _("critical") : _("not critical"));
1280
1281
0
    print_private_key_usage_period(str, prefix, der);
1282
1283
0
    idx->pkey_usage_period++;
1284
0
  } else if (strcmp(oid, "2.5.29.37") == 0) {
1285
0
    if (idx->keypurpose) {
1286
0
      addf(str,
1287
0
           "warning: more than one key purpose extension\n");
1288
0
    }
1289
1290
0
    addf(str, _("%s\t\tKey Purpose (%s):\n"), prefix,
1291
0
         critical ? _("critical") : _("not critical"));
1292
1293
0
    print_key_purpose(str, prefix, der);
1294
0
    idx->keypurpose++;
1295
0
  } else if (strcmp(oid, "2.5.29.17") == 0) {
1296
0
    if (idx->san) {
1297
0
      addf(str, "warning: more than one SKI extension\n");
1298
0
    }
1299
1300
0
    addf(str,
1301
0
         _("%s\t\tSubject Alternative Name (%s):\n"),
1302
0
         prefix, critical ? _("critical") : _("not critical"));
1303
0
    print_altname(str, prefix, der);
1304
0
    idx->san++;
1305
0
  } else if (strcmp(oid, "2.5.29.18") == 0) {
1306
0
    if (idx->ian) {
1307
0
      addf(str,
1308
0
           "warning: more than one Issuer AltName extension\n");
1309
0
    }
1310
1311
0
    addf(str,
1312
0
         _("%s\t\tIssuer Alternative Name (%s):\n"),
1313
0
         prefix, critical ? _("critical") : _("not critical"));
1314
1315
0
    print_altname(str, prefix, der);
1316
1317
0
    idx->ian++;
1318
0
  } else if (strcmp(oid, "2.5.29.31") == 0) {
1319
0
    if (idx->crldist) {
1320
0
      addf(str,
1321
0
           "warning: more than one CRL distribution point\n");
1322
0
    }
1323
1324
0
    addf(str,
1325
0
         _("%s\t\tCRL Distribution points (%s):\n"),
1326
0
         prefix, critical ? _("critical") : _("not critical"));
1327
1328
0
    print_crldist(str, der);
1329
0
    idx->crldist++;
1330
0
  } else if (strcmp(oid, "1.3.6.1.5.5.7.1.14") == 0) {
1331
0
    if (idx->proxy) {
1332
0
      addf(str, "warning: more than one proxy extension\n");
1333
0
    }
1334
1335
0
    addf(str,
1336
0
         _
1337
0
         ("%s\t\tProxy Certificate Information (%s):\n"),
1338
0
         prefix, critical ? _("critical") : _("not critical"));
1339
1340
0
    print_proxy(str, der);
1341
1342
0
    idx->proxy++;
1343
0
  } else if (strcmp(oid, "1.3.6.1.5.5.7.1.1") == 0) {
1344
0
    addf(str, _("%s\t\tAuthority Information "
1345
0
          "Access (%s):\n"), prefix,
1346
0
         critical ? _("critical") : _("not critical"));
1347
1348
0
    print_aia(str, der);
1349
0
  } else if (strcmp(oid, GNUTLS_X509EXT_OID_CT_SCT_V1) == 0) {
1350
0
    addf(str, _("%s\t\tCT Precertificate SCTs (%s):\n"),
1351
0
         prefix, critical ? _("critical") : _("not critical"));
1352
1353
0
    print_scts(str, der, prefix);
1354
0
  } else if (strcmp(oid, "2.5.29.30") == 0) {
1355
0
    if (idx->nc) {
1356
0
      addf(str,
1357
0
           "warning: more than one name constraints extension\n");
1358
0
    }
1359
0
    idx->nc++;
1360
1361
0
    addf(str, _("%s\t\tName Constraints (%s):\n"), prefix,
1362
0
         critical ? _("critical") : _("not critical"));
1363
1364
0
    print_nc(str, prefix, der);
1365
0
  } else if (strcmp(oid, GNUTLS_X509EXT_OID_TLSFEATURES) == 0) {
1366
0
    if (idx->tlsfeatures) {
1367
0
      addf(str,
1368
0
           "warning: more than one tlsfeatures extension\n");
1369
0
    }
1370
1371
0
    addf(str, _("%s\t\tTLS Features (%s):\n"),
1372
0
         prefix, critical ? _("critical") : _("not critical"));
1373
1374
0
    print_tlsfeatures(str, prefix, der);
1375
1376
0
    idx->tlsfeatures++;
1377
0
  } else if (strcmp(oid, "1.2.643.100.111") == 0) {
1378
0
    addf(str, _("%s\t\tSubject Signing Tool(%s):\n"),
1379
0
         prefix, critical ? _("critical") : _("not critical"));
1380
1381
0
    print_subject_sign_tool(str, prefix, der);
1382
0
  } else if (strcmp(oid, "1.2.643.100.112") == 0) {
1383
0
    addf(str, _("%s\t\tIssuer Signing Tool(%s):\n"),
1384
0
         prefix, critical ? _("critical") : _("not critical"));
1385
1386
0
    print_issuer_sign_tool(str, prefix, der);
1387
0
  } else if (strcmp(oid, "2.5.4.3") == 0) {
1388
0
    int ret;
1389
0
    gnutls_datum_t tmp = { NULL, 0 };
1390
1391
0
    addf(str, _("%s\t\tCommon Name (%s):\n"),
1392
0
         prefix, critical ? _("critical") : _("not critical"));
1393
1394
0
    ret =
1395
0
        _gnutls_x509_decode_string(ASN1_ETYPE_PRINTABLE_STRING,
1396
0
                 der->data, der->size, &tmp, 0);
1397
0
    if (ret < 0) {
1398
0
      addf(str, "error: x509_decode_string: %s\n",
1399
0
           gnutls_strerror(ret));
1400
0
    } else {
1401
0
      addf(str, "%s\t\t\t%s\n", prefix, tmp.data);
1402
0
      gnutls_free(tmp.data);
1403
0
    }
1404
0
  } else {
1405
0
    addf(str, _("%s\t\tUnknown extension %s (%s):\n"),
1406
0
         prefix, oid, critical ? _("critical") : _("not critical"));
1407
1408
0
    addf(str, _("%s\t\t\tASCII: "), prefix);
1409
0
    _gnutls_buffer_asciiprint(str, (char *)der->data, der->size);
1410
1411
0
    addf(str, "\n");
1412
0
    addf(str, _("%s\t\t\tHexdump: "), prefix);
1413
0
    _gnutls_buffer_hexprint(str, (char *)der->data, der->size);
1414
0
    adds(str, "\n");
1415
0
  }
1416
0
}
1417
1418
static void
1419
print_extensions(gnutls_buffer_st * str, const char *prefix, int type,
1420
     cert_type_t cert)
1421
0
{
1422
0
  unsigned i;
1423
0
  int err;
1424
0
  gnutls_datum_t der = { NULL, 0 };
1425
0
  struct ext_indexes_st idx;
1426
1427
0
  memset(&idx, 0, sizeof(idx));
1428
1429
0
  for (i = 0;; i++) {
1430
0
    char oid[MAX_OID_SIZE] = "";
1431
0
    size_t sizeof_oid = sizeof(oid);
1432
0
    unsigned int critical;
1433
1434
0
    if (type == TYPE_CRT)
1435
0
      err =
1436
0
          gnutls_x509_crt_get_extension_info(cert.crt, i,
1437
0
                     oid,
1438
0
                     &sizeof_oid,
1439
0
                     &critical);
1440
1441
0
    else if (type == TYPE_CRQ)
1442
0
      err =
1443
0
          gnutls_x509_crq_get_extension_info(cert.crq, i,
1444
0
                     oid,
1445
0
                     &sizeof_oid,
1446
0
                     &critical);
1447
0
    else {
1448
0
      gnutls_assert();
1449
0
      return;
1450
0
    }
1451
1452
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1453
0
      break;
1454
0
    if (err < 0) {
1455
0
      addf(str, "error: get_extension_info: %s\n",
1456
0
           gnutls_strerror(err));
1457
0
      break;
1458
0
    }
1459
1460
0
    if (i == 0)
1461
0
      addf(str, _("%s\tExtensions:\n"), prefix);
1462
1463
0
    if (type == TYPE_CRT)
1464
0
      err =
1465
0
          gnutls_x509_crt_get_extension_data2(cert.crt, i,
1466
0
                &der);
1467
0
    else
1468
0
      err =
1469
0
          gnutls_x509_crq_get_extension_data2(cert.crq, i,
1470
0
                &der);
1471
1472
0
    if (err < 0) {
1473
0
      der.data = NULL;
1474
0
      der.size = 0;
1475
0
    }
1476
1477
0
    print_extension(str, prefix, &idx, oid, critical, &der);
1478
0
    gnutls_free(der.data);
1479
0
  }
1480
0
}
1481
1482
static void reverse_datum(gnutls_datum_t * d)
1483
0
{
1484
0
  unsigned int i;
1485
0
  unsigned char c;
1486
1487
0
  for (i = 0; i < d->size / 2; i++) {
1488
0
    c = d->data[i];
1489
0
    d->data[i] = d->data[d->size - i - 1];
1490
0
    d->data[d->size - i - 1] = c;
1491
0
  }
1492
0
}
1493
1494
static void
1495
print_pubkey(gnutls_buffer_st * str, const char *key_name,
1496
       gnutls_pubkey_t pubkey, gnutls_x509_spki_st * spki,
1497
       gnutls_certificate_print_formats_t format)
1498
0
{
1499
0
  int err;
1500
0
  const char *name;
1501
0
  unsigned bits;
1502
0
  unsigned pk;
1503
1504
0
  err = gnutls_pubkey_get_pk_algorithm(pubkey, &bits);
1505
0
  if (err < 0) {
1506
0
    addf(str, "error: get_pk_algorithm: %s\n",
1507
0
         gnutls_strerror(err));
1508
0
    return;
1509
0
  }
1510
1511
0
  pk = err;
1512
1513
0
  name = gnutls_pk_algorithm_get_name(pk);
1514
0
  if (name == NULL)
1515
0
    name = _("unknown");
1516
1517
0
  addf(str, _("\t%sPublic Key Algorithm: %s\n"), key_name, name);
1518
1519
0
  addf(str, _("\tAlgorithm Security Level: %s (%d bits)\n"),
1520
0
       gnutls_sec_param_get_name(gnutls_pk_bits_to_sec_param
1521
0
               (err, bits)), bits);
1522
1523
0
  if (spki && pk == GNUTLS_PK_RSA_PSS && spki->pk == pk) {
1524
0
    addf(str, _("\t\tParameters:\n"));
1525
0
    addf(str, "\t\t\tHash Algorithm: %s\n",
1526
0
         gnutls_digest_get_name(spki->rsa_pss_dig));
1527
0
    addf(str, "\t\t\tSalt Length: %d\n", spki->salt_size);
1528
0
  }
1529
1530
0
  switch (pk) {
1531
0
  case GNUTLS_PK_RSA:
1532
0
  case GNUTLS_PK_RSA_PSS:
1533
0
    {
1534
0
      gnutls_datum_t m, e;
1535
1536
0
      err = gnutls_pubkey_get_pk_rsa_raw(pubkey, &m, &e);
1537
0
      if (err < 0)
1538
0
        addf(str, "error: get_pk_rsa_raw: %s\n",
1539
0
             gnutls_strerror(err));
1540
0
      else {
1541
0
        if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS) {
1542
0
          addf(str,
1543
0
               _("\t\tModulus (bits %d): "),
1544
0
               bits);
1545
0
          _gnutls_buffer_hexprint(str,
1546
0
                m.data, m.size);
1547
0
          adds(str, "\n");
1548
0
          addf(str,
1549
0
               _("\t\tExponent (bits %d): "),
1550
0
               e.size * 8);
1551
0
          _gnutls_buffer_hexprint(str,
1552
0
                e.data, e.size);
1553
0
          adds(str, "\n");
1554
0
        } else {
1555
0
          addf(str,
1556
0
               _("\t\tModulus (bits %d):\n"),
1557
0
               bits);
1558
0
          _gnutls_buffer_hexdump(str, m.data,
1559
0
                     m.size,
1560
0
                     "\t\t\t");
1561
0
          addf(str,
1562
0
               _
1563
0
               ("\t\tExponent (bits %d):\n"),
1564
0
               e.size * 8);
1565
0
          _gnutls_buffer_hexdump(str, e.data,
1566
0
                     e.size,
1567
0
                     "\t\t\t");
1568
0
        }
1569
1570
0
        gnutls_free(m.data);
1571
0
        gnutls_free(e.data);
1572
0
      }
1573
1574
0
    }
1575
0
    break;
1576
1577
0
  case GNUTLS_PK_EDDSA_ED25519:
1578
0
  case GNUTLS_PK_EDDSA_ED448:
1579
0
  case GNUTLS_PK_ECDH_X25519:
1580
0
  case GNUTLS_PK_ECDH_X448:
1581
0
  case GNUTLS_PK_ECDSA:
1582
0
    {
1583
0
      gnutls_datum_t x, y;
1584
0
      gnutls_ecc_curve_t curve;
1585
1586
0
      err =
1587
0
          gnutls_pubkey_get_pk_ecc_raw(pubkey, &curve,
1588
0
               &x, &y);
1589
0
      if (err < 0) {
1590
0
        addf(str, "error: get_pk_ecc_raw: %s\n",
1591
0
             gnutls_strerror(err));
1592
0
      } else {
1593
0
        addf(str, _("\t\tCurve:\t%s\n"),
1594
0
             gnutls_ecc_curve_get_name(curve));
1595
0
        if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS) {
1596
0
          adds(str, _("\t\tX: "));
1597
0
          _gnutls_buffer_hexprint(str,
1598
0
                x.data, x.size);
1599
0
          adds(str, "\n");
1600
0
          if (y.size > 0) {
1601
0
            adds(str, _("\t\tY: "));
1602
0
            _gnutls_buffer_hexprint(str,
1603
0
                  y.data,
1604
0
                  y.size);
1605
0
            adds(str, "\n");
1606
0
          }
1607
0
        } else {
1608
0
          adds(str, _("\t\tX:\n"));
1609
0
          _gnutls_buffer_hexdump(str, x.data,
1610
0
                     x.size,
1611
0
                     "\t\t\t");
1612
0
          if (y.size > 0) {
1613
0
            adds(str, _("\t\tY:\n"));
1614
0
            _gnutls_buffer_hexdump(str,
1615
0
                       y.data,
1616
0
                       y.size,
1617
0
                       "\t\t\t");
1618
0
          }
1619
0
        }
1620
1621
0
        gnutls_free(x.data);
1622
0
        gnutls_free(y.data);
1623
1624
0
      }
1625
0
    }
1626
0
    break;
1627
0
  case GNUTLS_PK_DSA:
1628
0
    {
1629
0
      gnutls_datum_t p, q, g, y;
1630
1631
0
      err =
1632
0
          gnutls_pubkey_get_pk_dsa_raw(pubkey, &p, &q,
1633
0
               &g, &y);
1634
0
      if (err < 0)
1635
0
        addf(str, "error: get_pk_dsa_raw: %s\n",
1636
0
             gnutls_strerror(err));
1637
0
      else {
1638
0
        if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS) {
1639
0
          addf(str,
1640
0
               _
1641
0
               ("\t\tPublic key (bits %d): "),
1642
0
               bits);
1643
0
          _gnutls_buffer_hexprint(str,
1644
0
                y.data, y.size);
1645
0
          adds(str, "\n");
1646
0
          adds(str, _("\t\tP: "));
1647
0
          _gnutls_buffer_hexprint(str,
1648
0
                p.data, p.size);
1649
0
          adds(str, "\n");
1650
0
          adds(str, _("\t\tQ: "));
1651
0
          _gnutls_buffer_hexprint(str,
1652
0
                q.data, q.size);
1653
0
          adds(str, "\n");
1654
0
          adds(str, _("\t\tG: "));
1655
0
          _gnutls_buffer_hexprint(str,
1656
0
                g.data, g.size);
1657
0
          adds(str, "\n");
1658
0
        } else {
1659
0
          addf(str,
1660
0
               _
1661
0
               ("\t\tPublic key (bits %d):\n"),
1662
0
               bits);
1663
0
          _gnutls_buffer_hexdump(str, y.data,
1664
0
                     y.size,
1665
0
                     "\t\t\t");
1666
0
          adds(str, _("\t\tP:\n"));
1667
0
          _gnutls_buffer_hexdump(str, p.data,
1668
0
                     p.size,
1669
0
                     "\t\t\t");
1670
0
          adds(str, _("\t\tQ:\n"));
1671
0
          _gnutls_buffer_hexdump(str, q.data,
1672
0
                     q.size,
1673
0
                     "\t\t\t");
1674
0
          adds(str, _("\t\tG:\n"));
1675
0
          _gnutls_buffer_hexdump(str, g.data,
1676
0
                     g.size,
1677
0
                     "\t\t\t");
1678
0
        }
1679
1680
0
        gnutls_free(p.data);
1681
0
        gnutls_free(q.data);
1682
0
        gnutls_free(g.data);
1683
0
        gnutls_free(y.data);
1684
1685
0
      }
1686
0
    }
1687
0
    break;
1688
1689
0
  case GNUTLS_PK_GOST_01:
1690
0
  case GNUTLS_PK_GOST_12_256:
1691
0
  case GNUTLS_PK_GOST_12_512:
1692
0
    {
1693
0
      gnutls_datum_t x, y;
1694
0
      gnutls_ecc_curve_t curve;
1695
0
      gnutls_digest_algorithm_t digest;
1696
0
      gnutls_gost_paramset_t param;
1697
1698
0
      err =
1699
0
          gnutls_pubkey_export_gost_raw2(pubkey, &curve,
1700
0
                 &digest,
1701
0
                 &param, &x, &y, 0);
1702
0
      if (err < 0)
1703
0
        addf(str, "error: get_pk_gost_raw: %s\n",
1704
0
             gnutls_strerror(err));
1705
0
      else {
1706
0
        addf(str, _("\t\tCurve:\t%s\n"),
1707
0
             gnutls_ecc_curve_get_name(curve));
1708
0
        addf(str, _("\t\tDigest:\t%s\n"),
1709
0
             gnutls_digest_get_name(digest));
1710
0
        addf(str, _("\t\tParamSet: %s\n"),
1711
0
             gnutls_gost_paramset_get_name(param));
1712
0
        reverse_datum(&x);
1713
0
        reverse_datum(&y);
1714
0
        if (format == GNUTLS_CRT_PRINT_FULL_NUMBERS) {
1715
0
          adds(str, _("\t\tX: "));
1716
0
          _gnutls_buffer_hexprint(str,
1717
0
                x.data, x.size);
1718
0
          adds(str, "\n");
1719
0
          adds(str, _("\t\tY: "));
1720
0
          _gnutls_buffer_hexprint(str,
1721
0
                y.data, y.size);
1722
0
          adds(str, "\n");
1723
0
        } else {
1724
0
          adds(str, _("\t\tX:\n"));
1725
0
          _gnutls_buffer_hexdump(str, x.data,
1726
0
                     x.size,
1727
0
                     "\t\t\t");
1728
0
          adds(str, _("\t\tY:\n"));
1729
0
          _gnutls_buffer_hexdump(str, y.data,
1730
0
                     y.size,
1731
0
                     "\t\t\t");
1732
0
        }
1733
1734
0
        gnutls_free(x.data);
1735
0
        gnutls_free(y.data);
1736
1737
0
      }
1738
0
    }
1739
0
    break;
1740
1741
0
  default:
1742
0
    break;
1743
0
  }
1744
0
}
1745
1746
static int
1747
print_crt_sig_params(gnutls_buffer_st * str, gnutls_x509_crt_t crt,
1748
         gnutls_certificate_print_formats_t format)
1749
0
{
1750
0
  int ret;
1751
0
  gnutls_pk_algorithm_t pk;
1752
0
  gnutls_x509_spki_st params;
1753
0
  gnutls_sign_algorithm_t sign;
1754
1755
0
  sign = gnutls_x509_crt_get_signature_algorithm(crt);
1756
0
  pk = gnutls_sign_get_pk_algorithm(sign);
1757
0
  if (pk == GNUTLS_PK_RSA_PSS) {
1758
0
    ret = _gnutls_x509_read_sign_params(crt->cert,
1759
0
                "signatureAlgorithm",
1760
0
                &params);
1761
0
    if (ret < 0) {
1762
0
      addf(str, "error: read_pss_params: %s\n",
1763
0
           gnutls_strerror(ret));
1764
0
    } else
1765
0
      addf(str, "\t\tSalt Length: %d\n", params.salt_size);
1766
0
  }
1767
1768
0
  return 0;
1769
0
}
1770
1771
static void print_pk_name(gnutls_buffer_st * str, gnutls_x509_crt_t crt)
1772
0
{
1773
0
  const char *p;
1774
0
  char *name = get_pk_name(crt, NULL);
1775
0
  if (name == NULL)
1776
0
    p = _("unknown");
1777
0
  else
1778
0
    p = name;
1779
1780
0
  addf(str, "\tSubject Public Key Algorithm: %s\n", p);
1781
0
  gnutls_free(name);
1782
0
}
1783
1784
static int
1785
print_crt_pubkey(gnutls_buffer_st * str, gnutls_x509_crt_t crt,
1786
     gnutls_certificate_print_formats_t format)
1787
0
{
1788
0
  gnutls_pubkey_t pubkey = NULL;
1789
0
  gnutls_x509_spki_st params;
1790
0
  int ret, pk;
1791
1792
0
  ret = _gnutls_x509_crt_read_spki_params(crt, &params);
1793
0
  if (ret < 0)
1794
0
    return ret;
1795
1796
0
  pk = gnutls_x509_crt_get_pk_algorithm(crt, NULL);
1797
0
  if (pk < 0) {
1798
0
    gnutls_assert();
1799
0
    pk = GNUTLS_PK_UNKNOWN;
1800
0
  }
1801
1802
0
  if (pk == GNUTLS_PK_UNKNOWN) {
1803
0
    print_pk_name(str, crt);  /* print basic info only */
1804
0
    return 0;
1805
0
  }
1806
1807
0
  ret = gnutls_pubkey_init(&pubkey);
1808
0
  if (ret < 0)
1809
0
    return ret;
1810
1811
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
1812
0
  if (ret < 0) {
1813
0
    if (ret != GNUTLS_E_UNIMPLEMENTED_FEATURE)
1814
0
      addf(str, "error importing public key: %s\n",
1815
0
           gnutls_strerror(ret));
1816
0
    print_pk_name(str, crt);  /* print basic info only */
1817
0
    ret = 0;
1818
0
    goto cleanup;
1819
0
  }
1820
1821
0
  print_pubkey(str, _("Subject "), pubkey, &params, format);
1822
0
  ret = 0;
1823
1824
0
 cleanup:
1825
0
  gnutls_pubkey_deinit(pubkey);
1826
1827
0
  return ret;
1828
0
}
1829
1830
static void
1831
print_cert(gnutls_buffer_st * str, gnutls_x509_crt_t cert,
1832
     gnutls_certificate_print_formats_t format)
1833
0
{
1834
  /* Version. */
1835
0
  {
1836
0
    int version = gnutls_x509_crt_get_version(cert);
1837
0
    if (version < 0)
1838
0
      addf(str, "error: get_version: %s\n",
1839
0
           gnutls_strerror(version));
1840
0
    else
1841
0
      addf(str, _("\tVersion: %d\n"), version);
1842
0
  }
1843
1844
  /* Serial. */
1845
0
  {
1846
0
    char serial[128];
1847
0
    size_t serial_size = sizeof(serial);
1848
0
    int err;
1849
1850
0
    err = gnutls_x509_crt_get_serial(cert, serial, &serial_size);
1851
0
    if (err < 0)
1852
0
      addf(str, "error: get_serial: %s\n",
1853
0
           gnutls_strerror(err));
1854
0
    else {
1855
0
      adds(str, _("\tSerial Number (hex): "));
1856
0
      _gnutls_buffer_hexprint(str, serial, serial_size);
1857
0
      adds(str, "\n");
1858
0
    }
1859
0
  }
1860
1861
  /* Issuer. */
1862
0
  if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL) {
1863
0
    gnutls_datum_t dn;
1864
0
    int err;
1865
1866
0
    err = gnutls_x509_crt_get_issuer_dn3(cert, &dn, 0);
1867
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1868
0
      addf(str, _("\tIssuer:\n"));
1869
0
    } else if (err < 0) {
1870
0
      addf(str, "error: get_issuer_dn: %s\n",
1871
0
           gnutls_strerror(err));
1872
0
    } else {
1873
0
      addf(str, _("\tIssuer: %s\n"), dn.data);
1874
0
      gnutls_free(dn.data);
1875
0
    }
1876
0
  }
1877
1878
  /* Validity. */
1879
0
  {
1880
0
    time_t tim;
1881
1882
0
    adds(str, _("\tValidity:\n"));
1883
1884
0
    tim = gnutls_x509_crt_get_activation_time(cert);
1885
0
    if (tim != -1) {
1886
0
      char s[42];
1887
0
      size_t max = sizeof(s);
1888
0
      struct tm t;
1889
1890
0
      if (gmtime_r(&tim, &t) == NULL)
1891
0
        addf(str, "error: gmtime_r (%ld)\n",
1892
0
             (unsigned long)tim);
1893
0
      else if (strftime
1894
0
         (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1895
0
        addf(str, "error: strftime (%ld)\n",
1896
0
             (unsigned long)tim);
1897
0
      else
1898
0
        addf(str, _("\t\tNot Before: %s\n"), s);
1899
0
    } else {
1900
0
      addf(str, _("\t\tNot Before: %s\n"), _("unknown"));
1901
0
    }
1902
1903
0
    tim = gnutls_x509_crt_get_expiration_time(cert);
1904
0
    if (tim != -1) {
1905
0
      char s[42];
1906
0
      size_t max = sizeof(s);
1907
0
      struct tm t;
1908
1909
0
      if (gmtime_r(&tim, &t) == NULL)
1910
0
        addf(str, "error: gmtime_r (%ld)\n",
1911
0
             (unsigned long)tim);
1912
0
      else if (strftime
1913
0
         (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
1914
0
        addf(str, "error: strftime (%ld)\n",
1915
0
             (unsigned long)tim);
1916
0
      else
1917
0
        addf(str, _("\t\tNot After: %s\n"), s);
1918
0
    } else {
1919
0
      addf(str, _("\t\tNot After: %s\n"), _("unknown"));
1920
0
    }
1921
0
  }
1922
1923
  /* Subject. */
1924
0
  {
1925
0
    gnutls_datum_t dn;
1926
0
    int err;
1927
1928
0
    err = gnutls_x509_crt_get_dn3(cert, &dn, 0);
1929
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1930
0
      addf(str, _("\tSubject:\n"));
1931
0
    } else if (err < 0) {
1932
0
      addf(str, "error: get_dn: %s\n", gnutls_strerror(err));
1933
0
    } else {
1934
0
      addf(str, _("\tSubject: %s\n"), dn.data);
1935
0
      gnutls_free(dn.data);
1936
0
    }
1937
0
  }
1938
1939
  /* SubjectPublicKeyInfo. */
1940
0
  print_crt_pubkey(str, cert, format);
1941
1942
0
  print_unique_ids(str, cert);
1943
1944
  /* Extensions. */
1945
0
  if (gnutls_x509_crt_get_version(cert) >= 3) {
1946
0
    cert_type_t ccert;
1947
1948
0
    ccert.crt = cert;
1949
0
    print_extensions(str, "", TYPE_CRT, ccert);
1950
0
  }
1951
1952
  /* Signature. */
1953
0
  if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL) {
1954
0
    int err;
1955
0
    size_t size = 0;
1956
0
    char *buffer = NULL;
1957
0
    char *name;
1958
0
    const char *p;
1959
1960
0
    name = get_sign_name(cert, &err);
1961
0
    if (name == NULL)
1962
0
      p = _("unknown");
1963
0
    else
1964
0
      p = name;
1965
1966
0
    addf(str, _("\tSignature Algorithm: %s\n"), p);
1967
0
    gnutls_free(name);
1968
1969
0
    print_crt_sig_params(str, cert, format);
1970
1971
0
    if (err != GNUTLS_SIGN_UNKNOWN
1972
0
        && gnutls_sign_is_secure2(err,
1973
0
                GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS)
1974
0
        == 0) {
1975
0
      adds(str,
1976
0
           _("warning: signed using a broken signature "
1977
0
             "algorithm that can be forged.\n"));
1978
0
    }
1979
1980
0
    err = gnutls_x509_crt_get_signature(cert, buffer, &size);
1981
0
    if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) {
1982
0
      addf(str, "error: get_signature: %s\n",
1983
0
           gnutls_strerror(err));
1984
0
      return;
1985
0
    }
1986
1987
0
    buffer = gnutls_malloc(size);
1988
0
    if (!buffer) {
1989
0
      addf(str, "error: malloc: %s\n",
1990
0
           gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
1991
0
      return;
1992
0
    }
1993
1994
0
    err = gnutls_x509_crt_get_signature(cert, buffer, &size);
1995
0
    if (err < 0) {
1996
0
      gnutls_free(buffer);
1997
0
      addf(str, "error: get_signature2: %s\n",
1998
0
           gnutls_strerror(err));
1999
0
      return;
2000
0
    }
2001
2002
0
    adds(str, _("\tSignature:\n"));
2003
0
    _gnutls_buffer_hexdump(str, buffer, size, "\t\t");
2004
2005
0
    gnutls_free(buffer);
2006
0
  }
2007
0
}
2008
2009
static void print_fingerprint(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
2010
0
{
2011
0
  int err;
2012
0
  char buffer[MAX_HASH_SIZE];
2013
0
  size_t size = sizeof(buffer);
2014
2015
0
  adds(str, _("\tFingerprint:\n"));
2016
2017
0
  err =
2018
0
      gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buffer,
2019
0
              &size);
2020
0
  if (err < 0) {
2021
0
    addf(str, "error: get_fingerprint: %s\n", gnutls_strerror(err));
2022
0
    return;
2023
0
  }
2024
2025
0
  adds(str, _("\t\tsha1:"));
2026
0
  _gnutls_buffer_hexprint(str, buffer, size);
2027
0
  adds(str, "\n");
2028
2029
0
  size = sizeof(buffer);
2030
0
  err =
2031
0
      gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, buffer,
2032
0
              &size);
2033
0
  if (err < 0) {
2034
0
    addf(str, "error: get_fingerprint: %s\n", gnutls_strerror(err));
2035
0
    return;
2036
0
  }
2037
0
  adds(str, _("\t\tsha256:"));
2038
0
  _gnutls_buffer_hexprint(str, buffer, size);
2039
0
  adds(str, "\n");
2040
0
}
2041
2042
typedef int get_id_func(void *obj, unsigned, unsigned char *, size_t *);
2043
2044
static void print_obj_id(gnutls_buffer_st * str, const char *prefix, void *obj,
2045
       get_id_func * get_id)
2046
0
{
2047
0
  unsigned char sha1_buffer[MAX_HASH_SIZE];
2048
0
  unsigned char sha2_buffer[MAX_HASH_SIZE];
2049
0
  int err;
2050
0
  size_t sha1_size, sha2_size;
2051
2052
0
  sha1_size = sizeof(sha1_buffer);
2053
0
  err = get_id(obj, GNUTLS_KEYID_USE_SHA1, sha1_buffer, &sha1_size);
2054
0
  if (err == GNUTLS_E_UNIMPLEMENTED_FEATURE) /* unsupported algo */
2055
0
    return;
2056
2057
0
  if (err < 0) {
2058
0
    addf(str, "error: get_key_id(sha1): %s\n",
2059
0
         gnutls_strerror(err));
2060
0
    return;
2061
0
  }
2062
2063
0
  sha2_size = sizeof(sha2_buffer);
2064
0
  err = get_id(obj, GNUTLS_KEYID_USE_SHA256, sha2_buffer, &sha2_size);
2065
0
  if (err == GNUTLS_E_UNIMPLEMENTED_FEATURE) /* unsupported algo */
2066
0
    return;
2067
2068
0
  if (err < 0) {
2069
0
    addf(str, "error: get_key_id(sha256): %s\n",
2070
0
         gnutls_strerror(err));
2071
0
    return;
2072
0
  }
2073
2074
0
  addf(str, _("%sPublic Key ID:\n%s\tsha1:"), prefix, prefix);
2075
0
  _gnutls_buffer_hexprint(str, sha1_buffer, sha1_size);
2076
0
  addf(str, "\n%s\tsha256:", prefix);
2077
0
  _gnutls_buffer_hexprint(str, sha2_buffer, sha2_size);
2078
0
  adds(str, "\n");
2079
2080
0
  addf(str, _("%sPublic Key PIN:\n%s\tpin-sha256:"), prefix, prefix);
2081
0
  _gnutls_buffer_base64print(str, sha2_buffer, sha2_size);
2082
0
  adds(str, "\n");
2083
2084
0
  return;
2085
0
}
2086
2087
static void print_keyid(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
2088
0
{
2089
0
  int err;
2090
0
  const char *name;
2091
0
  unsigned int bits;
2092
0
  unsigned char sha1_buffer[MAX_HASH_SIZE];
2093
0
  size_t sha1_size;
2094
2095
0
  err = gnutls_x509_crt_get_pk_algorithm(cert, &bits);
2096
0
  if (err < 0)
2097
0
    return;
2098
2099
0
  print_obj_id(str, "\t", cert,
2100
0
         (get_id_func *) gnutls_x509_crt_get_key_id);
2101
2102
0
  if (IS_EC(err)) {
2103
0
    gnutls_ecc_curve_t curve;
2104
2105
0
    err = gnutls_x509_crt_get_pk_ecc_raw(cert, &curve, NULL, NULL);
2106
0
    if (err < 0)
2107
0
      return;
2108
2109
0
    name = gnutls_ecc_curve_get_name(curve);
2110
0
    bits = 0;
2111
0
  } else if (IS_GOSTEC(err)) {
2112
0
    gnutls_ecc_curve_t curve;
2113
2114
0
    err =
2115
0
        gnutls_x509_crt_get_pk_gost_raw(cert, &curve, NULL, NULL,
2116
0
                NULL, NULL);
2117
0
    if (err < 0)
2118
0
      return;
2119
2120
0
    name = gnutls_ecc_curve_get_name(curve);
2121
0
    bits = 0;
2122
0
  } else {
2123
0
    name = gnutls_pk_get_name(err);
2124
0
  }
2125
2126
0
  if (name == NULL)
2127
0
    return;
2128
2129
0
  sha1_size = sizeof(sha1_buffer);
2130
0
  err =
2131
0
      gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA1, sha1_buffer,
2132
0
               &sha1_size);
2133
0
  if (err == GNUTLS_E_UNIMPLEMENTED_FEATURE) /* unsupported algo */
2134
0
    return;
2135
0
}
2136
2137
static void
2138
print_other(gnutls_buffer_st * str, gnutls_x509_crt_t cert,
2139
      gnutls_certificate_print_formats_t format)
2140
0
{
2141
0
  if (format != GNUTLS_CRT_PRINT_UNSIGNED_FULL) {
2142
0
    print_fingerprint(str, cert);
2143
0
  }
2144
0
  print_keyid(str, cert);
2145
0
}
2146
2147
static void print_oneline(gnutls_buffer_st * str, gnutls_x509_crt_t cert)
2148
0
{
2149
0
  int err;
2150
2151
  /* Subject. */
2152
0
  {
2153
0
    gnutls_datum_t dn;
2154
2155
0
    err = gnutls_x509_crt_get_dn3(cert, &dn, 0);
2156
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2157
0
      addf(str, _("no subject,"));
2158
0
    } else if (err < 0) {
2159
0
      addf(str, "unknown subject (%s), ",
2160
0
           gnutls_strerror(err));
2161
0
    } else {
2162
0
      addf(str, "subject `%s', ", dn.data);
2163
0
      gnutls_free(dn.data);
2164
0
    }
2165
0
  }
2166
2167
  /* Issuer. */
2168
0
  {
2169
0
    gnutls_datum_t dn;
2170
2171
0
    err = gnutls_x509_crt_get_issuer_dn3(cert, &dn, 0);
2172
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2173
0
      addf(str, _("no issuer,"));
2174
0
    } else if (err < 0) {
2175
0
      addf(str, "unknown issuer (%s), ",
2176
0
           gnutls_strerror(err));
2177
0
    } else {
2178
0
      addf(str, "issuer `%s', ", dn.data);
2179
0
      gnutls_free(dn.data);
2180
0
    }
2181
0
  }
2182
2183
0
  {
2184
0
    char serial[128];
2185
0
    size_t serial_size = sizeof(serial);
2186
2187
0
    err = gnutls_x509_crt_get_serial(cert, serial, &serial_size);
2188
0
    if (err >= 0) {
2189
0
      adds(str, "serial 0x");
2190
0
      _gnutls_buffer_hexprint(str, serial, serial_size);
2191
0
      adds(str, ", ");
2192
0
    }
2193
0
  }
2194
2195
  /* Key algorithm and size. */
2196
0
  {
2197
0
    unsigned int bits;
2198
0
    const char *p;
2199
0
    char *name = get_pk_name(cert, &bits);
2200
0
    if (name == NULL)
2201
0
      p = _("unknown");
2202
0
    else
2203
0
      p = name;
2204
0
    addf(str, "%s key %d bits, ", p, bits);
2205
0
    gnutls_free(name);
2206
0
  }
2207
2208
  /* Signature Algorithm. */
2209
0
  {
2210
0
    char *name = get_sign_name(cert, &err);
2211
0
    const char *p;
2212
2213
0
    if (name == NULL)
2214
0
      p = _("unknown");
2215
0
    else
2216
0
      p = name;
2217
2218
0
    if (err != GNUTLS_SIGN_UNKNOWN
2219
0
        && gnutls_sign_is_secure2(err,
2220
0
                GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS)
2221
0
        == 0)
2222
0
      addf(str, _("signed using %s (broken!), "), p);
2223
0
    else
2224
0
      addf(str, _("signed using %s, "), p);
2225
0
    gnutls_free(name);
2226
0
  }
2227
2228
  /* Validity. */
2229
0
  {
2230
0
    time_t tim;
2231
2232
0
    tim = gnutls_x509_crt_get_activation_time(cert);
2233
0
    {
2234
0
      char s[42];
2235
0
      size_t max = sizeof(s);
2236
0
      struct tm t;
2237
2238
0
      if (gmtime_r(&tim, &t) == NULL)
2239
0
        addf(str, "unknown activation (%ld), ",
2240
0
             (unsigned long)tim);
2241
0
      else if (strftime
2242
0
         (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
2243
0
        addf(str, "failed activation (%ld), ",
2244
0
             (unsigned long)tim);
2245
0
      else
2246
0
        addf(str, "activated `%s', ", s);
2247
0
    }
2248
2249
0
    tim = gnutls_x509_crt_get_expiration_time(cert);
2250
0
    {
2251
0
      char s[42];
2252
0
      size_t max = sizeof(s);
2253
0
      struct tm t;
2254
2255
0
      if (gmtime_r(&tim, &t) == NULL)
2256
0
        addf(str, "unknown expiry (%ld), ",
2257
0
             (unsigned long)tim);
2258
0
      else if (strftime
2259
0
         (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
2260
0
        addf(str, "failed expiry (%ld), ",
2261
0
             (unsigned long)tim);
2262
0
      else
2263
0
        addf(str, "expires `%s', ", s);
2264
0
    }
2265
0
  }
2266
2267
0
  {
2268
0
    int pathlen;
2269
0
    char *policyLanguage;
2270
2271
0
    err = gnutls_x509_crt_get_proxy(cert, NULL,
2272
0
            &pathlen, &policyLanguage,
2273
0
            NULL, NULL);
2274
0
    if (err == 0) {
2275
0
      addf(str, "proxy certificate (policy=");
2276
0
      if (strcmp(policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
2277
0
        addf(str, "id-ppl-inheritALL");
2278
0
      else if (strcmp
2279
0
         (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
2280
0
        addf(str, "id-ppl-independent");
2281
0
      else
2282
0
        addf(str, "%s", policyLanguage);
2283
0
      if (pathlen >= 0)
2284
0
        addf(str, ", pathlen=%d), ", pathlen);
2285
0
      else
2286
0
        addf(str, "), ");
2287
0
      gnutls_free(policyLanguage);
2288
0
    }
2289
0
  }
2290
2291
0
  {
2292
0
    unsigned char buffer[MAX_HASH_SIZE];
2293
0
    size_t size = sizeof(buffer);
2294
2295
0
    err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256,
2296
0
             buffer, &size);
2297
0
    if (err >= 0) {
2298
0
      addf(str, "pin-sha256=\"");
2299
0
      _gnutls_buffer_base64print(str, buffer, size);
2300
0
      adds(str, "\"");
2301
0
    }
2302
0
  }
2303
2304
0
}
2305
2306
/**
2307
 * gnutls_x509_crt_print:
2308
 * @cert: The data to be printed
2309
 * @format: Indicate the format to use
2310
 * @out: Newly allocated datum with null terminated string.
2311
 *
2312
 * This function will pretty print a X.509 certificate, suitable for
2313
 * display to a human.
2314
 *
2315
 * If the format is %GNUTLS_CRT_PRINT_FULL then all fields of the
2316
 * certificate will be output, on multiple lines.  The
2317
 * %GNUTLS_CRT_PRINT_ONELINE format will generate one line with some
2318
 * selected fields, which is useful for logging purposes.
2319
 *
2320
 * The output @out needs to be deallocated using gnutls_free().
2321
 *
2322
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2323
 *   negative error value.
2324
 **/
2325
int
2326
gnutls_x509_crt_print(gnutls_x509_crt_t cert,
2327
          gnutls_certificate_print_formats_t format,
2328
          gnutls_datum_t * out)
2329
0
{
2330
0
  gnutls_buffer_st str;
2331
0
  int ret;
2332
2333
0
  if (format == GNUTLS_CRT_PRINT_COMPACT) {
2334
0
    _gnutls_buffer_init(&str);
2335
2336
0
    print_oneline(&str, cert);
2337
2338
0
    ret = _gnutls_buffer_append_data(&str, "\n", 1);
2339
0
    if (ret < 0)
2340
0
      return gnutls_assert_val(ret);
2341
2342
0
    print_keyid(&str, cert);
2343
2344
0
    return _gnutls_buffer_to_datum(&str, out, 1);
2345
0
  } else if (format == GNUTLS_CRT_PRINT_ONELINE) {
2346
0
    _gnutls_buffer_init(&str);
2347
2348
0
    print_oneline(&str, cert);
2349
2350
0
    return _gnutls_buffer_to_datum(&str, out, 1);
2351
0
  } else {
2352
0
    _gnutls_buffer_init(&str);
2353
2354
0
    _gnutls_buffer_append_str(&str,
2355
0
            _
2356
0
            ("X.509 Certificate Information:\n"));
2357
2358
0
    print_cert(&str, cert, format);
2359
2360
0
    _gnutls_buffer_append_str(&str, _("Other Information:\n"));
2361
2362
0
    print_other(&str, cert, format);
2363
2364
0
    return _gnutls_buffer_to_datum(&str, out, 1);
2365
0
  }
2366
0
}
2367
2368
static void
2369
print_crl(gnutls_buffer_st * str, gnutls_x509_crl_t crl, int notsigned)
2370
0
{
2371
  /* Version. */
2372
0
  {
2373
0
    int version = gnutls_x509_crl_get_version(crl);
2374
0
    if (version < 0)
2375
0
      addf(str, "error: get_version: %s\n",
2376
0
           gnutls_strerror(version));
2377
0
    else
2378
0
      addf(str, _("\tVersion: %d\n"), version);
2379
0
  }
2380
2381
  /* Issuer. */
2382
0
  if (!notsigned) {
2383
0
    gnutls_datum_t dn;
2384
0
    int err;
2385
2386
0
    err = gnutls_x509_crl_get_issuer_dn3(crl, &dn, 0);
2387
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2388
0
      addf(str, _("\tIssuer:\n"));
2389
0
    } else if (err < 0) {
2390
0
      addf(str, "error: get_issuer_dn: %s\n",
2391
0
           gnutls_strerror(err));
2392
0
    } else {
2393
0
      addf(str, _("\tIssuer: %s\n"), dn.data);
2394
0
      gnutls_free(dn.data);
2395
0
    }
2396
0
  }
2397
2398
  /* Validity. */
2399
0
  {
2400
0
    time_t tim;
2401
2402
0
    adds(str, _("\tUpdate dates:\n"));
2403
2404
0
    tim = gnutls_x509_crl_get_this_update(crl);
2405
0
    {
2406
0
      char s[42];
2407
0
      size_t max = sizeof(s);
2408
0
      struct tm t;
2409
2410
0
      if (gmtime_r(&tim, &t) == NULL)
2411
0
        addf(str, "error: gmtime_r (%ld)\n",
2412
0
             (unsigned long)tim);
2413
0
      else if (strftime
2414
0
         (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
2415
0
        addf(str, "error: strftime (%ld)\n",
2416
0
             (unsigned long)tim);
2417
0
      else
2418
0
        addf(str, _("\t\tIssued: %s\n"), s);
2419
0
    }
2420
2421
0
    tim = gnutls_x509_crl_get_next_update(crl);
2422
0
    {
2423
0
      char s[42];
2424
0
      size_t max = sizeof(s);
2425
0
      struct tm t;
2426
2427
0
      if (tim == -1)
2428
0
        addf(str, "\t\tNo next update time.\n");
2429
0
      else if (gmtime_r(&tim, &t) == NULL)
2430
0
        addf(str, "error: gmtime_r (%ld)\n",
2431
0
             (unsigned long)tim);
2432
0
      else if (strftime
2433
0
         (s, max, "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
2434
0
        addf(str, "error: strftime (%ld)\n",
2435
0
             (unsigned long)tim);
2436
0
      else
2437
0
        addf(str, _("\t\tNext at: %s\n"), s);
2438
0
    }
2439
0
  }
2440
2441
  /* Extensions. */
2442
0
  if (gnutls_x509_crl_get_version(crl) >= 2) {
2443
0
    size_t i;
2444
0
    int err = 0;
2445
0
    int aki_idx = 0;
2446
0
    int crl_nr = 0;
2447
2448
0
    for (i = 0;; i++) {
2449
0
      char oid[MAX_OID_SIZE] = "";
2450
0
      size_t sizeof_oid = sizeof(oid);
2451
0
      unsigned int critical;
2452
2453
0
      err = gnutls_x509_crl_get_extension_info(crl, i,
2454
0
                 oid,
2455
0
                 &sizeof_oid,
2456
0
                 &critical);
2457
0
      if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2458
0
        break;
2459
0
      if (err < 0) {
2460
0
        addf(str,
2461
0
             "error: get_extension_info: %s\n",
2462
0
             gnutls_strerror(err));
2463
0
        break;
2464
0
      }
2465
2466
0
      if (i == 0)
2467
0
        adds(str, _("\tExtensions:\n"));
2468
2469
0
      if (strcmp(oid, "2.5.29.20") == 0) {
2470
0
        char nr[128];
2471
0
        size_t nr_size = sizeof(nr);
2472
2473
0
        if (crl_nr) {
2474
0
          addf(str,
2475
0
               "warning: more than one CRL number\n");
2476
0
        }
2477
2478
0
        err =
2479
0
            gnutls_x509_crl_get_number(crl, nr,
2480
0
                     &nr_size,
2481
0
                     &critical);
2482
2483
0
        addf(str, _("\t\tCRL Number (%s): "),
2484
0
             critical ? _("critical") :
2485
0
             _("not critical"));
2486
2487
0
        if (err < 0)
2488
0
          addf(str,
2489
0
               "error: get_number: %s\n",
2490
0
               gnutls_strerror(err));
2491
0
        else {
2492
0
          _gnutls_buffer_hexprint(str, nr,
2493
0
                nr_size);
2494
0
          addf(str, "\n");
2495
0
        }
2496
2497
0
        crl_nr++;
2498
0
      } else if (strcmp(oid, "2.5.29.35") == 0) {
2499
0
        gnutls_datum_t der;
2500
2501
0
        if (aki_idx) {
2502
0
          addf(str,
2503
0
               "warning: more than one AKI extension\n");
2504
0
        }
2505
2506
0
        addf(str,
2507
0
             _
2508
0
             ("\t\tAuthority Key Identifier (%s):\n"),
2509
0
             critical ? _("critical") :
2510
0
             _("not critical"));
2511
2512
0
        err =
2513
0
            gnutls_x509_crl_get_extension_data2(crl, i,
2514
0
                  &der);
2515
0
        if (err < 0) {
2516
0
          addf(str,
2517
0
               "error: get_extension_data2: %s\n",
2518
0
               gnutls_strerror(err));
2519
0
          continue;
2520
0
        }
2521
0
        print_aki(str, &der);
2522
0
        gnutls_free(der.data);
2523
2524
0
        aki_idx++;
2525
0
      } else {
2526
0
        gnutls_datum_t der;
2527
2528
0
        addf(str,
2529
0
             _("\t\tUnknown extension %s (%s):\n"),
2530
0
             oid,
2531
0
             critical ? _("critical") :
2532
0
             _("not critical"));
2533
2534
0
        err =
2535
0
            gnutls_x509_crl_get_extension_data2(crl,
2536
0
                  i,
2537
0
                  &der);
2538
0
        if (err < 0) {
2539
0
          addf(str,
2540
0
               "error: get_extension_data2: %s\n",
2541
0
               gnutls_strerror(err));
2542
0
          continue;
2543
0
        }
2544
2545
0
        adds(str, _("\t\t\tASCII: "));
2546
0
        _gnutls_buffer_asciiprint(str, (char *)der.data,
2547
0
                der.size);
2548
0
        adds(str, "\n");
2549
2550
0
        adds(str, _("\t\t\tHexdump: "));
2551
0
        _gnutls_buffer_hexprint(str, der.data,
2552
0
              der.size);
2553
0
        adds(str, "\n");
2554
2555
0
        gnutls_free(der.data);
2556
0
      }
2557
0
    }
2558
0
  }
2559
2560
  /* Revoked certificates. */
2561
0
  {
2562
0
    int num = gnutls_x509_crl_get_crt_count(crl);
2563
0
    gnutls_x509_crl_iter_t iter = NULL;
2564
0
    int j;
2565
2566
0
    if (num)
2567
0
      addf(str, _("\tRevoked certificates (%d):\n"), num);
2568
0
    else
2569
0
      adds(str, _("\tNo revoked certificates.\n"));
2570
2571
0
    for (j = 0; j < num; j++) {
2572
0
      unsigned char serial[128];
2573
0
      size_t serial_size = sizeof(serial);
2574
0
      int err;
2575
0
      time_t tim;
2576
2577
0
      err =
2578
0
          gnutls_x509_crl_iter_crt_serial(crl, &iter, serial,
2579
0
                  &serial_size, &tim);
2580
0
      if (err < 0) {
2581
0
        addf(str, "error: iter_crt_serial: %s\n",
2582
0
             gnutls_strerror(err));
2583
0
        break;
2584
0
      } else {
2585
0
        char s[42];
2586
0
        size_t max = sizeof(s);
2587
0
        struct tm t;
2588
2589
0
        adds(str, _("\t\tSerial Number (hex): "));
2590
0
        _gnutls_buffer_hexprint(str, serial,
2591
0
              serial_size);
2592
0
        adds(str, "\n");
2593
2594
0
        if (gmtime_r(&tim, &t) == NULL)
2595
0
          addf(str,
2596
0
               "error: gmtime_r (%ld)\n",
2597
0
               (unsigned long)tim);
2598
0
        else if (strftime
2599
0
           (s, max,
2600
0
            "%a %b %d %H:%M:%S UTC %Y", &t) == 0)
2601
0
          addf(str,
2602
0
               "error: strftime (%ld)\n",
2603
0
               (unsigned long)tim);
2604
0
        else
2605
0
          addf(str, _("\t\tRevoked at: %s\n"), s);
2606
0
      }
2607
0
    }
2608
0
    gnutls_x509_crl_iter_deinit(iter);
2609
0
  }
2610
2611
  /* Signature. */
2612
0
  if (!notsigned) {
2613
0
    int err;
2614
0
    size_t size = 0;
2615
0
    char *buffer = NULL;
2616
0
    char *name;
2617
0
    const char *p;
2618
2619
0
    name = crl_get_sign_name(crl, &err);
2620
0
    if (name == NULL)
2621
0
      p = _("unknown");
2622
0
    else
2623
0
      p = name;
2624
2625
0
    addf(str, _("\tSignature Algorithm: %s\n"), p);
2626
0
    gnutls_free(name);
2627
2628
0
    if (err != GNUTLS_SIGN_UNKNOWN
2629
0
        && gnutls_sign_is_secure2(err,
2630
0
                GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS)
2631
0
        == 0) {
2632
0
      adds(str,
2633
0
           _("warning: signed using a broken signature "
2634
0
             "algorithm that can be forged.\n"));
2635
0
    }
2636
2637
0
    err = gnutls_x509_crl_get_signature(crl, buffer, &size);
2638
0
    if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) {
2639
0
      addf(str, "error: get_signature: %s\n",
2640
0
           gnutls_strerror(err));
2641
0
      return;
2642
0
    }
2643
2644
0
    buffer = gnutls_malloc(size);
2645
0
    if (!buffer) {
2646
0
      addf(str, "error: malloc: %s\n",
2647
0
           gnutls_strerror(GNUTLS_E_MEMORY_ERROR));
2648
0
      return;
2649
0
    }
2650
2651
0
    err = gnutls_x509_crl_get_signature(crl, buffer, &size);
2652
0
    if (err < 0) {
2653
0
      gnutls_free(buffer);
2654
0
      addf(str, "error: get_signature2: %s\n",
2655
0
           gnutls_strerror(err));
2656
0
      return;
2657
0
    }
2658
2659
0
    adds(str, _("\tSignature:\n"));
2660
0
    _gnutls_buffer_hexdump(str, buffer, size, "\t\t");
2661
2662
0
    gnutls_free(buffer);
2663
0
  }
2664
0
}
2665
2666
/**
2667
 * gnutls_x509_crl_print:
2668
 * @crl: The data to be printed
2669
 * @format: Indicate the format to use
2670
 * @out: Newly allocated datum with null terminated string.
2671
 *
2672
 * This function will pretty print a X.509 certificate revocation
2673
 * list, suitable for display to a human.
2674
 *
2675
 * The output @out needs to be deallocated using gnutls_free().
2676
 *
2677
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2678
 *   negative error value.
2679
 **/
2680
int
2681
gnutls_x509_crl_print(gnutls_x509_crl_t crl,
2682
          gnutls_certificate_print_formats_t format,
2683
          gnutls_datum_t * out)
2684
0
{
2685
0
  gnutls_buffer_st str;
2686
2687
0
  _gnutls_buffer_init(&str);
2688
2689
0
  _gnutls_buffer_append_str
2690
0
      (&str, _("X.509 Certificate Revocation List Information:\n"));
2691
2692
0
  print_crl(&str, crl, format == GNUTLS_CRT_PRINT_UNSIGNED_FULL);
2693
2694
0
  return _gnutls_buffer_to_datum(&str, out, 1);
2695
0
}
2696
2697
static int
2698
print_crq_sig_params(gnutls_buffer_st * str, gnutls_x509_crq_t crt,
2699
         gnutls_certificate_print_formats_t format)
2700
0
{
2701
0
  int ret;
2702
0
  gnutls_pk_algorithm_t pk;
2703
0
  gnutls_x509_spki_st params;
2704
0
  gnutls_sign_algorithm_t sign;
2705
2706
0
  sign = gnutls_x509_crq_get_signature_algorithm(crt);
2707
0
  pk = gnutls_sign_get_pk_algorithm(sign);
2708
0
  if (pk == GNUTLS_PK_RSA_PSS) {
2709
0
    ret = _gnutls_x509_read_sign_params(crt->crq,
2710
0
                "signatureAlgorithm",
2711
0
                &params);
2712
0
    if (ret < 0) {
2713
0
      addf(str, "error: read_pss_params: %s\n",
2714
0
           gnutls_strerror(ret));
2715
0
    } else
2716
0
      addf(str, "\t\tSalt Length: %d\n", params.salt_size);
2717
0
  }
2718
2719
0
  return 0;
2720
0
}
2721
2722
static int
2723
print_crq_pubkey(gnutls_buffer_st * str, gnutls_x509_crq_t crq,
2724
     gnutls_certificate_print_formats_t format)
2725
0
{
2726
0
  gnutls_pubkey_t pubkey;
2727
0
  gnutls_x509_spki_st params;
2728
0
  int ret;
2729
2730
0
  ret = _gnutls_x509_crq_read_spki_params(crq, &params);
2731
0
  if (ret < 0)
2732
0
    return ret;
2733
2734
0
  ret = gnutls_pubkey_init(&pubkey);
2735
0
  if (ret < 0)
2736
0
    return ret;
2737
2738
0
  ret = gnutls_pubkey_import_x509_crq(pubkey, crq, 0);
2739
0
  if (ret < 0)
2740
0
    goto cleanup;
2741
2742
0
  print_pubkey(str, _("Subject "), pubkey, &params, format);
2743
0
  ret = 0;
2744
2745
0
 cleanup:
2746
0
  gnutls_pubkey_deinit(pubkey);
2747
2748
0
  if (ret < 0) {   /* print only name */
2749
0
    const char *p;
2750
0
    char *name = crq_get_pk_name(crq);
2751
0
    if (name == NULL)
2752
0
      p = _("unknown");
2753
0
    else
2754
0
      p = name;
2755
2756
0
    addf(str, "\tSubject Public Key Algorithm: %s\n", p);
2757
0
    gnutls_free(name);
2758
0
    ret = 0;
2759
0
  }
2760
2761
0
  return ret;
2762
0
}
2763
2764
static void
2765
print_crq(gnutls_buffer_st * str, gnutls_x509_crq_t cert,
2766
    gnutls_certificate_print_formats_t format)
2767
0
{
2768
  /* Version. */
2769
0
  {
2770
0
    int version = gnutls_x509_crq_get_version(cert);
2771
0
    if (version < 0)
2772
0
      addf(str, "error: get_version: %s\n",
2773
0
           gnutls_strerror(version));
2774
0
    else
2775
0
      addf(str, _("\tVersion: %d\n"), version);
2776
0
  }
2777
2778
  /* Subject */
2779
0
  {
2780
0
    gnutls_datum_t dn;
2781
0
    int err;
2782
2783
0
    err = gnutls_x509_crq_get_dn3(cert, &dn, 0);
2784
0
    if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2785
0
      addf(str, _("\tSubject:\n"));
2786
0
    } else if (err < 0) {
2787
0
      addf(str, "error: get_dn: %s\n", gnutls_strerror(err));
2788
0
    } else {
2789
0
      addf(str, _("\tSubject: %s\n"), dn.data);
2790
0
      gnutls_free(dn.data);
2791
0
    }
2792
0
  }
2793
2794
0
  {
2795
0
    char *name;
2796
0
    const char *p;
2797
2798
0
    print_crq_pubkey(str, cert, format);
2799
2800
0
    name = crq_get_sign_name(cert);
2801
0
    if (name == NULL)
2802
0
      p = _("unknown");
2803
0
    else
2804
0
      p = name;
2805
2806
0
    addf(str, _("\tSignature Algorithm: %s\n"), p);
2807
2808
0
    gnutls_free(name);
2809
2810
0
    print_crq_sig_params(str, cert, format);
2811
0
  }
2812
2813
  /* parse attributes */
2814
0
  {
2815
0
    size_t i;
2816
0
    int err = 0;
2817
0
    int extensions = 0;
2818
0
    int challenge = 0;
2819
2820
0
    for (i = 0;; i++) {
2821
0
      char oid[MAX_OID_SIZE] = "";
2822
0
      size_t sizeof_oid = sizeof(oid);
2823
2824
0
      err =
2825
0
          gnutls_x509_crq_get_attribute_info(cert, i,
2826
0
                     oid,
2827
0
                     &sizeof_oid);
2828
0
      if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
2829
0
        break;
2830
0
      if (err < 0) {
2831
0
        addf(str,
2832
0
             "error: get_extension_info: %s\n",
2833
0
             gnutls_strerror(err));
2834
0
        break;
2835
0
      }
2836
2837
0
      if (i == 0)
2838
0
        adds(str, _("\tAttributes:\n"));
2839
2840
0
      if (strcmp(oid, "1.2.840.113549.1.9.14") == 0) {
2841
0
        cert_type_t ccert;
2842
2843
0
        if (extensions) {
2844
0
          addf(str,
2845
0
               "warning: more than one extensionsRequest\n");
2846
0
        }
2847
2848
0
        ccert.crq = cert;
2849
0
        print_extensions(str, "\t", TYPE_CRQ, ccert);
2850
2851
0
        extensions++;
2852
0
      } else if (strcmp(oid, "1.2.840.113549.1.9.7") == 0) {
2853
0
        char *pass;
2854
0
        size_t size;
2855
2856
0
        if (challenge) {
2857
0
          adds(str,
2858
0
               "warning: more than one Challenge password attribute\n");
2859
0
        }
2860
2861
0
        err =
2862
0
            gnutls_x509_crq_get_challenge_password
2863
0
            (cert, NULL, &size);
2864
0
        if (err < 0
2865
0
            && err != GNUTLS_E_SHORT_MEMORY_BUFFER) {
2866
0
          addf(str,
2867
0
               "error: get_challenge_password: %s\n",
2868
0
               gnutls_strerror(err));
2869
0
          continue;
2870
0
        }
2871
2872
0
        size++;
2873
2874
0
        pass = gnutls_malloc(size);
2875
0
        if (!pass) {
2876
0
          addf(str, "error: malloc: %s\n",
2877
0
               gnutls_strerror
2878
0
               (GNUTLS_E_MEMORY_ERROR));
2879
0
          continue;
2880
0
        }
2881
2882
0
        err =
2883
0
            gnutls_x509_crq_get_challenge_password
2884
0
            (cert, pass, &size);
2885
0
        if (err < 0)
2886
0
          addf(str,
2887
0
               "error: get_challenge_password: %s\n",
2888
0
               gnutls_strerror(err));
2889
0
        else
2890
0
          addf(str,
2891
0
               _
2892
0
               ("\t\tChallenge password: %s\n"),
2893
0
               pass);
2894
2895
0
        gnutls_free(pass);
2896
2897
0
        challenge++;
2898
0
      } else {
2899
0
        char *buffer;
2900
0
        size_t extlen = 0;
2901
2902
0
        addf(str, _("\t\tUnknown attribute %s:\n"),
2903
0
             oid);
2904
2905
0
        err =
2906
0
            gnutls_x509_crq_get_attribute_data
2907
0
            (cert, i, NULL, &extlen);
2908
0
        if (err < 0) {
2909
0
          addf(str,
2910
0
               "error: get_attribute_data: %s\n",
2911
0
               gnutls_strerror(err));
2912
0
          continue;
2913
0
        }
2914
2915
0
        buffer = gnutls_malloc(extlen);
2916
0
        if (!buffer) {
2917
0
          addf(str, "error: malloc: %s\n",
2918
0
               gnutls_strerror
2919
0
               (GNUTLS_E_MEMORY_ERROR));
2920
0
          continue;
2921
0
        }
2922
2923
0
        err =
2924
0
            gnutls_x509_crq_get_attribute_data
2925
0
            (cert, i, buffer, &extlen);
2926
0
        if (err < 0) {
2927
0
          gnutls_free(buffer);
2928
0
          addf(str,
2929
0
               "error: get_attribute_data2: %s\n",
2930
0
               gnutls_strerror(err));
2931
0
          continue;
2932
0
        }
2933
2934
0
        adds(str, _("\t\t\tASCII: "));
2935
0
        _gnutls_buffer_asciiprint(str, buffer, extlen);
2936
0
        adds(str, "\n");
2937
2938
0
        adds(str, _("\t\t\tHexdump: "));
2939
0
        _gnutls_buffer_hexprint(str, buffer, extlen);
2940
0
        adds(str, "\n");
2941
2942
0
        gnutls_free(buffer);
2943
0
      }
2944
0
    }
2945
0
  }
2946
0
}
2947
2948
static void print_crq_other(gnutls_buffer_st * str, gnutls_x509_crq_t crq)
2949
0
{
2950
0
  int ret;
2951
2952
  /* on unknown public key algorithms don't print the key ID */
2953
0
  ret = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
2954
0
  if (ret < 0)
2955
0
    return;
2956
2957
0
  print_obj_id(str, "\t", crq,
2958
0
         (get_id_func *) gnutls_x509_crq_get_key_id);
2959
0
}
2960
2961
/**
2962
 * gnutls_x509_crq_print:
2963
 * @crq: The data to be printed
2964
 * @format: Indicate the format to use
2965
 * @out: Newly allocated datum with null terminated string.
2966
 *
2967
 * This function will pretty print a certificate request, suitable for
2968
 * display to a human.
2969
 *
2970
 * The output @out needs to be deallocated using gnutls_free().
2971
 *
2972
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2973
 *   negative error value.
2974
 *
2975
 * Since: 2.8.0
2976
 **/
2977
int
2978
gnutls_x509_crq_print(gnutls_x509_crq_t crq,
2979
          gnutls_certificate_print_formats_t format,
2980
          gnutls_datum_t * out)
2981
0
{
2982
0
  gnutls_buffer_st str;
2983
2984
0
  _gnutls_buffer_init(&str);
2985
2986
0
  _gnutls_buffer_append_str
2987
0
      (&str, _("PKCS #10 Certificate Request Information:\n"));
2988
2989
0
  print_crq(&str, crq, format);
2990
2991
0
  _gnutls_buffer_append_str(&str, _("Other Information:\n"));
2992
2993
0
  print_crq_other(&str, crq);
2994
2995
0
  return _gnutls_buffer_to_datum(&str, out, 1);
2996
0
}
2997
2998
static void
2999
print_pubkey_other(gnutls_buffer_st * str, gnutls_pubkey_t pubkey,
3000
       gnutls_certificate_print_formats_t format)
3001
0
{
3002
0
  int ret;
3003
0
  unsigned int usage;
3004
3005
0
  ret = gnutls_pubkey_get_key_usage(pubkey, &usage);
3006
0
  if (ret < 0) {
3007
0
    addf(str, "error: get_key_usage: %s\n", gnutls_strerror(ret));
3008
0
    return;
3009
0
  }
3010
3011
0
  adds(str, "\n");
3012
0
  if (pubkey->key_usage) {
3013
0
    adds(str, _("Public Key Usage:\n"));
3014
0
    print_key_usage2(str, "\t", pubkey->key_usage);
3015
0
  }
3016
3017
  /* on unknown public key algorithms don't print the key ID */
3018
0
  ret = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
3019
0
  if (ret < 0)
3020
0
    return;
3021
3022
0
  print_obj_id(str, "", pubkey, (get_id_func *) gnutls_pubkey_get_key_id);
3023
0
}
3024
3025
/**
3026
 * gnutls_pubkey_print:
3027
 * @pubkey: The data to be printed
3028
 * @format: Indicate the format to use
3029
 * @out: Newly allocated datum with null terminated string.
3030
 *
3031
 * This function will pretty print public key information, suitable for
3032
 * display to a human.
3033
 *
3034
 * Only %GNUTLS_CRT_PRINT_FULL and %GNUTLS_CRT_PRINT_FULL_NUMBERS
3035
 * are implemented.
3036
 *
3037
 * The output @out needs to be deallocated using gnutls_free().
3038
 *
3039
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
3040
 *   negative error value.
3041
 *
3042
 * Since: 3.1.5
3043
 **/
3044
int
3045
gnutls_pubkey_print(gnutls_pubkey_t pubkey,
3046
        gnutls_certificate_print_formats_t format,
3047
        gnutls_datum_t * out)
3048
0
{
3049
0
  gnutls_buffer_st str;
3050
3051
0
  _gnutls_buffer_init(&str);
3052
3053
0
  _gnutls_buffer_append_str(&str, _("Public Key Information:\n"));
3054
3055
0
  print_pubkey(&str, "", pubkey, NULL, format);
3056
0
  print_pubkey_other(&str, pubkey, format);
3057
3058
0
  return _gnutls_buffer_to_datum(&str, out, 1);
3059
0
}
3060
3061
/**
3062
 * gnutls_x509_ext_print:
3063
 * @exts: The data to be printed
3064
 * @exts_size: the number of available structures
3065
 * @format: Indicate the format to use
3066
 * @out: Newly allocated datum with null terminated string.
3067
 *
3068
 * This function will pretty print X.509 certificate extensions,
3069
 * suitable for display to a human.
3070
 *
3071
 * The output @out needs to be deallocated using gnutls_free().
3072
 *
3073
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
3074
 *   negative error value.
3075
 **/
3076
int
3077
gnutls_x509_ext_print(gnutls_x509_ext_st * exts, unsigned int exts_size,
3078
          gnutls_certificate_print_formats_t format,
3079
          gnutls_datum_t * out)
3080
0
{
3081
0
  gnutls_buffer_st str;
3082
0
  struct ext_indexes_st idx;
3083
0
  unsigned i;
3084
3085
0
  memset(&idx, 0, sizeof(idx));
3086
0
  _gnutls_buffer_init(&str);
3087
3088
0
  for (i = 0; i < exts_size; i++)
3089
0
    print_extension(&str, "", &idx, (char *)exts[i].oid,
3090
0
        exts[i].critical, &exts[i].data);
3091
3092
0
  return _gnutls_buffer_to_datum(&str, out, 1);
3093
0
}