early-access version 2698

This commit is contained in:
pineappleEA
2022-04-24 22:29:35 +02:00
parent c96f949832
commit caa0c2911b
486 changed files with 37806 additions and 14362 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_bitstr.c,v 1.30 2020/09/03 17:19:27 tb Exp $ */
/* $OpenBSD: a_bitstr.c,v 1.33 2021/12/25 08:52:44 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -60,7 +60,28 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
const ASN1_ITEM ASN1_BIT_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BIT_STRING,
.sname = "ASN1_BIT_STRING",
};
ASN1_BIT_STRING *
ASN1_BIT_STRING_new(void)
{
return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
}
void
ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
}
int
ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
@@ -68,6 +89,127 @@ ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
return ASN1_STRING_set(x, d, len);
}
int
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w, v, iv;
unsigned char *c;
w = n/8;
v = 1 << (7 - (n & 0x07));
iv = ~v;
if (!value)
v = 0;
if (a == NULL)
return 0;
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
if ((a->length < (w + 1)) || (a->data == NULL)) {
if (!value)
return(1); /* Don't need to set */
if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
a->data = c;
a->length = w + 1;
}
a->data[w] = ((a->data[w]) & iv) | v;
while ((a->length > 0) && (a->data[a->length - 1] == 0))
a->length--;
return (1);
}
int
ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
{
int w, v;
w = n / 8;
v = 1 << (7 - (n & 0x07));
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
return (0);
return ((a->data[w] & v) != 0);
}
/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int
ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data)
return 1;
/* Check each byte of the internal representation of the bit string. */
ok = 1;
for (i = 0; i < a->length && ok; ++i) {
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}
int
ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
BIT_STRING_BITNAME *tbl, int indent)
{
BIT_STRING_BITNAME *bnam;
char first = 1;
BIO_printf(out, "%*s", indent, "");
for (bnam = tbl; bnam->lname; bnam++) {
if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
if (!first)
BIO_puts(out, ", ");
BIO_puts(out, bnam->lname);
first = 0;
}
}
BIO_puts(out, "\n");
return 1;
}
int
ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
BIT_STRING_BITNAME *tbl)
{
int bitnum;
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
if (bitnum < 0)
return 0;
if (bs) {
if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
return 0;
}
return 1;
}
int
ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
{
BIT_STRING_BITNAME *bnam;
for (bnam = tbl; bnam->lname; bnam++) {
if (!strcmp(bnam->sname, name) ||
!strcmp(bnam->lname, name))
return bnam->bitnum;
}
return -1;
}
int
i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
@@ -192,73 +334,14 @@ c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len)
}
int
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
{
int w, v, iv;
unsigned char *c;
w = n/8;
v = 1 << (7 - (n & 0x07));
iv = ~v;
if (!value)
v = 0;
if (a == NULL)
return 0;
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
if ((a->length < (w + 1)) || (a->data == NULL)) {
if (!value)
return(1); /* Don't need to set */
if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
a->data = c;
a->length = w + 1;
}
a->data[w] = ((a->data[w]) & iv) | v;
while ((a->length > 0) && (a->data[a->length - 1] == 0))
a->length--;
return (1);
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
}
int
ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
ASN1_BIT_STRING *
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
{
int w, v;
w = n / 8;
v = 1 << (7 - (n & 0x07));
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
return (0);
return ((a->data[w] & v) != 0);
}
/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int
ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data)
return 1;
/* Check each byte of the internal representation of the bit string. */
ok = 1;
for (i = 0; i < a->length && ok; ++i) {
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_BIT_STRING_it);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_enum.c,v 1.20 2019/04/28 05:05:56 tb Exp $ */
/* $OpenBSD: a_enum.c,v 1.23 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -60,7 +60,9 @@
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
/*
@@ -68,6 +70,24 @@
* for comments on encoding see a_int.c
*/
const ASN1_ITEM ASN1_ENUMERATED_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ENUMERATED,
.sname = "ASN1_ENUMERATED",
};
ASN1_ENUMERATED *
ASN1_ENUMERATED_new(void)
{
return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it);
}
void
ASN1_ENUMERATED_free(ASN1_ENUMERATED *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ENUMERATED_it);
}
int
ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
{
@@ -175,7 +195,7 @@ BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
}
return (ret);
err:
err:
if (ret != ai)
ASN1_ENUMERATED_free(ret);
return (NULL);
@@ -192,3 +212,143 @@ ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
BN_set_negative(ret, 1);
return (ret);
}
/* Based on a_int.c: equivalent ENUMERATED functions */
int
i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (a == NULL)
return (0);
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n = 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int
a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
{
int ret = 0;
int i, j,k, m,n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int first = 1;
size_t num = 0, slen = 0;
bs->type = V_ASN1_ENUMERATED;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i-1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i-1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
sp = realloc(s, num + i);
if (sp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
return (1);
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return (ret);
}
int
i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it);
}
ASN1_ENUMERATED *
d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len)
{
return (ASN1_ENUMERATED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ENUMERATED_it);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_int.c,v 1.34 2019/04/28 05:03:56 tb Exp $ */
/* $OpenBSD: a_int.c,v 1.38 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -61,9 +61,29 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
const ASN1_ITEM ASN1_INTEGER_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.sname = "ASN1_INTEGER",
};
ASN1_INTEGER *
ASN1_INTEGER_new(void)
{
return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
}
void
ASN1_INTEGER_free(ASN1_INTEGER *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
}
static int
ASN1_INTEGER_valid(const ASN1_INTEGER *a)
{
@@ -101,6 +121,276 @@ ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
return ret;
}
int
ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type = V_ASN1_INTEGER;
/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
if (a->length < (int)(sizeof(long) + 1)) {
free(a->data);
a->data = calloc(1, sizeof(long) + 1);
}
if (a->data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
/*
* XXX this particular API is a gibbering eidrich horror that makes it
* impossible to determine valid return cases from errors.. "a bit
* ugly" is preserved for posterity, unfortunately this is probably
* unfixable without changing public API
*/
long
ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
unsigned long r = 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_INTEGER)
neg = 1;
else if (i != V_ASN1_INTEGER)
return -1;
if (!ASN1_INTEGER_valid(a))
return -1; /* XXX best effort */
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly, return all ones */
return -1;
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (r > LONG_MAX)
return -1;
if (neg)
return -(long)r;
return (long)r;
}
ASN1_INTEGER *
BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
{
ASN1_INTEGER *ret;
int len, j;
if (ai == NULL)
ret = ASN1_INTEGER_new();
else
ret = ai;
if (ret == NULL) {
ASN1error(ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if (!ASN1_INTEGER_valid(ret))
goto err;
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_INTEGER;
else
ret->type = V_ASN1_INTEGER;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = realloc(ret->data, len + 4);
if (!new_data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length = BN_bn2bin(bn, ret->data);
/* Correct zero case */
if (!ret->length) {
ret->data[0] = 0;
ret->length = 1;
}
return (ret);
err:
if (ret != ai)
ASN1_INTEGER_free(ret);
return (NULL);
}
BIGNUM *
ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
{
BIGNUM *ret;
if (!ASN1_INTEGER_valid(ai))
return (NULL);
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
ASN1error(ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return (ret);
}
int
i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (a == NULL)
return (0);
if (a->type & V_ASN1_NEG) {
if (BIO_write(bp, "-", 1) != 1)
goto err;
n = 1;
}
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n += 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int
a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
{
int ret = 0;
int i, j,k, m,n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int num = 0, slen = 0, first = 1;
bs->type = V_ASN1_INTEGER;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i - 1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
if ((sp = recallocarray(s, slen, num + i, 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
return (1);
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return (ret);
}
/*
* This converts an ASN1 INTEGER into its content encoding.
@@ -289,13 +579,25 @@ c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
*pp = pend;
return (ret);
err:
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_INTEGER_free(ret);
return (NULL);
}
int
i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
}
ASN1_INTEGER *
d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
{
return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_INTEGER_it);
}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
* ASN1 integers: some broken software can encode a positive INTEGER
@@ -364,151 +666,9 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
*pp = p;
return (ret);
err:
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_INTEGER_free(ret);
return (NULL);
}
int
ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type = V_ASN1_INTEGER;
/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
if (a->length < (int)(sizeof(long) + 1)) {
free(a->data);
a->data = calloc(1, sizeof(long) + 1);
}
if (a->data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
/*
* XXX this particular API is a gibbering eidrich horror that makes it
* impossible to determine valid return cases from errors.. "a bit
* ugly" is preserved for posterity, unfortunately this is probably
* unfixable without changing public API
*/
long
ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
unsigned long r = 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_INTEGER)
neg = 1;
else if (i != V_ASN1_INTEGER)
return -1;
if (!ASN1_INTEGER_valid(a))
return -1; /* XXX best effort */
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly, return all ones */
return -1;
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (r > LONG_MAX)
return -1;
if (neg)
return -(long)r;
return (long)r;
}
ASN1_INTEGER *
BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
{
ASN1_INTEGER *ret;
int len, j;
if (ai == NULL)
ret = ASN1_INTEGER_new();
else
ret = ai;
if (ret == NULL) {
ASN1error(ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if (!ASN1_INTEGER_valid(ret))
goto err;
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_INTEGER;
else
ret->type = V_ASN1_INTEGER;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = realloc(ret->data, len + 4);
if (!new_data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length = BN_bn2bin(bn, ret->data);
/* Correct zero case */
if (!ret->length) {
ret->data[0] = 0;
ret->length = 1;
}
return (ret);
err:
if (ret != ai)
ASN1_INTEGER_free(ret);
return (NULL);
}
BIGNUM *
ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
{
BIGNUM *ret;
if (!ASN1_INTEGER_valid(ai))
return (NULL);
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
ASN1error(ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return (ret);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_mbstr.c,v 1.23 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: a_mbstr.c,v 1.24 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -248,7 +248,7 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
err:
err:
if (free_out) {
ASN1_STRING_free(dest);
*out = NULL;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_object.c,v 1.31 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: a_object.c,v 1.46 2022/04/10 12:42:33 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -61,308 +61,31 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/buffer.h>
#include <openssl/objects.h>
int
i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
#include "asn1_locl.h"
if ((a == NULL) || (a->data == NULL))
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
if (pp == NULL)
return objsize;
p = *pp;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
return (objsize);
}
int
a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
int i, first, len = 0, c, use_bn;
char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p;
unsigned long l;
BIGNUM *bl = NULL;
if (num == 0)
return (0);
else if (num == -1)
num = strlen(buf);
p = buf;
c = *(p++);
num--;
if ((c >= '0') && (c <= '2')) {
first= c-'0';
} else {
ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0) {
ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c = *(p++);
num--;
for (;;) {
if (num <= 0)
break;
if ((c != '.') && (c != ' ')) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
goto err;
}
l = 0;
use_bn = 0;
for (;;) {
if (num <= 0)
break;
num--;
c = *(p++);
if ((c == ' ') || (c == '.'))
break;
if ((c < '0') || (c > '9')) {
ASN1error(ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
use_bn = 1;
if (!bl)
bl = BN_new();
if (!bl || !BN_set_word(bl, l))
goto err;
}
if (use_bn) {
if (!BN_mul_word(bl, 10L) ||
!BN_add_word(bl, c-'0'))
goto err;
} else
l = l * 10L + (long)(c - '0');
}
if (len == 0) {
if ((first < 2) && (l >= 40)) {
ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn) {
if (!BN_add_word(bl, first * 40))
goto err;
} else
l += (long)first * 40;
}
i = 0;
if (use_bn) {
int blsize;
blsize = BN_num_bits(bl);
blsize = (blsize + 6) / 7;
if (blsize > tmpsize) {
if (tmp != ftmp)
free(tmp);
tmpsize = blsize + 32;
tmp = malloc(tmpsize);
if (!tmp)
goto err;
}
while (blsize--)
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
} else {
for (;;) {
tmp[i++] = (unsigned char)l & 0x7f;
l >>= 7L;
if (l == 0L)
break;
}
}
if (out != NULL) {
if (len + i > olen) {
ASN1error(ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
out[len++] = tmp[i]|0x80;
out[len++] = tmp[0];
} else
len += i;
}
if (tmp != ftmp)
free(tmp);
BN_free(bl);
return (len);
err:
if (tmp != ftmp)
free(tmp);
BN_free(bl);
return (0);
}
int
i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int
i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
{
char *tmp = NULL;
size_t tlen = 256;
int i = -1;
if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp, "NULL", 4));
if ((tmp = malloc(tlen)) == NULL)
return -1;
i = i2t_ASN1_OBJECT(tmp, tlen, a);
if (i > (int)(tlen - 1)) {
freezero(tmp, tlen);
if ((tmp = malloc(i + 1)) == NULL)
return -1;
tlen = i + 1;
i = i2t_ASN1_OBJECT(tmp, tlen, a);
}
if (i <= 0)
i = BIO_write(bp, "<INVALID>", 9);
else
i = BIO_write(bp, tmp, i);
freezero(tmp, tlen);
return (i);
}
ASN1_OBJECT *
d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length)
{
const unsigned char *p;
long len;
int tag, xclass;
int inf, i;
ASN1_OBJECT *ret = NULL;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_OBJECT) {
i = ASN1_R_EXPECTING_AN_OBJECT;
goto err;
}
ret = c2i_ASN1_OBJECT(a, &p, len);
if (ret)
*pp = p;
return ret;
err:
ASN1error(i);
return (NULL);
}
ASN1_OBJECT *
c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len)
{
ASN1_OBJECT *ret;
const unsigned char *p;
unsigned char *data;
int i, length;
/*
* Sanity check OID encoding:
* - need at least one content octet
* - MSB must be clear in the last octet
* - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
*/
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
return (NULL);
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
length = (int)len;
for (i = 0; i < length; i++, p++) {
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
return (NULL);
}
}
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
if ((a == NULL) || ((*a) == NULL) ||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
if ((ret = ASN1_OBJECT_new()) == NULL)
return (NULL);
} else
ret = *a;
p = *pp;
/* detach data from object */
data = (unsigned char *)ret->data;
freezero(data, ret->length);
data = malloc(length);
if (data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(data, p, length);
/* reattach data to object, after which it remains const */
ret->data = data;
ret->length = length;
ret->sn = NULL;
ret->ln = NULL;
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
p += length;
if (a != NULL)
*a = ret;
*pp = p;
return (ret);
err:
if (a == NULL || ret != *a)
ASN1_OBJECT_free(ret);
return (NULL);
}
const ASN1_ITEM ASN1_OBJECT_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OBJECT,
.sname = "ASN1_OBJECT",
};
ASN1_OBJECT *
ASN1_OBJECT_new(void)
{
ASN1_OBJECT *ret;
ASN1_OBJECT *a;
ret = malloc(sizeof(ASN1_OBJECT));
if (ret == NULL) {
if ((a = calloc(1, sizeof(ASN1_OBJECT))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->data = NULL;
ret->nid = 0;
ret->sn = NULL;
ret->ln = NULL;
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
return (ret);
a->flags = ASN1_OBJECT_FLAG_DYNAMIC;
return a;
}
void
@@ -399,3 +122,539 @@ ASN1_OBJECT_create(int nid, unsigned char *data, int len,
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return (OBJ_dup(&o));
}
static int
oid_add_arc(CBB *cbb, uint64_t arc)
{
int started = 0;
uint8_t val;
int i;
for (i = (sizeof(arc) * 8) / 7; i >= 0; i--) {
val = (arc >> (i * 7)) & 0x7f;
if (!started && i != 0 && val == 0)
continue;
if (i > 0)
val |= 0x80;
if (!CBB_add_u8(cbb, val))
return 0;
started = 1;
}
return 1;
}
static int
oid_parse_arc(CBS *cbs, uint64_t *out_arc)
{
uint64_t arc = 0;
uint8_t val;
do {
if (!CBS_get_u8(cbs, &val))
return 0;
if (arc == 0 && val == 0x80)
return 0;
if (out_arc != NULL && arc > (UINT64_MAX >> 7))
return 0;
arc = (arc << 7) | (val & 0x7f);
} while (val & 0x80);
if (out_arc != NULL)
*out_arc = arc;
return 1;
}
static int
oid_add_arc_txt(CBB *cbb, uint64_t arc, int first)
{
const char *fmt = ".%llu";
char s[22]; /* Digits in decimal representation of 2^64-1, plus '.' and NUL. */
int n;
if (first)
fmt = "%llu";
n = snprintf(s, sizeof(s), fmt, (unsigned long long)arc);
if (n < 0 || (size_t)n >= sizeof(s))
return 0;
if (!CBB_add_bytes(cbb, s, n))
return 0;
return 1;
}
static int
oid_parse_arc_txt(CBS *cbs, uint64_t *out_arc, char *separator, int first)
{
uint64_t arc = 0;
int digits = 0;
uint8_t val;
if (!first) {
if (!CBS_get_u8(cbs, &val))
return 0;
if ((*separator == 0 && val != '.' && val != ' ') ||
(*separator != 0 && val != *separator)) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
return 0;
}
*separator = val;
}
while (CBS_len(cbs) > 0) {
if (!CBS_peek_u8(cbs, &val))
return 0;
if (val == '.' || val == ' ')
break;
if (!CBS_get_u8(cbs, &val))
return 0;
if (val < '0' || val > '9') {
/* For the first arc we treat this as the separator. */
if (first) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
return 0;
}
ASN1error(ASN1_R_INVALID_DIGIT);
return 0;
}
val -= '0';
if (digits > 0 && arc == 0 && val == 0) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
digits++;
if (arc > UINT64_MAX / 10) {
ASN1error(ASN1_R_TOO_LONG);
return 0;
}
arc = arc * 10 + val;
}
if (digits < 1) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
*out_arc = arc;
return 1;
}
static int
a2c_ASN1_OBJECT_internal(CBB *cbb, CBS *cbs)
{
uint64_t arc, si1, si2;
char separator = 0;
if (!oid_parse_arc_txt(cbs, &si1, &separator, 1))
return 0;
if (CBS_len(cbs) == 0) {
ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
return 0;
}
if (!oid_parse_arc_txt(cbs, &si2, &separator, 0))
return 0;
/*
* X.690 section 8.19 - the first two subidentifiers are encoded as
* (x * 40) + y, with x being limited to [0,1,2]. The second
* subidentifier cannot exceed 39 for x < 2.
*/
if (si1 > 2) {
ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
return 0;
}
if ((si1 < 2 && si2 >= 40) || si2 > UINT64_MAX - si1 * 40) {
ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
return 0;
}
arc = si1 * 40 + si2;
if (!oid_add_arc(cbb, arc))
return 0;
while (CBS_len(cbs) > 0) {
if (!oid_parse_arc_txt(cbs, &arc, &separator, 0))
return 0;
if (!oid_add_arc(cbb, arc))
return 0;
}
return 1;
}
static int
c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb)
{
uint64_t arc, si1, si2;
/*
* X.690 section 8.19 - the first two subidentifiers are encoded as
* (x * 40) + y, with x being limited to [0,1,2].
*/
if (!oid_parse_arc(cbs, &arc))
return 0;
if ((si1 = arc / 40) > 2)
si1 = 2;
si2 = arc - si1 * 40;
if (!oid_add_arc_txt(cbb, si1, 1))
return 0;
if (!oid_add_arc_txt(cbb, si2, 0))
return 0;
while (CBS_len(cbs) > 0) {
if (!oid_parse_arc(cbs, &arc))
return 0;
if (!oid_add_arc_txt(cbb, arc, 0))
return 0;
}
/* NUL terminate. */
if (!CBB_add_u8(cbb, 0))
return 0;
return 1;
}
int
a2d_ASN1_OBJECT(unsigned char *out, int out_len, const char *in, int in_len)
{
uint8_t *data = NULL;
size_t data_len;
CBS cbs;
CBB cbb;
int ret = 0;
memset(&cbb, 0, sizeof(cbb));
if (in_len == -1)
in_len = strlen(in);
if (in_len <= 0)
goto err;
CBS_init(&cbs, in, in_len);
if (!CBB_init(&cbb, 0))
goto err;
if (!a2c_ASN1_OBJECT_internal(&cbb, &cbs))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if (out != NULL) {
if (out_len <= 0 || (size_t)out_len < data_len) {
ASN1error(ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
memcpy(out, data, data_len);
}
ret = (int)data_len;
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
static int
i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb)
{
CBS cbs;
CBS_init(&cbs, aobj->data, aobj->length);
return c2a_ASN1_OBJECT(&cbs, cbb);
}
static int
i2t_ASN1_OBJECT_name(const ASN1_OBJECT *aobj, CBB *cbb, const char **out_name)
{
const char *name;
int nid;
*out_name = NULL;
if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
return 0;
if ((name = OBJ_nid2ln(nid)) == NULL)
name = OBJ_nid2sn(nid);
if (name == NULL)
return 0;
*out_name = name;
if (!CBB_add_bytes(cbb, name, strlen(name)))
return 0;
/* NUL terminate. */
if (!CBB_add_u8(cbb, 0))
return 0;
return 1;
}
static int
i2t_ASN1_OBJECT_cbb(const ASN1_OBJECT *aobj, CBB *cbb, int no_name)
{
const char *name;
if (!no_name) {
if (i2t_ASN1_OBJECT_name(aobj, cbb, &name))
return 1;
if (name != NULL)
return 0;
}
return i2t_ASN1_OBJECT_oid(aobj, cbb);
}
int
i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, int no_name)
{
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
int ret = 0;
if (buf_len < 0)
return 0;
if (buf_len > 0)
buf[0] = '\0';
if (!CBB_init(&cbb, 0))
goto err;
if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, no_name))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
ret = strlcpy(buf, data, buf_len);
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
int
i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *aobj)
{
return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, 0);
}
ASN1_OBJECT *
t2i_ASN1_OBJECT_internal(const char *oid)
{
ASN1_OBJECT *aobj = NULL;
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
CBS cbs;
memset(&cbb, 0, sizeof(cbb));
CBS_init(&cbs, oid, strlen(oid));
if (!CBB_init(&cbb, 0))
goto err;
if (!a2c_ASN1_OBJECT_internal(&cbb, &cbs))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if ((aobj = ASN1_OBJECT_new()) == NULL)
goto err;
aobj->data = data;
aobj->length = (int)data_len;
aobj->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
data = NULL;
err:
CBB_cleanup(&cbb);
free(data);
return aobj;
}
int
i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *aobj)
{
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
int ret = -1;
if (aobj == NULL || aobj->data == NULL)
return BIO_write(bp, "NULL", 4);
if (!CBB_init(&cbb, 0))
goto err;
if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, 0)) {
ret = BIO_write(bp, "<INVALID>", 9);
goto err;
}
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
ret = BIO_write(bp, data, strlen(data));
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
int
c2i_ASN1_OBJECT_cbs(ASN1_OBJECT **out_aobj, CBS *content)
{
ASN1_OBJECT *aobj = NULL;
uint8_t *data = NULL;
size_t data_len;
CBS cbs;
if (out_aobj == NULL || *out_aobj != NULL)
goto err;
/* Parse and validate OID encoding per X.690 8.19.2. */
CBS_dup(content, &cbs);
if (CBS_len(&cbs) == 0) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
goto err;
}
while (CBS_len(&cbs) > 0) {
if (!oid_parse_arc(&cbs, NULL)) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
goto err;
}
}
if (!CBS_stow(content, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if ((aobj = ASN1_OBJECT_new()) == NULL)
goto err;
aobj->data = data;
aobj->length = (int)data_len; /* XXX - change length to size_t. */
aobj->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
*out_aobj = aobj;
return 1;
err:
ASN1_OBJECT_free(aobj);
free(data);
return 0;
}
ASN1_OBJECT *
c2i_ASN1_OBJECT(ASN1_OBJECT **out_aobj, const unsigned char **pp, long len)
{
ASN1_OBJECT *aobj = NULL;
CBS content;
if (out_aobj != NULL) {
ASN1_OBJECT_free(*out_aobj);
*out_aobj = NULL;
}
if (len < 0) {
ASN1error(ASN1_R_LENGTH_ERROR);
return NULL;
}
CBS_init(&content, *pp, len);
if (!c2i_ASN1_OBJECT_cbs(&aobj, &content))
return NULL;
*pp = CBS_data(&content);
if (out_aobj != NULL)
*out_aobj = aobj;
return aobj;
}
int
i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
if ((a == NULL) || (a->data == NULL))
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
if (pp == NULL)
return objsize;
p = *pp;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
return (objsize);
}
ASN1_OBJECT *
d2i_ASN1_OBJECT(ASN1_OBJECT **out_aobj, const unsigned char **pp, long length)
{
ASN1_OBJECT *aobj = NULL;
uint32_t tag_number;
CBS cbs, content;
if (out_aobj != NULL) {
ASN1_OBJECT_free(*out_aobj);
*out_aobj = NULL;
}
if (length < 0) {
ASN1error(ASN1_R_LENGTH_ERROR);
return NULL;
}
CBS_init(&cbs, *pp, length);
if (!asn1_get_primitive(&cbs, 0, &tag_number, &content)) {
ASN1error(ASN1_R_BAD_OBJECT_HEADER);
return NULL;
}
if (tag_number != V_ASN1_OBJECT) {
ASN1error(ASN1_R_EXPECTING_AN_OBJECT);
return NULL;
}
if (!c2i_ASN1_OBJECT_cbs(&aobj, &content))
return NULL;
*pp = CBS_data(&content);
if (out_aobj != NULL)
*out_aobj = aobj;
return aobj;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_octet.c,v 1.10 2015/07/29 14:58:34 jsing Exp $ */
/* $OpenBSD: a_octet.c,v 1.11 2021/12/25 08:52:44 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -59,6 +59,26 @@
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
const ASN1_ITEM ASN1_OCTET_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OCTET_STRING,
.sname = "ASN1_OCTET_STRING",
};
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_new(void)
{
return (ASN1_OCTET_STRING *)ASN1_item_new(&ASN1_OCTET_STRING_it);
}
void
ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_OCTET_STRING_it);
}
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
@@ -77,3 +97,16 @@ ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{
return ASN1_STRING_set(x, d, len);
}
int
i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_OCTET_STRING_it);
}
ASN1_OCTET_STRING *
d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a, const unsigned char **in, long len)
{
return (ASN1_OCTET_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_OCTET_STRING_it);
}

186
externals/libressl/crypto/asn1/a_pkey.c vendored Executable file
View File

@@ -0,0 +1,186 @@
/* $OpenBSD: a_pkey.c,v 1.3 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_locl.h"
#include "evp_locl.h"
EVP_PKEY *
d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
{
const unsigned char *p = *pp;
EVP_PKEY *ret;
if ((a == NULL) || (*a == NULL)) {
if ((ret = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_EVP_LIB);
return (NULL);
}
} else {
ret = *a;
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(ret->engine);
ret->engine = NULL;
#endif
}
if (!EVP_PKEY_set_type(ret, type)) {
ASN1error(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
}
if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, pp, length)) {
if (ret->ameth->priv_decode) {
PKCS8_PRIV_KEY_INFO *p8 = NULL;
*pp = p; /* XXX */
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
if (!p8)
goto err;
EVP_PKEY_free(ret);
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
} else {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
}
if (a != NULL)
(*a) = ret;
return (ret);
err:
if (a == NULL || *a != ret)
EVP_PKEY_free(ret);
return (NULL);
}
int
i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{
if (a->ameth && a->ameth->old_priv_encode) {
return a->ameth->old_priv_encode(a, pp);
}
if (a->ameth && a->ameth->priv_encode) {
PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
PKCS8_PRIV_KEY_INFO_free(p8);
return ret;
}
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return (-1);
}
/* This works like d2i_PrivateKey() except it automatically works out the type */
EVP_PKEY *
d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length)
{
STACK_OF(ASN1_TYPE) *inkey;
const unsigned char *p;
int keytype;
p = *pp;
/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
* by analyzing it we can determine the passed structure: this
* assumes the input is surrounded by an ASN1 SEQUENCE.
*/
inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
/* Since we only need to discern "traditional format" RSA and DSA
* keys we can just count the elements.
*/
if (sk_ASN1_TYPE_num(inkey) == 6)
keytype = EVP_PKEY_DSA;
else if (sk_ASN1_TYPE_num(inkey) == 4)
keytype = EVP_PKEY_EC;
else if (sk_ASN1_TYPE_num(inkey) == 3) {
/* This seems to be PKCS8, not traditional format */
PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(
NULL, pp, length);
EVP_PKEY *ret;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
if (!p8) {
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return NULL;
}
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
if (a) {
*a = ret;
}
return ret;
} else
keytype = EVP_PKEY_RSA;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
return d2i_PrivateKey(keytype, a, pp, length);
}

