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_STRING(BIO *bp, const ASN1_STRING *a, int type) 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->length == 0) { 26e1051a39Sopenharmony_ci if (BIO_write(bp, "0", 1) != 1) 27e1051a39Sopenharmony_ci goto err; 28e1051a39Sopenharmony_ci n = 1; 29e1051a39Sopenharmony_ci } else { 30e1051a39Sopenharmony_ci for (i = 0; i < a->length; i++) { 31e1051a39Sopenharmony_ci if ((i != 0) && (i % 35 == 0)) { 32e1051a39Sopenharmony_ci if (BIO_write(bp, "\\\n", 2) != 2) 33e1051a39Sopenharmony_ci goto err; 34e1051a39Sopenharmony_ci n += 2; 35e1051a39Sopenharmony_ci } 36e1051a39Sopenharmony_ci buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; 37e1051a39Sopenharmony_ci buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; 38e1051a39Sopenharmony_ci if (BIO_write(bp, buf, 2) != 2) 39e1051a39Sopenharmony_ci goto err; 40e1051a39Sopenharmony_ci n += 2; 41e1051a39Sopenharmony_ci } 42e1051a39Sopenharmony_ci } 43e1051a39Sopenharmony_ci return n; 44e1051a39Sopenharmony_ci err: 45e1051a39Sopenharmony_ci return -1; 46e1051a39Sopenharmony_ci} 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ciint a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) 49e1051a39Sopenharmony_ci{ 50e1051a39Sopenharmony_ci int i, j, k, m, n, again, bufsize; 51e1051a39Sopenharmony_ci unsigned char *s = NULL, *sp; 52e1051a39Sopenharmony_ci unsigned char *bufp; 53e1051a39Sopenharmony_ci int num = 0, slen = 0, first = 1; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci bufsize = BIO_gets(bp, buf, size); 56e1051a39Sopenharmony_ci for (;;) { 57e1051a39Sopenharmony_ci if (bufsize < 1) { 58e1051a39Sopenharmony_ci if (first) 59e1051a39Sopenharmony_ci break; 60e1051a39Sopenharmony_ci else 61e1051a39Sopenharmony_ci goto err; 62e1051a39Sopenharmony_ci } 63e1051a39Sopenharmony_ci first = 0; 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci i = bufsize; 66e1051a39Sopenharmony_ci if (buf[i - 1] == '\n') 67e1051a39Sopenharmony_ci buf[--i] = '\0'; 68e1051a39Sopenharmony_ci if (i == 0) 69e1051a39Sopenharmony_ci goto err; 70e1051a39Sopenharmony_ci if (buf[i - 1] == '\r') 71e1051a39Sopenharmony_ci buf[--i] = '\0'; 72e1051a39Sopenharmony_ci if (i == 0) 73e1051a39Sopenharmony_ci goto err; 74e1051a39Sopenharmony_ci again = (buf[i - 1] == '\\'); 75e1051a39Sopenharmony_ci 76e1051a39Sopenharmony_ci for (j = i - 1; j > 0; j--) { 77e1051a39Sopenharmony_ci if (!ossl_isxdigit(buf[j])) { 78e1051a39Sopenharmony_ci i = j; 79e1051a39Sopenharmony_ci break; 80e1051a39Sopenharmony_ci } 81e1051a39Sopenharmony_ci } 82e1051a39Sopenharmony_ci buf[i] = '\0'; 83e1051a39Sopenharmony_ci /* 84e1051a39Sopenharmony_ci * We have now cleared all the crap off the end of the line 85e1051a39Sopenharmony_ci */ 86e1051a39Sopenharmony_ci if (i < 2) 87e1051a39Sopenharmony_ci goto err; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci bufp = (unsigned char *)buf; 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci k = 0; 92e1051a39Sopenharmony_ci i -= again; 93e1051a39Sopenharmony_ci if (i % 2 != 0) { 94e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS); 95e1051a39Sopenharmony_ci OPENSSL_free(s); 96e1051a39Sopenharmony_ci return 0; 97e1051a39Sopenharmony_ci } 98e1051a39Sopenharmony_ci i /= 2; 99e1051a39Sopenharmony_ci if (num + i > slen) { 100e1051a39Sopenharmony_ci sp = OPENSSL_realloc(s, (unsigned int)num + i * 2); 101e1051a39Sopenharmony_ci if (sp == NULL) { 102e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 103e1051a39Sopenharmony_ci OPENSSL_free(s); 104e1051a39Sopenharmony_ci return 0; 105e1051a39Sopenharmony_ci } 106e1051a39Sopenharmony_ci s = sp; 107e1051a39Sopenharmony_ci slen = num + i * 2; 108e1051a39Sopenharmony_ci } 109e1051a39Sopenharmony_ci for (j = 0; j < i; j++, k += 2) { 110e1051a39Sopenharmony_ci for (n = 0; n < 2; n++) { 111e1051a39Sopenharmony_ci m = OPENSSL_hexchar2int(bufp[k + n]); 112e1051a39Sopenharmony_ci if (m < 0) { 113e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS); 114e1051a39Sopenharmony_ci OPENSSL_free(s); 115e1051a39Sopenharmony_ci return 0; 116e1051a39Sopenharmony_ci } 117e1051a39Sopenharmony_ci s[num + j] <<= 4; 118e1051a39Sopenharmony_ci s[num + j] |= m; 119e1051a39Sopenharmony_ci } 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci num += i; 122e1051a39Sopenharmony_ci if (again) 123e1051a39Sopenharmony_ci bufsize = BIO_gets(bp, buf, size); 124e1051a39Sopenharmony_ci else 125e1051a39Sopenharmony_ci break; 126e1051a39Sopenharmony_ci } 127e1051a39Sopenharmony_ci bs->length = num; 128e1051a39Sopenharmony_ci bs->data = s; 129e1051a39Sopenharmony_ci return 1; 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci err: 132e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_SHORT_LINE); 133e1051a39Sopenharmony_ci OPENSSL_free(s); 134e1051a39Sopenharmony_ci return 0; 135e1051a39Sopenharmony_ci} 136