1139747Simp/*
24Srgrimes * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
34Srgrimes *
44Srgrimes * Licensed under the Apache License 2.0 (the "License").  You may not use
58876Srgrimes * this file except in compliance with the License.  You can obtain a copy
64Srgrimes * in the file LICENSE in the source distribution or at
74Srgrimes * https://www.openssl.org/source/license.html
84Srgrimes */
94Srgrimes
104Srgrimes#include <stdio.h>
118876Srgrimes#include "crypto/ctype.h"
128876Srgrimes#include "internal/cryptlib.h"
134Srgrimes#include <openssl/buffer.h>
144Srgrimes#include <openssl/asn1.h>
158876Srgrimes
164Srgrimesint i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
178876Srgrimes{
184Srgrimes    int i, n = 0;
194Srgrimes    static const char *h = "0123456789ABCDEF";
204Srgrimes    char buf[2];
214Srgrimes
228876Srgrimes    if (a == NULL)
234Srgrimes        return 0;
244Srgrimes
254Srgrimes    if (a->type & V_ASN1_NEG) {
264Srgrimes        if (BIO_write(bp, "-", 1) != 1)
274Srgrimes            goto err;
284Srgrimes        n = 1;
294Srgrimes    }
304Srgrimes
314Srgrimes    if (a->length == 0) {
324Srgrimes        if (BIO_write(bp, "00", 2) != 2)
33116176Sobrien            goto err;
34116176Sobrien        n += 2;
35116176Sobrien    } else {
36116176Sobrien        for (i = 0; i < a->length; i++) {
372056Swollman            if ((i != 0) && (i % 35 == 0)) {
3842654Sjdp                if (BIO_write(bp, "\\\n", 2) != 2)
3986998Sdd                    goto err;
40131952Smarcel                n += 2;
4186998Sdd            }
4286998Sdd            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
4317848Spst            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
4486998Sdd            if (BIO_write(bp, buf, 2) != 2)
452056Swollman                goto err;
4649558Sphk            n += 2;
47222801Smarcel        }
48126399Sphk    }
49183054Ssam    return n;
5012734Sbde err:
512056Swollman    return -1;
5212473Sbde}
534Srgrimes
544Srgrimesint a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
554Srgrimes{
56118990Smarcel    int i, j, k, m, n, again, bufsize;
5779418Sjulian    unsigned char *s = NULL, *sp;
584Srgrimes    unsigned char *bufp;
594Srgrimes    int num = 0, slen = 0, first = 1;
604Srgrimes
614Srgrimes    bs->type = V_ASN1_INTEGER;
62283248Spfg
6318296Sbde    bufsize = BIO_gets(bp, buf, size);
644Srgrimes    for (;;) {
654Srgrimes        if (bufsize < 1)
664Srgrimes            goto err;
674Srgrimes        i = bufsize;
68222801Smarcel        if (buf[i - 1] == '\n')
6912515Sphk            buf[--i] = '\0';
70132002Smarcel        if (i == 0)
71163192Sbde            goto err;
7286998Sdd        if (buf[i - 1] == '\r')
7385944Speter            buf[--i] = '\0';
74132482Smarcel        if (i == 0)
75150819Srwatson            goto err;
76126399Sphk        again = (buf[i - 1] == '\\');
7717848Spst
78148919Sobrien        for (j = 0; j < i; j++) {
79148919Sobrien            if (!ossl_isxdigit(buf[j]))
80148919Sobrien            {
8118296Sbde                i = j;
82148919Sobrien                break;
83283296Spfg            }
84148919Sobrien        }
85183054Ssam        buf[i] = '\0';
86183054Ssam        /*
87148919Sobrien         * We have now cleared all the crap off the end of the line
88148919Sobrien         */
89156412Sjhb        if (i < 2)
90283296Spfg            goto err;
91283296Spfg
92283296Spfg        bufp = (unsigned char *)buf;
93148919Sobrien        if (first) {
94183054Ssam            first = 0;
95148919Sobrien            if ((bufp[0] == '0') && (bufp[1] == '0')) {
96183054Ssam                bufp += 2;
97283296Spfg                i -= 2;
98283296Spfg            }
99283296Spfg        }
100283296Spfg        k = 0;
101283296Spfg        i -= again;
102283296Spfg        if (i % 2 != 0) {
103283296Spfg            ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
104283296Spfg            OPENSSL_free(s);
105283296Spfg            return 0;
106283296Spfg        }
107283296Spfg        i /= 2;
108283296Spfg        if (num + i > slen) {
109283296Spfg            sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
110283296Spfg            if (sp == NULL) {
111283296Spfg                ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
112283296Spfg                OPENSSL_free(s);
113283296Spfg                return 0;
114283296Spfg            }
115283296Spfg            s = sp;
116283296Spfg            slen = num + i * 2;
117283296Spfg        }
118283296Spfg        for (j = 0; j < i; j++, k += 2) {
119283296Spfg            for (n = 0; n < 2; n++) {
120283296Spfg                m = OPENSSL_hexchar2int(bufp[k + n]);
121283296Spfg                if (m < 0) {
122283296Spfg                    ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS);
123183054Ssam                    goto err;
124283296Spfg                }
125283296Spfg                s[num + j] <<= 4;
126283296Spfg                s[num + j] |= m;
127283296Spfg            }
128156412Sjhb        }
129283296Spfg        num += i;
130283296Spfg        if (again)
131283296Spfg            bufsize = BIO_gets(bp, buf, size);
132283296Spfg        else
133283296Spfg            break;
134283296Spfg    }
135283296Spfg    bs->length = num;
136283296Spfg    bs->data = s;
137283296Spfg    return 1;
138283296Spfg err:
139283296Spfg    ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE);
140283296Spfg    OPENSSL_free(s);
141283296Spfg    return 0;
142283296Spfg}
143283296Spfg
144148919Sobrienint i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
145183054Ssam{
146148919Sobrien    return i2a_ASN1_INTEGER(bp, a);
147148919Sobrien}
148148919Sobrien
1494Srgrimesint a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
1504Srgrimes{
1514Srgrimes    int rv = a2i_ASN1_INTEGER(bp, bs, buf, size);
1524Srgrimes    if (rv == 1)
1534Srgrimes        bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG);
154283248Spfg    return rv;
1554Srgrimes}
1564Srgrimes