1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2020 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 "crypto/ctype.h" 12e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 13e1051a39Sopenharmony_ci#include <openssl/buffer.h> 14e1051a39Sopenharmony_ci#include <openssl/asn1.h> 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ciint i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a) 17e1051a39Sopenharmony_ci{ 18e1051a39Sopenharmony_ci int i, n = 0; 19e1051a39Sopenharmony_ci static const char *h = "0123456789ABCDEF"; 20e1051a39Sopenharmony_ci char buf[2]; 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci if (a == NULL) 23e1051a39Sopenharmony_ci return 0; 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci if (a->type & V_ASN1_NEG) { 26e1051a39Sopenharmony_ci if (BIO_write(bp, "-", 1) != 1) 27e1051a39Sopenharmony_ci goto err; 28e1051a39Sopenharmony_ci n = 1; 29e1051a39Sopenharmony_ci } 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ci if (a->length == 0) { 32e1051a39Sopenharmony_ci if (BIO_write(bp, "00", 2) != 2) 33e1051a39Sopenharmony_ci goto err; 34e1051a39Sopenharmony_ci n += 2; 35e1051a39Sopenharmony_ci } else { 36e1051a39Sopenharmony_ci for (i = 0; i < a->length; i++) { 37e1051a39Sopenharmony_ci if ((i != 0) && (i % 35 == 0)) { 38e1051a39Sopenharmony_ci if (BIO_write(bp, "\\\n", 2) != 2) 39e1051a39Sopenharmony_ci goto err; 40e1051a39Sopenharmony_ci n += 2; 41e1051a39Sopenharmony_ci } 42e1051a39Sopenharmony_ci buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; 43e1051a39Sopenharmony_ci buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; 44e1051a39Sopenharmony_ci if (BIO_write(bp, buf, 2) != 2) 45e1051a39Sopenharmony_ci goto err; 46e1051a39Sopenharmony_ci n += 2; 47e1051a39Sopenharmony_ci } 48e1051a39Sopenharmony_ci } 49e1051a39Sopenharmony_ci return n; 50e1051a39Sopenharmony_ci err: 51e1051a39Sopenharmony_ci return -1; 52e1051a39Sopenharmony_ci} 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ciint a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) 55e1051a39Sopenharmony_ci{ 56e1051a39Sopenharmony_ci int i, j, k, m, n, again, bufsize; 57e1051a39Sopenharmony_ci unsigned char *s = NULL, *sp; 58e1051a39Sopenharmony_ci unsigned char *bufp; 59e1051a39Sopenharmony_ci int num = 0, slen = 0, first = 1; 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ci bs->type = V_ASN1_INTEGER; 62e1051a39Sopenharmony_ci 63e1051a39Sopenharmony_ci bufsize = BIO_gets(bp, buf, size); 64e1051a39Sopenharmony_ci for (;;) { 65e1051a39Sopenharmony_ci if (bufsize < 1) 66e1051a39Sopenharmony_ci goto err; 67e1051a39Sopenharmony_ci i = bufsize; 68e1051a39Sopenharmony_ci if (buf[i - 1] == '\n') 69e1051a39Sopenharmony_ci buf[--i] = '\0'; 70e1051a39Sopenharmony_ci if (i == 0) 71e1051a39Sopenharmony_ci goto err; 72e1051a39Sopenharmony_ci if (buf[i - 1] == '\r') 73e1051a39Sopenharmony_ci buf[--i] = '\0'; 74e1051a39Sopenharmony_ci if (i == 0) 75e1051a39Sopenharmony_ci goto err; 76e1051a39Sopenharmony_ci again = (buf[i - 1] == '\\'); 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci for (j = 0; j < i; j++) { 79e1051a39Sopenharmony_ci if (!ossl_isxdigit(buf[j])) 80e1051a39Sopenharmony_ci { 81e1051a39Sopenharmony_ci i = j; 82e1051a39Sopenharmony_ci break; 83e1051a39Sopenharmony_ci } 84e1051a39Sopenharmony_ci } 85e1051a39Sopenharmony_ci buf[i] = '\0'; 86e1051a39Sopenharmony_ci /* 87e1051a39Sopenharmony_ci * We have now cleared all the crap off the end of the line 88e1051a39Sopenharmony_ci */ 89e1051a39Sopenharmony_ci if (i < 2) 90e1051a39Sopenharmony_ci goto err; 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci bufp = (unsigned char *)buf; 93e1051a39Sopenharmony_ci if (first) { 94e1051a39Sopenharmony_ci first = 0; 95e1051a39Sopenharmony_ci if ((bufp[0] == '0') && (bufp[1] == '0')) { 96e1051a39Sopenharmony_ci bufp += 2; 97e1051a39Sopenharmony_ci i -= 2; 98e1051a39Sopenharmony_ci } 99e1051a39Sopenharmony_ci } 100e1051a39Sopenharmony_ci k = 0; 101e1051a39Sopenharmony_ci i -= again; 102e1051a39Sopenharmony_ci if (i % 2 != 0) { 103e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS); 104e1051a39Sopenharmony_ci OPENSSL_free(s); 105e1051a39Sopenharmony_ci return 0; 106e1051a39Sopenharmony_ci } 107e1051a39Sopenharmony_ci i /= 2; 108e1051a39Sopenharmony_ci if (num + i > slen) { 109e1051a39Sopenharmony_ci sp = OPENSSL_clear_realloc(s, slen, num + i * 2); 110e1051a39Sopenharmony_ci if (sp == NULL) { 111e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 112e1051a39Sopenharmony_ci OPENSSL_free(s); 113e1051a39Sopenharmony_ci return 0; 114e1051a39Sopenharmony_ci } 115e1051a39Sopenharmony_ci s = sp; 116e1051a39Sopenharmony_ci slen = num + i * 2; 117e1051a39Sopenharmony_ci } 118e1051a39Sopenharmony_ci for (j = 0; j < i; j++, k += 2) { 119e1051a39Sopenharmony_ci for (n = 0; n < 2; n++) { 120e1051a39Sopenharmony_ci m = OPENSSL_hexchar2int(bufp[k + n]); 121e1051a39Sopenharmony_ci if (m < 0) { 122e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS); 123e1051a39Sopenharmony_ci goto err; 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci s[num + j] <<= 4; 126e1051a39Sopenharmony_ci s[num + j] |= m; 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci num += i; 130e1051a39Sopenharmony_ci if (again) 131e1051a39Sopenharmony_ci bufsize = BIO_gets(bp, buf, size); 132e1051a39Sopenharmony_ci else 133e1051a39Sopenharmony_ci break; 134e1051a39Sopenharmony_ci } 135e1051a39Sopenharmony_ci bs->length = num; 136e1051a39Sopenharmony_ci bs->data = s; 137e1051a39Sopenharmony_ci return 1; 138e1051a39Sopenharmony_ci err: 139e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE); 140e1051a39Sopenharmony_ci OPENSSL_free(s); 141e1051a39Sopenharmony_ci return 0; 142e1051a39Sopenharmony_ci} 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ciint i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a) 145e1051a39Sopenharmony_ci{ 146e1051a39Sopenharmony_ci return i2a_ASN1_INTEGER(bp, a); 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ciint a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) 150e1051a39Sopenharmony_ci{ 151e1051a39Sopenharmony_ci int rv = a2i_ASN1_INTEGER(bp, bs, buf, size); 152e1051a39Sopenharmony_ci if (rv == 1) 153e1051a39Sopenharmony_ci bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG); 154e1051a39Sopenharmony_ci return rv; 155e1051a39Sopenharmony_ci} 156