1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci#include <openssl/objects.h>
13e1051a39Sopenharmony_ci#include <openssl/buffer.h>
14e1051a39Sopenharmony_ci#include "crypto/bn.h"
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci/* Number of octets per line */
17e1051a39Sopenharmony_ci#define ASN1_BUF_PRINT_WIDTH    15
18e1051a39Sopenharmony_ci/* Maximum indent */
19e1051a39Sopenharmony_ci#define ASN1_PRINT_MAX_INDENT 128
20e1051a39Sopenharmony_ci
21e1051a39Sopenharmony_ciint ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int indent)
22e1051a39Sopenharmony_ci{
23e1051a39Sopenharmony_ci    size_t i;
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci    for (i = 0; i < buflen; i++) {
26e1051a39Sopenharmony_ci        if ((i % ASN1_BUF_PRINT_WIDTH) == 0) {
27e1051a39Sopenharmony_ci            if (i > 0 && BIO_puts(bp, "\n") <= 0)
28e1051a39Sopenharmony_ci                return 0;
29e1051a39Sopenharmony_ci            if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
30e1051a39Sopenharmony_ci                return 0;
31e1051a39Sopenharmony_ci        }
32e1051a39Sopenharmony_ci        /*
33e1051a39Sopenharmony_ci         * Use colon separators for each octet for compatibility as
34e1051a39Sopenharmony_ci         * this function is used to print out key components.
35e1051a39Sopenharmony_ci         */
36e1051a39Sopenharmony_ci        if (BIO_printf(bp, "%02x%s", buf[i],
37e1051a39Sopenharmony_ci                       (i == buflen - 1) ? "" : ":") <= 0)
38e1051a39Sopenharmony_ci                return 0;
39e1051a39Sopenharmony_ci    }
40e1051a39Sopenharmony_ci    if (BIO_write(bp, "\n", 1) <= 0)
41e1051a39Sopenharmony_ci        return 0;
42e1051a39Sopenharmony_ci    return 1;
43e1051a39Sopenharmony_ci}
44e1051a39Sopenharmony_ci
45e1051a39Sopenharmony_ciint ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
46e1051a39Sopenharmony_ci                  unsigned char *ign, int indent)
47e1051a39Sopenharmony_ci{
48e1051a39Sopenharmony_ci    int n, rv = 0;
49e1051a39Sopenharmony_ci    const char *neg;
50e1051a39Sopenharmony_ci    unsigned char *buf = NULL, *tmp = NULL;
51e1051a39Sopenharmony_ci    int buflen;
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci    if (num == NULL)
54e1051a39Sopenharmony_ci        return 1;
55e1051a39Sopenharmony_ci    neg = BN_is_negative(num) ? "-" : "";
56e1051a39Sopenharmony_ci    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
57e1051a39Sopenharmony_ci        return 0;
58e1051a39Sopenharmony_ci    if (BN_is_zero(num)) {
59e1051a39Sopenharmony_ci        if (BIO_printf(bp, "%s 0\n", number) <= 0)
60e1051a39Sopenharmony_ci            return 0;
61e1051a39Sopenharmony_ci        return 1;
62e1051a39Sopenharmony_ci    }
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ci    if (BN_num_bytes(num) <= BN_BYTES) {
65e1051a39Sopenharmony_ci        if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
66e1051a39Sopenharmony_ci                       (unsigned long)bn_get_words(num)[0], neg,
67e1051a39Sopenharmony_ci                       (unsigned long)bn_get_words(num)[0]) <= 0)
68e1051a39Sopenharmony_ci            return 0;
69e1051a39Sopenharmony_ci        return 1;
70e1051a39Sopenharmony_ci    }
71e1051a39Sopenharmony_ci
72e1051a39Sopenharmony_ci    buflen = BN_num_bytes(num) + 1;
73e1051a39Sopenharmony_ci    buf = tmp = OPENSSL_malloc(buflen);
74e1051a39Sopenharmony_ci    if (buf == NULL)
75e1051a39Sopenharmony_ci        goto err;
76e1051a39Sopenharmony_ci    buf[0] = 0;
77e1051a39Sopenharmony_ci    if (BIO_printf(bp, "%s%s\n", number,
78e1051a39Sopenharmony_ci                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
79e1051a39Sopenharmony_ci        goto err;
80e1051a39Sopenharmony_ci    n = BN_bn2bin(num, buf + 1);
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci    if (buf[1] & 0x80)
83e1051a39Sopenharmony_ci        n++;
84e1051a39Sopenharmony_ci    else
85e1051a39Sopenharmony_ci        tmp++;
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
88e1051a39Sopenharmony_ci        goto err;
89e1051a39Sopenharmony_ci    rv = 1;
90e1051a39Sopenharmony_ci    err:
91e1051a39Sopenharmony_ci    OPENSSL_clear_free(buf, buflen);
92e1051a39Sopenharmony_ci    return rv;
93e1051a39Sopenharmony_ci}
94