160
externals/libressl/crypto/asn1/a_pubkey.c vendored Executable file
View File

@@ -0,0 +1,160 @@
/* $OpenBSD: a_pubkey.c,v 1.3 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "evp_locl.h"
EVP_PKEY *
d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
{
EVP_PKEY *ret;
if ((a == NULL) || (*a == NULL)) {
if ((ret = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_EVP_LIB);
return (NULL);
}
} else
ret = *a;
if (!EVP_PKEY_set_type(ret, type)) {
ASN1error(ERR_R_EVP_LIB);
goto err;
}
switch (EVP_PKEY_id(ret)) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) ==
NULL) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if (!d2i_DSAPublicKey(&(ret->pkey.dsa), pp, length)) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if (!o2i_ECPublicKey(&(ret->pkey.ec), pp, length)) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
default:
ASN1error(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
/* break; */
}
if (a != NULL)
(*a) = ret;
return (ret);
err:
if (a == NULL || *a != ret)
EVP_PKEY_free(ret);
return (NULL);
}
int
i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
{
switch (a->type) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
return (i2d_RSAPublicKey(a->pkey.rsa, pp));
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
return (i2d_DSAPublicKey(a->pkey.dsa, pp));
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
return (i2o_ECPublicKey(a->pkey.ec, pp));
#endif
default:
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return (-1);
}
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_strex.c,v 1.28 2018/05/19 10:46:28 tb Exp $ */
/* $OpenBSD: a_strex.c,v 1.31 2021/12/25 12:11:57 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -322,22 +322,6 @@ do_dump(unsigned long lflags, char_io *io_ch, void *arg, const ASN1_STRING *str)
return outlen + 1;
}
/* Lookup table to convert tags to character widths,
* 0 = UTF8 encoded, -1 is used for non string types
* otherwise it is the number of bytes per character
*/
static const signed char tag2nbyte[] = {
-1, -1, -1, -1, -1, /* 0-4 */
-1, -1, -1, -1, -1, /* 5-9 */
-1, -1, 0, -1, /* 10-13 */
-1, -1, -1, -1, /* 15-17 */
-1, 1, 1, /* 18-20 */
-1, 1, 1, 1, /* 21-24 */
-1, 1, -1, /* 25-27 */
4, -1, 2 /* 28-30 */
};
/* This is the main function, print out an
* ASN1_STRING taking note of various escape
* and display options. Returns number of
@@ -371,19 +355,16 @@ do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
/* Decide what to do with type, either dump content or display it */
/* Dump everything */
if (lflags & ASN1_STRFLGS_DUMP_ALL)
if (lflags & ASN1_STRFLGS_DUMP_ALL) {
/* Dump everything. */
type = -1;
/* Ignore the string type */
else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
} else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) {
/* Ignore the string type. */
type = 1;
else {
/* Else determine width based on type */
if ((type > 0) && (type < 31))
type = tag2nbyte[type];
else
type = -1;
if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
} else {
/* Else determine width based on type. */
type = asn1_tag2charwidth(type);
if (type == -1 && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
type = 1;
}
@@ -513,7 +494,7 @@ do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, int indent,
else
ent = X509_NAME_get_entry(n, i);
if (prev != -1) {
if (prev == ent->set) {
if (prev == X509_NAME_ENTRY_set(ent)) {
if (!io_ch(arg, sep_mv, sep_mv_len))
return -1;
outlen += sep_mv_len;
@@ -526,7 +507,7 @@ do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, int indent,
outlen += indent;
}
}
prev = ent->set;
prev = X509_NAME_ENTRY_set(ent);
fn = X509_NAME_ENTRY_get_object(ent);
val = X509_NAME_ENTRY_get_data(ent);
fn_nid = OBJ_obj2nid(fn);
@@ -618,32 +599,3 @@ ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags)
{
return do_print_ex(send_fp_chars, fp, flags, str);
}
/* Utility function: convert any string type to UTF8, returns number of bytes
* in output string or a negative error code
*/
int
ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
{
ASN1_STRING stmp, *str = &stmp;
int mbflag, type, ret;
if (!in)
return -1;
type = in->type;
if ((type < 0) || (type > 30))
return -1;
mbflag = tag2nbyte[type];
if (mbflag == -1)
return -1;
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
B_ASN1_UTF8STRING);
if (ret < 0)
return ret;
*out = stmp.data;
return stmp.length;
}

423
externals/libressl/crypto/asn1/a_string.c vendored Executable file
View File

@@ -0,0 +1,423 @@
/* $OpenBSD: a_string.c,v 1.7 2022/03/17 17:17:58 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "asn1_locl.h"
ASN1_STRING *
ASN1_STRING_new(void)
{
return ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
}
ASN1_STRING *
ASN1_STRING_type_new(int type)
{
ASN1_STRING *astr;
if ((astr = calloc(1, sizeof(ASN1_STRING))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
astr->type = type;
return astr;
}
static void
ASN1_STRING_clear(ASN1_STRING *astr)
{
if (!(astr->flags & ASN1_STRING_FLAG_NDEF))
freezero(astr->data, astr->length);
astr->flags &= ~ASN1_STRING_FLAG_NDEF;
astr->data = NULL;
astr->length = 0;
}
void
ASN1_STRING_free(ASN1_STRING *astr)
{
if (astr == NULL)
return;
ASN1_STRING_clear(astr);
free(astr);
}
int
ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int cmp;
if (a == NULL || b == NULL)
return -1;
if ((cmp = (a->length - b->length)) != 0)
return cmp;
if ((cmp = memcmp(a->data, b->data, a->length)) != 0)
return cmp;
return (a->type - b->type);
}
int
ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *src)
{
if (src == NULL)
return 0;
if (!ASN1_STRING_set(dst, src->data, src->length))
return 0;
dst->type = src->type;
dst->flags = src->flags & ~ASN1_STRING_FLAG_NDEF;
return 1;
}
ASN1_STRING *
ASN1_STRING_dup(const ASN1_STRING *src)
{
ASN1_STRING *astr;
if (src == NULL)
return NULL;
if ((astr = ASN1_STRING_new()) == NULL)
return NULL;
if (!ASN1_STRING_copy(astr, src)) {
ASN1_STRING_free(astr);
return NULL;
}
return astr;
}
int
ASN1_STRING_set(ASN1_STRING *astr, const void *_data, int len)
{
const char *data = _data;
if (len == -1) {
size_t slen;
if (data == NULL)
return 0;
if ((slen = strlen(data)) > INT_MAX)
return 0;
len = (int)slen;
}
ASN1_STRING_clear(astr);
if (len < 0 || len >= INT_MAX)
return 0;
if ((astr->data = calloc(1, len + 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
astr->length = len;
if (data != NULL) {
memcpy(astr->data, data, len);
astr->data[len] = '\0';
}
return 1;
}
void
ASN1_STRING_set0(ASN1_STRING *astr, void *data, int len)
{
ASN1_STRING_clear(astr);
astr->data = data;
astr->length = len;
}
void
asn1_add_error(const unsigned char *address, int offset)
{
ERR_asprintf_error_data("offset=%d", offset);
}
int
ASN1_STRING_length(const ASN1_STRING *astr)
{
return astr->length;
}
void
ASN1_STRING_length_set(ASN1_STRING *astr, int len)
{
/* This is dangerous and unfixable. */
astr->length = len;
}
int
ASN1_STRING_type(const ASN1_STRING *astr)
{
return astr->type;
}
unsigned char *
ASN1_STRING_data(ASN1_STRING *astr)
{
return astr->data;
}
const unsigned char *
ASN1_STRING_get0_data(const ASN1_STRING *astr)
{
return astr->data;
}
int
ASN1_STRING_print(BIO *bp, const ASN1_STRING *astr)
{
int i, n;
char buf[80];
const char *p;
if (astr == NULL)
return 0;
n = 0;
p = (const char *)astr->data;
for (i = 0; i < astr->length; i++) {
if ((p[i] > '~') || ((p[i] < ' ') &&
(p[i] != '\n') && (p[i] != '\r')))
buf[n] = '.';
else
buf[n] = p[i];
n++;
if (n >= 80) {
if (BIO_write(bp, buf, n) <= 0)
return 0;
n = 0;
}
}
if (n > 0) {
if (BIO_write(bp, buf, n) <= 0)
return 0;
}
return 1;
}
/*
* Utility function: convert any string type to UTF8, returns number of bytes
* in output string or a negative error code
*/
int
ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
{
ASN1_STRING stmp, *str = &stmp;
int mbflag, ret;
if (in == NULL)
return -1;
if ((mbflag = asn1_tag2charwidth(in->type)) == -1)
return -1;
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
B_ASN1_UTF8STRING);
if (ret < 0)
return ret;
*out = stmp.data;
return stmp.length;
}
int
i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *astr, int type)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (astr == NULL)
return 0;
if (astr->length == 0) {
if (BIO_write(bp, "0", 1) != 1)
goto err;
n = 1;
} else {
for (i = 0; i < astr->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)astr->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)astr->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return n;
err:
return -1;
}
int
a2i_ASN1_STRING(BIO *bp, ASN1_STRING *astr, char *buf, int size)
{
int ret = 0;
int i, j, k, m, n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int first = 1;
size_t num = 0, slen = 0;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1) {
if (first)
break;
else
goto err_sl;
}
first = 0;
i = bufsize;
if (buf[i-1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i-1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
k = 0;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
sp = realloc(s, num + i);
if (sp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
astr->length = num;
astr->data = s;
return 1;
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return ret;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_strnid.c,v 1.21 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: a_strnid.c,v 1.25 2021/12/13 17:55:53 schwarze Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -56,8 +56,9 @@
*
*/
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
@@ -65,12 +66,15 @@
#include <openssl/objects.h>
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static ASN1_STRING_TABLE *stable_get(int nid);
static void st_free(ASN1_STRING_TABLE *tbl);
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
const ASN1_STRING_TABLE * const *b);
/* This is the global mask for the mbstring functions: this is use to
/*
* This is the global mask for the mbstring functions: this is used to
* mask out certain types (such as BMPString and UTF8String) because
* certain software (e.g. Netscape) has problems with them.
*/
@@ -89,7 +93,8 @@ ASN1_STRING_get_default_mask(void)
return global_mask;
}
/* This function sets the default to various "flavours" of configuration.
/*
* This function sets the default to various "flavours" of configuration
* based on an ASCII string. Currently this is:
* MASK:XXXX : a numerical mask value.
* nobmp : Don't use BMPStrings (just Printable, T61).
@@ -103,20 +108,26 @@ ASN1_STRING_set_default_mask_asc(const char *p)
{
unsigned long mask;
char *end;
int save_errno;
if (!strncmp(p, "MASK:", 5)) {
if (!p[5])
if (strncmp(p, "MASK:", 5) == 0) {
if (p[5] == '\0')
return 0;
save_errno = errno;
errno = 0;
mask = strtoul(p + 5, &end, 0);
if (*end)
if (errno == ERANGE && mask == ULONG_MAX)
return 0;
} else if (!strcmp(p, "nombstr"))
errno = save_errno;
if (*end != '\0')
return 0;
} else if (strcmp(p, "nombstr") == 0)
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
else if (!strcmp(p, "pkix"))
else if (strcmp(p, "pkix") == 0)
mask = ~((unsigned long)B_ASN1_T61STRING);
else if (!strcmp(p, "utf8only"))
else if (strcmp(p, "utf8only") == 0)
mask = B_ASN1_UTF8STRING;
else if (!strcmp(p, "default"))
else if (strcmp(p, "default") == 0)
mask = 0xFFFFFFFFL;
else
return 0;
@@ -124,7 +135,8 @@ ASN1_STRING_set_default_mask_asc(const char *p)
return 1;
}
/* The following function generates an ASN1_STRING based on limits in a table.
/*
* The following function generates an ASN1_STRING based on limits in a table.
* Frequently the types and length of an ASN1_STRING are restricted by a
* corresponding OID. For example certificates and certificate requests.
*/
@@ -137,12 +149,13 @@ ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if (!out)
if (out == NULL)
out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if (tbl) {
if (tbl != NULL) {
mask = tbl->mask;
if (!(tbl->flags & STABLE_NO_MASK))
if ((tbl->flags & STABLE_NO_MASK) == 0)
mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
@@ -154,7 +167,8 @@ ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
return *out;
}
/* Now the tables and helper functions for the string table:
/*
* Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
@@ -231,20 +245,59 @@ ASN1_STRING_TABLE *
ASN1_STRING_TABLE_get(int nid)
{
int idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
if (stable != NULL) {
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
if (idx >= 0)
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
return OBJ_bsearch_table(&fnd, tbl_standard,
sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
if (ttmp)
return ttmp;
if (!stable)
}
/*
* Return a string table pointer which can be modified: either directly
* from table or a copy of an internal value added to the table.
*/
static ASN1_STRING_TABLE *
stable_get(int nid)
{
ASN1_STRING_TABLE *tmp, *rv;
/* Always need a string table so allocate one if NULL */
if (stable == NULL) {
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if (stable == NULL)
return NULL;
}
tmp = ASN1_STRING_TABLE_get(nid);
if (tmp != NULL && (tmp->flags & STABLE_FLAGS_MALLOC) != 0)
return tmp;
if ((rv = calloc(1, sizeof(*rv))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
if (idx < 0)
}
if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
free(rv);
return NULL;
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
if (tmp != NULL) {
rv->nid = tmp->nid;
rv->minsize = tmp->minsize;
rv->maxsize = tmp->maxsize;
rv->mask = tmp->mask;
rv->flags = tmp->flags | STABLE_FLAGS_MALLOC;
} else {
rv->nid = nid;
rv->minsize = -1;
rv->maxsize = -1;
rv->flags = STABLE_FLAGS_MALLOC;
}
return rv;
}
int
@@ -252,37 +305,20 @@ ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask,
unsigned long flags)
{
ASN1_STRING_TABLE *tmp;
char new_nid = 0;
flags &= ~STABLE_FLAGS_MALLOC;
if (!stable)
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if (!stable) {
if ((tmp = stable_get(nid)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = malloc(sizeof(ASN1_STRING_TABLE));
if (!tmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
new_nid = 1;
} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
if (minsize != -1)
if (minsize >= 0)
tmp->minsize = minsize;
if (maxsize != -1)
if (maxsize >= 0)
tmp->maxsize = maxsize;
tmp->mask = mask;
if (new_nid) {
if (sk_ASN1_STRING_TABLE_push(stable, tmp) == 0) {
free(tmp);
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
}
if (mask != 0)
tmp->mask = mask;
if (flags != 0)
tmp->flags = flags | STABLE_FLAGS_MALLOC;
return 1;
}
@@ -292,7 +328,7 @@ ASN1_STRING_TABLE_cleanup(void)
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if (!tmp)
if (tmp == NULL)
return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_time.c,v 1.27 2015/10/19 16:32:37 beck Exp $ */
/* $OpenBSD: a_time.c,v 1.33 2021/12/25 07:48:09 jsing Exp $ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@@ -80,6 +80,45 @@ const ASN1_ITEM ASN1_TIME_it = {
.sname = "ASN1_TIME",
};
ASN1_TIME *
ASN1_TIME_new(void)
{
return (ASN1_TIME *)ASN1_item_new(&ASN1_TIME_it);
}
void
ASN1_TIME_free(ASN1_TIME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it);
}
/* Public API in OpenSSL. Kept internal for now. */
static int
ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
{
time_t now;
if (s != NULL)
return ASN1_time_parse(s->data, s->length, tm, 0) != -1;
time(&now);
memset(tm, 0, sizeof(*tm));
return gmtime_r(&now, tm) != NULL;
}
int
ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to)
{
struct tm tm_from, tm_to;
if (!ASN1_TIME_to_tm(from, &tm_from))
return 0;
if (!ASN1_TIME_to_tm(to, &tm_to))
return 0;
return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
}
ASN1_TIME *
d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len)
@@ -93,15 +132,3 @@ i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_TIME_it);
}
ASN1_TIME *
ASN1_TIME_new(void)
{
return (ASN1_TIME *)ASN1_item_new(&ASN1_TIME_it);
}
void
ASN1_TIME_free(ASN1_TIME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_time_tm.c,v 1.15 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: a_time_tm.c,v 1.19 2022/03/31 13:04:47 tb Exp $ */
/*
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
*
@@ -163,10 +163,9 @@ ASN1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode)
return (-1);
lt = tm;
if (lt == NULL) {
memset(&ltm, 0, sizeof(ltm));
if (lt == NULL)
lt = &ltm;
}
memset(lt, 0, sizeof(*lt));
/* Timezone is required and must be GMT (Zulu). */
if (bytes[len - 1] != 'Z')
@@ -260,10 +259,10 @@ ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
int allocated = 0;
struct tm tm;
size_t len;
char * p;
char *p;
if (gmtime_r(&t, &tm) == NULL)
return (NULL);
if (gmtime_r(&t, &tm) == NULL)
return (NULL);
if (offset_day || offset_sec) {
if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec))
@@ -289,8 +288,10 @@ ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
}
if (s == NULL) {
if ((s = ASN1_TIME_new()) == NULL)
if ((s = ASN1_TIME_new()) == NULL) {
free(p);
return (NULL);
}
allocated = 1;
}
@@ -299,7 +300,7 @@ ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
case GENTIME_LENGTH:
s->type = V_ASN1_GENERALIZEDTIME;
break;
case UTCTIME_LENGTH:
case UTCTIME_LENGTH:
s->type = V_ASN1_UTCTIME;
break;
default:
@@ -354,7 +355,6 @@ ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
return (NULL);
memset(&tm, 0, sizeof(tm));
if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type))
return (NULL);
if ((str = gentime_string_from_tm(&tm)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: a_type.c,v 1.21 2019/10/24 16:36:10 jsing Exp $ */
/* $OpenBSD: a_type.c,v 1.23 2021/12/25 12:19:16 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -56,11 +56,51 @@
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/objects.h>
typedef struct {
ASN1_INTEGER *num;
ASN1_OCTET_STRING *value;
} ASN1_int_octetstring;
static const ASN1_TEMPLATE ASN1_INT_OCTETSTRING_seq_tt[] = {
{
.offset = offsetof(ASN1_int_octetstring, num),
.field_name = "num",
.item = &ASN1_INTEGER_it,
},
{
.offset = offsetof(ASN1_int_octetstring, value),
.field_name = "value",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM ASN1_INT_OCTETSTRING_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = ASN1_INT_OCTETSTRING_seq_tt,
.tcount = sizeof(ASN1_INT_OCTETSTRING_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(ASN1_int_octetstring),
.sname = "ASN1_INT_OCTETSTRING",
};
ASN1_TYPE *
ASN1_TYPE_new(void)
{
return (ASN1_TYPE *)ASN1_item_new(&ASN1_ANY_it);
}
void
ASN1_TYPE_free(ASN1_TYPE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ANY_it);
}
int
ASN1_TYPE_get(const ASN1_TYPE *a)
{
@@ -155,6 +195,108 @@ ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
return result;
}
int
ASN1_TYPE_set_octetstring(ASN1_TYPE *a, const unsigned char *data, int len)
{
ASN1_STRING *os;
if ((os = ASN1_OCTET_STRING_new()) == NULL)
return (0);
if (!ASN1_STRING_set(os, data, len)) {
ASN1_OCTET_STRING_free(os);
return (0);
}
ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
return (1);
}
int
ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
{
int ret, num;
unsigned char *p;
if ((a->type != V_ASN1_OCTET_STRING) ||
(a->value.octet_string == NULL)) {
ASN1error(ASN1_R_DATA_IS_WRONG);
return (-1);
}
p = ASN1_STRING_data(a->value.octet_string);
ret = ASN1_STRING_length(a->value.octet_string);
if (ret < max_len)
num = ret;
else
num = max_len;
memcpy(data, p, num);
return (ret);
}
int
ASN1_TYPE_set_int_octetstring(ASN1_TYPE *at, long num, const unsigned char *data,
int len)
{
ASN1_int_octetstring *ios;
ASN1_STRING *sp = NULL;
int ret = 0;
if ((ios = (ASN1_int_octetstring *)ASN1_item_new(
&ASN1_INT_OCTETSTRING_it)) == NULL)
goto err;
if (!ASN1_INTEGER_set(ios->num, num))
goto err;
if (!ASN1_OCTET_STRING_set(ios->value, data, len))
goto err;
if ((sp = ASN1_item_pack(ios, &ASN1_INT_OCTETSTRING_it, NULL)) == NULL)
goto err;
ASN1_TYPE_set(at, V_ASN1_SEQUENCE, sp);
sp = NULL;
ret = 1;
err:
ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it);
ASN1_STRING_free(sp);
return ret;
}
int
ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *at, long *num, unsigned char *data,
int max_len)
{
ASN1_STRING *sp = at->value.sequence;
ASN1_int_octetstring *ios = NULL;
int ret = -1;
int len;
if (at->type != V_ASN1_SEQUENCE || sp == NULL)
goto err;
if ((ios = ASN1_item_unpack(sp, &ASN1_INT_OCTETSTRING_it)) == NULL)
goto err;
if (num != NULL)
*num = ASN1_INTEGER_get(ios->num);
if (data != NULL) {
len = ASN1_STRING_length(ios->value);
if (len > max_len)
len = max_len;
memcpy(data, ASN1_STRING_data(ios->value), len);
}
ret = ASN1_STRING_length(ios->value);
err:
ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it);
if (ret == -1)
ASN1error(ASN1_R_DATA_IS_WRONG);
return ret;
}
ASN1_TYPE *
ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
{
@@ -185,3 +327,16 @@ ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
return NULL;
return ASN1_item_unpack(t->value.sequence, it);
}
int
i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ANY_it);
}
ASN1_TYPE *
d2i_ASN1_TYPE(ASN1_TYPE **a, const unsigned char **in, long len)
{
return (ASN1_TYPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ANY_it);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: ameth_lib.c,v 1.21 2019/11/02 16:06:25 inoguchi Exp $ */
/* $OpenBSD: ameth_lib.c,v 1.25 2022/01/10 12:10:26 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
@@ -69,6 +69,7 @@
#endif
#include "asn1_locl.h"
#include "evp_locl.h"
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth;
@@ -340,34 +341,21 @@ EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info)
void
EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, const EVP_PKEY_ASN1_METHOD *src)
{
dst->pub_decode = src->pub_decode;
dst->pub_encode = src->pub_encode;
dst->pub_cmp = src->pub_cmp;
dst->pub_print = src->pub_print;
EVP_PKEY_ASN1_METHOD preserve;
dst->priv_decode = src->priv_decode;
dst->priv_encode = src->priv_encode;
dst->priv_print = src->priv_print;
preserve.pkey_id = dst->pkey_id;
preserve.pkey_base_id = dst->pkey_base_id;
preserve.pkey_flags = dst->pkey_flags;
preserve.pem_str = dst->pem_str;
preserve.info = dst->info;
dst->old_priv_encode = src->old_priv_encode;
dst->old_priv_decode = src->old_priv_decode;
*dst = *src;
dst->pkey_size = src->pkey_size;
dst->pkey_bits = src->pkey_bits;
dst->param_decode = src->param_decode;
dst->param_encode = src->param_encode;
dst->param_missing = src->param_missing;
dst->param_copy = src->param_copy;
dst->param_cmp = src->param_cmp;
dst->param_print = src->param_print;
dst->sig_print = src->sig_print;
dst->pkey_free = src->pkey_free;
dst->pkey_ctrl = src->pkey_ctrl;
dst->item_sign = src->item_sign;
dst->item_verify = src->item_verify;
dst->pkey_id = preserve.pkey_id;
dst->pkey_base_id = preserve.pkey_base_id;
dst->pkey_flags = preserve.pkey_flags;
dst->pem_str = preserve.pem_str;
dst->info = preserve.info;
}
void
@@ -441,3 +429,24 @@ EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
{
ameth->pkey_ctrl = pkey_ctrl;
}
void
EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_check)(const EVP_PKEY *pk))
{
ameth->pkey_check = pkey_check;
}
void
EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_public_check)(const EVP_PKEY *pk))
{
ameth->pkey_public_check = pkey_public_check;
}
void
EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_param_check)(const EVP_PKEY *pk))
{
ameth->pkey_param_check = pkey_param_check;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn1_err.c,v 1.21 2018/03/29 02:29:24 inoguchi Exp $ */
/* $OpenBSD: asn1_err.c,v 1.22 2020/12/08 15:06:42 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@@ -85,6 +85,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) , "bad object header"},
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ) , "bad password read"},
{ERR_REASON(ASN1_R_BAD_TAG) , "bad tag"},
{ERR_REASON(ASN1_R_BAD_TEMPLATE) , "bad template"},
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "bmpstring is wrong length"},
{ERR_REASON(ASN1_R_BN_LIB) , "bn lib"},
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn1_gen.c,v 1.17 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: asn1_gen.c,v 1.18 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2002.
*/
@@ -258,7 +258,7 @@ ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
/* Obtain new ASN1_TYPE structure */
ret = d2i_ASN1_TYPE(NULL, &cp, len);
err:
err:
free(orig_der);
free(new_der);
@@ -478,7 +478,7 @@ asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
der = NULL;
bad:
bad:
free(der);
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
@@ -771,9 +771,9 @@ asn1_str2type(const char *str, int format, int utype)
atmp->type = utype;
return atmp;
bad_str:
bad_str:
ERR_asprintf_error_data("string=%s", str);
bad_form:
bad_form:
ASN1_TYPE_free(atmp);
return NULL;
}

639
externals/libressl/crypto/asn1/asn1_item.c vendored Executable file
View File

@@ -0,0 +1,639 @@
/* $OpenBSD: asn1_item.c,v 1.4 2022/01/14 08:38:05 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <limits.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "evp_locl.h"
/*
* ASN1_ITEM version of dup: this follows the model above except we don't need
* to allocate the buffer. At some point this could be rewritten to directly dup
* the underlying structure instead of doing and encode and decode.
*/
int
ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
unsigned char *md, unsigned int *len)
{
int i;
unsigned char *str = NULL;
i = ASN1_item_i2d(asn, &str, it);
if (!str)
return (0);
if (!EVP_Digest(str, i, md, len, type, NULL)) {
free(str);
return (0);
}
free(str);
return (1);
}
void *
ASN1_item_dup(const ASN1_ITEM *it, void *x)
{
unsigned char *b = NULL;
const unsigned char *p;
long i;
void *ret;
if (x == NULL)
return (NULL);
i = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
ret = ASN1_item_d2i(NULL, &p, i, it);
free(b);
return (ret);
}
/* Pack an ASN1 object into an ASN1_STRING. */
ASN1_STRING *
ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
{
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
} else
octmp = *oct;
free(octmp->data);
octmp->data = NULL;
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
ASN1error(ASN1_R_ENCODE_ERROR);
goto err;
}
if (!octmp->data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (oct)
*oct = octmp;
return octmp;
err:
if (!oct || octmp != *oct)
ASN1_STRING_free(octmp);
return NULL;
}
/* Extract an ASN1 object from an ASN1_STRING. */
void *
ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
{
const unsigned char *p;
void *ret;
p = oct->data;
if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
ASN1error(ASN1_R_DECODE_ERROR);
return ret;
}
int
ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type)
{
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
}
int
ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
{
const EVP_MD *type;
EVP_PKEY *pkey;
unsigned char *buf_in = NULL, *buf_out = NULL;
size_t inl = 0, outl = 0, outll = 0;
int signid, paramtype;
int rv;
type = EVP_MD_CTX_md(ctx);
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!type || !pkey) {
ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED);
return 0;
}
if (pkey->ameth->item_sign) {
rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
signature);
if (rv == 1)
outl = signature->length;
/* Return value meanings:
* <=0: error.
* 1: method does everything.
* 2: carry on as normal.
* 3: ASN1 method sets algorithm identifiers: just sign.
*/
if (rv <= 0)
ASN1error(ERR_R_EVP_LIB);
if (rv <= 1)
goto err;
} else
rv = 2;
if (rv == 2) {
if (!pkey->ameth ||
!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
pkey->ameth->pkey_id)) {
ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
}
if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
paramtype = V_ASN1_NULL;
else
paramtype = V_ASN1_UNDEF;
if (algor1)
X509_ALGOR_set0(algor1,
OBJ_nid2obj(signid), paramtype, NULL);
if (algor2)
X509_ALGOR_set0(algor2,
OBJ_nid2obj(signid), paramtype, NULL);
}
inl = ASN1_item_i2d(asn, &buf_in, it);
outll = outl = EVP_PKEY_size(pkey);
buf_out = malloc(outl);
if ((buf_in == NULL) || (buf_out == NULL)) {
outl = 0;
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestSignUpdate(ctx, buf_in, inl) ||
!EVP_DigestSignFinal(ctx, buf_out, &outl)) {
outl = 0;
ASN1error(ERR_R_EVP_LIB);
goto err;
}
free(signature->data);
signature->data = buf_out;
buf_out = NULL;
signature->length = outl;
/* In the interests of compatibility, I'll make sure that
* the bit string has a 'not-used bits' value of 0
*/
signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
err:
EVP_MD_CTX_cleanup(ctx);
freezero((char *)buf_in, inl);
freezero((char *)buf_out, outll);
return (outl);
}
int
ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
{
EVP_MD_CTX ctx;
unsigned char *buf_in = NULL;
int ret = -1, inl;
int mdnid, pknid;
if (!pkey) {
ASN1error(ERR_R_PASSED_NULL_PARAMETER);
return -1;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
return -1;
}
EVP_MD_CTX_init(&ctx);
/* Convert signature OID into digest and public key OIDs */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
if (mdnid == NID_undef) {
if (!pkey->ameth || !pkey->ameth->item_verify) {
ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
ret = pkey->ameth->item_verify(&ctx, it, asn, a,
signature, pkey);
/* Return value of 2 means carry on, anything else means we
* exit straight away: either a fatal error of the underlying
* verification routine handles all verification.
*/
if (ret != 2)
goto err;
ret = -1;
} else {
const EVP_MD *type;
type = EVP_get_digestbynid(mdnid);
if (type == NULL) {
ASN1error(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err;
}
/* Check public key OID matches public key type */
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
ASN1error(ASN1_R_WRONG_PUBLIC_KEY_TYPE);
goto err;
}
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
}
inl = ASN1_item_i2d(asn, &buf_in, it);
if (buf_in == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
freezero(buf_in, (unsigned int)inl);
if (EVP_DigestVerifyFinal(&ctx, signature->data,
(size_t)signature->length) <= 0) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
/* we don't need to zero the 'ctx' because we just checked
* public information */
/* memset(&ctx,0,sizeof(ctx)); */
ret = 1;
err:
EVP_MD_CTX_cleanup(&ctx);
return (ret);
}
#define HEADER_SIZE 8
#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
int
asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
const unsigned char *q;
long slen;
int i, inf, tag, xclass;
size_t want = HEADER_SIZE;
int eos = 0;
size_t off = 0;
size_t len = 0;
b = BUF_MEM_new();
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return -1;
}
ERR_clear_error();
for (;;) {
if (want >= (len - off)) {
want -= (len - off);
if (len + want < len ||
!BUF_MEM_grow_clean(b, len + want)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
i = BIO_read(in, &(b->data[len]), want);
if ((i < 0) && ((len - off) == 0)) {
ASN1error(ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0) {
if (len + i < len) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
len += i;
}
}
/* else data already loaded */
p = (unsigned char *) & (b->data[off]);
q = p;
inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
if (inf & 0x80) {
unsigned long e;
e = ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
goto err;
else
ERR_clear_error(); /* clear error */
}
i = q - p; /* header length */
off += i; /* end of data */
if (inf & 1) {
/* no data body so go round again */
eos++;
if (eos < 0) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
goto err;
}
want = HEADER_SIZE;
} else if (eos && slen == 0 && tag == V_ASN1_EOC) {
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want = HEADER_SIZE;
} else {
/* suck in slen bytes of data */
want = slen;
if (want > (len - off)) {
size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
want -= (len - off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
while (want > 0) {
/*
* Read content in chunks of increasing size
* so we can return an error for EOF without
* having to allocate the entire content length
* in one go.
*/
size_t chunk = want > chunk_max ? chunk_max : want;
if (!BUF_MEM_grow_clean(b, len + chunk)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
want -= chunk;
while (chunk > 0) {
i = BIO_read(in, &(b->data[len]), chunk);
if (i <= 0) {
ASN1error(ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/*
* This can't overflow because |len+want|
* didn't overflow.
*/
len += i;
chunk -= i;
}
if (chunk_max < INT_MAX/2)
chunk_max *= 2;
}
}
if (off + slen < off) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
off += slen;
if (eos <= 0) {
break;
} else
want = HEADER_SIZE;
}
}
if (off > INT_MAX) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
*pb = b;
return off;
err:
if (b != NULL)
BUF_MEM_free(b);
return -1;
}
void *
ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p = (const unsigned char *)b->data;
ret = ASN1_item_d2i(x, &p, len, it);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
void *
ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
{
BIO *b;
char *ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_item_d2i_bio(it, b, x);
BIO_free(b);
return (ret);
}
int
ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
{
unsigned char *b = NULL;
int i, j = 0, n, ret = 1;
n = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
free(b);
return (ret);
}
int
ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_item_i2d_bio(it, b, x);
BIO_free(b);
return (ret);
}

View File

@@ -1,436 +1,202 @@
/* $OpenBSD: asn1_lib.c,v 1.44 2018/11/17 09:34:11 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
/* $OpenBSD: asn1_lib.c,v 1.52 2022/03/26 14:47:58 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max);
static void asn1_put_length(unsigned char **pp, int length);
#include "bytestring.h"
static int
_asn1_check_infinite_end(const unsigned char **p, long len)
asn1_get_identifier_cbs(CBS *cbs, int der_mode, uint8_t *out_class,
int *out_constructed, uint32_t *out_tag_number)
{
/* If there is 0 or 1 byte left, the length check should pick
* things up */
if (len <= 0)
return (1);
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
(*p) += 2;
return (1);
}
return (0);
}
uint8_t tag_class, tag_val;
int tag_constructed;
uint32_t tag_number;
int
ASN1_check_infinite_end(unsigned char **p, long len)
{
return _asn1_check_infinite_end((const unsigned char **)p, len);
}
/*
* Decode ASN.1 identifier octets - see ITU-T X.690 section 8.1.2.
*/
int
ASN1_const_check_infinite_end(const unsigned char **p, long len)
{
return _asn1_check_infinite_end(p, len);
}
*out_class = 0;
*out_constructed = 0;
*out_tag_number = 0;
int
ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
int *pclass, long omax)
{
int i, ret;
long l;
const unsigned char *p = *pp;
int tag, xclass, inf;
long max = omax;
if (!CBS_get_u8(cbs, &tag_val))
return 0;
if (!max)
goto err;
ret = (*p & V_ASN1_CONSTRUCTED);
xclass = (*p & V_ASN1_PRIVATE);
i = *p & V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
p++;
if (--max == 0)
goto err;
l = 0;
while (*p & 0x80) {
l <<= 7L;
l |= *(p++) & 0x7f;
if (--max == 0)
goto err;
if (l > (INT_MAX >> 7L))
goto err;
}
l <<= 7L;
l |= *(p++) & 0x7f;
tag = (int)l;
if (--max == 0)
goto err;
} else {
tag = i;
p++;
if (--max == 0)
goto err;
}
*ptag = tag;
*pclass = xclass;
if (!asn1_get_length(&p, &inf, plength, (int)max))
goto err;
/*
* ASN.1 tag class, encoding (primitive or constructed) and tag number
* are encoded in one or more identifier octets - the first octet
* contains the 2 bit tag class, the 1 bit encoding type and 5 bits
* of tag number.
*
* For tag numbers larger than 30 (0x1e) the 5 bit tag number in the
* first octet is set to all ones (0x1f) - the tag number is then
* encoded in subsequent octets - each of which have a one bit
* continuation flag and 7 bits of tag number in big-endian form.
* The encoding should not contain leading zeros but can for BER.
*/
tag_class = (tag_val >> 6) & 0x3;
tag_constructed = (tag_val >> 5) & 0x1;
tag_number = tag_val & 0x1f;
if (inf && !(ret & V_ASN1_CONSTRUCTED))
goto err;
if (*plength > (omax - (p - *pp))) {
ASN1error(ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret |= 0x80;
}
*pp = p;
return (ret | inf);
err:
ASN1error(ASN1_R_HEADER_TOO_LONG);
return (0x80);
}
static int
asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
{
const unsigned char *p = *pp;
unsigned long ret = 0;
unsigned int i;
if (max-- < 1)
return (0);
if (*p == 0x80) {
*inf = 1;
ret = 0;
p++;
} else {
*inf = 0;
i = *p & 0x7f;
if (*(p++) & 0x80) {
if (max < (int)i)
return (0);
/* skip leading zeroes */
while (i && *p == 0) {
p++;
i--;
}
if (i > sizeof(long))
/* Long form. */
if (tag_number == 0x1f) {
tag_number = 0;
do {
if (!CBS_get_u8(cbs, &tag_val))
return 0;
while (i-- > 0) {
ret <<= 8L;
ret |= *(p++);
}
} else
ret = i;
if (der_mode && tag_number == 0 && tag_val == 0x80)
return 0;
if (tag_number > (UINT32_MAX >> 7))
return 0;
tag_number = tag_number << 7 | (tag_val & 0x7f);
} while ((tag_val & 0x80) != 0);
}
if (ret > LONG_MAX)
return 0;
*pp = p;
*rl = (long)ret;
return (1);
}
/* class 0 is constructed
* constructed == 2 for indefinite length constructed */
void
ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
int xclass)
{
unsigned char *p = *pp;
int i, ttag;
*out_class = tag_class;
*out_constructed = tag_constructed;
*out_tag_number = tag_number;
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
i |= (xclass & V_ASN1_PRIVATE);
if (tag < 31)
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
else {
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
for(i = 0, ttag = tag; ttag > 0; i++)
ttag >>= 7;
ttag = i;
while (i-- > 0) {
p[i] = tag & 0x7f;
if (i != (ttag - 1))
p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++) = 0x80;
else
asn1_put_length(&p, length);
*pp = p;
}
int
ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void
asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p = *pp;
int i, l;
if (length <= 127)
*(p++) = (unsigned char)length;
else {
l = length;
for (i = 0; l > 0; i++)
l >>= 8;
*(p++) = i | 0x80;
l = i;
while (i-- > 0) {
p[i] = length & 0xff;
length >>= 8;
}
p += l;
}
*pp = p;
}
int
ASN1_object_size(int constructed, int length, int tag)
{
int ret;
ret = length;
ret++;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127) {
while (length > 0) {
length >>= 8;
ret++;
}
}
return (ret);
}
int
ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
if (str == NULL)
return 0;
dst->type = str->type;
if (!ASN1_STRING_set(dst, str->data, str->length))
return 0;
dst->flags = str->flags;
return 1;
}
ASN1_STRING *
ASN1_STRING_dup(const ASN1_STRING *str)
static int
asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite,
uint32_t *out_length)
{
ASN1_STRING *ret;
uint8_t len_bytes;
uint32_t length;
uint8_t val;
if (!str)
return NULL;
ret = ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret, str)) {
ASN1_STRING_free(ret);
return NULL;
/*
* Decode ASN.1 length octets - see ITU-T X.690 section 8.1.3.
*/
*out_length = 0;
*out_indefinite = 0;
if (!CBS_get_u8(cbs, &val))
return 0;
/*
* Short form - length is encoded in the lower 7 bits of a single byte.
*/
if (val < 0x80) {
*out_length = val;
return 1;
}
return ret;
/*
* Indefinite length - content continues until an End of Content (EOC)
* marker is reached. Must be used with constructed encoding.
*/
if (val == 0x80) {
*out_indefinite = 1;
return 1;
}
/*
* Long form - the lower 7 bits of the first byte specifies the number
* of bytes used to encode the length, the following bytes specify the
* length in big-endian form. The encoding should not contain leading
* zeros but can for BER. A length value of 0x7f is invalid.
*/
if ((len_bytes = val & 0x7f) == 0x7f)
return 0;
length = 0;
while (len_bytes-- > 0) {
if (!CBS_get_u8(cbs, &val))
return 0;
if (der_mode && length == 0 && val == 0)
return 0;
if (length > (UINT32_MAX >> 8))
return 0;
length = (length << 8) | val;
}
*out_length = length;
return 1;
}
int
ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_tag_class,
int *out_constructed, uint32_t *out_tag_number, int *out_indefinite,
uint32_t *out_length)
{
const char *data = _data;
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
if (len < 0) {
if (data == NULL)
return (0);
else
len = strlen(data);
}
if ((str->length < len) || (str->data == NULL)) {
unsigned char *tmp;
tmp = realloc(str->data, len + 1);
if (tmp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
str->data = tmp;
}
str->length = len;
if (data != NULL) {
memmove(str->data, data, len);
}
str->data[str->length] = '\0';
return (1);
}
*out_tag_class = 0;
*out_constructed = 0;
*out_tag_number = 0;
*out_indefinite = 0;
*out_length = 0;
void
ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
freezero(str->data, str->length);
str->data = data;
str->length = len;
}
if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed,
&tag_number))
return 0;
if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length))
return 0;
ASN1_STRING *
ASN1_STRING_new(void)
{
return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
}
/* Indefinite length can only be used with constructed encoding. */
if (indefinite && !constructed)
return 0;
ASN1_STRING *
ASN1_STRING_type_new(int type)
{
ASN1_STRING *ret;
*out_tag_class = tag_class;
*out_constructed = constructed;
*out_tag_number = tag_number;
*out_indefinite = indefinite;
*out_length = length;
ret = malloc(sizeof(ASN1_STRING));
if (ret == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->type = type;
ret->data = NULL;
ret->flags = 0;
return (ret);
}
void
ASN1_STRING_free(ASN1_STRING *a)
{
if (a == NULL)
return;
if (a->data != NULL && !(a->flags & ASN1_STRING_FLAG_NDEF))
freezero(a->data, a->length);
free(a);
return 1;
}
int
ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
CBS *out_content)
{
int i;
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
i = (a->length - b->length);
if (i == 0) {
i = memcmp(a->data, b->data, a->length);
if (i == 0)
return (a->type - b->type);
else
return (i);
} else
return (i);
}
*out_tag_number = 0;
void
asn1_add_error(const unsigned char *address, int offset)
{
ERR_asprintf_error_data("offset=%d", offset);
}
CBS_init(out_content, NULL, 0);
int
ASN1_STRING_length(const ASN1_STRING *x)
{
return (x->length);
}
if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed,
&tag_number))
return 0;
if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length))
return 0;
void
ASN1_STRING_length_set(ASN1_STRING *x, int len)
{
x->length = len;
}
/* A primitive is not constructed and has a definite length. */
if (constructed || indefinite)
return 0;
int
ASN1_STRING_type(const ASN1_STRING *x)
{
return (x->type);
}
if (!CBS_get_bytes(cbs, out_content, length))
return 0;
unsigned char *
ASN1_STRING_data(ASN1_STRING *x)
{
return (x->data);
}
*out_tag_number = tag_number;
const unsigned char *
ASN1_STRING_get0_data(const ASN1_STRING *x)
{
return (x->data);
return 1;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn1_locl.h,v 1.12 2019/10/24 16:36:10 jsing Exp $ */
/* $OpenBSD: asn1_locl.h,v 1.24 2022/03/26 14:47:58 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
@@ -56,6 +56,8 @@
*
*/
#include "bytestring.h"
__BEGIN_HIDDEN_DECLS
/* Internal ASN1 structures and functions: not for application use */
@@ -63,6 +65,20 @@ __BEGIN_HIDDEN_DECLS
ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t);
void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t);
/* These are used internally in the ASN1_OBJECT to keep track of
* whether the names and data need to be free()ed */
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
struct asn1_object_st {
const char *sn, *ln;
int nid;
int length;
const unsigned char *data; /* data remains const after init */
int flags; /* Should we free this one */
} /* ASN1_OBJECT */;
/* ASN1 print context structure */
struct asn1_pctx_st {
@@ -122,6 +138,9 @@ struct evp_pkey_asn1_method_st {
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
int (*pkey_check)(const EVP_PKEY *pk);
int (*pkey_public_check)(const EVP_PKEY *pk);
int (*pkey_param_check)(const EVP_PKEY *pk);
} /* EVP_PKEY_ASN1_METHOD */;
/* Method to handle CRL access.
@@ -142,6 +161,23 @@ struct x509_crl_method_st {
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
};
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp);
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length);
/*
* Unicode codepoint constants
*/
@@ -155,4 +191,18 @@ struct x509_crl_method_st {
int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
int UTF8_putc(unsigned char *str, int len, unsigned long value);
int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class,
int *out_constructed, uint32_t *out_tag_number, int *out_indefinite,
uint32_t *out_length);
int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
CBS *out_content);
int asn1_tag2charwidth(int tag);
int i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len,
int no_name);
ASN1_OBJECT *t2i_ASN1_OBJECT_internal(const char *oid);
__END_HIDDEN_DECLS

