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