180
externals/libressl/crypto/asn1/asn1_old.c vendored Executable file
View File

@@ -0,0 +1,180 @@
/* $OpenBSD: asn1_old.c,v 1.2 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "asn1_locl.h"
#ifndef NO_OLD_ASN1
void *
ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b, *p;
const unsigned char *p2;
int i;
char *ret;
if (x == NULL)
return (NULL);
i = i2d(x, NULL);
b = malloc(i + 10);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
i = i2d(x, &p);
p2 = b;
ret = d2i(NULL, &p2, i);
free(b);
return (ret);
}
void *
ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
void *ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_d2i_bio(xnew, d2i, b, x);
BIO_free(b);
return (ret);
}
void *
ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p = (unsigned char *)b->data;
ret = d2i(x, &p, len);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
int
ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_i2d_bio(i2d, b, x);
BIO_free(b);
return (ret);
}
int
ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
{
char *b;
unsigned char *p;
int i, j = 0, n, ret = 1;
n = i2d(x, NULL);
b = malloc(n);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
p = (unsigned char *)b;
i2d(x, &p);
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
free(b);
return (ret);
}
#endif

211
externals/libressl/crypto/asn1/asn1_old_lib.c vendored Executable file
View File

@@ -0,0 +1,211 @@
/* $OpenBSD: asn1_old_lib.c,v 1.3 2022/01/14 07:57:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "asn1_locl.h"
static void asn1_put_length(unsigned char **pp, int length);
int
ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
int *pclass, long omax)
{
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
CBS cbs;
int ret = 0;
*pclass = 0;
*ptag = 0;
*plength = 0;
CBS_init(&cbs, *pp, omax);
if (!asn1_get_object_cbs(&cbs, 0, &tag_class, &constructed, &tag_number,
&indefinite, &length)) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
return 0x80;
}
if (tag_number > INT_MAX) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
return 0x80;
}
/*
* API insanity ahead... in this case we add an error to the stack and
* signal an error by setting the 8th bit in the return value... but we
* still provide all of the decoded data.
*/
if (length > CBS_len(&cbs)) {
ASN1error(ASN1_R_TOO_LONG);
ret = 0x80;
}
*pclass = tag_class << 6;
*ptag = tag_number;
*plength = length;
*pp = CBS_data(&cbs);
if (constructed)
ret |= 1 << 5;
if (indefinite)
ret |= 1;
return ret;
}
/* class 0 is constructed
* constructed == 2 for indefinite length constructed */
void
ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
int xclass)
{
unsigned char *p = *pp;
int i, ttag;
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
i |= (xclass & V_ASN1_PRIVATE);
if (tag < 31)
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
else {
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
for(i = 0, ttag = tag; ttag > 0; i++)
ttag >>= 7;
ttag = i;
while (i-- > 0) {
p[i] = tag & 0x7f;
if (i != (ttag - 1))
p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++) = 0x80;
else
asn1_put_length(&p, length);
*pp = p;
}
int
ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void
asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p = *pp;
int i, l;
if (length <= 127)
*(p++) = (unsigned char)length;
else {
l = length;
for (i = 0; l > 0; i++)
l >>= 8;
*(p++) = i | 0x80;
l = i;
while (i-- > 0) {
p[i] = length & 0xff;
length >>= 8;
}
p += l;
}
*pp = p;
}
int
ASN1_object_size(int constructed, int length, int tag)
{
int ret;
ret = length;
ret++;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127) {
while (length > 0) {
length >>= 8;
ret++;
}
}
return (ret);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn1_par.c,v 1.28 2020/01/09 11:27:21 inoguchi Exp $ */
/* $OpenBSD: asn1_par.c,v 1.34 2022/02/12 03:07:24 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -80,7 +80,8 @@ asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
p="prim: ";
if (BIO_write(bp, p, 6) < 6)
goto err;
BIO_indent(bp, indent, 128);
if (!BIO_indent(bp, indent, 128))
goto err;
p = str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
@@ -97,7 +98,7 @@ asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
if (BIO_printf(bp, "%-18s", p) <= 0)
goto err;
return (1);
err:
err:
return (0);
}
@@ -232,16 +233,13 @@ asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
goto end;
}
} else if (tag == V_ASN1_BOOLEAN) {
int ii;
opp = op;
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
if (ii < 0) {
if (len == 1 && p < tot) {
BIO_printf(bp, ":%u", p[0]);
} else {
if (BIO_write(bp, "Bad boolean\n",
12) <= 0)
goto end;
}
BIO_printf(bp, ":%d", ii);
} else if (tag == V_ASN1_BMPSTRING) {
/* do the BMP thang */
} else if (tag == V_ASN1_OCTET_STRING) {
@@ -375,7 +373,7 @@ asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
}
ret = 1;
end:
end:
if (o != NULL)
ASN1_OBJECT_free(o);
ASN1_OCTET_STRING_free(os);
@@ -384,25 +382,3 @@ end:
*pp = p;
return (ret);
}
const char *
ASN1_tag2str(int tag)
{
static const char * const tag2str[] = {
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
};
if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
tag &= ~0x100;
if (tag < 0 || tag > 30)
return "(unknown)";
return tag2str[tag];
}

263
externals/libressl/crypto/asn1/asn1_types.c vendored Executable file
View File

@@ -0,0 +1,263 @@
/* $OpenBSD: asn1_types.c,v 1.1 2021/12/14 17:35:21 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stddef.h>
#include <openssl/asn1.h>
struct asn1_type {
const char *name;
uint32_t bit_value;
int char_width;
};
/*
* Universal class tag types - ITU X.680.
*/
static const struct asn1_type asn1_types[31] = {
[0] = {
/* Tag 0 (0x00) - Reserved for use by encoding rules */
.name = "EOC",
.bit_value = 0,
.char_width = -1,
},
[1] = {
/* Tag 1 (0x01) - Boolean */
.name = "BOOLEAN",
.bit_value = 0,
.char_width = -1,
},
[2] = {
/* Tag 2 (0x02) - Integer */
.name = "INTEGER",
.bit_value = 0,
.char_width = -1,
},
[3] = {
/* Tag 3 (0x03) - BitString */
.name = "BIT STRING",
.bit_value = B_ASN1_BIT_STRING,
.char_width = -1,
},
[4] = {
/* Tag 4 (0x04) - OctetString */
.name = "OCTET STRING",
.bit_value = B_ASN1_OCTET_STRING,
.char_width = -1,
},
[5] = {
/* Tag 5 (0x05) - Null */
.name = "NULL",
.bit_value = 0,
.char_width = -1,
},
[6] = {
/* Tag 6 (0x06) - Object Identifier */
.name = "OBJECT",
.bit_value = 0,
.char_width = -1,
},
[7] = {
/* Tag 7 (0x07) - Object Descriptor */
.name = "OBJECT DESCRIPTOR",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[8] = {
/* Tag 8 (0x08) - External */
.name = "EXTERNAL",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[9] = {
/* Tag 9 (0x09) - Real */
.name = "REAL",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[10] = {
/* Tag 10 (0x0a) - Enumerated */
.name = "ENUMERATED",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[11] = {
/* Tag 11 (0x0b) - Embedded PDV */
.name = "<ASN1 11 EMBEDDED PDV>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[12] = {
/* Tag 12 (0x0c) - UTF8String */
.name = "UTF8STRING",
.bit_value = B_ASN1_UTF8STRING,
.char_width = 0,
},
[13] = {
/* Tag 13 (0x0d) - Relative Object Identifier */
.name = "<ASN1 13 RELATIVE OID>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[14] = {
/* Tag 14 (0x0e) - Time */
.name = "<ASN1 14 TIME>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[15] = {
/* Tag 15 (0x0f) - Reserved */
.name = "<ASN1 15 RESERVED>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[16] = {
/* Tag 16 (0x10)- Sequence */
.name = "SEQUENCE",
.bit_value = B_ASN1_SEQUENCE,
.char_width = -1,
},
[17] = {
/* Tag 17 (0x11) - Set */
.name = "SET",
.bit_value = 0,
.char_width = -1,
},
[18] = {
/* Tag 18 (0x12) - NumericString */
.name = "NUMERICSTRING",
.bit_value = B_ASN1_NUMERICSTRING,
.char_width = -1,
},
[19] = {
/* Tag 19 (0x13) - PrintableString */
.name = "PRINTABLESTRING",
.bit_value = B_ASN1_PRINTABLESTRING,
.char_width = 1,
},
[20] = {
/* Tag 20 (0x14) - TeletexString (T61String) */
.name = "T61STRING",
.bit_value = B_ASN1_T61STRING,
.char_width = 1,
},
[21] = {
/* Tag 21 (0x15) - VideotexString */
.name = "VIDEOTEXSTRING",
.bit_value = B_ASN1_VIDEOTEXSTRING,
.char_width = -1,
},
[22] = {
/* Tag 22 (0x16) - IA5String */
.name = "IA5STRING",
.bit_value = B_ASN1_IA5STRING,
.char_width = 1,
},
[23] = {
/* Tag 23 (0x17) - UTCTime */
.name = "UTCTIME",
.bit_value = B_ASN1_UTCTIME,
.char_width = 1,
},
[24] = {
/* Tag 24 (0x18) - GeneralizedTime */
.name = "GENERALIZEDTIME",
.bit_value = B_ASN1_GENERALIZEDTIME,
.char_width = 1,
},
[25] = {
/* Tag 25 (0x19) - GraphicString */
.name = "GRAPHICSTRING",
.bit_value = B_ASN1_GRAPHICSTRING,
.char_width = -1,
},
[26] = {
/* Tag 26 (0x1a) - VisibleString (ISO646String) */
.name = "VISIBLESTRING",
.bit_value = B_ASN1_ISO64STRING,
.char_width = 1,
},
[27] = {
/* Tag 27 (0x1b) - GeneralString */
.name = "GENERALSTRING",
.bit_value = B_ASN1_GENERALSTRING,
.char_width = -1,
},
[28] = {
/* Tag 28 (0x1c) - UniversalString */
.name = "UNIVERSALSTRING",
.bit_value = B_ASN1_UNIVERSALSTRING,
.char_width = 4,
},
[29] = {
/* Tag 29 (0x1d) - Unallocated */
.name = "<ASN1 29>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[30] = {
/* Tag 30 (0x1e) - BMPString */
.name = "BMPSTRING",
.bit_value = B_ASN1_BMPSTRING,
.char_width = 2,
},
};
static const struct asn1_type *
asn1_type_by_tag(int tag)
{
if (tag < 0 || tag > 30)
return NULL;
return &asn1_types[tag];
}
int
asn1_tag2charwidth(int tag)
{
const struct asn1_type *at;
if ((at = asn1_type_by_tag(tag)) != NULL)
return at->char_width;
return -1;
}
unsigned long
ASN1_tag2bit(int tag)
{
const struct asn1_type *at;
if ((at = asn1_type_by_tag(tag)) != NULL)
return (unsigned long)at->bit_value;
return 0;
}
const char *
ASN1_tag2str(int tag)
{
const struct asn1_type *at;
if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
tag &= ~V_ASN1_NEG;
if ((at = asn1_type_by_tag(tag)) != NULL)
return at->name;
return "(unknown)";
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn_mime.c,v 1.27 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: asn_mime.c,v 1.29 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -63,6 +63,7 @@
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "evp_locl.h"
/* Generalised MIME like utilities for streaming ASN1. Although many
* have a PKCS7/CMS like flavour others are more general purpose.
@@ -267,7 +268,7 @@ asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
ret = 1;
err:
err:
return ret;
}
@@ -778,7 +779,7 @@ STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
return headers;
merr:
merr:
if (mhdr != NULL)
mime_hdr_free(mhdr);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
@@ -866,7 +867,7 @@ mime_hdr_new(char *name, char *value)
goto err;
}
return mhdr;
err:
err:
free(tmpname);
free(tmpval);
return NULL;
@@ -901,7 +902,7 @@ mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
goto err;
}
return 1;
err:
err:
free(tmpname);
free(tmpval);
return 0;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: asn_moid.c,v 1.13 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: asn_moid.c,v 1.14 2022/01/07 11:13:54 tb Exp $ */
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
@@ -65,6 +65,8 @@
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
/* Simple ASN1 OID module: add all objects in a given section */
static int do_create(char *value, char *name);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bio_asn1.c,v 1.13 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bio_asn1.c,v 1.17 2022/01/14 08:40:57 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -67,6 +67,8 @@
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include "bio_local.h"
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
@@ -116,9 +118,8 @@ static int asn1_bio_gets(BIO *h, char *str, int size);
static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int asn1_bio_new(BIO *h);
static int asn1_bio_free(BIO *data);
static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static long asn1_bio_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
@@ -148,35 +149,23 @@ static int
asn1_bio_new(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
if ((ctx->buf = malloc(DEFAULT_ASN1_BUF_SIZE)) == NULL) {
free(ctx);
return 0;
}
ctx->bufsize = DEFAULT_ASN1_BUF_SIZE;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->state = ASN1_STATE_START;
b->init = 1;
b->ptr = (char *)ctx;
b->flags = 0;
return 1;
}
static int
asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
{
ctx->buf = malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = NULL;
ctx->ex_pos = 0;
ctx->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
}
@@ -284,7 +273,7 @@ asn1_bio_write(BIO *b, const char *in , int inl)
}
done:
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
@@ -357,7 +346,7 @@ asn1_bio_gets(BIO *b, char *str, int size)
}
static long
asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
asn1_bio_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
if (b->next_bio == NULL)
return (0);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: bio_ndef.c,v 1.10 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bio_ndef.c,v 1.11 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -143,7 +143,7 @@ BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
return sarg.ndef_bio;
err:
err:
BIO_free(asn_bio);
free(ndef_aux);
return NULL;

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: p5_pbe.c,v 1.22 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: p5_pbe.c,v 1.23 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -159,7 +159,7 @@ PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
return 1;
err:
err:
if (pbe != NULL)
PBEPARAM_free(pbe);
ASN1_STRING_free(pbe_str);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: p5_pbev2.c,v 1.25 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: p5_pbev2.c,v 1.27 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999-2004.
*/
@@ -64,6 +64,8 @@
#include <openssl/err.h>
#include <openssl/x509.h>
#include "evp_locl.h"
/* PKCS#5 v2.0 password based encryption structures */
static const ASN1_TEMPLATE PBE2PARAM_seq_tt[] = {
@@ -272,10 +274,10 @@ PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
return ret;
merr:
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
err:
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
X509_ALGOR_free(kalg);
@@ -364,7 +366,7 @@ PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid,
PBKDF2PARAM_free(kdf);
return keyfunc;
merr:
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: p8_pkey.c,v 1.19 2018/08/24 20:17:33 tb Exp $ */
/* $OpenBSD: p8_pkey.c,v 1.20 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,6 +62,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* Minor tweak to operation: zero private key data */
static int
pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_crl.c,v 1.18 2019/05/12 15:56:31 tb Exp $ */
/* $OpenBSD: t_crl.c,v 1.20 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -66,6 +66,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
int
X509_CRL_print_fp(FILE *fp, X509_CRL *x)
{
@@ -138,6 +140,6 @@ X509_CRL_print(BIO *out, X509_CRL *x)
return 1;
err:
err:
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_pkey.c,v 1.16 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_pkey.c,v 1.17 2021/12/04 16:08:32 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -62,6 +62,8 @@
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include "bn_lcl.h"
int
ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_req.c,v 1.19 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: t_req.c,v 1.21 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -74,6 +74,8 @@
#include <openssl/rsa.h>
#endif
#include "x509_lcl.h"
int
X509_REQ_print_fp(FILE *fp, X509_REQ *x)
{
@@ -192,7 +194,7 @@ X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
ii = 0;
count = sk_ASN1_TYPE_num(
a->value.set);
get_next:
get_next:
at = sk_ASN1_TYPE_value(
a->value.set, ii);
type = at->type;
@@ -255,7 +257,7 @@ get_next:
return (1);
err:
err:
X509error(ERR_R_BUF_LIB);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_spki.c,v 1.11 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_spki.c,v 1.13 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -71,6 +71,8 @@
#include <openssl/rsa.h>
#endif
#include "x509_lcl.h"
/* Print out an SPKI */
int
@@ -94,7 +96,8 @@ NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
}
chal = spki->spkac->challenge;
if (chal->length)
BIO_printf(out, " Challenge String: %s\n", chal->data);
BIO_printf(out, " Challenge String: %.*s\n", chal->length,
chal->data);
i = OBJ_obj2nid(spki->sig_algor->algorithm);
BIO_printf(out, " Signature Algorithm: %s",
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_x509.c,v 1.32 2020/04/10 07:05:24 tb Exp $ */
/* $OpenBSD: t_x509.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -78,6 +78,7 @@
#endif
#include "asn1_locl.h"
#include "x509_lcl.h"
int
X509_print_fp(FILE *fp, X509 *x)
@@ -180,7 +181,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_issuer_name(x),
nmindent, nmflags) < 0)
nmindent, nmflags) < (nmflags == X509_FLAG_COMPAT ? 1 : 0))
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
@@ -203,7 +204,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_subject_name(x),
nmindent, nmflags) < 0)
nmindent, nmflags) < (nmflags == X509_FLAG_COMPAT ? 1 : 0))
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
@@ -243,7 +244,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
}
ret = 1;
err:
err:
free(m);
return (ret);
}
@@ -261,10 +262,12 @@ X509_ocspid_print(BIO *bp, X509 *x)
in OCSP requests */
if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
goto err;
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
if ((derlen = i2d_X509_NAME(x->cert_info->subject, NULL)) <= 0)
goto err;
if ((der = dertmp = malloc(derlen)) == NULL)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
if (i2d_X509_NAME(x->cert_info->subject, &dertmp) <= 0)
goto err;
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
goto err;
@@ -292,7 +295,7 @@ X509_ocspid_print(BIO *bp, X509 *x)
return (1);
err:
err:
free(der);
return (0);
}
@@ -348,36 +351,6 @@ X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig)
return 1;
}
int
ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
{
int i, n;
char buf[80];
const char *p;
if (v == NULL)
return (0);
n = 0;
p = (const char *)v->data;
for (i = 0; i < v->length; i++) {
if ((p[i] > '~') || ((p[i] < ' ') &&
(p[i] != '\n') && (p[i] != '\r')))
buf[n] = '.';
else
buf[n] = p[i];
n++;
if (n >= 80) {
if (BIO_write(bp, buf, n) <= 0)
return (0);
n = 0;
}
}
if (n > 0)
if (BIO_write(bp, buf, n) <= 0)
return (0);
return (1);
}
int
ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
{
@@ -443,7 +416,7 @@ ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
else
return (1);
err:
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
@@ -486,7 +459,7 @@ ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
else
return (1);
err:
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
@@ -532,7 +505,7 @@ X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
ret = 1;
if (0) {
err:
err:
X509error(ERR_R_BUF_LIB);
}
free(b);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: t_x509a.c,v 1.8 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_x509a.c,v 1.10 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,8 +62,9 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
/* X509_CERT_AUX and string set routines
*/
#include "x509_lcl.h"
/* X509_CERT_AUX and string set routines */
int
X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
@@ -105,8 +106,8 @@ X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
} else
BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
if (aux->alias)
BIO_printf(out, "%*sAlias: %s\n", indent, "",
aux->alias->data);
BIO_printf(out, "%*sAlias: %.*s\n", indent, "",
aux->alias->length, aux->alias->data);
if (aux->keyid) {
BIO_printf(out, "%*sKey Id: ", indent, "");
for (i = 0; i < aux->keyid->length; i++)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_dec.c,v 1.37 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_dec.c,v 1.49 2022/03/13 14:58:14 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -56,14 +56,18 @@
*
*/
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include "asn1_locl.h"
#include "bytestring.h"
/* Constructed types with a recursive definition (such as can be found in PKCS7)
* could eventually exceed the stack given malicious input with excessive
@@ -74,15 +78,16 @@
static int asn1_check_eoc(const unsigned char **in, long len);
static int asn1_find_end(const unsigned char **in, long len, char inf);
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
static int asn1_collect(CBB *cbb, const unsigned char **in, long len,
char inf, int tag, int aclass, int depth);
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
char *inf, char *cst, const unsigned char **in, long len, int exptag,
int expclass, char opt, ASN1_TLC *ctx);
static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx,
int depth);
static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth);
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
@@ -90,68 +95,44 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
ASN1_TLC *ctx);
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len,
int utype, const ASN1_ITEM *it);
/* Table to convert tags to bit values, used for MSTRING type */
static const unsigned long tag2bit[32] = {
0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */
B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */
B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */
B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */
B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */
B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */
B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
};
unsigned long
ASN1_tag2bit(int tag)
static void
asn1_tlc_invalidate(ASN1_TLC *ctx)
{
if ((tag < 0) || (tag > 30))
return 0;
return tag2bit[tag];
if (ctx != NULL)
ctx->valid = 0;
}
/* Macro to initialize and invalidate the cache */
#define asn1_tlc_clear(c) if (c) (c)->valid = 0
/* Version to avoid compiler warning about 'c' always non-NULL */
#define asn1_tlc_clear_nc(c) (c)->valid = 0
/* Decode an ASN1 item, this currently behaves just
* like a standard 'd2i' function. 'in' points to
* a buffer to read the data from, in future we will
* have more advanced versions that can input data
* a piece at a time and this will simply be a special
* case.
*/
ASN1_VALUE *
ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it)
{
ASN1_TLC c;
ASN1_VALUE *ptmpval = NULL;
ASN1_TLC ctx;
if (!pval)
asn1_tlc_invalidate(&ctx);
if (pval == NULL)
pval = &ptmpval;
asn1_tlc_clear_nc(&c);
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval;
return NULL;
if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &ctx, 0) <= 0)
return NULL;
return *pval;
}
int
ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_TEMPLATE *tt)
{
ASN1_TLC c;
ASN1_TLC ctx;
asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0);
asn1_tlc_invalidate(&ctx);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &ctx, 0);
}
/* Decode an item, taking care of IMPLICIT tagging, if any.
* If 'opt' set and tag mismatch return -1 to handle OPTIONAL
*/
@@ -210,6 +191,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
break;
case ASN1_ITYPE_MSTRING:
/*
* It never makes sense for multi-strings to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
goto err;
}
p = *in;
/* Just read in tag and class */
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
@@ -245,6 +236,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
it, tag, aclass, opt, ctx);
case ASN1_ITYPE_CHOICE:
/*
* It never makes sense for CHOICE types to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
goto err;
}
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
@@ -446,9 +447,9 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
return 0;
}
auxerr:
auxerr:
ASN1error(ASN1_R_AUX_ERROR);
err:
err:
if (combine == 0)
ASN1_item_ex_free(pval, it);
if (errtt)
@@ -535,7 +536,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen,
*in = p;
return 1;
err:
err:
ASN1_template_free(val, tt);
return 0;
}
@@ -652,7 +653,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
*in = p;
return 1;
err:
err:
ASN1_template_free(val, tt);
return 0;
}
@@ -663,15 +664,15 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
{
int ret = 0, utype;
long plen;
char cst, inf, free_cont = 0;
char cst, inf;
const unsigned char *p;
BUF_MEM buf;
const unsigned char *cont = NULL;
const unsigned char *content = NULL;
uint8_t *data = NULL;
size_t data_len = 0;
CBB cbb;
long len;
buf.length = 0;
buf.max = 0;
buf.data = NULL;
memset(&cbb, 0, sizeof(cbb));
if (!pval) {
ASN1error(ASN1_R_ILLEGAL_NULL);
@@ -726,69 +727,68 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
* when we have a exact match wont work
*/
if (utype == V_ASN1_OTHER) {
asn1_tlc_clear(ctx);
}
/* SEQUENCE and SET must be constructed */
else if (!cst) {
asn1_tlc_invalidate(ctx);
} else if (!cst) {
/* SEQUENCE and SET must be constructed */
ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
}
cont = *in;
content = *in;
/* If indefinite length constructed find the real end */
if (inf) {
if (!asn1_find_end(&p, plen, inf))
goto err;
len = p - cont;
len = p - content;
} else {
len = p - cont + plen;
len = p - content + plen;
p += plen;
buf.data = NULL;
}
} else if (cst) {
/* Should really check the internal tags are correct but
/*
* Should really check the internal tags are correct but
* some things may get this wrong. The relevant specs
* say that constructed string types should be OCTET STRINGs
* internally irrespective of the type. So instead just check
* for UNIVERSAL class and ignore the tag.
*/
if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
free_cont = 1;
if (!CBB_init(&cbb, 0))
goto err;
}
len = buf.length;
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
buf.data[len] = 0;
cont = (const unsigned char *)buf.data;
free_cont = 1;
if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > LONG_MAX)
goto err;
content = data;
len = data_len;
} else {
cont = p;
content = p;
len = plen;
p += plen;
}
/* We now have content length and type: translate into a structure */
if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
if (!asn1_ex_c2i(pval, content, len, utype, it))
goto err;
*in = p;
ret = 1;
err:
if (free_cont && buf.data)
free(buf.data);
err:
CBB_cleanup(&cbb);
freezero(data, data_len);
return ret;
}
/* Translate ASN1 content octets into a structure */
int
asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
char *free_cont, const ASN1_ITEM *it)
static int
asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, int utype,
const ASN1_ITEM *it)
{
ASN1_VALUE **opval = NULL;
ASN1_STRING *stmp;
@@ -798,10 +798,11 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
if (it->funcs != NULL) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
char free_content = 0;
if (pf->prim_c2i == NULL)
return 0;
return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
return pf->prim_c2i(pval, content, len, utype, &free_content, it);
}
/* If ANY type clear type and set pointer to internal value */
@@ -821,7 +822,7 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
}
switch (utype) {
case V_ASN1_OBJECT:
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &content, len))
goto err;
break;
@@ -840,19 +841,19 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
} else {
ASN1_BOOLEAN *tbool;
tbool = (ASN1_BOOLEAN *)pval;
*tbool = *cont;
*tbool = *content;
}
break;
case V_ASN1_BIT_STRING:
if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &content, len))
goto err;
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
tint = (ASN1_INTEGER **)pval;
if (!c2i_ASN1_INTEGER(tint, &cont, len))
if (!c2i_ASN1_INTEGER(tint, &content, len))
goto err;
/* Fixup type to match the expected form */
(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
@@ -884,10 +885,9 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
goto err;
}
/* All based on ASN1_STRING and handled the same */
if (!*pval) {
stmp = ASN1_STRING_type_new(utype);
if (!stmp) {
/* All based on ASN1_STRING and handled the same way. */
if (*pval == NULL) {
if ((stmp = ASN1_STRING_type_new(utype)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -896,19 +896,10 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
stmp = (ASN1_STRING *)*pval;
stmp->type = utype;
}
/* If we've already allocated a buffer use it */
if (*free_cont) {
free(stmp->data);
stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
stmp->length = len;
*free_cont = 0;
} else {
if (!ASN1_STRING_set(stmp, cont, len)) {
ASN1error(ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
}
if (!ASN1_STRING_set(stmp, content, len)) {
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
}
break;
}
@@ -918,7 +909,7 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
ret = 1;
err:
err:
if (!ret) {
ASN1_TYPE_free(typ);
if (opval)
@@ -927,7 +918,6 @@ err:
return ret;
}
/* This function finds the end of an ASN1 structure when passed its maximum
* length, whether it is indefinite length and a pointer to the content.
* This is more efficient than calling asn1_collect because it does not
@@ -996,21 +986,21 @@ asn1_find_end(const unsigned char **in, long len, char inf)
#endif
static int
asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf,
int tag, int aclass, int depth)
{
const unsigned char *p, *q;
long plen;
char cst, ininf;
if (depth > ASN1_MAX_STRING_NEST) {
ASN1error(ASN1_R_NESTED_ASN1_STRING);
return 0;
}
p = *in;
inf &= 1;
/* If no buffer and not indefinite length constructed just pass over
* the encoded data */
if (!buf && !inf) {
*in += len;
return 1;
}
while (len > 0) {
q = p;
/* Check for EOC */
@@ -1033,15 +1023,14 @@ asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
/* If indefinite length constructed update max length */
if (cst) {
if (depth >= ASN1_MAX_STRING_NEST) {
ASN1error(ASN1_R_NESTED_ASN1_STRING);
return 0;
}
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
if (!asn1_collect(cbb, &p, plen, ininf, tag, aclass,
depth + 1))
return 0;
} else if (plen && !collect_data(buf, &p, plen))
return 0;
} else if (plen > 0) {
if (!CBB_add_bytes(cbb, p, plen))
return 0;
p += plen;
}
len -= p - q;
}
if (inf) {
@@ -1052,22 +1041,6 @@ asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
return 1;
}
static int
collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
{
int len;
if (buf) {
len = buf->length;
if (!BUF_MEM_grow_clean(buf, len + plen)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
}
*p += plen;
return 1;
}
/* Check for ASN1 EOC and swallow it if found */
static int
@@ -1125,7 +1098,7 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
ASN1error(ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
return 0;
}
}
@@ -1133,7 +1106,7 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
if (i & 0x80) {
ASN1error(ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
return 0;
}
if (exptag >= 0) {
@@ -1143,13 +1116,13 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
*/
if (opt)
return -1;
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
ASN1error(ASN1_R_WRONG_TAG);
return 0;
}
/* We have a tag and class match:
* assume we are going to do something with it */
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
}
if (i & 1)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_enc.c,v 1.22 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_enc.c,v 1.24 2022/01/07 11:13:54 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -61,8 +61,11 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include "asn1_locl.h"
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
@@ -152,9 +155,27 @@ ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
break;
case ASN1_ITYPE_MSTRING:
/*
* It never makes sense for multi-strings to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
return 0;
}
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
/*
* It never makes sense for CHOICE types to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
return 0;
}
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = asn1_get_choice_selector(pval, it);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_fre.c,v 1.17 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_fre.c,v 1.18 2022/01/07 12:24:17 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -62,6 +62,8 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include "asn1_locl.h"
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_new.c,v 1.18 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_new.c,v 1.21 2022/01/07 12:24:17 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -64,6 +64,8 @@
#include <openssl/asn1t.h>
#include <string.h>
#include "asn1_locl.h"
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
@@ -103,10 +105,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!combine)
*pval = NULL;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
#endif
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
@@ -136,10 +134,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
@@ -160,10 +154,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
@@ -183,27 +173,15 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
goto auxerr;
break;
}
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
memerr:
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
auxerr:
auxerr:
ASN1error(ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
}
@@ -257,10 +235,6 @@ ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
*pval = NULL;
return 1;
}
#ifdef CRYPTO_MDEBUG
if (tt->field_name)
CRYPTO_push_info(tt->field_name);
#endif
/* If SET OF or SEQUENCE OF, its a STACK */
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *skval;
@@ -276,11 +250,7 @@ ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
}
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
done:
return ret;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_prn.c,v 1.21 2020/03/24 10:46:38 inoguchi Exp $ */
/* $OpenBSD: tasn_prn.c,v 1.22 2021/12/03 17:10:49 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -84,18 +84,14 @@ ASN1_PCTX default_pctx = {
ASN1_PCTX *
ASN1_PCTX_new(void)
{
ASN1_PCTX *ret;
ret = malloc(sizeof(ASN1_PCTX));
if (ret == NULL) {
ASN1_PCTX *p;
if ((p = calloc(1, sizeof(ASN1_PCTX))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
ret->nm_flags = 0;
ret->cert_flags = 0;
ret->oid_flags = 0;
ret->str_flags = 0;
return ret;
return p;
}
void

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_typ.c,v 1.13 2015/07/24 15:09:52 jsing Exp $ */
/* $OpenBSD: tasn_typ.c,v 1.17 2021/12/26 15:20:21 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -61,134 +61,6 @@
/* Declarations for string types */
const ASN1_ITEM ASN1_INTEGER_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.sname = "ASN1_INTEGER",
};
ASN1_INTEGER *
d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
{
return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_INTEGER_it);
}
int
i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
}
ASN1_INTEGER *
ASN1_INTEGER_new(void)
{
return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
}
void
ASN1_INTEGER_free(ASN1_INTEGER *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
}
const ASN1_ITEM ASN1_ENUMERATED_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ENUMERATED,
.sname = "ASN1_ENUMERATED",
};
ASN1_ENUMERATED *
d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len)
{
return (ASN1_ENUMERATED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ENUMERATED_it);
}
int
i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it);
}
ASN1_ENUMERATED *
ASN1_ENUMERATED_new(void)
{
return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it);
}
void
ASN1_ENUMERATED_free(ASN1_ENUMERATED *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ENUMERATED_it);
}
const ASN1_ITEM ASN1_BIT_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BIT_STRING,
.sname = "ASN1_BIT_STRING",
};
ASN1_BIT_STRING *
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
{
return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_BIT_STRING_it);
}
int
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
}
ASN1_BIT_STRING *
ASN1_BIT_STRING_new(void)
{
return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
}
void
ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
}
const ASN1_ITEM ASN1_OCTET_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OCTET_STRING,
.sname = "ASN1_OCTET_STRING",
};
ASN1_OCTET_STRING *
d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a, const unsigned char **in, long len)
{
return (ASN1_OCTET_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_OCTET_STRING_it);
}
int
i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_OCTET_STRING_it);
}
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_new(void)
{
return (ASN1_OCTET_STRING *)ASN1_item_new(&ASN1_OCTET_STRING_it);
}
void
ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_OCTET_STRING_it);
}
const ASN1_ITEM ASN1_NULL_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_NULL,
@@ -221,13 +93,6 @@ ASN1_NULL_free(ASN1_NULL *a)
}
const ASN1_ITEM ASN1_OBJECT_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OBJECT,
.sname = "ASN1_OBJECT",
};
const ASN1_ITEM ASN1_UTF8STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_UTF8STRING,
@@ -552,13 +417,13 @@ ASN1_BMPSTRING_free(ASN1_BMPSTRING *a)
ASN1_item_free((ASN1_VALUE *)a, &ASN1_BMPSTRING_it);
}
const ASN1_ITEM ASN1_ANY_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ANY,
.sname = "ASN1_ANY",
};
/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
const ASN1_ITEM ASN1_SEQUENCE_it = {
@@ -568,31 +433,6 @@ const ASN1_ITEM ASN1_SEQUENCE_it = {
};
ASN1_TYPE *
d2i_ASN1_TYPE(ASN1_TYPE **a, const unsigned char **in, long len)
{
return (ASN1_TYPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ANY_it);
}
int
i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ANY_it);
}
ASN1_TYPE *
ASN1_TYPE_new(void)
{
return (ASN1_TYPE *)ASN1_item_new(&ASN1_ANY_it);
}
void
ASN1_TYPE_free(ASN1_TYPE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ANY_it);
}
/* Multistring types */
@@ -712,6 +552,28 @@ const ASN1_ITEM ASN1_BOOLEAN_it = {
.sname = "ASN1_BOOLEAN",
};
int
i2d_ASN1_BOOLEAN(int a, unsigned char **out)
{
return ASN1_item_ex_i2d((ASN1_VALUE **)&a, out,
&ASN1_BOOLEAN_it, -1, 0);
}
int
d2i_ASN1_BOOLEAN(int *a, const unsigned char **in, long len)
{
ASN1_BOOLEAN abool;
if (ASN1_item_ex_d2i((ASN1_VALUE **)&abool, in, len, &ASN1_BOOLEAN_it,
-1, 0, 0, NULL) <= 0)
return -1;
if (a != NULL)
*a = abool;
return abool;
}
const ASN1_ITEM ASN1_TBOOLEAN_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BOOLEAN,

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: tasn_utl.c,v 1.12 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: tasn_utl.c,v 1.13 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -272,7 +272,7 @@ asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr)
goto err;
return adb->default_tt;
err:
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr)
ASN1error(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_algor.c,v 1.22 2018/05/01 19:01:27 tb Exp $ */
/* $OpenBSD: x_algor.c,v 1.23 2021/12/12 14:27:20 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -197,12 +197,10 @@ X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval,
void
X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
{
int param_type;
int param_type = V_ASN1_NULL;
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
if ((EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) != 0)
param_type = V_ASN1_UNDEF;
else
param_type = V_ASN1_NULL;
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_attrib.c,v 1.14 2020/06/04 21:21:03 schwarze Exp $ */
/* $OpenBSD: x_attrib.c,v 1.16 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -62,6 +62,8 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_ATTRIBUTE: this has the following form:
*
* typedef struct x509_attributes_st
@@ -192,7 +194,7 @@ X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
ASN1_TYPE_set(val, atrtype, value);
return (ret);
err:
err:
if (ret != NULL)
X509_ATTRIBUTE_free(ret);
if (val != NULL)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_crl.c,v 1.34 2019/03/13 20:34:00 tb Exp $ */
/* $OpenBSD: x_crl.c,v 1.37 2022/02/24 22:05:06 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -66,6 +66,7 @@
#include <openssl/x509v3.h>
#include "asn1_locl.h"
#include "x509_lcl.h"
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b);
@@ -287,9 +288,7 @@ crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
break;
case ASN1_OP_D2I_POST:
#ifndef OPENSSL_NO_SHA
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
#endif
X509_CRL_digest(crl, X509_CRL_HASH_EVP, crl->hash, NULL);
crl->idp = X509_CRL_get_ext_d2i(crl,
NID_issuing_distribution_point, NULL, NULL);
if (crl->idp)
@@ -659,14 +658,15 @@ X509_CRL_METHOD_new(int (*crl_init)(X509_CRL *crl),
{
X509_CRL_METHOD *m;
m = malloc(sizeof(X509_CRL_METHOD));
if (!m)
if ((m = calloc(1, sizeof(X509_CRL_METHOD))) == NULL)
return NULL;
m->crl_init = crl_init;
m->crl_free = crl_free;
m->crl_lookup = crl_lookup;
m->crl_verify = crl_verify;
m->flags = X509_CRL_METHOD_DYNAMIC;
return m;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_exten.c,v 1.16 2015/07/24 15:09:52 jsing Exp $ */
/* $OpenBSD: x_exten.c,v 1.17 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@@ -61,6 +61,8 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include "x509_lcl.h"
static const ASN1_TEMPLATE X509_EXTENSION_seq_tt[] = {
{
.offset = offsetof(X509_EXTENSION, object),

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_name.c,v 1.34 2018/02/20 17:09:20 jsing Exp $ */
/* $OpenBSD: x_name.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,6 +65,7 @@
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "x509_lcl.h"
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
@@ -256,7 +257,7 @@ x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
*val = (ASN1_VALUE *)ret;
return 1;
memerr:
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
if (ret) {
if (ret->entries)
@@ -336,7 +337,7 @@ x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
*in = p;
return ret;
err:
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
ASN1error(ERR_R_NESTED_ASN1_ERROR);
@@ -421,7 +422,7 @@ x509_name_encode(X509_NAME *a)
a->modified = 0;
return len;
memerr:
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
ASN1error(ERR_R_MALLOC_FAILURE);
@@ -511,7 +512,7 @@ x509_name_canon(X509_NAME *a)
i2d_name_canon(intname, &p);
ret = 1;
err:
err:
if (tmpentry)
X509_NAME_ENTRY_free(tmpentry);
if (intname)
@@ -626,19 +627,13 @@ i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
int
X509_NAME_set(X509_NAME **xn, X509_NAME *name)
{
X509_NAME *in;
if (!xn || !name)
return (0);
if (*xn != name) {
in = X509_NAME_dup(name);
if (in != NULL) {
X509_NAME_free(*xn);
*xn = in;
}
}
return (*xn != NULL);
if (*xn == name)
return *xn != NULL;
if ((name = X509_NAME_dup(name)) == NULL)
return 0;
X509_NAME_free(*xn);
*xn = name;
return 1;
}
int

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_pkey.c,v 1.20 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: x_pkey.c,v 1.21 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -91,7 +91,7 @@ X509_PKEY_new(void)
ret->references = 1;
return (ret);
err:
err:
if (ret) {
X509_ALGOR_free(ret->enc_algor);
free(ret);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_pubkey.c,v 1.27 2018/03/17 14:55:39 jsing Exp $ */
/* $OpenBSD: x_pubkey.c,v 1.31 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -72,6 +72,8 @@
#endif
#include "asn1_locl.h"
#include "evp_locl.h"
#include "x509_lcl.h"
/* Minor tweak to operation: free up EVP_PKEY */
static int
@@ -110,7 +112,6 @@ const ASN1_ITEM X509_PUBKEY_it = {
.sname = "X509_PUBKEY",
};
X509_PUBKEY *
d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len)
{
@@ -168,7 +169,7 @@ X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
return 1;
error:
error:
if (pk != NULL)
X509_PUBKEY_free(pk);
return 0;
@@ -221,7 +222,7 @@ X509_PUBKEY_get0(X509_PUBKEY *key)
return ret;
error:
error:
EVP_PKEY_free(ret);
return (NULL);
}
@@ -239,168 +240,473 @@ X509_PUBKEY_get(X509_PUBKEY *key)
return pkey;
}
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
* and encode or decode as X509_PUBKEY
/*
* Decode an X509_PUBKEY into the specified key type.
*/
EVP_PKEY *
d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
static int
pubkey_ex_d2i(int pkey_type, ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it)
{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
xpk = d2i_X509_PUBKEY(NULL, pp, length);
if (!xpk)
return NULL;
pktmp = X509_PUBKEY_get(xpk);
X509_PUBKEY_free(xpk);
if (!pktmp)
return NULL;
if (a) {
EVP_PKEY_free(*a);
*a = pktmp;
const ASN1_EXTERN_FUNCS *ef = it->funcs;
const unsigned char *p = *in;
X509_PUBKEY *xpk = NULL;
ASN1_VALUE *key = NULL;
EVP_PKEY *pkey = NULL;
int ret = 0;
if ((xpk = d2i_X509_PUBKEY(NULL, &p, len)) == NULL)
goto err;
if ((pkey = X509_PUBKEY_get(xpk)) == NULL)
goto err;
switch (pkey_type) {
case EVP_PKEY_NONE:
key = (ASN1_VALUE *)pkey;
pkey = NULL;
break;
case EVP_PKEY_DSA:
key = (ASN1_VALUE *)EVP_PKEY_get1_DSA(pkey);
break;
case EVP_PKEY_RSA:
key = (ASN1_VALUE *)EVP_PKEY_get1_RSA(pkey);
break;
case EVP_PKEY_EC:
key = (ASN1_VALUE *)EVP_PKEY_get1_EC_KEY(pkey);
break;
default:
goto err;
}
return pktmp;
if (key == NULL)
goto err;
ef->asn1_ex_free(pval, it);
*pval = key;
*in = p;
ret = 1;
err:
EVP_PKEY_free(pkey);
X509_PUBKEY_free(xpk);
return ret;
}
int
i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
/*
* Encode the specified key type into an X509_PUBKEY.
*/
static int
pubkey_ex_i2d(int pkey_type, ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it)
{
X509_PUBKEY *xpk = NULL;
int ret;
if (!a)
return 0;
if (!X509_PUBKEY_set(&xpk, a))
return 0;
ret = i2d_X509_PUBKEY(xpk, pp);
EVP_PKEY *pkey, *pktmp;
int ret = -1;
if ((pkey = pktmp = EVP_PKEY_new()) == NULL)
goto err;
switch (pkey_type) {
case EVP_PKEY_NONE:
pkey = (EVP_PKEY *)*pval;
break;
case EVP_PKEY_DSA:
if (!EVP_PKEY_set1_DSA(pkey, (DSA *)*pval))
goto err;
break;
case EVP_PKEY_RSA:
if (!EVP_PKEY_set1_RSA(pkey, (RSA *)*pval))
goto err;
break;
case EVP_PKEY_EC:
if (!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY*)*pval))
goto err;
break;
default:
goto err;
}
if (!X509_PUBKEY_set(&xpk, pkey))
goto err;
ret = i2d_X509_PUBKEY(xpk, out);
err:
EVP_PKEY_free(pktmp);
X509_PUBKEY_free(xpk);
return ret;
}
/* The following are equivalents but which return RSA and DSA
* keys
*/
#ifndef OPENSSL_NO_RSA
RSA *
d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
static int
pkey_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
RSA *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return NULL;
key = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (!key)
return NULL;
*pp = q;
if (a) {
RSA_free(*a);
*a = key;
}
return key;
if ((*pval = (ASN1_VALUE *)EVP_PKEY_new()) == NULL)
return 0;
return 1;
}
static void
pkey_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY_free((EVP_PKEY *)*pval);
*pval = NULL;
}
static int
pkey_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_NONE, pval, in, len, it);
}
static int
pkey_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_NONE, pval, out, it);
}
const ASN1_EXTERN_FUNCS pkey_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = pkey_pubkey_ex_new,
.asn1_ex_free = pkey_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = pkey_pubkey_ex_d2i,
.asn1_ex_i2d = pkey_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM EVP_PKEY_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &pkey_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
EVP_PKEY *
d2i_PUBKEY(EVP_PKEY **pkey, const unsigned char **in, long len)
{
return (EVP_PKEY *)ASN1_item_d2i((ASN1_VALUE **)pkey, in, len,
&EVP_PKEY_PUBKEY_it);
}
int
i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
i2d_PUBKEY(EVP_PKEY *pkey, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return ASN1_item_i2d((ASN1_VALUE *)pkey, out, &EVP_PKEY_PUBKEY_it);
}
EVP_PKEY *
d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **pkey)
{
return (EVP_PKEY *)ASN1_item_d2i_bio(&EVP_PKEY_PUBKEY_it, bp,
(ASN1_VALUE **)pkey);
}
int
i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_item_i2d_bio(&EVP_PKEY_PUBKEY_it, bp, (ASN1_VALUE *)pkey);
}
EVP_PKEY *
d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **pkey)
{
return (EVP_PKEY *)ASN1_item_d2i_fp(&EVP_PKEY_PUBKEY_it, fp,
(ASN1_VALUE **)pkey);
}
int
i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_item_i2d_fp(&EVP_PKEY_PUBKEY_it, fp, (ASN1_VALUE *)pkey);
}
/*
* The following are equivalents but which return RSA and DSA keys.
*/
#ifndef OPENSSL_NO_RSA
static int
rsa_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if ((*pval = (ASN1_VALUE *)RSA_new()) == NULL)
return 0;
pktmp = EVP_PKEY_new();
if (!pktmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_RSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
return 1;
}
static void
rsa_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
RSA_free((RSA *)*pval);
*pval = NULL;
}
static int
rsa_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_RSA, pval, in, len, it);
}
static int
rsa_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_RSA, pval, out, it);
}
const ASN1_EXTERN_FUNCS rsa_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = rsa_pubkey_ex_new,
.asn1_ex_free = rsa_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = rsa_pubkey_ex_d2i,
.asn1_ex_i2d = rsa_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM RSA_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &rsa_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
RSA *
d2i_RSA_PUBKEY(RSA **rsa, const unsigned char **in, long len)
{
return (RSA *)ASN1_item_d2i((ASN1_VALUE **)rsa, in, len,
&RSA_PUBKEY_it);
}
int
i2d_RSA_PUBKEY(RSA *rsa, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)rsa, out, &RSA_PUBKEY_it);
}
RSA *
d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
{
return (RSA *)ASN1_item_d2i_bio(&RSA_PUBKEY_it, bp, (ASN1_VALUE **)rsa);
}
int
i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(&RSA_PUBKEY_it, bp, (ASN1_VALUE *)rsa);
}
RSA *
d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
{
return (RSA *)ASN1_item_d2i_fp(&RSA_PUBKEY_it, fp, (ASN1_VALUE **)rsa);
}
int
i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(&RSA_PUBKEY_it, fp, (ASN1_VALUE *)rsa);
}
#endif
#ifndef OPENSSL_NO_DSA
DSA *
d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
static int
dsa_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
DSA *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return NULL;
key = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
if (!key)
return NULL;
*pp = q;
if (a) {
DSA_free(*a);
*a = key;
}
return key;
if ((*pval = (ASN1_VALUE *)DSA_new()) == NULL)
return 0;
return 1;
}
static void
dsa_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
DSA_free((DSA *)*pval);
*pval = NULL;
}
static int
dsa_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_DSA, pval, in, len, it);
}
static int
dsa_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_DSA, pval, out, it);
}
const ASN1_EXTERN_FUNCS dsa_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = dsa_pubkey_ex_new,
.asn1_ex_free = dsa_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = dsa_pubkey_ex_d2i,
.asn1_ex_i2d = dsa_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM DSA_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &dsa_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
DSA *
d2i_DSA_PUBKEY(DSA **dsa, const unsigned char **in, long len)
{
return (DSA *)ASN1_item_d2i((ASN1_VALUE **)dsa, in, len,
&DSA_PUBKEY_it);
}
int
i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
i2d_DSA_PUBKEY(DSA *dsa, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return 0;
pktmp = EVP_PKEY_new();
if (!pktmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_DSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
return ASN1_item_i2d((ASN1_VALUE *)dsa, out, &DSA_PUBKEY_it);
}
DSA *
d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return (DSA *)ASN1_item_d2i_bio(&DSA_PUBKEY_it, bp, (ASN1_VALUE **)dsa);
}
int
i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_item_i2d_bio(&DSA_PUBKEY_it, bp, (ASN1_VALUE *)dsa);
}
DSA *
d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return (DSA *)ASN1_item_d2i_fp(&DSA_PUBKEY_it, fp, (ASN1_VALUE **)dsa);
}
int
i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_item_i2d_fp(&DSA_PUBKEY_it, fp, (ASN1_VALUE *)dsa);
}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *
d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
static int
ec_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
EC_KEY *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return (NULL);
key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (!key)
return (NULL);
*pp = q;
if (a) {
EC_KEY_free(*a);
*a = key;
}
return (key);
if ((*pval = (ASN1_VALUE *)EC_KEY_new()) == NULL)
return 0;
return 1;
}
static void
ec_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EC_KEY_free((EC_KEY *)*pval);
*pval = NULL;
}
static int
ec_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_EC, pval, in, len, it);
}
static int
ec_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_EC, pval, out, it);
}
const ASN1_EXTERN_FUNCS ec_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = ec_pubkey_ex_new,
.asn1_ex_free = ec_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = ec_pubkey_ex_d2i,
.asn1_ex_i2d = ec_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM EC_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &ec_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
EC_KEY *
d2i_EC_PUBKEY(EC_KEY **ec, const unsigned char **in, long len)
{
return (EC_KEY *)ASN1_item_d2i((ASN1_VALUE **)ec, in, len,
&EC_PUBKEY_it);
}
int
i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
i2d_EC_PUBKEY(EC_KEY *ec, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return (0);
if ((pktmp = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return (ret);
return ASN1_item_i2d((ASN1_VALUE *)ec, out, &EC_PUBKEY_it);
}
EC_KEY *
d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **ec)
{
return (EC_KEY *)ASN1_item_d2i_bio(&EC_PUBKEY_it, bp, (ASN1_VALUE **)ec);
}
int
i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ec)
{
return ASN1_item_i2d_bio(&EC_PUBKEY_it, bp, (ASN1_VALUE *)ec);
}
EC_KEY *
d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **ec)
{
return (EC_KEY *)ASN1_item_d2i_fp(&EC_PUBKEY_it, fp, (ASN1_VALUE **)ec);
}
int
i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *ec)
{
return ASN1_item_i2d_fp(&EC_PUBKEY_it, fp, (ASN1_VALUE *)ec);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_req.c,v 1.17 2018/02/22 16:50:30 jsing Exp $ */
/* $OpenBSD: x_req.c,v 1.18 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -61,6 +61,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_REQ_INFO is handled in an unusual way to get round
* invalid encodings. Some broken certificate requests don't
* encode the attributes field if it is empty. This is in

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_sig.c,v 1.11 2015/02/11 04:00:39 jsing Exp $ */
/* $OpenBSD: x_sig.c,v 1.13 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -61,6 +61,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
static const ASN1_TEMPLATE X509_SIG_seq_tt[] = {
{
.offset = offsetof(X509_SIG, algor),
@@ -108,3 +110,22 @@ X509_SIG_free(X509_SIG *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_SIG_it);
}
void
X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
const ASN1_OCTET_STRING **pdigest)
{
if (palg != NULL)
*palg = sig->algor;
if (pdigest != NULL)
*pdigest = sig->digest;
}
void
X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, ASN1_OCTET_STRING **pdigest)
{
if (palg != NULL)
*palg = sig->algor;
if (pdigest != NULL)
*pdigest = sig->digest;
}

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_x509.c,v 1.26 2018/02/17 15:50:42 jsing Exp $ */
/* $OpenBSD: x_x509.c,v 1.30 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,6 +65,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static const ASN1_AUX X509_CINF_aux = {
.flags = ASN1_AFLG_ENCODING,
.enc_offset = offsetof(X509_CINF, enc),
@@ -185,6 +187,10 @@ x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
ret->akid = NULL;
ret->aux = NULL;
ret->crldp = NULL;
#ifndef OPENSSL_NO_RFC3779
ret->rfc3779_addr = NULL;
ret->rfc3779_asid = NULL;
#endif
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
@@ -202,6 +208,10 @@ x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
policy_cache_free(ret->policy_cache);
GENERAL_NAMES_free(ret->altname);
NAME_CONSTRAINTS_free(ret->nc);
#ifndef OPENSSL_NO_RFC3779
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
ASIdentifiers_free(ret->rfc3779_asid);
#endif
free(ret->name);
ret->name = NULL;
break;
@@ -329,7 +339,7 @@ d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
}
return ret;
err:
err:
X509_free(ret);
return NULL;
}
@@ -345,6 +355,13 @@ i2d_X509_AUX(X509 *a, unsigned char **pp)
return length;
}
int
i2d_re_X509_tbs(X509 *x, unsigned char **pp)
{
x->cert_info->enc.modified = 1;
return i2d_X509_CINF(x->cert_info, pp);
}
void
X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg,
const X509 *x)

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: x_x509a.c,v 1.15 2018/05/01 19:01:27 tb Exp $ */
/* $OpenBSD: x_x509a.c,v 1.18 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -62,6 +62,8 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_CERT_AUX routines. These are used to encode additional
* user modifiable data about a certificate. This data is
* appended to the X509 encoding when the *_X509_AUX routines
@@ -226,7 +228,7 @@ X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj)
if (rc != 0)
return rc;
err:
err:
ASN1_OBJECT_free(objtmp);
return 0;
}
@@ -248,7 +250,7 @@ X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj)
if (rc != 0)
return rc;
err:
err:
ASN1_OBJECT_free(objtmp);
return 0;
}
@@ -270,56 +272,3 @@ X509_reject_clear(X509 *x)
x->aux->reject = NULL;
}
}
static const ASN1_TEMPLATE X509_CERT_PAIR_seq_tt[] = {
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(X509_CERT_PAIR, forward),
.field_name = "forward",
.item = &X509_it,
},
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 1,
.offset = offsetof(X509_CERT_PAIR, reverse),
.field_name = "reverse",
.item = &X509_it,
},
};
const ASN1_ITEM X509_CERT_PAIR_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_CERT_PAIR_seq_tt,
.tcount = sizeof(X509_CERT_PAIR_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(X509_CERT_PAIR),
.sname = "X509_CERT_PAIR",
};
X509_CERT_PAIR *
d2i_X509_CERT_PAIR(X509_CERT_PAIR **a, const unsigned char **in, long len)
{
return (X509_CERT_PAIR *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_CERT_PAIR_it);
}
int
i2d_X509_CERT_PAIR(X509_CERT_PAIR *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CERT_PAIR_it);
}
X509_CERT_PAIR *
X509_CERT_PAIR_new(void)
{
return (X509_CERT_PAIR *)ASN1_item_new(&X509_CERT_PAIR_it);
}
void
X509_CERT_PAIR_free(X509_CERT_PAIR *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_CERT_PAIR_it);
}