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;
return 0;
free(str);
return(1);
- }
+}
#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;
i=i2d(x,NULL);
b=malloc(i+10);
if (b == NULL)
- { ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+ {
+ ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL);
+ }
p= b;
i=i2d(x,&p);
p2= b;
ret=d2i(NULL,&p2,i);
free(b);
return(ret);
- }
+}
#endif
*/
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
- {
+{
unsigned char *b = NULL;
const unsigned char *p;
long i;
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
- { ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL);
+ }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
free(b);
return(ret);
- }
+}
*/
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
- {
+{
int j,k;
unsigned int i;
unsigned char buf[sizeof(long)+1];
a->type=V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long)+1))
- {
+ {
if (a->data != NULL)
free(a->data);
if ((a->data=(unsigned char *)malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
- }
+ }
if (a->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE);
return(0);
- }
+ }
d=v;
if (d < 0)
- {
+ {
d= -d;
a->type=V_ASN1_NEG_ENUMERATED;
- }
+ }
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);
- }
+}
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
- {
+{
int neg=0,i;
long r=0;
return -1;
if (a->length > (int)sizeof(long))
- {
+ {
/* hmm... a bit ugly */
return(0xffffffffL);
- }
+ }
if (a->data == NULL)
return 0;
for (i=0; i<a->length; i++)
- {
+ {
r<<=8;
r|=(unsigned char)a->data[i];
- }
+ }
if (neg) r= -r;
return(r);
- }
+}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
- {
+{
ASN1_ENUMERATED *ret;
int len,j;
else
ret=ai;
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
else ret->type=V_ASN1_ENUMERATED;
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)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
goto err;
- }
- ret->data=new_data;
}
+ ret->data=new_data;
+ }
ret->length=BN_bn2bin(bn,ret->data);
return(ret);
err:
if (ret != ai) M_ASN1_ENUMERATED_free(ret);
return(NULL);
- }
+}
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
- {
+{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
- }
+}
#if 0
int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
- {
+{
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
- }
+}
ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
unsigned char **pp, long length)
- {
+{
ASN1_GENERALIZEDTIME *ret=NULL;
ret=(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
return(NULL);
- }
+ }
if (!ASN1_GENERALIZEDTIME_check(ret))
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
goto err;
- }
+ }
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_GENERALIZEDTIME_free(ret);
return(NULL);
- }
+}
#endif
int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
- {
+{
static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[9]={99, 99,12,31,23,59,59,12,59};
char *a;
*/
if (l < 13) goto err;
for (i=0; i<7; i++)
- {
+ {
if ((i == 6) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
- { i++; break; }
+ { i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (++o > l) goto err;
if ((n < min[i]) || (n > max[i])) goto err;
- }
+ }
/* Optional fractional seconds: decimal point followed by one
* or more digits.
*/
if (a[o] == '.')
- {
+ {
if (++o > l) goto err;
i = o;
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
o++;
/* Must have at least one digit after decimal point */
if (i == o) goto err;
- }
+ }
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
- {
+ {
o++;
if (o+4 > l) goto err;
for (i=7; i<9; i++)
- {
+ {
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
o++;
- }
}
+ }
else
- {
+ {
/* Missing time zone information. */
goto err;
- }
+ }
return(o == l);
err:
return(0);
- }
+}
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
- {
+{
ASN1_GENERALIZEDTIME t;
t.type=V_ASN1_GENERALIZEDTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_GENERALIZEDTIME_check(&t))
- {
+ {
if (s != NULL)
- {
+ {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type=V_ASN1_GENERALIZEDTIME;
- }
- return(1);
}
+ return(1);
+ }
else
return(0);
- }
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
time_t t)
- {
+{
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
- }
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
time_t t, int offset_day, long offset_sec)
- {
+{
char *p;
struct tm *ts;
struct tm data;
return(NULL);
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
- {
+ {
p=malloc(len);
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
if (s->data != NULL)
free(s->data);
s->data=(unsigned char *)p;
- }
+ }
(void) snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_GENERALIZEDTIME;
return(s);
- }
+}
#ifndef OPENSSL_NO_FP_API
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_I2D_FP,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);
- }
+}
#endif
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=(char *)malloc(n);
if (b == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_I2D_BIO,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
#ifndef OPENSSL_NO_FP_API
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,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);
- }
+}
#endif
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,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);
- }
+}
{ return M_ASN1_INTEGER_dup(x);}
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
- {
+{
int neg, ret;
/* Compare signs */
neg = x->type & V_ASN1_NEG;
if (neg != (y->type & V_ASN1_NEG))
- {
+ {
if (neg)
return -1;
else
return 1;
- }
+ }
ret = ASN1_STRING_cmp(x, y);
return -ret;
else
return ret;
- }
+}
/*
*/
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
- {
+{
int pad=0,ret,i,neg;
unsigned char *p,*n,pb=0;
if (a->length == 0)
ret=1;
else
- {
+ {
ret=a->length;
i=a->data[0];
if (!neg && (i > 127)) {
pad=1;
pb=0;
- } else if(neg) {
+ } else if(neg) {
if(i>128) {
pad=1;
pb=0xFF;
- } else if(i == 128) {
+ } else if(i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
pad=1;
pb=0xFF;
break;
- }
}
}
+ }
ret+=pad;
- }
+ }
if (pp == NULL) return(ret);
p= *pp;
*(p--) = 0;
n--;
i--;
- }
+ }
/* Complement and increment next octet */
*(p--) = ((*(n--)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
- }
+}
*pp+=ret;
return(ret);
- }
+}
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long len)
- {
+{
ASN1_INTEGER *ret=NULL;
const unsigned char *p, *pend;
unsigned char *to,*s;
int i;
if ((a == NULL) || ((*a) == NULL))
- {
+ {
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
- }
+ }
else
ret=(*a);
* signifies a missing NULL parameter. */
s=(unsigned char *)malloc((int)len+1);
if (s == NULL)
- {
+ {
i=ERR_R_MALLOC_FAILURE;
goto err;
- }
+ }
to=s;
if(!len) {
/* Strictly speaking this is an illegal INTEGER but we
* tolerate it.
*/
ret->type=V_ASN1_INTEGER;
- } else if (*p & 0x80) /* a negative number */
- {
+} else if (*p & 0x80) /* a negative number */
+ {
ret->type=V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
- }
+ }
i = len;
p += i - 1;
to += i - 1;
*(to--) = 0;
i--;
p--;
- }
+ }
/* Special case: if all zeros then the number will be of
* the form FF followed by n zero bytes: this corresponds to
* 1 followed by n zero bytes. We've already written n zeros
*s = 1;
s[len] = 0;
len++;
- } else {
+ } else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
- }
- } else {
+ }
+} else {
ret->type=V_ASN1_INTEGER;
if ((*p == 0) && (len != 1))
- {
+ {
p++;
len--;
- }
+ }
memcpy(s,p,(int)len);
- }
+}
if (ret->data != NULL) free(ret->data);
ret->data=s;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
- }
+}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long length)
- {
+{
ASN1_INTEGER *ret=NULL;
const unsigned char *p;
unsigned char *s;
int i;
if ((a == NULL) || ((*a) == NULL))
- {
+ {
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
- }
+ }
else
ret=(*a);
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_INTEGER)
- {
+ {
i=ASN1_R_EXPECTING_AN_INTEGER;
goto err;
- }
+ }
/* We must malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)malloc((int)len+1);
if (s == NULL)
- {
+ {
i=ERR_R_MALLOC_FAILURE;
goto err;
- }
+ }
ret->type=V_ASN1_INTEGER;
if(len) {
if ((*p == 0) && (len != 1))
- {
+ {
p++;
len--;
- }
+ }
memcpy(s,p,(int)len);
p+=len;
- }
+}
if (ret->data != NULL) free(ret->data);
ret->data=s;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_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];
a->type=V_ASN1_INTEGER;
if (a->length < (int)(sizeof(long)+1))
- {
+ {
if (a->data != NULL)
free(a->data);
if ((a->data=(unsigned char *)malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
- }
+ }
if (a->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_INTEGER_SET,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);
- }
+}
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
- {
+{
int neg=0,i;
long r=0;
return -1;
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 (neg) r= -r;
return(r);
- }
+}
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
- {
+{
ASN1_INTEGER *ret;
int len,j;
else
ret=ai;
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
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)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
goto err;
- }
- ret->data=new_data;
}
+ 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) M_ASN1_INTEGER_free(ret);
return(NULL);
- }
+}
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
- {
+{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
- }
+}
IMPLEMENT_STACK_OF(ASN1_INTEGER)
IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
#include <openssl/bn.h>
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
- {
+{
unsigned char *p;
int objsize;
*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;
c= *(p++);
num--;
if ((c >= '0') && (c <= '2'))
- {
+ {
first= c-'0';
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
- }
+ }
if (num <= 0)
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
goto err;
- }
+ }
c= *(p++);
num--;
for (;;)
- {
+ {
if (num <= 0) break;
if ((c != '.') && (c != ' '))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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'))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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)
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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);
if (bl)
if (bl)
BN_free(bl);
return(0);
- }
+}
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
}
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
- {
+{
char buf[80], *p = buf;
int i;
return(BIO_write(bp,"NULL",4));
i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
if (i > (int)(sizeof(buf) - 1))
- {
+ {
p = malloc(i + 1);
if (!p)
return -1;
i2t_ASN1_OBJECT(p,i + 1,a);
- }
+ }
if (i <= 0)
return BIO_write(bp, "<INVALID>", 9);
BIO_write(bp,p,i);
if (p != buf)
free(p);
return(i);
- }
+}
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long length)
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;
}
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long len)
- {
+{
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
unsigned char *data;
* subidentifiers, see: X.690 8.19.2
*/
for (i = 0, p = *pp; i < len; i++, p++)
- {
+ {
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
- {
+ {
ASN1err(ASN1_F_C2I_ASN1_OBJECT,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;
ret->data = NULL;
/* once detached we can change it */
if ((data == NULL) || (ret->length < len))
- {
+ {
ret->length=0;
if (data != NULL) free(data);
data=(unsigned char *)malloc(len ? (int)len : 1);
if (data == NULL)
- { i=ERR_R_MALLOC_FAILURE; goto err; }
+ { i=ERR_R_MALLOC_FAILURE; goto err; }
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
- }
+ }
memcpy(data,p,(int)len);
/* reattach data to object, after which it remains const */
ret->data =data;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
- }
+}
ASN1_OBJECT *ASN1_OBJECT_new(void)
- {
+{
ASN1_OBJECT *ret;
ret=(ASN1_OBJECT *)malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
ret->length=0;
ret->data=NULL;
ret->nid=0;
ret->ln=NULL;
ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
return(ret);
- }
+}
void ASN1_OBJECT_free(ASN1_OBJECT *a)
- {
+{
if (a == NULL) return;
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
- {
+ {
#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
if (a->sn != NULL) free((void *)a->sn);
if (a->ln != NULL) free((void *)a->ln);
#endif
a->sn=a->ln=NULL;
- }
+ }
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
- {
+ {
if (a->data != NULL) free((void *)a->data);
a->data=NULL;
a->length=0;
- }
+ }
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
free(a);
- }
+}
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
const char *sn, const char *ln)
- {
+{
ASN1_OBJECT o;
o.sn=sn;
o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return(OBJ_dup(&o));
- }
+}
IMPLEMENT_STACK_OF(ASN1_OBJECT)
IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
#include <openssl/asn1.h>
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
- {
+{
int c;
int ia5=0;
int t61=0;
if (s == NULL) return(V_ASN1_PRINTABLESTRING);
while ((*s) && (len-- != 0))
- {
+ {
c= *(s++);
if (!( ((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
ia5=1;
if (c&0x80)
t61=1;
- }
+ }
if (t61) return(V_ASN1_T61STRING);
if (ia5) return(V_ASN1_IA5STRING);
return(V_ASN1_PRINTABLESTRING);
- }
+}
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
- {
+{
int i;
unsigned char *p;
if ((s->length%4) != 0) return(0);
p=s->data;
for (i=0; i<s->length; i+=4)
- {
+ {
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
break;
else
p+=4;
- }
+ }
if (i < s->length) return(0);
p=s->data;
for (i=3; i<s->length; i+=4)
- {
+ {
*(p++)=s->data[i];
- }
+ }
*(p)='\0';
s->length/=4;
s->type=ASN1_PRINTABLE_type(s->data,s->length);
return(1);
- }
+}
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);
}
+ 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;
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!type || !pkey)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, 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)
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
if (rv <= 1)
goto err;
- }
+ }
else
rv = 2;
if (rv == 2)
- {
+ {
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
- {
+ {
if (!pkey->ameth ||
!OBJ_find_sigid_by_algs(&signid,
EVP_MD_nid(type),
pkey->ameth->pkey_id))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
- }
}
+ }
else
signid = type->pkey_type;
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((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL))
- {
+ {
outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
- {
+ {
outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
goto err;
- }
+ }
if (signature->data != NULL) free(signature->data);
signature->data=buf_out;
buf_out=NULL;
err:
EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL)
- { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); free(buf_in); }
+ { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); free(buf_in); }
if (buf_out != NULL)
- { OPENSSL_cleanse((char *)buf_out,outll); free(buf_out); }
+ { OPENSSL_cleanse((char *)buf_out,outll); free(buf_out); }
return(outl);
- }
+}
#if 0
int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
- {
+{
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME);
return -1;
- }
+}
#endif
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
- {
+{
return ASN1_TIME_adj(s, t, 0, 0);
- }
+}
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
int offset_day, long offset_sec)
- {
+{
struct tm *ts;
struct tm data;
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
return NULL;
- }
+ }
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
if((ts->tm_year >= 50) && (ts->tm_year < 150))
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
- }
+}
int ASN1_TIME_check(ASN1_TIME *t)
- {
+{
if (t->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_check(t);
else if (t->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_check(t);
return 0;
- }
+}
/* Convert an ASN1_TIME structure to GeneralizedTime */
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
- {
+{
ASN1_GENERALIZEDTIME *ret;
char *str;
int newlen;
if (!ASN1_TIME_check(t)) return NULL;
if (!out || !*out)
- {
+ {
if (!(ret = ASN1_GENERALIZEDTIME_new ()))
return NULL;
if (out) *out = ret;
- }
+ }
else ret = *out;
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME)
- {
+ {
if(!ASN1_STRING_set(ret, t->data, t->length))
return NULL;
return ret;
- }
+ }
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
BUF_strlcat(str, (char *)t->data, newlen);
return ret;
- }
+}
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
- {
+{
ASN1_TIME t;
t.length = strlen(str);
t.type = V_ASN1_UTCTIME;
if (!ASN1_TIME_check(&t))
- {
+ {
t.type = V_ASN1_GENERALIZEDTIME;
if (!ASN1_TIME_check(&t))
return 0;
- }
+ }
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
return 0;
return 1;
- }
+}
#include <openssl/objects.h>
int ASN1_TYPE_get(ASN1_TYPE *a)
- {
+{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return(a->type);
else
return(0);
- }
+}
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
- {
+{
if (a->value.ptr != NULL)
- {
+ {
ASN1_TYPE **tmp_a = &a;
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
- }
+ }
a->type=type;
if (type == V_ASN1_BOOLEAN)
a->value.boolean = value ? 0xff : 0;
else
a->value.ptr=value;
- }
+}
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
- {
+{
if (!value || (type == V_ASN1_BOOLEAN))
- {
+ {
void *p = (void *)value;
ASN1_TYPE_set(a, type, p);
- }
+ }
else if (type == V_ASN1_OBJECT)
- {
+ {
ASN1_OBJECT *odup;
odup = OBJ_dup(value);
if (!odup)
return 0;
ASN1_TYPE_set(a, type, odup);
- }
+ }
else
- {
+ {
ASN1_STRING *sdup;
sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
- }
- return 1;
}
+ return 1;
+}
IMPLEMENT_STACK_OF(ASN1_TYPE)
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
- {
+{
int result = -1;
if (!a || !b || a->type != b->type) return -1;
switch (a->type)
- {
+ {
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
(ASN1_STRING *) b->value.ptr);
break;
- }
+ }
return result;
- }
+}
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
- {
+{
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
- }
+}
ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
long length)
- {
+{
ASN1_UTCTIME *ret=NULL;
ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
return(NULL);
- }
+ }
if (!ASN1_UTCTIME_check(ret))
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
goto err;
- }
+ }
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_UTCTIME_free(ret);
return(NULL);
- }
+}
#endif
int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
- {
+{
static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[8]={99,12,31,23,59,59,12,59};
char *a;
if (l < 11) goto err;
for (i=0; i<6; i++)
- {
+ {
if ((i == 5) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
- { i++; break; }
+ { i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (++o > l) goto err;
if ((n < min[i]) || (n > max[i])) goto err;
- }
+ }
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
- {
+ {
o++;
if (o+4 > l) goto err;
for (i=6; i<8; i++)
- {
+ {
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
o++;
- }
}
+ }
return(o == l);
err:
return(0);
- }
+}
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
- {
+{
ASN1_UTCTIME t;
t.type=V_ASN1_UTCTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_UTCTIME_check(&t))
- {
+ {
if (s != NULL)
- {
+ {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type = V_ASN1_UTCTIME;
- }
- return(1);
}
+ return(1);
+ }
else
return(0);
- }
+}
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
- {
+{
return ASN1_UTCTIME_adj(s, t, 0, 0);
- }
+}
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
int offset_day, long offset_sec)
- {
+{
char *p;
struct tm *ts;
struct tm data;
return(NULL);
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
if((ts->tm_year < 50) || (ts->tm_year >= 150))
return NULL;
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
- {
+ {
p=malloc(len);
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
if (s->data != NULL)
free(s->data);
s->data=(unsigned char *)p;
- }
+ }
(void) snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_UTCTIME;
return(s);
- }
+}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
- {
+{
struct tm *tm;
struct tm data;
int offset;
if (s->data[12] == 'Z')
offset=0;
else
- {
+ {
offset = g2(s->data+13)*60+g2(s->data+15);
if (s->data[12] == '-')
offset = -offset;
- }
+ }
t -= offset*60; /* FIXME: may overflow in extreme cases */
#undef return_cmp
return 0;
- }
+}
#if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
- {
+{
struct tm tm;
int offset;
if(s->data[12] == 'Z')
offset=0;
else
- {
+ {
offset=g2(s->data+13)*60+g2(s->data+15);
if(s->data[12] == '-')
offset= -offset;
- }
+ }
#undef g2
return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
* non-standard.
* Also time_t is inappropriate for general
* UTC times because it may a 32 bit type. */
- }
+}
#endif
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
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))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
- }
+ }
if (mdnid == NID_undef)
- {
+ {
if (!pkey->ameth || !pkey->ameth->item_verify)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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
if (ret != 2)
goto err;
ret = -1;
- }
+ }
else
- {
+ {
const EVP_MD *type;
type=EVP_get_digestbynid(mdnid);
if (type == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
goto err;
- }
+ }
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
ret=0;
goto err;
- }
-
}
+ }
+
inl = ASN1_item_i2d(asn, &buf_in, it);
if (buf_in == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
ret=0;
goto err;
- }
+ }
OPENSSL_cleanse(buf_in,(unsigned int)inl);
free(buf_in);
if (EVP_DigestVerifyFinal(&ctx,signature->data,
(size_t)signature->length) <= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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)); */
err:
EVP_MD_CTX_cleanup(&ctx);
return(ret);
- }
+}
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
- {
+{
#ifndef OPENSSL_NO_RSA
&rsa_asn1_meths[0],
&rsa_asn1_meths[1],
#endif
&hmac_asn1_meth,
&cmac_asn1_meth
- };
+};
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
#ifdef TEST
void main()
- {
+{
int i;
for (i = 0;
i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
fprintf(stderr, "Number %d id=%d (%s)\n", i,
standard_methods[i]->pkey_id,
OBJ_nid2sn(standard_methods[i]->pkey_id));
- }
+}
#endif
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
const EVP_PKEY_ASN1_METHOD * const *b)
- {
+{
return ((*a)->pkey_id - (*b)->pkey_id);
- }
+}
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
const EVP_PKEY_ASN1_METHOD *, ameth);
int EVP_PKEY_asn1_get_count(void)
- {
+{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (app_methods)
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
return num;
- }
+}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
- {
+{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (idx < 0)
return NULL;
return standard_methods[idx];
idx -= num;
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
+}
static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
- {
+{
EVP_PKEY_ASN1_METHOD tmp;
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
tmp.pkey_id = type;
if (app_methods)
- {
+ {
int idx;
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
if (idx >= 0)
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
+ }
ret = OBJ_bsearch_ameth(&t, standard_methods,
sizeof(standard_methods)
/sizeof(EVP_PKEY_ASN1_METHOD *));
if (!ret || !*ret)
return NULL;
return *ret;
- }
+}
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
* also search through engines and set *pe to a functional reference
*/
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
- {
+{
const EVP_PKEY_ASN1_METHOD *t;
for (;;)
- {
+ {
t = pkey_asn1_find(type);
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
break;
type = t->pkey_base_id;
- }
+ }
if (pe)
- {
+ {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
/* type will contain the final unaliased type */
e = ENGINE_get_pkey_asn1_meth_engine(type);
if (e)
- {
+ {
*pe = e;
return ENGINE_get_pkey_asn1_meth(e, type);
- }
+ }
#endif
*pe = NULL;
- }
- return t;
}
+ return t;
+}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
const char *str, int len)
- {
+{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
if (len == -1)
len = strlen(str);
if (pe)
- {
+ {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
if (ameth)
- {
+ {
/* Convert structural into
* functional reference
*/
ENGINE_free(e);
*pe = e;
return ameth;
- }
+ }
#endif
*pe = NULL;
- }
+ }
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
- {
+ {
ameth = EVP_PKEY_asn1_get0(i);
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
continue;
if (((int)strlen(ameth->pem_str) == len) &&
!strncasecmp(ameth->pem_str, str, len))
return ameth;
- }
- return NULL;
}
+ return NULL;
+}
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (app_methods == NULL)
- {
+ {
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
if (!app_methods)
return 0;
- }
+ }
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
return 0;
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
return 1;
- }
+}
int EVP_PKEY_asn1_add_alias(int to, int from)
- {
+{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
if (!ameth)
return 0;
ameth->pkey_base_id = to;
return EVP_PKEY_asn1_add0(ameth);
- }
+}
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
const char **pinfo, const char **ppem_str,
const EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (!ameth)
return 0;
if (ppkey_id)
if (ppem_str)
*ppem_str = ameth->pem_str;
return 1;
- }
+}
const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
- {
+{
return pkey->ameth;
- }
+}
EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
const char *pem_str, const char *info)
- {
+{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = malloc(sizeof(EVP_PKEY_ASN1_METHOD));
if (!ameth)
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
if (info)
- {
+ {
ameth->info = BUF_strdup(info);
if (!ameth->info)
goto err;
- }
+ }
else
ameth->info = NULL;
if (pem_str)
- {
+ {
ameth->pem_str = BUF_strdup(pem_str);
if (!ameth->pem_str)
goto err;
- }
+ }
else
ameth->pem_str = NULL;
EVP_PKEY_asn1_free(ameth);
return NULL;
- }
+}
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->item_sign = src->item_sign;
dst->item_verify = src->item_verify;
- }
+}
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
- {
+ {
if (ameth->pem_str)
free(ameth->pem_str);
if (ameth->info)
free(ameth->info);
free(ameth);
- }
}
+}
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
ASN1_PCTX *pctx),
int (*pkey_size)(const EVP_PKEY *pk),
int (*pkey_bits)(const EVP_PKEY *pk))
- {
+{
ameth->pub_decode = pub_decode;
ameth->pub_encode = pub_encode;
ameth->pub_cmp = pub_cmp;
ameth->pub_print = pub_print;
ameth->pkey_size = pkey_size;
ameth->pkey_bits = pkey_bits;
- }
+}
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
- {
+{
ameth->priv_decode = priv_decode;
ameth->priv_encode = priv_encode;
ameth->priv_print = priv_print;
- }
+}
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
int (*param_decode)(EVP_PKEY *pkey,
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
- {
+{
ameth->param_decode = param_decode;
ameth->param_encode = param_encode;
ameth->param_missing = param_missing;
ameth->param_copy = param_copy;
ameth->param_cmp = param_cmp;
ameth->param_print = param_print;
- }
+}
void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
void (*pkey_free)(EVP_PKEY *pkey))
- {
+{
ameth->pkey_free = pkey_free;
- }
+}
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
long arg1, void *arg2))
- {
+{
ameth->pkey_ctrl = pkey_ctrl;
- }
+}
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
static ERR_STRING_DATA ASN1_str_functs[]=
- {
+{
{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
{ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
{0,NULL}
- };
+};
static ERR_STRING_DATA ASN1_str_reasons[]=
- {
+{
{ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"},
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) ,"asn1 parse error"},
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
{ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"},
{ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"},
{0,NULL}
- };
+};
#endif
void ERR_load_ASN1_strings(void)
- {
+{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
- {
+ {
ERR_load_strings(0,ASN1_str_functs);
ERR_load_strings(0,ASN1_str_reasons);
- }
-#endif
}
+#endif
+}
#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
-#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
+#define ASN1_GEN_STR(str,val){str, sizeof(str) - 1, val}
#define ASN1_FLAG_EXP_MAX 20
struct tag_name_st
- {
+{
const char *strnam;
int len;
int tag;
- };
+};
typedef struct
- {
+{
int exp_tag;
int exp_class;
int exp_constructed;
int exp_pad;
long exp_len;
- } tag_exp_type;
+} tag_exp_type;
typedef struct
- {
+{
int imp_tag;
int imp_class;
int utype;
const char *str;
tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
int exp_count;
- } tag_exp_arg;
+} tag_exp_arg;
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
- {
+{
X509V3_CTX cnf;
if (!nconf)
X509V3_set_nconf(&cnf, nconf);
return ASN1_generate_v3(str, &cnf);
- }
+}
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
- {
+{
ASN1_TYPE *ret;
tag_exp_arg asn1_tags;
tag_exp_type *etmp;
return NULL;
if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
- {
+ {
if (!cnf)
- {
+ {
ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
- }
- ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
}
+ ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+ }
else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
/* Do we need IMPLICIT tagging? */
if (asn1_tags.imp_tag != -1)
- {
+ {
/* If IMPLICIT we will replace the underlying tag */
/* Skip existing tag+len */
r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
* consistent.
*/
if (r & 0x1)
- {
+ {
/* Indefinite length constructed */
hdr_constructed = 2;
hdr_len = 0;
- }
+ }
else
/* Just retain constructed flag */
hdr_constructed = r & V_ASN1_CONSTRUCTED;
* because it will mess up if indefinite length
*/
len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
- }
+ }
else
len = cpy_len;
/* Work out length in any EXPLICIT, starting from end */
for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
- {
+ {
/* Content length: number of content octets + any padding */
len += etmp->exp_pad;
etmp->exp_len = len;
/* Total object length: length including new header */
len = ASN1_object_size(0, len, etmp->exp_tag);
- }
+ }
/* Allocate buffer for new encoding */
/* Output explicit tags first */
for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
- {
+ {
ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
etmp->exp_tag, etmp->exp_class);
if (etmp->exp_pad)
*p++ = 0;
- }
+ }
/* If IMPLICIT, output tag */
if (asn1_tags.imp_tag != -1)
- {
+ {
if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
&& (asn1_tags.imp_tag == V_ASN1_SEQUENCE
|| asn1_tags.imp_tag == V_ASN1_SET) )
hdr_constructed = V_ASN1_CONSTRUCTED;
ASN1_put_object(&p, hdr_constructed, hdr_len,
asn1_tags.imp_tag, asn1_tags.imp_class);
- }
+ }
/* Copy across original encoding */
memcpy(p, cpy_start, cpy_len);
return ret;
- }
+}
static int asn1_cb(const char *elem, int len, void *bitstr)
- {
+{
tag_exp_arg *arg = bitstr;
int i;
int utype;
int tmp_tag, tmp_class;
for(i = 0, p = elem; i < len; p++, i++)
- {
+ {
/* Look for the ':' in name value pairs */
if (*p == ':')
- {
+ {
vstart = p + 1;
vlen = len - (vstart - elem);
len = p - elem;
break;
- }
}
+ }
utype = asn1_str2tag(elem, len);
if (utype == -1)
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
ERR_add_error_data(2, "tag=", elem);
return -1;
- }
+ }
/* If this is not a modifier mark end of string and exit */
if (!(utype & ASN1_GEN_FLAG))
- {
+ {
arg->utype = utype;
arg->str = vstart;
/* If no value and not end of string, error */
if (!vstart && elem[len])
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
return -1;
- }
- return 0;
}
+ return 0;
+ }
switch(utype)
- {
+ {
case ASN1_GEN_FLAG_IMP:
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1)
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
- }
+ }
if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
return -1;
break;
else if (!strncmp(vstart, "BITLIST", 7))
arg->format = ASN1_GEN_FORMAT_BITLIST;
else
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
return -1;
- }
+ }
break;
- }
+ }
return 1;
- }
+}
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
- {
+{
char erch[2];
long tag_num;
char *eptr;
if (eptr && *eptr && (eptr > vstart + vlen))
return 0;
if (tag_num < 0)
- {
+ {
ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
return 0;
- }
+ }
*ptag = tag_num;
/* If we have non numeric characters, parse them */
if (eptr)
else
vlen = 0;
if (vlen)
- {
+ {
switch (*eptr)
- {
+ {
case 'U':
*pclass = V_ASN1_UNIVERSAL;
return 0;
break;
- }
}
+ }
else
*pclass = V_ASN1_CONTEXT_SPECIFIC;
return 1;
- }
+}
/* Handle multiple types: SET and SEQUENCE */
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
- {
+{
ASN1_TYPE *ret = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL;
if (!sk)
goto bad;
if (section)
- {
+ {
if (!cnf)
goto bad;
sect = X509V3_get_section(cnf, (char *)section);
if (!sect)
goto bad;
for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
- {
+ {
ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
if (!typ)
goto bad;
if (!sk_ASN1_TYPE_push(sk, typ))
goto bad;
- }
}
+ }
/* Now we has a STACK of the components, convert to the correct form */
X509V3_section_free(cnf, sect);
return ret;
- }
+}
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
- {
+{
tag_exp_type *exp_tmp;
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok)
- {
+ {
ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
- }
+ }
if (arg->exp_count == ASN1_FLAG_EXP_MAX)
- {
+ {
ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
return 0;
- }
+ }
exp_tmp = &arg->exp_list[arg->exp_count++];
* reset implicit tag since it has been used.
*/
if (arg->imp_tag != -1)
- {
+ {
exp_tmp->exp_tag = arg->imp_tag;
exp_tmp->exp_class = arg->imp_class;
arg->imp_tag = -1;
arg->imp_class = -1;
- }
+ }
else
- {
+ {
exp_tmp->exp_tag = exp_tag;
exp_tmp->exp_class = exp_class;
- }
+ }
exp_tmp->exp_constructed = exp_constructed;
exp_tmp->exp_pad = exp_pad;
return 1;
- }
+}
static int asn1_str2tag(const char *tagstr, int len)
- {
+{
unsigned int i;
static const struct tag_name_st *tntmp, tnst [] = {
ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
- };
+};
if (len == -1)
len = strlen(tagstr);
tntmp = tnst;
for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
- {
+ {
if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
return tntmp->tag;
- }
+ }
return -1;
- }
+}
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
- {
+{
ASN1_TYPE *atmp = NULL;
CONF_VALUE vtmp;
int no_unused = 1;
if (!(atmp = ASN1_TYPE_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
return NULL;
- }
+ }
if (!str)
str = "";
switch(utype)
- {
+ {
case V_ASN1_NULL:
if (str && *str)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
- }
+ }
break;
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
vtmp.name = NULL;
vtmp.section = NULL;
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
- }
+ }
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
- }
+ }
break;
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
- }
+ }
break;
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
- }
+ }
break;
else if (format == ASN1_GEN_FORMAT_UTF8)
format = MBSTRING_UTF8;
else
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
- }
+ }
if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-1, format, ASN1_tag2bit(utype)) <= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
break;
case V_ASN1_OCTET_STRING:
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_form;
- }
+ }
if (format == ASN1_GEN_FORMAT_HEX)
- {
+ {
if (!(rdata = string_to_hex((char *)str, &rdlen)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
goto bad_str;
- }
+ }
atmp->value.asn1_string->data = rdata;
atmp->value.asn1_string->length = rdlen;
atmp->value.asn1_string->type = utype;
- }
+ }
else if (format == ASN1_GEN_FORMAT_ASCII)
ASN1_STRING_set(atmp->value.asn1_string, str, -1);
else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
- {
+ {
if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
goto bad_str;
- }
+ }
no_unused = 0;
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
- }
+ }
if ((utype == V_ASN1_BIT_STRING) && no_unused)
- {
+ {
atmp->value.asn1_string->flags
&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
atmp->value.asn1_string->flags
|= ASN1_STRING_FLAG_BITS_LEFT;
- }
+ }
break;
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
- }
+ }
atmp->type = utype;
ASN1_TYPE_free(atmp);
return NULL;
- }
+}
static int bitstr_cb(const char *elem, int len, void *bitstr)
- {
+{
long bitnum;
char *eptr;
if (!elem)
if (eptr && *eptr && (eptr != elem + len))
return 0;
if (bitnum < 0)
- {
+ {
ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
return 0;
- }
+ }
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
- {
+ {
ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
return 0;
- }
- return 1;
}
+ return 1;
+}
const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
static int _asn1_check_infinite_end(const unsigned char **p, long len)
- {
+{
/* 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);
}
+ return(0);
+}
int ASN1_check_infinite_end(unsigned char **p, long len)
- {
+{
return _asn1_check_infinite_end((const unsigned char **)p, len);
- }
+}
int ASN1_const_check_infinite_end(const unsigned char **p, long len)
- {
+{
return _asn1_check_infinite_end(p, len);
- }
+}
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;
xclass=(*p&V_ASN1_PRIVATE);
i= *p&V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG)
- { /* high-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;
#endif
if (*plength > (omax - (p - *pp)))
- {
+ {
ASN1err(ASN1_F_ASN1_GET_OBJECT,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:
ASN1err(ASN1_F_ASN1_GET_OBJECT,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 (i > sizeof(long))
return 0;
if (max-- == 0) return(0);
while (i-- > 0)
- {
+ {
ret<<=8L;
ret|= *(p++);
if (max-- == 0) return(0);
- }
}
+ }
else
ret=i;
- }
+ }
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;
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;
}
+ 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;
+ 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);
}
+ return(ret);
+}
static int _asn1_Finish(ASN1_const_CTX *c)
- {
+{
if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
- {
+ {
if (!ASN1_const_check_infinite_end(&c->p,c->slen))
- {
+ {
c->error=ERR_R_MISSING_ASN1_EOS;
return(0);
- }
}
+ }
if ( ((c->slen != 0) && !(c->inf & 1)) ||
((c->slen < 0) && (c->inf & 1)))
- {
+ {
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
return(0);
- }
- return(1);
}
+ return(1);
+}
int asn1_Finish(ASN1_CTX *c)
- {
+{
return _asn1_Finish((ASN1_const_CTX *)c);
- }
+}
int asn1_const_Finish(ASN1_const_CTX *c)
- {
+{
return _asn1_Finish(c);
- }
+}
int asn1_GetSequence(ASN1_const_CTX *c, long *length)
- {
+{
const unsigned char *q;
q=c->p;
c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
*length);
if (c->inf & 0x80)
- {
+ {
c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
return(0);
- }
+ }
if (c->tag != V_ASN1_SEQUENCE)
- {
+ {
c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
return(0);
- }
+ }
(*length)-=(c->p-q);
if (c->max && (*length < 0))
- {
+ {
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
return(0);
- }
+ }
if (c->inf == (1|V_ASN1_CONSTRUCTED))
c->slen= *length+ *(c->pp)-c->p;
c->eos=0;
return(1);
- }
+}
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
- {
+{
if (str == NULL)
return 0;
dst->type = str->type;
return 0;
dst->flags = str->flags;
return 1;
- }
+}
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
- {
+{
ASN1_STRING *ret;
if (!str)
return NULL;
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret,str))
- {
+ {
ASN1_STRING_free(ret);
return NULL;
- }
- return ret;
}
+ return ret;
+}
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
- {
+{
unsigned char *c;
const char *data=_data;
if (len < 0)
- {
+ {
if (data == NULL)
return(0);
else
len=strlen(data);
- }
+ }
if ((str->length < len) || (str->data == NULL))
- {
+ {
c=str->data;
if (c == NULL)
str->data=malloc(len+1);
str->data=realloc(c,len+1);
if (str->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
- }
}
+ }
str->length=len;
if (data != NULL)
- {
+ {
memcpy(str->data,data,len);
/* an allowance for strings :-) */
str->data[len]='\0';
- }
- return(1);
}
+ return(1);
+}
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
- {
+{
if (str->data)
free(str->data);
str->data = data;
str->length = len;
- }
+}
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 *ret;
ret=(ASN1_STRING *)malloc(sizeof(ASN1_STRING));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,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 && !(a->flags & ASN1_STRING_FLAG_NDEF))
free(a->data);
free(a);
- }
+}
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
- {
+{
int i;
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);
- }
+}
void asn1_add_error(const unsigned char *address, int offset)
- {
+{
char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
(void) snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
(void) snprintf(buf2,sizeof buf2,"%d",offset);
ERR_add_error_data(4,"address=",buf1," offset=",buf2);
- }
+}
int ASN1_STRING_length(const ASN1_STRING *x)
{ return M_ASN1_STRING_length(x); }
int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
- {
+{
static const char fmt[]="%-18s";
char str[128];
const char *p;
return(1);
err:
return(0);
- }
+}
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
- {
+{
return(asn1_parse2(bp,&pp,len,0,0,indent,0));
- }
+}
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
- {
+{
return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
- }
+}
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
int depth, int indent, int dump)
- {
+{
const unsigned char *p,*ep,*tot,*op,*opp;
long len;
int tag,xclass,ret=0;
tot=p+length;
op=p-1;
while ((p < tot) && (op < p))
- {
+ {
op=p;
j=ASN1_get_object(&p,&len,&tag,&xclass,length);
#ifdef LINT
j=j;
#endif
if (j & 0x80)
- {
+ {
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
goto end;
ret=0;
goto end;
- }
+ }
hl=(p-op);
length-=hl;
/* if j == 0x21 it is a constructed indefinite length object */
<= 0) goto end;
if (j != (V_ASN1_CONSTRUCTED | 1))
- {
+ {
if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
depth,(long)hl,len) <= 0)
goto end;
- }
+ }
else
- {
+ {
if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
depth,(long)hl) <= 0)
goto end;
- }
+ }
if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
goto end;
if (j & V_ASN1_CONSTRUCTED)
- {
+ {
ep=p+len;
if (BIO_write(bp,"\n",1) <= 0) goto end;
if (len > length)
- {
+ {
BIO_printf(bp,
"length is greater than %ld\n",length);
ret=0;
goto end;
- }
+ }
if ((j == 0x21) && (len == 0))
- {
+ {
for (;;)
- {
+ {
r=asn1_parse2(bp,&p,(long)(tot-p),
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
if ((r == 2) || (p >= tot)) break;
- }
}
+ }
else
while (p < ep)
- {
+ {
r=asn1_parse2(bp,&p,(long)len,
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
- }
- }
+ }
+ }
else if (xclass != 0)
- {
+ {
p+=len;
if (BIO_write(bp,"\n",1) <= 0) goto end;
- }
+ }
else
- {
+ {
nl=0;
if ( (tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) ||
(tag == V_ASN1_GENERALIZEDTIME))
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if ((len > 0) &&
BIO_write(bp,(const char *)p,(int)len)
!= (int)len)
goto end;
- }
+ }
else if (tag == V_ASN1_OBJECT)
- {
+ {
opp=op;
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
i2a_ASN1_OBJECT(bp,o);
- }
+ }
else
- {
+ {
if (BIO_write(bp,":BAD OBJECT",11) <= 0)
goto end;
- }
}
+ }
else if (tag == V_ASN1_BOOLEAN)
- {
+ {
int ii;
opp=op;
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
if (ii < 0)
- {
+ {
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
goto end;
- }
- BIO_printf(bp,":%d",ii);
}
+ BIO_printf(bp,":%d",ii);
+ }
else if (tag == V_ASN1_BMPSTRING)
- {
+ {
/* do the BMP thang */
- }
+ }
else if (tag == V_ASN1_OCTET_STRING)
- {
+ {
int i,printable=1;
opp=op;
os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
if (os != NULL && os->length > 0)
- {
+ {
opp = os->data;
/* testing whether the octet string is
* printable */
for (i=0; i<os->length; i++)
- {
+ {
if (( (opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) ||
(opp[i] > '~'))
- {
+ {
printable=0;
break;
- }
}
+ }
if (printable)
/* printable string */
- {
+ {
if (BIO_write(bp,":",1) <= 0)
goto end;
if (BIO_write(bp,(const char *)opp,
os->length) <= 0)
goto end;
- }
+ }
else if (!dump)
/* not printable => print octet string
* as hex dump */
- {
+ {
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
goto end;
for (i=0; i<os->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X"
, opp[i]) <= 0)
goto end;
- }
}
+ }
else
/* print the normal dump */
- {
+ {
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0)
goto end;
- }
+ }
if (BIO_dump_indent(bp,
(const char *)opp,
((dump == -1 || dump >
dump_indent) <= 0)
goto end;
nl=1;
- }
}
+ }
if (os != NULL)
- {
+ {
M_ASN1_OCTET_STRING_free(os);
os=NULL;
- }
}
+ }
else if (tag == V_ASN1_INTEGER)
- {
+ {
ASN1_INTEGER *bs;
int i;
opp=op;
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
if (bs != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
- }
+ }
if (bs->length == 0)
- {
+ {
if (BIO_write(bp,"00",2) <= 0)
goto end;
- }
}
+ }
else
- {
+ {
if (BIO_write(bp,"BAD INTEGER",11) <= 0)
goto end;
- }
- M_ASN1_INTEGER_free(bs);
}
+ M_ASN1_INTEGER_free(bs);
+ }
else if (tag == V_ASN1_ENUMERATED)
- {
+ {
ASN1_ENUMERATED *bs;
int i;
opp=op;
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
if (bs != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
- }
+ }
if (bs->length == 0)
- {
+ {
if (BIO_write(bp,"00",2) <= 0)
goto end;
- }
}
+ }
else
- {
+ {
if (BIO_write(bp,"BAD ENUMERATED",14) <= 0)
goto end;
- }
- M_ASN1_ENUMERATED_free(bs);
}
+ M_ASN1_ENUMERATED_free(bs);
+ }
else if (len > 0 && dump)
- {
+ {
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0)
goto end;
- }
+ }
if (BIO_dump_indent(bp,(const char *)p,
((dump == -1 || dump > len)?len:dump),
dump_indent) <= 0)
goto end;
nl=1;
- }
+ }
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0) goto end;
- }
+ }
p+=len;
if ((tag == V_ASN1_EOC) && (xclass == 0))
- {
+ {
ret=2; /* End of sequence */
goto end;
- }
}
- length-=len;
}
+ length-=len;
+ }
ret=1;
end:
if (o != NULL) ASN1_OBJECT_free(o);
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
*pp=p;
return(ret);
- }
+}
const char *ASN1_tag2str(int tag)
{
"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;
int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const ASN1_ITEM *it)
- {
+{
/* If streaming create stream BIO and copy all content through it */
if (flags & SMIME_STREAM)
- {
+ {
BIO *bio, *tbio;
bio = BIO_new_NDEF(out, val, it);
if (!bio)
- {
+ {
ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
SMIME_crlf_copy(in, bio, flags);
(void)BIO_flush(bio);
/* Free up successive BIOs until we hit the old output BIO */
do
- {
+ {
tbio = BIO_pop(bio);
BIO_free(bio);
bio = tbio;
- } while (bio != out);
- }
+ } while (bio != out);
+ }
/* else just write out ASN1 structure which will have all content
* stored internally
*/
else
ASN1_item_i2d_bio(it, out, val);
return 1;
- }
+}
/* Base 64 read and write of ASN1 structure */
static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const ASN1_ITEM *it)
- {
+{
BIO *b64;
int r;
b64 = BIO_new(BIO_f_base64());
if(!b64)
- {
+ {
ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
/* prepend the b64 BIO so all data is base64 encoded.
*/
out = BIO_push(b64, out);
BIO_pop(out);
BIO_free(b64);
return r;
- }
+}
/* Streaming ASN1 PEM write */
int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const char *hdr,
const ASN1_ITEM *it)
- {
+{
int r;
BIO_printf(out, "-----BEGIN %s-----\n", hdr);
r = B64_write_ASN1(out, val, in, flags, it);
BIO_printf(out, "-----END %s-----\n", hdr);
return r;
- }
+}
static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
{
if(!(b64 = BIO_new(BIO_f_base64()))) {
ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
return 0;
- }
+}
bio = BIO_push(b64, bio);
val = ASN1_item_d2i_bio(it, bio, NULL);
if(!val)
/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
- {
+{
const EVP_MD *md;
int i, have_unknown = 0, write_comma, ret = 0, md_nid;
have_unknown = 0;
write_comma = 0;
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
- {
+ {
if (write_comma)
BIO_write(out, ",", 1);
write_comma = 1;
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
md = EVP_get_digestbynid(md_nid);
if (md && md->md_ctrl)
- {
+ {
int rv;
char *micstr;
rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
if (rv > 0)
- {
+ {
BIO_puts(out, micstr);
free(micstr);
continue;
- }
+ }
if (rv != -2)
goto err;
- }
+ }
switch(md_nid)
- {
+ {
case NID_sha1:
BIO_puts(out, "sha1");
break;
if (have_unknown)
write_comma = 0;
else
- {
+ {
BIO_puts(out, "unknown");
have_unknown = 1;
- }
+ }
break;
- }
}
+ }
ret = 1;
err:
return ret;
- }
+}
/* SMIME sender */
if(c < 10) c += '0';
else c += 'A' - 10;
bound[i] = c;
- }
+ }
bound[32] = 0;
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
BIO_printf(bio, "Content-Type: multipart/signed;");
BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
mime_eol, mime_eol);
return 1;
- }
+}
/* Determine smime-type header */
if (ctype_nid == NID_pkcs7_enveloped)
msg_type = "enveloped-data";
else if (ctype_nid == NID_pkcs7_signed)
- {
+ {
if (econt_nid == NID_id_smime_ct_receipt)
msg_type = "signed-receipt";
else if (sk_X509_ALGOR_num(mdalgs) >= 0)
msg_type = "signed-data";
else
msg_type = "certs-only";
- }
+ }
else if (ctype_nid == NID_id_smime_ct_compressedData)
- {
+ {
msg_type = "compressed-data";
cname = "smime.p7z";
- }
+ }
/* MIME headers */
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
BIO_printf(bio, "Content-Disposition: attachment;");
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
const ASN1_ITEM *it)
- {
+{
BIO *tmpbio;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
* already set up to finalise when it is written through.
*/
if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
- {
+ {
SMIME_crlf_copy(data, out, flags);
return 1;
- }
+ }
if (!aux || !aux->asn1_cb)
- {
+ {
ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
ASN1_R_STREAMING_NOT_SUPPORTED);
return 0;
- }
+ }
sarg.out = out;
sarg.ndef_bio = NULL;
/* Now remove any digests prepended to the BIO */
while (sarg.ndef_bio != out)
- {
+ {
tmpbio = BIO_pop(sarg.ndef_bio);
BIO_free(sarg.ndef_bio);
sarg.ndef_bio = tmpbio;
- }
+ }
return rv;
- }
+}
/* SMIME reader: handle multipart/signed and opaque signing.
* in multipart case the content is placed in a memory BIO
if (!(headers = mime_parse_hdr(bio))) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
return NULL;
- }
+}
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
return NULL;
- }
+}
/* Handle multipart/signed */
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
return NULL;
- }
+ }
ret = multi_split(bio, prm->param_value, &parts);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
if(!ret || (sk_BIO_num(parts) != 2) ) {
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
/* Parse the signature piece */
asnin = sk_BIO_value(parts, 1);
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
/* Get content type */
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
return NULL;
- }
+ }
if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
strcmp(hdr->value, "application/pkcs7-signature")) {
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
/* Read in ASN1 */
if(!(val = b64_read_asn1(asnin, it))) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
if(bcont) {
*bcont = sk_BIO_value(parts, 0);
BIO_free(asnin);
sk_BIO_free(parts);
- } else sk_BIO_pop_free(parts, BIO_vfree);
+ } else sk_BIO_pop_free(parts, BIO_vfree);
return val;
- }
+}
/* OK, if not multipart/signed try opaque signature */
ERR_add_error_data(2, "type: ", hdr->value);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return NULL;
- }
+}
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
if(!(val = b64_read_asn1(bio, it))) {
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
return NULL;
- }
+}
return val;
}
return 0;
out = BIO_push(bf, out);
if(flags & SMIME_BINARY)
- {
+ {
while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
BIO_write(out, linebuf, len);
- }
+ }
else
- {
+ {
if(flags & SMIME_TEXT)
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
- {
+ {
eol = strip_eol(linebuf, &len);
if (len)
BIO_write(out, linebuf, len);
if(eol) BIO_write(out, "\r\n", 2);
- }
}
+ }
(void)BIO_flush(out);
BIO_pop(out);
BIO_free(bf);
if (!(headers = mime_parse_hdr(in))) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
return 0;
- }
+}
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return 0;
- }
+}
if (strcmp (hdr->value, "text/plain")) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
ERR_add_error_data(2, "type: ", hdr->value);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return 0;
- }
+}
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
BIO_write(out, iobuf, len);
if(state == 1) {
first = 1;
part++;
- } else if(state == 2) {
+ } else if(state == 2) {
sk_BIO_push(parts, bpart);
return 1;
- } else if(part) {
+ } else if(part) {
/* Strip CR+LF from linebuf */
next_eol = strip_eol(linebuf, &len);
if(first) {
if(bpart) sk_BIO_push(parts, bpart);
bpart = BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(bpart, 0);
- } else if (eol)
+ } else if (eol)
BIO_write(bpart, "\r\n", 2);
eol = next_eol;
if (len)
BIO_write(bpart, linebuf, len);
- }
}
+}
return 0;
}
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
- }
+ }
break;
case MIME_TYPE:
ntmp = NULL;
q = p + 1;
state = MIME_NAME;
- } else if(c == '(') {
+ } else if(c == '(') {
save_state = state;
state = MIME_COMMENT;
- }
+ }
break;
case MIME_COMMENT:
if(c == ')') {
state = save_state;
- }
+ }
break;
case MIME_NAME:
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
- }
+ }
break ;
case MIME_VALUE:
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
ntmp = NULL;
q = p + 1;
- } else if (c == '"') {
+ } else if (c == '"') {
mime_debug("Found Quote\n");
state = MIME_QUOTE;
- } else if(c == '(') {
+ } else if(c == '(') {
save_state = state;
state = MIME_COMMENT;
- }
+ }
break;
case MIME_QUOTE:
if(c == '"') {
mime_debug("Found Match Quote\n");
state = MIME_VALUE;
- }
- break;
}
+ break;
}
+}
if(state == MIME_TYPE) {
mhdr = mime_hdr_new(ntmp, strip_ends(q));
sk_MIME_HEADER_push(headers, mhdr);
- } else if(state == MIME_VALUE)
+} else if(state == MIME_VALUE)
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
if(p == linebuf) break; /* Blank line means end of headers */
}
if(p[1]) return p + 1;
/* Else null string */
return NULL;
- }
- if(!isspace((unsigned char)c)) return p;
}
+ if(!isspace((unsigned char)c)) return p;
+}
return NULL;
}
if(p - 1 == name) return NULL;
*p = 0;
return name;
- }
+ }
if(isspace((unsigned char)c)) *p = 0;
else return name;
- }
+}
return NULL;
}
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpname = NULL;
+ }
+} else tmpname = NULL;
if(value) {
if(!(tmpval = BUF_strdup(value))) return NULL;
for(p = tmpval ; *p; p++) {
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpval = NULL;
+ }
+} else tmpval = NULL;
mhdr = (MIME_HEADER *) malloc(sizeof(MIME_HEADER));
if (!mhdr) {
OPENSSL_free(tmpname);
return NULL;
- }
+}
mhdr->name = tmpname;
mhdr->value = tmpval;
if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) {
free(mhdr);
return NULL;
- }
+}
return mhdr;
}
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpname = NULL;
+ }
+} else tmpname = NULL;
if(value) {
tmpval = BUF_strdup(value);
if(!tmpval) return 0;
- } else tmpval = NULL;
+} else tmpval = NULL;
/* Parameter values are case sensitive so leave as is */
mparam = (MIME_PARAM *) malloc(sizeof(MIME_PARAM));
if(!mparam) return 0;
if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
if(!strncmp(line + blen + 2, "--", 2)) return 2;
else return 1;
- }
+}
return 0;
}
static int strip_eol(char *linebuf, int *plen)
- {
+{
int len = *plen;
char *p, c;
int is_eol = 0;
p = linebuf + len - 1;
for (p = linebuf + len - 1; len > 0; len--, p--)
- {
+ {
c = *p;
if (c == '\n')
is_eol = 1;
else if (c != '\r')
break;
- }
+ }
*plen = len;
return is_eol;
- }
+}
static int do_create(char *value, char *name);
static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
- {
+{
int i;
const char *oid_section;
STACK_OF(CONF_VALUE) *sktmp;
CONF_VALUE *oval;
oid_section = CONF_imodule_get_value(md);
if(!(sktmp = NCONF_get_section(cnf, oid_section)))
- {
+ {
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
return 0;
- }
+ }
for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
- {
+ {
oval = sk_CONF_VALUE_value(sktmp, i);
if(!do_create(oval->value, oval->name))
- {
+ {
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
return 0;
- }
}
- return 1;
}
+ return 1;
+}
static void oid_module_finish(CONF_IMODULE *md)
- {
+{
OBJ_cleanup();
- }
+}
void ASN1_add_oid_module(void)
- {
+{
CONF_module_add("oid_section", oid_module_init, oid_module_finish);
- }
+}
/* Create an OID based on a name value pair. Accept two formats.
* shortname = 1.2.3.4
static int do_create(char *value, char *name)
- {
+{
int nid;
ASN1_OBJECT *oid;
char *ln, *ostr, *p, *lntmp;
p = strrchr(value, ',');
if (!p)
- {
+ {
ln = name;
ostr = value;
- }
+ }
else
- {
+ {
ln = NULL;
ostr = p + 1;
if (!*ostr)
return 0;
while(isspace((unsigned char)*ostr)) ostr++;
- }
+ }
nid = OBJ_create(ostr, name, ln);
return 0;
if (p)
- {
+ {
ln = value;
while(isspace((unsigned char)*ln)) ln++;
p--;
while(isspace((unsigned char)*p))
- {
+ {
if (p == ln)
return 0;
p--;
- }
+ }
p++;
lntmp = malloc((p - ln) + 1);
if (lntmp == NULL)
lntmp[p - ln] = 0;
oid = OBJ_nid2obj(nid);
oid->ln = lntmp;
- }
+ }
return 1;
- }
+}
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum
- {
+{
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
- } asn1_bio_state_t;
+} asn1_bio_state_t;
typedef struct BIO_ASN1_EX_FUNCS_st
- {
+{
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
- } BIO_ASN1_EX_FUNCS;
+} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_BUF_CTX_t
- {
+{
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
int ex_len;
int ex_pos;
void *ex_arg;
- } BIO_ASN1_BUF_CTX;
+} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf,int num);
asn1_bio_state_t other_state);
static BIO_METHOD methods_asn1=
- {
+{
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_new,
asn1_bio_free,
asn1_bio_callback_ctrl,
- };
+};
BIO_METHOD *BIO_f_asn1(void)
- {
+{
return(&methods_asn1);
- }
+}
static int asn1_bio_new(BIO *b)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
free(ctx);
return 0;
- }
+}
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->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
- }
+}
static int asn1_bio_free(BIO *b)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
b->ptr = NULL;
b->flags = 0;
return 1;
- }
+}
static int asn1_bio_write(BIO *b, const char *in , int inl)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret;
unsigned char *p;
ret = -1;
for(;;)
- {
+ {
switch (ctx->state)
- {
+ {
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (ctx->buflen)
ctx->bufpos += ret;
else
- {
+ {
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
- }
+ }
break;
BIO_clear_retry_flags(b);
return 0;
- }
-
}
+ }
+
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (wrlen > 0) ? wrlen : ret;
- }
+}
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next)
- {
+{
int ret;
if (ctx->ex_len <= 0)
return 1;
for(;;)
- {
+ {
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
ctx->ex_len);
if (ret <= 0)
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else
- {
+ {
if(cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
&ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
- }
}
- return ret;
}
+ return ret;
+}
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state)
- {
+{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
- {
+ {
BIO_clear_retry_flags(b);
return 0;
- }
+ }
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
- }
+}
static int asn1_bio_read(BIO *b, char *in , int inl)
- {
+{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in , inl);
- }
+}
static int asn1_bio_puts(BIO *b, const char *str)
- {
+{
return asn1_bio_write(b, str, strlen(str));
- }
+}
static int asn1_bio_gets(BIO *b, char *str, int size)
- {
+{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str , size);
- }
+}
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
- {
+{
if (b->next_bio == NULL) return(0);
return BIO_callback_ctrl(b->next_bio,cmd,fp);
- }
+}
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
if (ctx == NULL)
return 0;
switch(cmd)
- {
+ {
case BIO_C_SET_PREFIX:
ex_func = arg2;
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER)
- {
+ {
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
- }
+ }
if (ctx->state == ASN1_STATE_POST_COPY)
- {
+ {
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
- }
+ }
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else
- {
+ {
BIO_clear_retry_flags(b);
return 0;
- }
+ }
break;
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
- }
+ }
return ret;
- }
+}
static int asn1_bio_set_ex(BIO *b, int cmd,
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
- {
+{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
- }
+}
static int asn1_bio_get_ex(BIO *b, int cmd,
asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
- {
+{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0)
- {
+ {
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
- }
- return ret;
}
+ return ret;
+}
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
- {
+{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
- }
+}
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
- {
+{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
- }
+}
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
- {
+{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
- }
+}
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
- {
+{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
- }
+}
/* BIO support data stored in the ASN1 BIO ex_arg */
typedef struct ndef_aux_st
- {
+{
/* ASN1 structure this BIO refers to */
ASN1_VALUE *val;
const ASN1_ITEM *it;
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
- } NDEF_SUPPORT;
+} NDEF_SUPPORT;
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
- {
+{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
if (!aux || !aux->asn1_cb)
- {
+ {
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
- }
+ }
ndef_aux = malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
if (ndef_aux)
free(ndef_aux);
return NULL;
- }
+}
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
*plen = *ndef_aux->boundary - *pbuf;
return 1;
- }
+}
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
if (!parg)
*pbuf = NULL;
*plen = 0;
return 1;
- }
+}
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
if (!ndef_prefix_free(b, pbuf, plen, parg))
return 0;
free(*pndef_aux);
*pndef_aux = NULL;
return 1;
- }
+}
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
return 1;
- }
+}
EVP_PKEY *d2i_PrivateKey(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)
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_EVP_LIB);
return(NULL);
- }
}
+ }
else
- {
+ {
ret= *a;
#ifndef OPENSSL_NO_ENGINE
if (ret->engine)
- {
+ {
ENGINE_finish(ret->engine);
ret->engine = NULL;
- }
-#endif
}
+#endif
+ }
if (!EVP_PKEY_set_type(ret, type))
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,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;
p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
if (!p8) goto err;
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
goto err;
- }
- }
+ }
+ }
if (a != NULL) (*a)=ret;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
return(NULL);
- }
+}
/* This works like d2i_PrivateKey() except it automatically works out the type */
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 */
+ { /* 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)
- {
+ {
ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,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);
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)
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
return(NULL);
- }
}
+ }
else ret= *a;
if (!EVP_PKEY_set_type(ret, type))
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,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,
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
(const unsigned char **)pp,length)) /* TMP UGLY CAST */
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if (!o2i_ECPublicKey(&(ret->pkey.ec),
(const unsigned char **)pp, length))
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
default:
ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
/* break; */
- }
+ }
if (a != NULL) (*a)=ret;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
return(NULL);
- }
+}
#include <openssl/asn1_mac.h>
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
- {
+{
ASN1_STRING *os;
if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
return(1);
- }
+}
/* int max_len: for returned value */
int ASN1_TYPE_get_octetstring(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))
- {
+ {
ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
return(-1);
- }
+ }
p=M_ASN1_STRING_data(a->value.octet_string);
ret=M_ASN1_STRING_length(a->value.octet_string);
if (ret < max_len)
num=max_len;
memcpy(data,p,num);
return(ret);
- }
+}
int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
int len)
- {
+{
int n,size;
ASN1_OCTET_STRING os,*osp;
ASN1_INTEGER in;
if ((osp=ASN1_STRING_new()) == NULL) return(0);
/* Grow the 'string' */
if (!ASN1_STRING_set(osp,NULL,size))
- {
+ {
ASN1_STRING_free(osp);
return(0);
- }
+ }
M_ASN1_STRING_length_set(osp, size);
p=M_ASN1_STRING_data(osp);
ASN1_TYPE_set(a,V_ASN1_SEQUENCE,osp);
return(1);
- }
+}
/* we return the actual length..., num may be missing, in which
* case, set it to zero */
/* int max_len: for returned value */
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
int max_len)
- {
+{
int ret= -1,n;
ASN1_INTEGER *ai=NULL;
ASN1_OCTET_STRING *os=NULL;
ASN1_const_CTX c;
if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL))
- {
+ {
goto err;
- }
+ }
p=M_ASN1_STRING_data(a->value.sequence);
length=M_ASN1_STRING_length(a->value.sequence);
if (data != NULL)
memcpy(data,M_ASN1_STRING_data(os),n);
if (0)
- {
+ {
err:
ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
- }
+ }
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
if (ai != NULL) M_ASN1_INTEGER_free(ai);
return(ret);
- }
+}
/* Based on a_int.c: equivalent ENUMERATED functions */
int i2a_ASN1_ENUMERATED(BIO *bp, 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;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
again=(buf[i-1] == '\\');
for (j=0; j<i; j++)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
bufp=(unsigned char *)buf;
if (first)
- {
+ {
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
- {
+ {
bufp+=2;
i-=2;
- }
}
+ }
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
sp=(unsigned char *)realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include <openssl/asn1.h>
int i2a_ASN1_INTEGER(BIO *bp, 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;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
again=(buf[i-1] == '\\');
for (j=0; j<i; j++)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
bufp=(unsigned char *)buf;
if (first)
- {
+ {
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
- {
+ {
bufp+=2;
i-=2;
- }
}
+ }
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
else
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include <openssl/asn1.h>
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
- {
+{
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,"0",1) != 1) goto err;
n=1;
- }
+ }
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_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
- {
+{
int ret=0;
int i,j,k,m,n,again,bufsize;
unsigned char *s=NULL,*sp;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1)
- {
+ {
if (first)
break;
else
goto err_sl;
- }
+ }
first=0;
i=bufsize;
again=(buf[i-1] == '\\');
for (j=i-1; j>0; j--)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
sp=(unsigned char *)realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include "asn1_locl.h"
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;
- }
+}
ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1);
- }
+}
#endif
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));
default:
ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1);
- }
}
+}
#ifndef OPENSSL_NO_RC4
typedef struct netscape_pkey_st
- {
+{
long version;
X509_ALGOR *algor;
ASN1_OCTET_STRING *private_key;
- } NETSCAPE_PKEY;
+} NETSCAPE_PKEY;
typedef struct netscape_encrypted_pkey_st
- {
+{
ASN1_OCTET_STRING *os;
/* This is the same structure as DigestInfo so use it:
* although this isn't really anything to do with
* digests.
*/
X509_SIG *enckey;
- } NETSCAPE_ENCRYPTED_PKEY;
+} NETSCAPE_ENCRYPTED_PKEY;
ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
int i2d_RSA_NET(const RSA *a, unsigned char **pp,
int (*cb)(char *buf, int len, const char *prompt, int verify),
int sgckey)
- {
+{
int i, j, ret = 0;
int rsalen, pkeylen, olen;
NETSCAPE_PKEY *pkey = NULL;
enckey->enckey->algor->parameter->type=V_ASN1_NULL;
if (pp == NULL)
- {
+ {
olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
NETSCAPE_PKEY_free(pkey);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return olen;
- }
+ }
/* Since its RC4 encrypted length is actual length */
if ((zz=(unsigned char *)malloc(rsalen)) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
pkey->private_key->data = zz;
/* Write out private key encoding */
i2d_RSAPrivateKey(a,&zz);
if ((zz=malloc(pkeylen)) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!ASN1_STRING_set(enckey->os, "private-key", -1))
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
enckey->enckey->digest->data = zz;
i2d_NETSCAPE_PKEY(pkey,&zz);
cb=EVP_read_pw_string;
i=cb((char *)buf,256,"Enter Private Key password:",1);
if (i != 0)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
goto err;
- }
+ }
i = strlen((char *)buf);
/* If the key is used for SGC the algorithm is modified a little. */
if(sgckey) {
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
- }
+}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return(ret);
- }
+}
RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
int (*cb)(char *buf, int len, const char *prompt, int verify),
int sgckey)
- {
+{
RSA *ret=NULL;
const unsigned char *p;
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
if(!enckey) {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
return NULL;
- }
+}
if ((enckey->os->length != 11) || (strncmp("private-key",
(char *)enckey->os->data,11) != 0))
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return NULL;
- }
+ }
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
goto err;
- }
+}
if (cb == NULL)
cb=EVP_read_pw_string;
if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return ret;
- }
+}
static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
int (*cb)(char *buf, int len, const char *prompt,
int verify), int sgckey)
- {
+{
NETSCAPE_PKEY *pkey=NULL;
RSA *ret=NULL;
int i,j;
i=cb((char *)buf,256,"Enter Private Key password:",0);
if (i != 0)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
goto err;
- }
+ }
i = strlen((char *)buf);
if(sgckey){
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
- }
+}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
zz=os->data;
if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
goto err;
- }
+ }
zz=pkey->private_key->data;
if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
goto err;
- }
+ }
err:
EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_PKEY_free(pkey);
return(ret);
- }
+}
#endif /* OPENSSL_NO_RC4 */
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen)
- {
+{
PBEPARAM *pbe=NULL;
ASN1_STRING *pbe_str=NULL;
unsigned char *sstr;
pbe = PBEPARAM_new();
if (!pbe)
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if(iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if (!ASN1_INTEGER_set(pbe->iter, iter))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
sstr = ASN1_STRING_data(pbe->salt);
if (salt)
memcpy(sstr, salt, saltlen);
goto err;
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
PBEPARAM_free(pbe);
pbe = NULL;
if (pbe_str != NULL)
ASN1_STRING_free(pbe_str);
return 0;
- }
+}
/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen)
- {
+{
X509_ALGOR *ret;
ret = X509_ALGOR_new();
if (!ret)
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
return NULL;
- }
+ }
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
return ret;
X509_ALGOR_free(ret);
return NULL;
- }
+}
if (key->pkey->value.octet_string)
OPENSSL_cleanse(key->pkey->value.octet_string->data,
key->pkey->value.octet_string->length);
- }
+}
return 1;
}
int version,
int ptype, void *pval,
unsigned char *penc, int penclen)
- {
+{
unsigned char **ppenc = NULL;
if (version >= 0)
- {
+ {
if (!ASN1_INTEGER_set(priv->version, version))
return 0;
- }
+ }
if (penc)
- {
+ {
int pmtype;
ASN1_OCTET_STRING *oct;
oct = ASN1_OCTET_STRING_new();
else
pmtype = V_ASN1_OCTET_STRING;
ASN1_TYPE_set(priv->pkey, pmtype, oct);
- }
+ }
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
- {
+ {
/* If call fails do not swallow 'enc' */
if (ppenc)
*ppenc = NULL;
return 0;
- }
- return 1;
}
+ return 1;
+}
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
PKCS8_PRIV_KEY_INFO *p8)
- {
+{
if (ppkalg)
*ppkalg = p8->pkeyalg->algorithm;
if(p8->pkey->type == V_ASN1_OCTET_STRING)
- {
+ {
p8->broken = PKCS8_OK;
if (pk)
- {
+ {
*pk = p8->pkey->value.octet_string->data;
*ppklen = p8->pkey->value.octet_string->length;
- }
}
+ }
else if (p8->pkey->type == V_ASN1_SEQUENCE)
- {
+ {
p8->broken = PKCS8_NO_OCTET;
if (pk)
- {
+ {
*pk = p8->pkey->value.sequence->data;
*ppklen = p8->pkey->value.sequence->length;
- }
}
+ }
else
return 0;
if (pa)
*pa = p8->pkeyalg;
return 1;
- }
+}
#ifndef OPENSSL_NO_FP_API
int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_CRL_print(b, x);
BIO_free(b);
return(ret);
- }
+}
#endif
int X509_CRL_print(BIO *out, X509_CRL *x)
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)
- {
+{
int n,i;
const char *neg;
if(!BIO_indent(bp,off,128))
return 0;
if (BN_is_zero(num))
- {
+ {
if (BIO_printf(bp, "%s 0\n", number) <= 0)
return 0;
return 1;
- }
+ }
if (BN_num_bytes(num) <= BN_BYTES)
- {
+ {
if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
<= 0) return(0);
- }
+ }
else
- {
+ {
buf[0]=0;
if (BIO_printf(bp,"%s%s",number,
(neg[0] == '-')?" (Negative)":"") <= 0)
else buf++;
for (i=0; i<n; i++)
- {
+ {
if ((i%15) == 0)
- {
+ {
if(BIO_puts(bp,"\n") <= 0
|| !BIO_indent(bp,off+4,128))
return 0;
- }
+ }
if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
<= 0) return(0);
- }
- if (BIO_write(bp,"\n",1) <= 0) return(0);
}
- return(1);
+ if (BIO_write(bp,"\n",1) <= 0) return(0);
}
+ return(1);
+}
#ifndef OPENSSL_NO_FP_API
int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_REQ_PRINT_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_REQ_print(b, x);
BIO_free(b);
return(ret);
- }
+}
#endif
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
- {
+{
unsigned long l;
int i;
const char *neg;
ri=x->req_info;
if(!(cflag & X509_FLAG_NO_HEADER))
- {
+ {
if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VERSION))
- {
+ {
neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
l=0;
for (i=0; i<ri->version->length; i++)
- { l<<=8; l+=ri->version->data[i]; }
+ { l<<=8; l+=ri->version->data[i]; }
if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
l) <= 0)
goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SUBJECT))
{
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
}
if(!(cflag & X509_FLAG_NO_PUBKEY))
- {
+ {
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
goto err;
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
pkey=X509_REQ_get_pubkey(x);
if (pkey == NULL)
- {
+ {
BIO_printf(bp,"%12sUnable to load Public Key\n","");
ERR_print_errors(bp);
- }
+ }
else
- {
+ {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
- }
}
+ }
if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
- {
+ {
/* may not be */
if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
goto err;
sk=x->req_info->attributes;
if (sk_X509_ATTRIBUTE_num(sk) == 0)
- {
+ {
if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
goto err;
- }
+ }
else
- {
+ {
for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
- {
+ {
ASN1_TYPE *at;
X509_ATTRIBUTE *a;
ASN1_BIT_STRING *bs=NULL;
if(BIO_printf(bp,"%12s","") <= 0)
goto err;
if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
- {
+ {
if (a->single)
- {
+ {
t=a->value.single;
type=t->type;
bs=t->value.bit_string;
- }
+ }
else
- {
+ {
ii=0;
count=sk_ASN1_TYPE_num(a->value.set);
get_next:
at=sk_ASN1_TYPE_value(a->value.set,ii);
type=at->type;
bs=at->value.asn1_string;
- }
}
+ }
for (j=25-j; j>0; j--)
if (BIO_write(bp," ",1) != 1) goto err;
if (BIO_puts(bp,":") <= 0) goto err;
if ( (type == V_ASN1_PRINTABLESTRING) ||
(type == V_ASN1_T61STRING) ||
(type == V_ASN1_IA5STRING))
- {
+ {
if (BIO_write(bp,(char *)bs->data,bs->length)
!= bs->length)
goto err;
BIO_puts(bp,"\n");
- }
+ }
else
- {
+ {
BIO_puts(bp,"unable to print attribute\n");
- }
- if (++ii < count) goto get_next;
}
+ if (++ii < count) goto get_next;
}
}
+ }
if(!(cflag & X509_FLAG_NO_EXTENSIONS))
- {
+ {
exts = X509_REQ_get_extensions(x);
if(exts)
- {
+ {
BIO_printf(bp,"%8sRequested Extensions:\n","");
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
- {
+ {
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
int j;
if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
goto err;
if(!X509V3_EXT_print(bp, ex, cflag, 16))
- {
+ {
BIO_printf(bp, "%16s", "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
- }
- if (BIO_write(bp,"\n",1) <= 0) goto err;
}
- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ if (BIO_write(bp,"\n",1) <= 0) goto err;
}
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
}
+ }
if(!(cflag & X509_FLAG_NO_SIGDUMP))
- {
+ {
if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
- }
+ }
return(1);
err:
X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
return(0);
- }
+}
int X509_REQ_print(BIO *bp, X509_REQ *x)
- {
+{
return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
- }
+}
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
if(!pkey) BIO_printf(out, " Unable to load public key\n");
else
- {
+ {
EVP_PKEY_print_public(out, pkey, 4, NULL);
EVP_PKEY_free(pkey);
- }
+ }
chal = spki->spkac->challenge;
if(chal->length)
BIO_printf(out, " Challenge String: %s\n", chal->data);
n=spki->signature->length;
s=(char *)spki->signature->data;
for (i=0; i<n; i++)
- {
+ {
if ((i%18) == 0) BIO_write(out,"\n ",7);
BIO_printf(out,"%02x%s",(unsigned char)s[i],
((i+1) == n)?"":":");
- }
+ }
BIO_write(out,"\n",1);
return 1;
}
#ifndef OPENSSL_NO_FP_API
int X509_print_fp(FILE *fp, X509 *x)
- {
+{
return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
- }
+}
int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
{
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_print_ex(b, x, nmflag, cflag);
BIO_free(b);
}
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
- {
+{
long l;
int ret=0,i;
char *m=NULL,mlch = ' ';
ci=x->cert_info;
if(!(cflag & X509_FLAG_NO_HEADER))
- {
+ {
if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VERSION))
- {
+ {
l=X509_get_version(x);
if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SERIAL))
- {
+ {
if (BIO_write(bp," Serial Number:",22) <= 0) goto err;
bs=X509_get_serialNumber(x);
if (bs->length <= (int)sizeof(long))
- {
+ {
l=ASN1_INTEGER_get(bs);
if (bs->type == V_ASN1_NEG_INTEGER)
- {
+ {
l= -l;
neg="-";
- }
+ }
else
neg="";
if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
goto err;
- }
+ }
else
- {
+ {
neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02x%c",bs->data[i],
((i+1 == bs->length)?'\n':':')) <= 0)
goto err;
- }
}
-
}
+ }
+
if(!(cflag & X509_FLAG_NO_SIGNAME))
- {
+ {
if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
goto err;
#if 0
if (BIO_puts(bp, "\n") <= 0)
goto err;
#endif
- }
+ }
if(!(cflag & X509_FLAG_NO_ISSUER))
- {
+ {
if (BIO_printf(bp," Issuer:%c",mlch) <= 0) goto err;
if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VALIDITY))
- {
+ {
if (BIO_write(bp," Validity\n",17) <= 0) goto err;
if (BIO_write(bp," Not Before: ",24) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SUBJECT))
- {
+ {
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_PUBKEY))
- {
+ {
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
goto err;
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
pkey=X509_get_pubkey(x);
if (pkey == NULL)
- {
+ {
BIO_printf(bp,"%12sUnable to load Public Key\n","");
ERR_print_errors(bp);
- }
+ }
else
- {
+ {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
- }
}
+ }
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
X509V3_extensions_print(bp, "X509v3 extensions",
ci->extensions, cflag, 8);
if(!(cflag & X509_FLAG_NO_SIGDUMP))
- {
+ {
if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_AUX))
- {
+ {
if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
- }
+ }
ret=1;
err:
if (m != NULL) free(m);
return(ret);
- }
+}
int X509_ocspid_print (BIO *bp, X509 *x)
- {
+{
unsigned char *der=NULL ;
unsigned char *dertmp;
int derlen;
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
+ {
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
- }
+ }
free (der);
der=NULL;
SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
+ {
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
goto err;
- }
+ }
BIO_printf(bp,"\n");
return (1);
err:
if (der != NULL) free(der);
return(0);
- }
+}
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
n=sig->length;
s=sig->data;
for (i=0; i<n; i++)
- {
+ {
if ((i%18) == 0)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0) return 0;
if (BIO_indent(bp, indent, indent) <= 0) return 0;
- }
+ }
if (BIO_printf(bp,"%02x%s",s[i],
((i+1) == n)?"":":") <= 0) return 0;
- }
+ }
if (BIO_write(bp,"\n",1) != 1) return 0;
return 1;
sig_nid = OBJ_obj2nid(sigalg->algorithm);
if (sig_nid != NID_undef)
- {
+ {
int pkey_nid, dig_nid;
const EVP_PKEY_ASN1_METHOD *ameth;
if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
- {
+ {
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
if (ameth && ameth->sig_print)
return ameth->sig_print(bp, sigalg, sig, 9, 0);
- }
}
+ }
if (sig)
return X509_signature_dump(bp, sig, 9);
else if (BIO_puts(bp, "\n") <= 0)
}
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
- {
+{
int i,n;
char buf[80];
const char *p;
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]='.';
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)
{
};
int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
- {
+{
char *v;
int gmt=0;
int i;
if (tm->length >= 14 &&
(v[12] >= '0') && (v[12] <= '9') &&
(v[13] >= '0') && (v[13] <= '9'))
- {
+ {
s= (v[12]-'0')*10+(v[13]-'0');
/* Check for fractions of seconds. */
if (tm->length >= 15 && v[14] == '.')
- {
+ {
int l = tm->length;
f = &v[14]; /* The decimal point. */
f_len = 1;
while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
++f_len;
- }
}
+ }
if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
err:
BIO_write(bp,"Bad time value",14);
return(0);
- }
+}
int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
- {
+{
const char *v;
int gmt=0;
int i;
err:
BIO_write(bp,"Bad time value",14);
return(0);
- }
+}
int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
- {
+{
char *s,*c,*b;
int ret=0,l,i;
b=X509_NAME_oneline(name,NULL,0);
if (!*b)
- {
+ {
free(b);
return 1;
- }
+ }
s=b+1; /* skip the first slash */
c=s;
for (;;)
- {
+ {
if ( ((*s == '/') &&
((s[1] >= 'A') && (s[1] <= 'Z') && (
(s[2] == '=') ||
(s[3] == '='))
))) ||
(*s == '\0'))
- {
+ {
i=s-c;
if (BIO_write(bp,c,i) != i) goto err;
c=s+1; /* skip following slash */
if (*s != '\0')
- {
+ {
if (BIO_write(bp,", ",2) != 2) goto err;
- }
- l--;
}
+ l--;
+ }
if (*s == '\0') break;
s++;
l--;
- }
+ }
ret=1;
if (0)
- {
+ {
err:
X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
- }
+ }
free(b);
return(ret);
- }
+}
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)
- {
+{
if ((tag < 0) || (tag > 30)) return 0;
return tag2bit[tag];
- }
+}
/* Macro to initialize and invalidate the cache */
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;
if (!pval)
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval;
return NULL;
- }
+}
int ASN1_template_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
- {
+{
ASN1_TLC c;
asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
- }
+}
/* Decode an item, taking care of IMPLICIT tagging, if any.
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)
- {
+{
const ASN1_TEMPLATE *tt, *errtt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
else asn1_cb = 0;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
- {
+ {
/* tagging or OPTIONAL is currently illegal on an item
* template because the flags can't get passed down.
* In practice this isn't a problem: we include the
* template itself.
*/
if ((tag != -1) || opt)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
goto err;
- }
+ }
return asn1_template_ex_d2i(pval, in, len,
it->templates, opt, ctx);
- }
+ }
return asn1_d2i_ex_primitive(pval, in, len, it,
tag, aclass, opt, ctx);
break;
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
&p, len, -1, 0, 1, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* Must be UNIVERSAL class */
if (oclass != V_ASN1_UNIVERSAL)
- {
+ {
/* If OPTIONAL, assume this is OK */
if (opt) return -1;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
- }
+ }
/* Check tag matches bit map */
if (!(ASN1_tag2bit(otag) & it->utype))
- {
+ {
/* If OPTIONAL, assume this is OK */
if (opt)
return -1;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_MSTRING_WRONG_TAG);
goto err;
- }
+ }
return asn1_d2i_ex_primitive(pval, in, len,
it, otag, 0, 0, ctx);
/* If OPTIONAL see if it is there */
if (opt)
- {
+ {
int exptag;
p = *in;
if (tag == -1)
ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
&p, len, exptag, aclass, 1, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if (ret == -1)
return -1;
- }
+ }
/* This is the old style evil hack IMPLICIT handling:
* since the underlying code is expecting a tag and
*/
if (tag != -1)
- {
+ {
wp = *(unsigned char **)in;
imphack = *wp;
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
| it->utype);
- }
+ }
ptmpval = cf->asn1_d2i(pval, in, len);
/* Allocate structure */
if (!*pval && !ASN1_item_ex_new(pval, it))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* CHOICE type, try each possibility in turn */
p = *in;
for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
- {
+ {
pchptr = asn1_get_field_ptr(pval, tt);
/* We mark field as OPTIONAL so its absence
* can be recognised.
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* Did we fall off the end without reading anything? */
if (i == it->tcount)
- {
+ {
/* If OPTIONAL, this is OK */
if (opt)
- {
+ {
/* Free and zero it */
ASN1_item_ex_free(pval, it);
return -1;
- }
+ }
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_NO_MATCHING_CHOICE_TYPE);
goto err;
- }
+ }
asn1_set_choice_selector(pval, i, it);
*in = p;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if (tag == -1)
- {
+ {
tag = V_ASN1_SEQUENCE;
aclass = V_ASN1_UNIVERSAL;
- }
+ }
/* Get SEQUENCE length and update len, p */
ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
&p, len, tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
if (aux && (aux->flags & ASN1_AFLG_BROKEN))
- {
+ {
len = tmplen - (p - *in);
seq_nolen = 1;
- }
+ }
/* If indefinite we don't do a length check */
else seq_nolen = seq_eoc;
if (!cst)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
goto err;
- }
+ }
if (!*pval && !ASN1_item_ex_new(pval, it))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
/* Get each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
break;
q = p;
if (asn1_check_eoc(&p, len))
- {
+ {
if (!seq_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_UNEXPECTED_EOC);
goto err;
- }
+ }
len -= p - q;
seq_eoc = 0;
q = p;
break;
- }
+ }
/* This determines the OPTIONAL flag value. The field
* cannot be omitted if it is the last of a SEQUENCE
* and there is still data to be read. This isn't
ret = asn1_template_ex_d2i(pseqval, &p, len,
seqtt, isopt, ctx);
if (!ret)
- {
+ {
errtt = seqtt;
goto err;
- }
+ }
else if (ret == -1)
- {
+ {
/* OPTIONAL component absent.
* Free and zero the field.
*/
ASN1_template_free(pseqval, seqtt);
continue;
- }
+ }
/* Update length */
len -= p - q;
- }
+ }
/* Check for EOC if expecting one */
if (seq_eoc && !asn1_check_eoc(&p, len))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
goto err;
- }
+ }
/* Check all data read */
if (!seq_nolen && len)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_SEQUENCE_LENGTH_MISMATCH);
goto err;
- }
+ }
/* If we get here we've got no more data in the SEQUENCE,
* however we may not have read all fields so check all
* remaining are OPTIONAL and clear any that are.
*/
for (; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
goto err;
if (seqtt->flags & ASN1_TFLG_OPTIONAL)
- {
+ {
ASN1_VALUE **pseqval;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
- }
+ }
else
- {
+ {
errtt = seqtt;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_FIELD_MISSING);
goto err;
- }
}
+ }
/* Save encoding */
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
default:
return 0;
- }
+ }
auxerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
err:
else
ERR_add_error_data(2, "Type=", it->sname);
return 0;
- }
+}
/* Templates are handled with two separate functions.
* One handles any EXPLICIT tag and the other handles the rest.
const unsigned char **in, long inlen,
const ASN1_TEMPLATE *tt, char opt,
ASN1_TLC *ctx)
- {
+{
int flags, aclass;
int ret;
long len;
/* Check if EXPLICIT tag expected */
if (flags & ASN1_TFLG_EXPTAG)
- {
+ {
char cst;
/* Need to work out amount of data available to the inner
* content and where it starts: so read in EXPLICIT header to
&p, inlen, tt->tag, aclass, opt, ctx);
q = p;
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
if (!cst)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
return 0;
- }
+ }
/* We've found the field so it can't be OPTIONAL now */
ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
/* We read the field in OK so update length */
len -= p - q;
if (exp_eoc)
- {
+ {
/* If NDEF we must have an EOC here */
if (!asn1_check_eoc(&p, len))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_MISSING_EOC);
goto err;
- }
}
+ }
else
- {
+ {
/* Otherwise we must hit the EXPLICIT tag end or its
* an error */
if (len)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_EXPLICIT_LENGTH_MISMATCH);
goto err;
- }
}
}
+ }
else
return asn1_template_noexp_d2i(val, in, inlen,
tt, opt, ctx);
err:
ASN1_template_free(val, tt);
return 0;
- }
+}
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_TEMPLATE *tt, char opt,
ASN1_TLC *ctx)
- {
+{
int flags, aclass;
int ret;
const unsigned char *p, *q;
q = p;
if (flags & ASN1_TFLG_SK_MASK)
- {
+ {
/* SET OF, SEQUENCE OF */
int sktag, skaclass;
char sk_eoc;
/* First work out expected inner tag value */
if (flags & ASN1_TFLG_IMPTAG)
- {
+ {
sktag = tt->tag;
skaclass = aclass;
- }
+ }
else
- {
+ {
skaclass = V_ASN1_UNIVERSAL;
if (flags & ASN1_TFLG_SET_OF)
sktag = V_ASN1_SET;
else
sktag = V_ASN1_SEQUENCE;
- }
+ }
/* Get the tag */
ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
&p, len, sktag, skaclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
if (!*val)
*val = (ASN1_VALUE *)sk_new_null();
else
- {
+ {
/* We've got a valid STACK: free up any items present */
STACK_OF(ASN1_VALUE) *sktmp
= (STACK_OF(ASN1_VALUE) *)*val;
ASN1_VALUE *vtmp;
while(sk_ASN1_VALUE_num(sktmp) > 0)
- {
+ {
vtmp = sk_ASN1_VALUE_pop(sktmp);
ASN1_item_ex_free(&vtmp,
ASN1_ITEM_ptr(tt->item));
- }
}
+ }
if (!*val)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
/* Read as many items as we can */
while(len > 0)
- {
+ {
ASN1_VALUE *skfield;
q = p;
/* See if EOC found */
if (asn1_check_eoc(&p, len))
- {
+ {
if (!sk_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ASN1_R_UNEXPECTED_EOC);
goto err;
- }
+ }
len -= p - q;
sk_eoc = 0;
break;
- }
+ }
skfield = NULL;
if (!ASN1_item_ex_d2i(&skfield, &p, len,
ASN1_ITEM_ptr(tt->item),
-1, 0, 0, ctx))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
skfield))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
}
+ }
if (sk_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
goto err;
- }
}
+ }
else if (flags & ASN1_TFLG_IMPTAG)
- {
+ {
/* IMPLICIT tagging */
ret = ASN1_item_ex_d2i(val, &p, len,
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
- }
+ }
else
- {
+ {
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-1, 0, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
- }
+ }
*in = p;
return 1;
err:
ASN1_template_free(val, tt);
return 0;
- }
+}
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
const unsigned char **in, long inlen,
const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx)
- {
+{
int ret = 0, utype;
long plen;
char cst, inf, free_cont = 0;
const unsigned char *cont = NULL;
long len;
if (!pval)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
return 0; /* Should never happen */
- }
+ }
if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
utype = tag;
tag = -1;
- }
+ }
else
utype = it->utype;
if (utype == V_ASN1_ANY)
- {
+ {
/* If type is ANY need to figure out type from tag */
unsigned char oclass;
if (tag >= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_ILLEGAL_TAGGED_ANY);
return 0;
- }
+ }
if (opt)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_ILLEGAL_OPTIONAL_ANY);
return 0;
- }
+ }
p = *in;
ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
&p, inlen, -1, 0, 0, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
if (oclass != V_ASN1_UNIVERSAL)
utype = V_ASN1_OTHER;
- }
+ }
if (tag == -1)
- {
+ {
tag = utype;
aclass = V_ASN1_UNIVERSAL;
- }
+ }
p = *in;
/* Check header */
ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
&p, inlen, tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
ret = 0;
/* SEQUENCE, SET and "OTHER" are left in encoded form */
if ((utype == V_ASN1_SEQUENCE)
|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
- {
+ {
/* Clear context cache for type OTHER because the auto clear
* 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)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
- }
+ }
cont = *in;
/* If indefinite length constructed find the real end */
if (inf)
- {
+ {
if (!asn1_find_end(&p, plen, inf))
goto err;
len = p - cont;
- }
+ }
else
- {
+ {
len = p - cont + plen;
p += plen;
buf.data = NULL;
- }
}
+ }
else if (cst)
- {
+ {
buf.length = 0;
buf.max = 0;
buf.data = NULL;
* for UNIVERSAL class and ignore the tag.
*/
if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
- {
+ {
free_cont = 1;
goto err;
- }
+ }
len = buf.length;
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1))
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
buf.data[len] = 0;
cont = (const unsigned char *)buf.data;
free_cont = 1;
- }
+ }
else
- {
+ {
cont = 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))
err:
if (free_cont && buf.data) free(buf.data);
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)
- {
+{
ASN1_VALUE **opval = NULL;
ASN1_STRING *stmp;
ASN1_TYPE *typ = NULL;
return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
/* If ANY type clear type and set pointer to internal value */
if (it->utype == V_ASN1_ANY)
- {
+ {
if (!*pval)
- {
+ {
typ = ASN1_TYPE_new();
if (typ == NULL)
goto err;
*pval = (ASN1_VALUE *)typ;
- }
+ }
else
typ = (ASN1_TYPE *)*pval;
ASN1_TYPE_set(typ, utype, NULL);
opval = pval;
pval = &typ->value.asn1_value;
- }
+ }
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
goto err;
case V_ASN1_NULL:
if (len)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_NULL_IS_WRONG_LENGTH);
goto err;
- }
+ }
*pval = (ASN1_VALUE *)1;
break;
case V_ASN1_BOOLEAN:
if (len != 1)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
goto err;
- }
+ }
else
- {
+ {
ASN1_BOOLEAN *tbool;
tbool = (ASN1_BOOLEAN *)pval;
*tbool = *cont;
- }
+ }
break;
case V_ASN1_BIT_STRING:
case V_ASN1_SEQUENCE:
default:
if (utype == V_ASN1_BMPSTRING && (len & 1))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
goto err;
- }
+ }
if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
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)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
- *pval = (ASN1_VALUE *)stmp;
}
+ *pval = (ASN1_VALUE *)stmp;
+ }
else
- {
+ {
stmp = (ASN1_STRING *)*pval;
stmp->type = utype;
- }
+ }
/* If we've already allocated a buffer use it */
if (*free_cont)
- {
+ {
if (stmp->data)
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))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
- }
}
- break;
}
+ break;
+ }
/* If ASN1_ANY and NULL type fix up value */
if (typ && (utype == V_ASN1_NULL))
typ->value.ptr = NULL;
ret = 1;
err:
if (!ret)
- {
+ {
ASN1_TYPE_free(typ);
if (opval)
*opval = NULL;
- }
- return ret;
}
+ return ret;
+}
/* This function finds the end of an ASN1 structure when passed its maximum
*/
static int asn1_find_end(const unsigned char **in, long len, char inf)
- {
+{
int expected_eoc;
long plen;
const unsigned char *p = *in, *q;
/* If not indefinite length constructed just add length */
if (inf == 0)
- {
+ {
*in += len;
return 1;
- }
+ }
expected_eoc = 1;
/* Indefinite length constructed form. Find the end when enough EOCs
* are found. If more indefinite length constructed headers
* skip to the end of the data.
*/
while (len > 0)
- {
+ {
if(asn1_check_eoc(&p, len))
- {
+ {
expected_eoc--;
if (expected_eoc == 0)
break;
len -= 2;
continue;
- }
+ }
q = p;
/* Just read in a header: only care about the length */
if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-1, 0, 0, NULL))
- {
+ {
ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
if (inf)
expected_eoc++;
else
p += plen;
len -= p - q;
- }
+ }
if (expected_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
return 0;
- }
+ }
*in = p;
return 1;
- }
+}
/* This function collects the asn1 data from a constructred string
* type into a buffer. The values of 'in' and 'len' should refer
* to the contents of the constructed type and 'inf' should be set
static int asn1_collect(BUF_MEM *buf, 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 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 */
if (asn1_check_eoc(&p, len))
- {
+ {
/* EOC is illegal outside indefinite length
* constructed form */
if (!inf)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT,
ASN1_R_UNEXPECTED_EOC);
return 0;
- }
+ }
inf = 0;
break;
- }
+ }
if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
len, tag, aclass, 0, NULL))
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
/* If indefinite length constructed update max length */
if (cst)
- {
+ {
if (depth >= ASN1_MAX_STRING_NEST)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT,
ASN1_R_NESTED_ASN1_STRING);
return 0;
- }
+ }
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
depth + 1))
return 0;
- }
+ }
else if (plen && !collect_data(buf, &p, plen))
return 0;
len -= p - q;
- }
+ }
if (inf)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
return 0;
- }
+ }
*in = p;
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))
- {
+ {
ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
return 0;
- }
- memcpy(buf->data + len, *p, plen);
}
+ memcpy(buf->data + len, *p, plen);
+ }
*p += plen;
return 1;
- }
+}
/* Check for ASN1 EOC and swallow it if found */
static int asn1_check_eoc(const unsigned char **in, long len)
- {
+{
const unsigned char *p;
if (len < 2) return 0;
p = *in;
if (!p[0] && !p[1])
- {
+ {
*in += 2;
return 1;
- }
- return 0;
}
+ return 0;
+}
/* Check an ASN1 tag and length: a bit like ASN1_get_object
* but it sets the length for indefinite length constructed
const unsigned char **in, long len,
int exptag, int expclass, char opt,
ASN1_TLC *ctx)
- {
+{
int i;
int ptag, pclass;
long plen;
q = p;
if (ctx && ctx->valid)
- {
+ {
i = ctx->ret;
plen = ctx->plen;
pclass = ctx->pclass;
ptag = ctx->ptag;
p += ctx->hdrlen;
- }
+ }
else
- {
+ {
i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
if (ctx)
- {
+ {
ctx->ret = i;
ctx->plen = plen;
ctx->pclass = pclass;
* header can't exceed total amount of data available.
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
- {
+ {
ASN1err(ASN1_F_ASN1_CHECK_TLEN,
ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
return 0;
- }
}
}
+ }
if (i & 0x80)
- {
+ {
ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
return 0;
- }
+ }
if (exptag >= 0)
- {
+ {
if ((exptag != ptag) || (expclass != pclass))
- {
+ {
/* If type is OPTIONAL, not an error:
* indicate missing type.
*/
asn1_tlc_clear(ctx);
ASN1err(ASN1_F_ASN1_CHECK_TLEN, 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);
- }
+ }
if (i & 1)
plen = len - (p - q);
*in = p;
return 1;
- }
+}
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it)
- {
+{
return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
- }
+}
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
- {
+{
return asn1_item_flags_i2d(val, out, it, 0);
- }
+}
/* Encode an ASN1 item, this is use by the
* standard 'i2d' function. 'out' points to
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags)
- {
+{
if (out && !*out)
- {
+ {
unsigned char *p, *buf;
int len;
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
*out = buf;
return len;
- }
+ }
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
- }
+}
/* Encode an item, taking care of IMPLICIT tagging (if any).
* This function performs the normal item handling: it can be
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
- {
+{
const ASN1_TEMPLATE *tt = NULL;
unsigned char *p = NULL;
int i, seqcontlen, seqlen, ndef = 1;
asn1_cb = aux->asn1_cb;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
return 0;
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount))
- {
+ {
ASN1_VALUE **pchval;
const ASN1_TEMPLATE *chtt;
chtt = it->templates + i;
pchval = asn1_get_field_ptr(pval, chtt);
return asn1_template_ex_i2d(pchval, out, chtt,
-1, aclass);
- }
+ }
/* Fixme: error condition if selector out of range */
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
seqcontlen = 0;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if (tag == -1)
- {
+ {
tag = V_ASN1_SEQUENCE;
/* Retain any other flags in aclass */
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
| V_ASN1_UNIVERSAL;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
/* First work out sequence content length */
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
/* FIXME: check for errors in enhanced version */
seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-1, aclass);
- }
+ }
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
if (!out)
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
- }
+ }
if (ndef == 2)
ASN1_put_eoc(out);
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
default:
return 0;
- }
- return 0;
}
+ return 0;
+}
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt)
- {
+{
return asn1_template_ex_i2d(pval, out, tt, -1, 0);
- }
+}
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt, int tag, int iclass)
- {
+{
int i, ret, flags, ttag, tclass, ndef;
flags = tt->flags;
/* Work out tag and class to use: tagging may come
* which should be noted and passed down to other levels.
*/
if (flags & ASN1_TFLG_TAG_MASK)
- {
+ {
/* Error if argument and template tagging */
if (tag != -1)
/* FIXME: error code here */
/* Get tagging from template */
ttag = tt->tag;
tclass = flags & ASN1_TFLG_TAG_CLASS;
- }
+ }
else if (tag != -1)
- {
+ {
/* No template tagging, get from arguments */
ttag = tag;
tclass = iclass & ASN1_TFLG_TAG_CLASS;
- }
+ }
else
- {
+ {
ttag = -1;
tclass = 0;
- }
+ }
/*
* Remove any class mask from iflag.
*/
else ndef = 1;
if (flags & ASN1_TFLG_SK_MASK)
- {
+ {
/* SET OF, SEQUENCE OF */
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
int isset, sktag, skaclass;
return 0;
if (flags & ASN1_TFLG_SET_OF)
- {
+ {
isset = 1;
/* 2 means we reorder */
if (flags & ASN1_TFLG_SEQUENCE_OF)
isset = 2;
- }
+ }
else isset = 0;
/* Work out inner tag value: if EXPLICIT
* or no tagging use underlying type.
*/
if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
- {
+ {
sktag = ttag;
skaclass = tclass;
- }
+ }
else
- {
+ {
skaclass = V_ASN1_UNIVERSAL;
if (isset)
sktag = V_ASN1_SET;
else sktag = V_ASN1_SEQUENCE;
- }
+ }
/* Determine total length of items */
skcontlen = 0;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
ASN1_ITEM_ptr(tt->item),
-1, iclass);
- }
+ }
sklen = ASN1_object_size(ndef, skcontlen, sktag);
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
isset, iclass);
if (ndef == 2)
- {
+ {
ASN1_put_eoc(out);
if (flags & ASN1_TFLG_EXPTAG)
ASN1_put_eoc(out);
- }
+ }
return ret;
- }
+ }
if (flags & ASN1_TFLG_EXPTAG)
- {
+ {
/* EXPLICIT tagging */
/* Find length of tagged item */
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
if (out)
- {
+ {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-1, iclass);
if (ndef == 2)
ASN1_put_eoc(out);
- }
- return ret;
}
+ return ret;
+ }
/* Either normal or IMPLICIT tagging: combine class and flags */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
} DER_ENC;
static int der_cmp(const void *a, const void *b)
- {
+{
const DER_ENC *d1 = a, *d2 = b;
int cmplen, i;
cmplen = (d1->length < d2->length) ? d1->length : d2->length;
if (i)
return i;
return d1->length - d2->length;
- }
+}
/* Output the content octets of SET OF or SEQUENCE OF */
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item,
int do_sort, int iclass)
- {
+{
int i;
ASN1_VALUE *skitem;
unsigned char *tmpdat = NULL, *p = NULL;
if (sk_ASN1_VALUE_num(sk) < 2)
do_sort = 0;
else
- {
+ {
derlst = malloc(sk_ASN1_VALUE_num(sk)
* sizeof(*derlst));
tmpdat = malloc(skcontlen);
free(derlst);
free(tmpdat);
return 0;
- }
}
+ }
/* If not sorting just output each item */
if (!do_sort)
- {
+ {
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
- }
- return 1;
}
+ return 1;
+ }
p = tmpdat;
/* Doing sort: build up a list of each member's DER encoding */
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
tder->data = p;
tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
tder->field = skitem;
- }
+ }
/* Now sort them */
qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
/* Output sorted DER encoding */
p = *out;
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
+ {
memcpy(p, tder->data, tder->length);
p += tder->length;
- }
+ }
*out = p;
/* If do_sort is 2 then reorder the STACK */
if (do_sort == 2)
- {
+ {
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
i++, tder++)
(void)sk_ASN1_VALUE_set(sk, i, tder->field);
- }
+ }
free(derlst);
free(tmpdat);
return 1;
- }
+}
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
- {
+{
int len;
int utype;
int usetag;
/* -2 return is special meaning use ndef */
if (len == -2)
- {
+ {
ndef = 2;
len = 0;
- }
+ }
/* If not implicitly tagged get tag from underlying type */
if (tag == -1) tag = utype;
/* Output tag+length followed by content octets */
if (out)
- {
+ {
if (usetag)
ASN1_put_object(out, ndef, len, tag, aclass);
asn1_ex_i2c(pval, *out, &utype, it);
ASN1_put_eoc(out);
else
*out += len;
- }
+ }
if (usetag)
return ASN1_object_size(ndef, len, tag);
return len;
- }
+}
/* Produce content octets from a structure */
int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
const ASN1_ITEM *it)
- {
+{
ASN1_BOOLEAN *tbool = NULL;
ASN1_STRING *strtmp;
ASN1_OBJECT *otmp;
/* Should type be omitted? */
if ((it->itype != ASN1_ITYPE_PRIMITIVE)
|| (it->utype != V_ASN1_BOOLEAN))
- {
+ {
if (!*pval) return -1;
- }
+ }
if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
/* If MSTRING type set the underlying type */
strtmp = (ASN1_STRING *)*pval;
utype = strtmp->type;
*putype = utype;
- }
+ }
else if (it->utype == V_ASN1_ANY)
- {
+ {
/* If ANY set type and pointer to value */
ASN1_TYPE *typ;
typ = (ASN1_TYPE *)*pval;
utype = typ->type;
*putype = utype;
pval = &typ->value.asn1_value;
- }
+ }
else utype = *putype;
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
otmp = (ASN1_OBJECT *)*pval;
cont = otmp->data;
if (*tbool == -1)
return -1;
if (it->utype != V_ASN1_ANY)
- {
+ {
/* Default handling if value == size field then omit */
if (*tbool && (it->size > 0))
return -1;
if (!*tbool && !it->size)
return -1;
- }
+ }
c = (unsigned char)*tbool;
cont = &c;
len = 1;
/* Special handling for NDEF */
if ((it->size == ASN1_TFLG_NDEF)
&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
- {
+ {
if (cout)
- {
+ {
strtmp->data = cout;
strtmp->length = 0;
- }
+ }
/* Special return code */
return -2;
- }
+ }
cont = strtmp->data;
len = strtmp->length;
break;
- }
+ }
if (cout && len)
memcpy(cout, cont, len);
return len;
- }
+}
/* Free up an ASN1 structure */
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
- {
+{
asn1_item_combine_free(&val, it, 0);
- }
+}
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
asn1_item_combine_free(pval, it, 0);
- }
+}
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
- {
+{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_COMPAT_FUNCS *cf;
asn1_cb = 0;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
- }
+ }
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount))
- {
+ {
ASN1_VALUE **pchval;
tt = it->templates + i;
pchval = asn1_get_field_ptr(pval, tt);
ASN1_template_free(pchval, tt);
- }
+ }
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
- {
+ {
free(*pval);
*pval = NULL;
- }
+ }
break;
case ASN1_ITYPE_COMPAT:
if (asn1_do_lock(pval, -1, it) > 0)
return;
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
- }
+ }
asn1_enc_free(pval, it);
/* If we free up as normal we will invalidate any
* ANY DEFINED BY field and we wont be able to
*/
tt = it->templates + it->tcount - 1;
for (i = 0; i < it->tcount; tt--, i++)
- {
+ {
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 0);
if (!seqtt)
continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
- }
+ }
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
- {
+ {
free(*pval);
*pval = NULL;
- }
- break;
}
+ break;
}
+}
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
int i;
if (tt->flags & ASN1_TFLG_SK_MASK)
- {
+ {
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
ASN1_VALUE *vtmp;
vtmp = sk_ASN1_VALUE_value(sk, i);
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
0);
- }
+ }
sk_ASN1_VALUE_free(sk);
*pval = NULL;
- }
+ }
else
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
tt->flags & ASN1_TFLG_COMBINE);
- }
+}
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int utype;
if (it)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_free)
- {
+ {
pf->prim_free(pval, it);
return;
- }
}
+ }
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
if (!it)
- {
+ {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
- }
+ }
else if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
utype = -1;
if (!*pval)
return;
- }
+ }
else
- {
+ {
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
- }
+ }
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
break;
ASN1_STRING_free((ASN1_STRING *)*pval);
*pval = NULL;
break;
- }
- *pval = NULL;
}
+ *pval = NULL;
+}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
- {
+{
ASN1_VALUE *ret = NULL;
if (ASN1_item_ex_new(&ret, it) > 0)
return ret;
return NULL;
- }
+}
/* Allocate an ASN1 structure */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
return asn1_item_ex_combine_new(pval, it, 0);
- }
+}
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine)
- {
+{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
#endif
switch(it->itype)
- {
+ {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_new)
- {
+ {
if (!ef->asn1_ex_new(pval, it))
goto memerr;
- }
+ }
break;
case ASN1_ITYPE_COMPAT:
*pval = cf->asn1_new();
if (!*pval)
goto memerr;
- }
+ }
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
- {
+ {
if (!ASN1_template_new(pval, it->templates))
goto memerr;
- }
+ }
else if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
- {
+ {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
- }
}
+ }
if (!combine)
- {
+ {
*pval = malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
- }
+ }
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
- {
+ {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
- }
}
+ }
if (!combine)
- {
+ {
*pval = malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
asn1_do_lock(pval, 0, it);
asn1_enc_init(pval, it);
- }
+ }
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
- }
+}
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
#endif
#endif
return 0;
- }
+}
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
const ASN1_EXTERN_FUNCS *ef;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
- }
}
+}
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
int ret;
if (tt->flags & ASN1_TFLG_OPTIONAL)
- {
+ {
asn1_template_clear(pval, tt);
return 1;
- }
+ }
/* If ANY DEFINED BY nothing to do */
if (tt->flags & ASN1_TFLG_ADB_MASK)
- {
+ {
*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;
skval = sk_ASN1_VALUE_new_null();
if (!skval)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
- }
+ }
*pval = (ASN1_VALUE *)skval;
ret = 1;
goto done;
- }
+ }
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
CRYPTO_pop_info();
#endif
return ret;
- }
+}
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
/* If ADB or STACK just NULL the field */
if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
*pval = NULL;
else
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
- }
+}
/* NB: could probably combine most of the real XXX_new() behaviour and junk
*/
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_TYPE *typ;
ASN1_STRING *str;
int utype;
if (it && it->funcs)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
- }
+ }
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
utype = it->utype;
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
return 1;
str->flags |= ASN1_STRING_FLAG_MSTRING;
*pval = (ASN1_VALUE *)str;
break;
- }
+ }
if (*pval)
return 1;
return 0;
- }
+}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int utype;
if (it && it->funcs)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_clear)
pf->prim_clear(pval, it);
else
*pval = NULL;
return;
- }
+ }
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else *pval = NULL;
- }
+}
/* ASN1_PCTX routines */
ASN1_PCTX default_pctx =
- {
+{
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
0, /* cert_flags */
0, /* oid_flags */
0 /* str_flags */
- };
+};
ASN1_PCTX *ASN1_PCTX_new(void)
- {
+{
ASN1_PCTX *ret;
ret = malloc(sizeof(ASN1_PCTX));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_PCTX_NEW, 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;
- }
+}
void ASN1_PCTX_free(ASN1_PCTX *p)
- {
+{
free(p);
- }
+}
unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
- {
+{
return p->flags;
- }
+}
void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
- {
+{
return p->nm_flags;
- }
+}
void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->nm_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
- {
+{
return p->cert_flags;
- }
+}
void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->cert_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
- {
+{
return p->oid_flags;
- }
+}
void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->oid_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
- {
+{
return p->str_flags;
- }
+}
void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->str_flags = flags;
- }
+}
/* Main print routines */
int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
const ASN1_ITEM *it, const ASN1_PCTX *pctx)
- {
+{
const char *sname;
if (pctx == NULL)
pctx = &default_pctx;
sname = it->sname;
return asn1_item_print_ctx(out, &ifld, indent, it,
NULL, sname, 0, pctx);
- }
+}
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_ITEM *it,
const char *fname, const char *sname,
int nohdr, const ASN1_PCTX *pctx)
- {
+{
const ASN1_TEMPLATE *tt;
const ASN1_EXTERN_FUNCS *ef;
ASN1_VALUE **tmpfld;
ASN1_PRINT_ARG parg;
int i;
if (aux && aux->asn1_cb)
- {
+ {
parg.out = out;
parg.indent = indent;
parg.pctx = pctx;
asn1_cb = aux->asn1_cb;
- }
+ }
else asn1_cb = 0;
if(*fld == NULL)
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
- {
+ {
if (!nohdr && !asn1_print_fsname(out, indent,
fname, sname, pctx))
return 0;
if (BIO_puts(out, "<ABSENT>\n") <= 0)
return 0;
- }
- return 1;
}
+ return 1;
+ }
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if(it->templates)
- {
+ {
if (!asn1_template_print_ctx(out, fld, indent,
it->templates, pctx))
return 0;
- }
+ }
/* fall thru */
case ASN1_ITYPE_MSTRING:
if (!asn1_primitive_print(out, fld, it,
/* Use new style print routine if possible */
ef = it->funcs;
if (ef && ef->asn1_ex_print)
- {
+ {
i = ef->asn1_ex_print(out, fld, indent, "", pctx);
if (!i)
return 0;
if ((i == 2) && (BIO_puts(out, "\n") <= 0))
return 0;
return 1;
- }
+ }
else if (sname &&
BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
return 0;
i = asn1_get_choice_selector(fld, it);
/* This should never happen... */
if((i < 0) || (i >= it->tcount))
- {
+ {
if (BIO_printf(out,
"ERROR: selector [%d] invalid\n", i) <= 0)
return 0;
return 1;
- }
+ }
tt = it->templates + i;
tmpfld = asn1_get_field_ptr(fld, tt);
if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (fname || sname)
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_puts(out, " {\n") <= 0)
return 0;
- }
+ }
else
- {
+ {
if (BIO_puts(out, "\n") <= 0)
return 0;
- }
}
+ }
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
- }
+ }
/* Print each field entry */
for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(fld, tt, 1);
tmpfld = asn1_get_field_ptr(fld, seqtt);
if (!asn1_template_print_ctx(out, tmpfld,
indent + 2, seqtt, pctx))
return 0;
- }
+ }
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_printf(out, "%*s}\n", indent, "") < 0)
return 0;
- }
+ }
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
- }
+ }
break;
default:
BIO_printf(out, "Unprocessed type %d\n", it->itype);
return 0;
- }
+ }
return 1;
- }
+}
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
- {
+{
int i, flags;
const char *sname, *fname;
flags = tt->flags;
else
fname = tt->field_name;
if(flags & ASN1_TFLG_SK_MASK)
- {
+ {
char *tname;
ASN1_VALUE *skitem;
STACK_OF(ASN1_VALUE) *stack;
/* SET OF, SEQUENCE OF */
if (fname)
- {
+ {
if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
- {
+ {
if(flags & ASN1_TFLG_SET_OF)
tname = "SET";
else
if (BIO_printf(out, "%*s%s OF %s {\n",
indent, "", tname, tt->field_name) <= 0)
return 0;
- }
+ }
else if (BIO_printf(out, "%*s%s:\n", indent, "",
fname) <= 0)
return 0;
- }
+ }
stack = (STACK_OF(ASN1_VALUE) *)*fld;
for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
- {
+ {
if ((i > 0) && (BIO_puts(out, "\n") <= 0))
return 0;
if (!asn1_item_print_ctx(out, &skitem, indent + 2,
ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
return 0;
- }
+ }
if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
return 0;
if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
return 0;
- }
- return 1;
}
+ return 1;
+ }
return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
fname, sname, 0, pctx);
- }
+}
static int asn1_print_fsname(BIO *out, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
- {
+{
static char spaces[] = " ";
const int nspaces = sizeof(spaces) - 1;
#endif
while (indent > nspaces)
- {
+ {
if (BIO_write(out, spaces, nspaces) != nspaces)
return 0;
indent -= nspaces;
- }
+ }
if (BIO_write(out, spaces, indent) != indent)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
if (!sname && !fname)
return 1;
if (fname)
- {
+ {
if (BIO_puts(out, fname) <= 0)
return 0;
- }
+ }
if (sname)
- {
+ {
if (fname)
- {
+ {
if (BIO_printf(out, " (%s)", sname) <= 0)
return 0;
- }
+ }
else
- {
+ {
if (BIO_puts(out, sname) <= 0)
return 0;
- }
}
+ }
if (BIO_write(out, ": ", 2) != 2)
return 0;
return 1;
- }
+}
static int asn1_print_boolean_ctx(BIO *out, int boolval,
const ASN1_PCTX *pctx)
- {
+{
const char *str;
switch (boolval)
- {
+ {
case -1:
str = "BOOL ABSENT";
break;
str = "TRUE";
break;
- }
+ }
if (BIO_puts(out, str) <= 0)
return 0;
return 1;
- }
+}
static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
const ASN1_PCTX *pctx)
- {
+{
char *s;
int ret = 1;
s = i2s_ASN1_INTEGER(NULL, str);
ret = 0;
free(s);
return ret;
- }
+}
static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
const ASN1_PCTX *pctx)
- {
+{
char objbuf[80];
const char *ln;
ln = OBJ_nid2ln(OBJ_obj2nid(oid));
if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
return 0;
return 1;
- }
+}
static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
const ASN1_PCTX *pctx)
- {
+{
if (str->type == V_ASN1_BIT_STRING)
- {
+ {
if (BIO_printf(out, " (%ld unused bits)\n",
str->flags & 0x7) <= 0)
return 0;
- }
+ }
else if (BIO_puts(out, "\n") <= 0)
return 0;
if ((str->length > 0)
indent + 2) <= 0)
return 0;
return 1;
- }
+}
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
const ASN1_ITEM *it, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
- {
+{
long utype;
ASN1_STRING *str;
int ret = 1, needlf = 1;
else
utype = it->utype;
if (utype == V_ASN1_ANY)
- {
+ {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
fld = &atype->value.asn1_value;
pname = NULL;
else
pname = ASN1_tag2str(utype);
- }
+ }
else
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
pname = ASN1_tag2str(utype);
else
pname = NULL;
- }
+ }
if (utype == V_ASN1_NULL)
- {
+ {
if (BIO_puts(out, "NULL\n") <= 0)
return 0;
return 1;
- }
+ }
if (pname)
- {
+ {
if (BIO_puts(out, pname) <= 0)
return 0;
if (BIO_puts(out, ":") <= 0)
return 0;
- }
+ }
switch (utype)
- {
+ {
case V_ASN1_BOOLEAN:
- {
+ {
int boolval = *(int *)fld;
if (boolval == -1)
boolval = it->size;
ret = asn1_print_boolean_ctx(out, boolval, pctx);
- }
+ }
break;
case V_ASN1_INTEGER:
default:
ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
- }
+ }
if (!ret)
return 0;
if (needlf && BIO_puts(out, "\n") <= 0)
return 0;
return 1;
- }
+}
*/
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int *sel = offset2ptr(*pval, it->utype);
return *sel;
- }
+}
/* Given an ASN1_ITEM CHOICE type set
* the selector value, return old value.
*/
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
- {
+{
int *sel, ret;
sel = offset2ptr(*pval, it->utype);
ret = *sel;
*sel = value;
return ret;
- }
+}
/* Do reference counting. The value 'op' decides what to do.
* if it is +1 then the count is incremented. If op is 0 count is
*/
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
- {
+{
const ASN1_AUX *aux;
int *lck, ret;
if ((it->itype != ASN1_ITYPE_SEQUENCE)
return 0;
lck = offset2ptr(*pval, aux->ref_offset);
if (op == 0)
- {
+ {
*lck = 1;
return 1;
- }
+ }
ret = CRYPTO_add(lck, op, aux->ref_lock);
return ret;
- }
+}
static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
const ASN1_AUX *aux;
if (!pval || !*pval)
return NULL;
if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
return NULL;
return offset2ptr(*pval, aux->enc_offset);
- }
+}
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc)
- {
+ {
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
- }
}
+}
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc)
- {
+ {
if (enc->enc)
free(enc->enc);
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
- }
}
+}
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc)
enc->modified = 0;
return 1;
- }
+}
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc || enc->modified)
return 0;
if (out)
- {
+ {
memcpy(*out, enc->enc, enc->len);
*out += enc->len;
- }
+ }
if (len)
*len = enc->len;
return 1;
- }
+}
/* Given an ASN1_TEMPLATE get a pointer to a field */
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
ASN1_VALUE **pvaltmp;
if (tt->flags & ASN1_TFLG_COMBINE)
return pval;
* (int *).
*/
return pvaltmp;
- }
+}
/* Handle ANY DEFINED BY template, find the selector, look up
* the relevant ASN1_TEMPLATE in the table and return it.
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
int nullerr)
- {
+{
const ASN1_ADB *adb;
const ASN1_ADB_TABLE *atbl;
long selector;
/* Check if NULL */
if (!sfld)
- {
+ {
if (!adb->null_tt)
goto err;
return adb->null_tt;
- }
+ }
/* Convert type to a long:
* NB: don't check for NID_undef here because it
ASN1err(ASN1_F_ASN1_DO_ADB,
ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
- }
+}
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
- {
+{
if (!alg)
return 0;
if (ptype != V_ASN1_UNDEF)
- {
+ {
if (alg->parameter == NULL)
alg->parameter = ASN1_TYPE_new();
if (alg->parameter == NULL)
return 0;
- }
+ }
if (alg)
- {
+ {
if (alg->algorithm)
ASN1_OBJECT_free(alg->algorithm);
alg->algorithm = aobj;
- }
+ }
if (ptype == 0)
return 1;
if (ptype == V_ASN1_UNDEF)
- {
+ {
if (alg->parameter)
- {
+ {
ASN1_TYPE_free(alg->parameter);
alg->parameter = NULL;
- }
}
+ }
else
ASN1_TYPE_set(alg->parameter, ptype, pval);
return 1;
- }
+}
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor)
- {
+{
if (paobj)
*paobj = algor->algorithm;
if (pptype)
- {
+ {
if (algor->parameter == NULL)
- {
+ {
*pptype = V_ASN1_UNDEF;
return;
- }
+ }
else
*pptype = algor->parameter->type;
if (ppval)
*ppval = algor->parameter->value.ptr;
- }
}
+}
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
- {
+{
int param_type;
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
- }
+}
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
- {
+{
X509_ATTRIBUTE *ret=NULL;
ASN1_TYPE *val=NULL;
if (ret != NULL) X509_ATTRIBUTE_free(ret);
if (val != NULL) ASN1_TYPE_free(val);
return(NULL);
- }
+}
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
static X509_CRL_METHOD int_crl_meth =
- {
+{
0,
0,0,
def_crl_lookup,
def_crl_verify
- };
+};
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
case ASN1_OP_D2I_POST:
(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
break;
- }
+}
return 1;
}
*/
static int crl_set_issuers(X509_CRL *crl)
- {
+{
int i, j;
GENERAL_NAMES *gens, *gtmp;
gens = NULL;
for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
- {
+ {
X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
STACK_OF(X509_EXTENSION) *exts;
ASN1_ENUMERATED *reason;
NID_certificate_issuer,
&j, NULL);
if (!gtmp && (j != -1))
- {
+ {
crl->flags |= EXFLAG_INVALID;
return 1;
- }
+ }
if (gtmp)
- {
+ {
gens = gtmp;
if (!crl->issuers)
- {
+ {
crl->issuers = sk_GENERAL_NAMES_new_null();
if (!crl->issuers)
return 0;
- }
+ }
if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
return 0;
- }
+ }
rev->issuer = gens;
reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
&j, NULL);
if (!reason && (j != -1))
- {
+ {
crl->flags |= EXFLAG_INVALID;
return 1;
- }
+ }
if (reason)
- {
+ {
rev->reason = ASN1_ENUMERATED_get(reason);
ASN1_ENUMERATED_free(reason);
- }
+ }
else
rev->reason = CRL_REASON_NONE;
exts = rev->extensions;
for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
- {
+ {
ext = sk_X509_EXTENSION_value(exts, j);
if (ext->critical > 0)
- {
+ {
if (OBJ_obj2nid(ext->object) ==
NID_certificate_issuer)
continue;
crl->flags |= EXFLAG_CRITICAL;
break;
- }
}
+ }
- }
+ }
return 1;
- }
+}
/* The X509_CRL structure needs a bit of customisation. Cache some extensions
* and hash of the whole CRL.
*/
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
- {
+{
X509_CRL *crl = (X509_CRL *)*pval;
STACK_OF(X509_EXTENSION) *exts;
X509_EXTENSION *ext;
int idx;
switch(operation)
- {
+ {
case ASN1_OP_NEW_POST:
crl->idp = NULL;
crl->akid = NULL;
exts = crl->crl->extensions;
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
- {
+ {
int nid;
ext = sk_X509_EXTENSION_value(exts, idx);
nid = OBJ_obj2nid(ext->object);
if (nid == NID_freshest_crl)
crl->flags |= EXFLAG_FRESHEST;
if (ext->critical > 0)
- {
+ {
/* We handle IDP and deltas */
if ((nid == NID_issuing_distribution_point)
|| (nid == NID_delta_crl))
break;;
crl->flags |= EXFLAG_CRITICAL;
break;
- }
}
+ }
if (!crl_set_issuers(crl))
return 0;
if (crl->meth->crl_init)
- {
+ {
if (crl->meth->crl_init(crl) == 0)
return 0;
- }
+ }
break;
case ASN1_OP_FREE_POST:
if (crl->meth->crl_free)
- {
+ {
if (!crl->meth->crl_free(crl))
return 0;
- }
+ }
if (crl->akid)
AUTHORITY_KEYID_free(crl->akid);
if (crl->idp)
ASN1_INTEGER_free(crl->base_crl_number);
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
break;
- }
- return 1;
}
+ return 1;
+}
/* Convert IDP into a more convenient form */
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
- {
+{
int idp_only = 0;
/* Set various flags according to IDP */
crl->idp_flags |= IDP_PRESENT;
if (idp->onlyuser > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYUSER;
- }
+ }
if (idp->onlyCA > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYCA;
- }
+ }
if (idp->onlyattr > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYATTR;
- }
+ }
if (idp_only > 1)
crl->idp_flags |= IDP_INVALID;
crl->idp_flags |= IDP_INDIRECT;
if (idp->onlysomereasons)
- {
+ {
crl->idp_flags |= IDP_REASONS;
if (idp->onlysomereasons->length > 0)
crl->idp_reasons = idp->onlysomereasons->data[0];
crl->idp_reasons |=
(idp->onlysomereasons->data[1] << 8);
crl->idp_reasons &= CRLDP_ALL_REASONS;
- }
+ }
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
- }
+}
ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b)
- {
+{
return(ASN1_STRING_cmp(
(ASN1_STRING *)(*a)->serialNumber,
(ASN1_STRING *)(*b)->serialNumber));
- }
+}
int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
{
if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
return 0;
- }
+}
inf->enc.modified = 1;
return 1;
}
int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
- {
+{
if (crl->meth->crl_verify)
return crl->meth->crl_verify(crl, r);
return 0;
- }
+}
int X509_CRL_get0_by_serial(X509_CRL *crl,
X509_REVOKED **ret, ASN1_INTEGER *serial)
- {
+{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret, serial, NULL);
return 0;
- }
+}
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
- {
+{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret,
X509_get_serialNumber(x),
X509_get_issuer_name(x));
return 0;
- }
+}
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
- {
+{
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
crl->sig_alg, crl->signature,crl->crl,r));
- }
+}
static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
X509_REVOKED *rev)
- {
+{
int i;
if (!rev->issuer)
- {
+ {
if (!nm)
return 1;
if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
return 1;
return 0;
- }
+ }
if (!nm)
nm = X509_CRL_get_issuer(crl);
for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
- {
+ {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
if (gen->type != GEN_DIRNAME)
continue;
if (!X509_NAME_cmp(nm, gen->d.directoryName))
return 1;
- }
+ }
return 0;
- }
+}
static int def_crl_lookup(X509_CRL *crl,
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
- {
+{
X509_REVOKED rtmp, *rev;
int idx;
rtmp.serialNumber = serial;
* Do this under a lock to avoid race condition.
*/
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
- {
+ {
CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
sk_X509_REVOKED_sort(crl->crl->revoked);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
- }
+ }
idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
if(idx < 0)
return 0;
/* Need to look for matching name */
for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
- {
+ {
rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
return 0;
if (crl_revoked_issuer_match(crl, issuer, rev))
- {
+ {
if (ret)
*ret = rev;
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
return 2;
return 1;
- }
}
- return 0;
}
+ return 0;
+}
void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
- {
+{
if (meth == NULL)
default_crl_method = &int_crl_meth;
else
default_crl_method = meth;
- }
+}
X509_CRL_METHOD *X509_CRL_METHOD_new(
int (*crl_init)(X509_CRL *crl),
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *ser, X509_NAME *issuer),
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
- {
+{
X509_CRL_METHOD *m;
m = malloc(sizeof(X509_CRL_METHOD));
if (!m)
m->crl_verify = crl_verify;
m->flags = X509_CRL_METHOD_DYNAMIC;
return m;
- }
+}
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
- {
+{
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
return;
free(m);
- }
+}
void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
- {
+{
crl->meth_data = dat;
- }
+}
void *X509_CRL_get_meth_data(X509_CRL *crl)
- {
+{
return crl->meth_data;
- }
+}
IMPLEMENT_STACK_OF(X509_REVOKED)
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
#include <openssl/x509.h>
X509_INFO *X509_INFO_new(void)
- {
+{
X509_INFO *ret=NULL;
ret=(X509_INFO *)malloc(sizeof(X509_INFO));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_X509_INFO_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
ret->enc_cipher.cipher=NULL;
ret->enc_len=0;
ret->crl=NULL;
ret->x_pkey=NULL;
return(ret);
- }
+}
void X509_INFO_free(X509_INFO *x)
- {
+{
int i;
if (x == NULL) return;
if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
if (x->enc_data != NULL) free(x->enc_data);
free(x);
- }
+}
IMPLEMENT_STACK_OF(X509_INFO)
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx)
- {
+{
return BIO_printf(out, "%ld\n", *(long *)pval);
- }
+}
memerr:
ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
if (ret)
- {
+ {
if (ret->entries)
sk_X509_NAME_ENTRY_free(ret->entries);
free(ret);
- }
+ }
return 0;
}
/* need to implement */
int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
- {
+{
return(0);
- }
+}
X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
- {
+{
int i;
M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new);
ret->cipher.cipher=EVP_get_cipherbyname(
OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm)));
if (ret->cipher.cipher == NULL)
- {
+ {
c.error=ASN1_R_UNSUPPORTED_CIPHER;
c.line=__LINE__;
goto err;
- }
+ }
if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING)
- {
+ {
i=ret->enc_algor->parameter->value.octet_string->length;
if (i > EVP_MAX_IV_LENGTH)
- {
+ {
c.error=ASN1_R_IV_TOO_LARGE;
c.line=__LINE__;
goto err;
- }
+ }
memcpy(ret->cipher.iv,
ret->enc_algor->parameter->value.octet_string->data,i);
- }
+ }
else
memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
M_ASN1_D2I_Finish(a,X509_PKEY_free,ASN1_F_D2I_X509_PKEY);
- }
+}
X509_PKEY *X509_PKEY_new(void)
- {
+{
X509_PKEY *ret=NULL;
ASN1_CTX c;
ret->references=1;
return(ret);
M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
- }
+}
void X509_PKEY_free(X509_PKEY *x)
- {
+{
int i;
if (x == NULL) return;
if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
if ((x->key_data != NULL) && (x->key_free)) free(x->key_data);
free(x);
- }
+}
/* Minor tweak to operation: free up EVP_PKEY */
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
- {
+{
if (operation == ASN1_OP_FREE_POST)
- {
+ {
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
EVP_PKEY_free(pubkey->pkey);
- }
- return 1;
}
+ return 1;
+}
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
- {
+{
X509_PUBKEY *pk=NULL;
if (x == NULL) return(0);
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
if (pkey->ameth)
- {
+ {
if (pkey->ameth->pub_encode)
- {
+ {
if (!pkey->ameth->pub_encode(pk, pkey))
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,
X509_R_PUBLIC_KEY_ENCODE_ERROR);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,
X509_R_METHOD_NOT_SUPPORTED);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
goto error;
- }
+ }
if (*x != NULL)
X509_PUBKEY_free(*x);
error:
if (pk != NULL) X509_PUBKEY_free(pk);
return 0;
- }
+}
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
- {
+{
EVP_PKEY *ret=NULL;
if (key == NULL) goto error;
if (key->pkey != NULL)
- {
+ {
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
return key->pkey;
- }
+ }
if (key->public_key == NULL) goto error;
if ((ret = EVP_PKEY_new()) == NULL)
- {
+ {
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
goto error;
- }
+ }
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
- {
+ {
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
goto error;
- }
+ }
if (ret->ameth->pub_decode)
- {
+ {
if (!ret->ameth->pub_decode(ret, key))
- {
+ {
X509err(X509_F_X509_PUBKEY_GET,
X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
goto error;
- }
+ }
/* Check to see if another thread set key->pkey first */
CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
if (key->pkey)
- {
+ {
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
EVP_PKEY_free(ret);
ret = key->pkey;
- }
+ }
else
- {
+ {
key->pkey = ret;
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
- }
+ }
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ret;
if (ret != NULL)
EVP_PKEY_free(ret);
return(NULL);
- }
+}
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
* and encode or decode as X509_PUBKEY
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
long length)
- {
+{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
xpk = d2i_X509_PUBKEY(NULL, pp, length);
X509_PUBKEY_free(xpk);
if(!pktmp) return NULL;
if(a)
- {
+ {
EVP_PKEY_free(*a);
*a = pktmp;
- }
- return pktmp;
}
+ return pktmp;
+}
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
- {
+{
X509_PUBKEY *xpk=NULL;
int ret;
if(!a) return 0;
ret = i2d_X509_PUBKEY(xpk, pp);
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)
- {
+{
EVP_PKEY *pkey;
RSA *key;
const unsigned char *q;
if (!key) return NULL;
*pp = q;
if (a)
- {
+ {
RSA_free(*a);
*a = key;
- }
- return key;
}
+ return key;
+}
int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if (!a) return 0;
pktmp = EVP_PKEY_new();
if (!pktmp)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
EVP_PKEY_set1_RSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
- }
+}
#endif
#ifndef OPENSSL_NO_DSA
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
long length)
- {
+{
EVP_PKEY *pkey;
DSA *key;
const unsigned char *q;
if (!key) return NULL;
*pp = q;
if (a)
- {
+ {
DSA_free(*a);
*a = key;
- }
- return key;
}
+ return key;
+}
int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if(!a) return 0;
pktmp = EVP_PKEY_new();
if(!pktmp)
- {
+ {
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
EVP_PKEY_set1_DSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
- }
+}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
- {
+{
EVP_PKEY *pkey;
EC_KEY *key;
const unsigned char *q;
if (!key) return(NULL);
*pp = q;
if (a)
- {
+ {
EC_KEY_free(*a);
*a = key;
- }
- return(key);
}
+ return(key);
+}
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
return(0);
- }
+ }
EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return(ret);
- }
+}
#endif
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
int ptype, void *pval,
unsigned char *penc, int penclen)
- {
+{
if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
return 0;
if (penc)
- {
+ {
if (pub->public_key->data)
free(pub->public_key->data);
pub->public_key->data = penc;
/* Set number of unused bits to zero */
pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
- }
- return 1;
}
+ return 1;
+}
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
X509_PUBKEY *pub)
- {
+{
if (ppkalg)
*ppkalg = pub->algor->algorithm;
if (pk)
- {
+ {
*pk = pub->public_key->data;
*ppklen = pub->public_key->length;
- }
+ }
if (pa)
*pa = pub->algor;
return 1;
- }
+}
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
- {
+{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
new_func, dup_func, free_func);
- }
+}
int X509_set_ex_data(X509 *r, int idx, void *arg)
- {
+{
return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
- }
+}
void *X509_get_ex_data(X509 *r, int idx)
- {
+{
return(CRYPTO_get_ex_data(&r->ex_data,idx));
- }
+}
/* X509_AUX ASN1 routines. X509_AUX is the name given to
* a certificate with extra info tagged on the end. Since these
{
X509_CERT_AUX *aux;
if (!name)
- {
+ {
if (!x || !x->aux || !x->aux->alias)
return 1;
ASN1_UTF8STRING_free(x->aux->alias);
x->aux->alias = NULL;
return 1;
- }
+ }
if(!(aux = aux_get(x))) return 0;
if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
return ASN1_STRING_set(aux->alias, name, len);
{
X509_CERT_AUX *aux;
if (!id)
- {
+ {
if (!x || !x->aux || !x->aux->keyid)
return 1;
ASN1_OCTET_STRING_free(x->aux->keyid);
x->aux->keyid = NULL;
return 1;
- }
+ }
if(!(aux = aux_get(x))) return 0;
if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
return ASN1_STRING_set(aux->keyid, id, len);
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;
return 0;
free(str);
return(1);
- }
+}
#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;
i=i2d(x,NULL);
b=malloc(i+10);
if (b == NULL)
- { ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+ {
+ ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL);
+ }
p= b;
i=i2d(x,&p);
p2= b;
ret=d2i(NULL,&p2,i);
free(b);
return(ret);
- }
+}
#endif
*/
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
- {
+{
unsigned char *b = NULL;
const unsigned char *p;
long i;
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
- { ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
+ {
+ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL);
+ }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
free(b);
return(ret);
- }
+}
*/
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
- {
+{
int j,k;
unsigned int i;
unsigned char buf[sizeof(long)+1];
a->type=V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long)+1))
- {
+ {
if (a->data != NULL)
free(a->data);
if ((a->data=(unsigned char *)malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
- }
+ }
if (a->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE);
return(0);
- }
+ }
d=v;
if (d < 0)
- {
+ {
d= -d;
a->type=V_ASN1_NEG_ENUMERATED;
- }
+ }
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);
- }
+}
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
- {
+{
int neg=0,i;
long r=0;
return -1;
if (a->length > (int)sizeof(long))
- {
+ {
/* hmm... a bit ugly */
return(0xffffffffL);
- }
+ }
if (a->data == NULL)
return 0;
for (i=0; i<a->length; i++)
- {
+ {
r<<=8;
r|=(unsigned char)a->data[i];
- }
+ }
if (neg) r= -r;
return(r);
- }
+}
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
- {
+{
ASN1_ENUMERATED *ret;
int len,j;
else
ret=ai;
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
else ret->type=V_ASN1_ENUMERATED;
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)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
goto err;
- }
- ret->data=new_data;
}
+ ret->data=new_data;
+ }
ret->length=BN_bn2bin(bn,ret->data);
return(ret);
err:
if (ret != ai) M_ASN1_ENUMERATED_free(ret);
return(NULL);
- }
+}
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
- {
+{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
- }
+}
#if 0
int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
- {
+{
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
- }
+}
ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
unsigned char **pp, long length)
- {
+{
ASN1_GENERALIZEDTIME *ret=NULL;
ret=(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
return(NULL);
- }
+ }
if (!ASN1_GENERALIZEDTIME_check(ret))
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
goto err;
- }
+ }
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_GENERALIZEDTIME_free(ret);
return(NULL);
- }
+}
#endif
int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
- {
+{
static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[9]={99, 99,12,31,23,59,59,12,59};
char *a;
*/
if (l < 13) goto err;
for (i=0; i<7; i++)
- {
+ {
if ((i == 6) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
- { i++; break; }
+ { i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (++o > l) goto err;
if ((n < min[i]) || (n > max[i])) goto err;
- }
+ }
/* Optional fractional seconds: decimal point followed by one
* or more digits.
*/
if (a[o] == '.')
- {
+ {
if (++o > l) goto err;
i = o;
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
o++;
/* Must have at least one digit after decimal point */
if (i == o) goto err;
- }
+ }
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
- {
+ {
o++;
if (o+4 > l) goto err;
for (i=7; i<9; i++)
- {
+ {
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
o++;
- }
}
+ }
else
- {
+ {
/* Missing time zone information. */
goto err;
- }
+ }
return(o == l);
err:
return(0);
- }
+}
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
- {
+{
ASN1_GENERALIZEDTIME t;
t.type=V_ASN1_GENERALIZEDTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_GENERALIZEDTIME_check(&t))
- {
+ {
if (s != NULL)
- {
+ {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type=V_ASN1_GENERALIZEDTIME;
- }
- return(1);
}
+ return(1);
+ }
else
return(0);
- }
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
time_t t)
- {
+{
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
- }
+}
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
time_t t, int offset_day, long offset_sec)
- {
+{
char *p;
struct tm *ts;
struct tm data;
return(NULL);
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
- {
+ {
p=malloc(len);
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
if (s->data != NULL)
free(s->data);
s->data=(unsigned char *)p;
- }
+ }
(void) snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_GENERALIZEDTIME;
return(s);
- }
+}
#ifndef OPENSSL_NO_FP_API
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_I2D_FP,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);
- }
+}
#endif
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=(char *)malloc(n);
if (b == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_I2D_BIO,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
#ifndef OPENSSL_NO_FP_API
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,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);
- }
+}
#endif
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,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);
- }
+}
{ return M_ASN1_INTEGER_dup(x);}
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
- {
+{
int neg, ret;
/* Compare signs */
neg = x->type & V_ASN1_NEG;
if (neg != (y->type & V_ASN1_NEG))
- {
+ {
if (neg)
return -1;
else
return 1;
- }
+ }
ret = ASN1_STRING_cmp(x, y);
return -ret;
else
return ret;
- }
+}
/*
*/
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
- {
+{
int pad=0,ret,i,neg;
unsigned char *p,*n,pb=0;
if (a->length == 0)
ret=1;
else
- {
+ {
ret=a->length;
i=a->data[0];
if (!neg && (i > 127)) {
pad=1;
pb=0;
- } else if(neg) {
+ } else if(neg) {
if(i>128) {
pad=1;
pb=0xFF;
- } else if(i == 128) {
+ } else if(i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
pad=1;
pb=0xFF;
break;
- }
}
}
+ }
ret+=pad;
- }
+ }
if (pp == NULL) return(ret);
p= *pp;
*(p--) = 0;
n--;
i--;
- }
+ }
/* Complement and increment next octet */
*(p--) = ((*(n--)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
- }
+}
*pp+=ret;
return(ret);
- }
+}
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long len)
- {
+{
ASN1_INTEGER *ret=NULL;
const unsigned char *p, *pend;
unsigned char *to,*s;
int i;
if ((a == NULL) || ((*a) == NULL))
- {
+ {
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
- }
+ }
else
ret=(*a);
* signifies a missing NULL parameter. */
s=(unsigned char *)malloc((int)len+1);
if (s == NULL)
- {
+ {
i=ERR_R_MALLOC_FAILURE;
goto err;
- }
+ }
to=s;
if(!len) {
/* Strictly speaking this is an illegal INTEGER but we
* tolerate it.
*/
ret->type=V_ASN1_INTEGER;
- } else if (*p & 0x80) /* a negative number */
- {
+} else if (*p & 0x80) /* a negative number */
+ {
ret->type=V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
- }
+ }
i = len;
p += i - 1;
to += i - 1;
*(to--) = 0;
i--;
p--;
- }
+ }
/* Special case: if all zeros then the number will be of
* the form FF followed by n zero bytes: this corresponds to
* 1 followed by n zero bytes. We've already written n zeros
*s = 1;
s[len] = 0;
len++;
- } else {
+ } else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
- }
- } else {
+ }
+} else {
ret->type=V_ASN1_INTEGER;
if ((*p == 0) && (len != 1))
- {
+ {
p++;
len--;
- }
+ }
memcpy(s,p,(int)len);
- }
+}
if (ret->data != NULL) free(ret->data);
ret->data=s;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
- }
+}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
long length)
- {
+{
ASN1_INTEGER *ret=NULL;
const unsigned char *p;
unsigned char *s;
int i;
if ((a == NULL) || ((*a) == NULL))
- {
+ {
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
ret->type=V_ASN1_INTEGER;
- }
+ }
else
ret=(*a);
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_INTEGER)
- {
+ {
i=ASN1_R_EXPECTING_AN_INTEGER;
goto err;
- }
+ }
/* We must malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)malloc((int)len+1);
if (s == NULL)
- {
+ {
i=ERR_R_MALLOC_FAILURE;
goto err;
- }
+ }
ret->type=V_ASN1_INTEGER;
if(len) {
if ((*p == 0) && (len != 1))
- {
+ {
p++;
len--;
- }
+ }
memcpy(s,p,(int)len);
p+=len;
- }
+}
if (ret->data != NULL) free(ret->data);
ret->data=s;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_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];
a->type=V_ASN1_INTEGER;
if (a->length < (int)(sizeof(long)+1))
- {
+ {
if (a->data != NULL)
free(a->data);
if ((a->data=(unsigned char *)malloc(sizeof(long)+1)) != NULL)
memset((char *)a->data,0,sizeof(long)+1);
- }
+ }
if (a->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_INTEGER_SET,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);
- }
+}
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
- {
+{
int neg=0,i;
long r=0;
return -1;
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 (neg) r= -r;
return(r);
- }
+}
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
- {
+{
ASN1_INTEGER *ret;
int len,j;
else
ret=ai;
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
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)
- {
+ {
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
goto err;
- }
- ret->data=new_data;
}
+ 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) M_ASN1_INTEGER_free(ret);
return(NULL);
- }
+}
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
- {
+{
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
- }
+}
IMPLEMENT_STACK_OF(ASN1_INTEGER)
IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
#include <openssl/bn.h>
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
- {
+{
unsigned char *p;
int objsize;
*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;
c= *(p++);
num--;
if ((c >= '0') && (c <= '2'))
- {
+ {
first= c-'0';
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
- }
+ }
if (num <= 0)
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
goto err;
- }
+ }
c= *(p++);
num--;
for (;;)
- {
+ {
if (num <= 0) break;
if ((c != '.') && (c != ' '))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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'))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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))
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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)
- {
+ {
ASN1err(ASN1_F_A2D_ASN1_OBJECT,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);
if (bl)
if (bl)
BN_free(bl);
return(0);
- }
+}
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
}
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
- {
+{
char buf[80], *p = buf;
int i;
return(BIO_write(bp,"NULL",4));
i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
if (i > (int)(sizeof(buf) - 1))
- {
+ {
p = malloc(i + 1);
if (!p)
return -1;
i2t_ASN1_OBJECT(p,i + 1,a);
- }
+ }
if (i <= 0)
return BIO_write(bp, "<INVALID>", 9);
BIO_write(bp,p,i);
if (p != buf)
free(p);
return(i);
- }
+}
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long length)
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;
}
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long len)
- {
+{
ASN1_OBJECT *ret=NULL;
const unsigned char *p;
unsigned char *data;
* subidentifiers, see: X.690 8.19.2
*/
for (i = 0, p = *pp; i < len; i++, p++)
- {
+ {
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
- {
+ {
ASN1err(ASN1_F_C2I_ASN1_OBJECT,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;
ret->data = NULL;
/* once detached we can change it */
if ((data == NULL) || (ret->length < len))
- {
+ {
ret->length=0;
if (data != NULL) free(data);
data=(unsigned char *)malloc(len ? (int)len : 1);
if (data == NULL)
- { i=ERR_R_MALLOC_FAILURE; goto err; }
+ { i=ERR_R_MALLOC_FAILURE; goto err; }
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
- }
+ }
memcpy(data,p,(int)len);
/* reattach data to object, after which it remains const */
ret->data =data;
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
- }
+}
ASN1_OBJECT *ASN1_OBJECT_new(void)
- {
+{
ASN1_OBJECT *ret;
ret=(ASN1_OBJECT *)malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
ret->length=0;
ret->data=NULL;
ret->nid=0;
ret->ln=NULL;
ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
return(ret);
- }
+}
void ASN1_OBJECT_free(ASN1_OBJECT *a)
- {
+{
if (a == NULL) return;
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
- {
+ {
#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
if (a->sn != NULL) free((void *)a->sn);
if (a->ln != NULL) free((void *)a->ln);
#endif
a->sn=a->ln=NULL;
- }
+ }
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
- {
+ {
if (a->data != NULL) free((void *)a->data);
a->data=NULL;
a->length=0;
- }
+ }
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
free(a);
- }
+}
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
const char *sn, const char *ln)
- {
+{
ASN1_OBJECT o;
o.sn=sn;
o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return(OBJ_dup(&o));
- }
+}
IMPLEMENT_STACK_OF(ASN1_OBJECT)
IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
#include <openssl/asn1.h>
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
- {
+{
int c;
int ia5=0;
int t61=0;
if (s == NULL) return(V_ASN1_PRINTABLESTRING);
while ((*s) && (len-- != 0))
- {
+ {
c= *(s++);
if (!( ((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
ia5=1;
if (c&0x80)
t61=1;
- }
+ }
if (t61) return(V_ASN1_T61STRING);
if (ia5) return(V_ASN1_IA5STRING);
return(V_ASN1_PRINTABLESTRING);
- }
+}
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
- {
+{
int i;
unsigned char *p;
if ((s->length%4) != 0) return(0);
p=s->data;
for (i=0; i<s->length; i+=4)
- {
+ {
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
break;
else
p+=4;
- }
+ }
if (i < s->length) return(0);
p=s->data;
for (i=3; i<s->length; i+=4)
- {
+ {
*(p++)=s->data[i];
- }
+ }
*(p)='\0';
s->length/=4;
s->type=ASN1_PRINTABLE_type(s->data,s->length);
return(1);
- }
+}
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);
}
+ 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;
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!type || !pkey)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, 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)
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
if (rv <= 1)
goto err;
- }
+ }
else
rv = 2;
if (rv == 2)
- {
+ {
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
- {
+ {
if (!pkey->ameth ||
!OBJ_find_sigid_by_algs(&signid,
EVP_MD_nid(type),
pkey->ameth->pkey_id))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
- }
}
+ }
else
signid = type->pkey_type;
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((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL))
- {
+ {
outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
- {
+ {
outl=0;
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
goto err;
- }
+ }
if (signature->data != NULL) free(signature->data);
signature->data=buf_out;
buf_out=NULL;
err:
EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL)
- { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); free(buf_in); }
+ { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); free(buf_in); }
if (buf_out != NULL)
- { OPENSSL_cleanse((char *)buf_out,outll); free(buf_out); }
+ { OPENSSL_cleanse((char *)buf_out,outll); free(buf_out); }
return(outl);
- }
+}
#if 0
int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
- {
+{
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME);
return -1;
- }
+}
#endif
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
- {
+{
return ASN1_TIME_adj(s, t, 0, 0);
- }
+}
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
int offset_day, long offset_sec)
- {
+{
struct tm *ts;
struct tm data;
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
return NULL;
- }
+ }
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
if((ts->tm_year >= 50) && (ts->tm_year < 150))
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
- }
+}
int ASN1_TIME_check(ASN1_TIME *t)
- {
+{
if (t->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_check(t);
else if (t->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_check(t);
return 0;
- }
+}
/* Convert an ASN1_TIME structure to GeneralizedTime */
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
- {
+{
ASN1_GENERALIZEDTIME *ret;
char *str;
int newlen;
if (!ASN1_TIME_check(t)) return NULL;
if (!out || !*out)
- {
+ {
if (!(ret = ASN1_GENERALIZEDTIME_new ()))
return NULL;
if (out) *out = ret;
- }
+ }
else ret = *out;
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME)
- {
+ {
if(!ASN1_STRING_set(ret, t->data, t->length))
return NULL;
return ret;
- }
+ }
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
BUF_strlcat(str, (char *)t->data, newlen);
return ret;
- }
+}
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
- {
+{
ASN1_TIME t;
t.length = strlen(str);
t.type = V_ASN1_UTCTIME;
if (!ASN1_TIME_check(&t))
- {
+ {
t.type = V_ASN1_GENERALIZEDTIME;
if (!ASN1_TIME_check(&t))
return 0;
- }
+ }
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
return 0;
return 1;
- }
+}
#include <openssl/objects.h>
int ASN1_TYPE_get(ASN1_TYPE *a)
- {
+{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return(a->type);
else
return(0);
- }
+}
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
- {
+{
if (a->value.ptr != NULL)
- {
+ {
ASN1_TYPE **tmp_a = &a;
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
- }
+ }
a->type=type;
if (type == V_ASN1_BOOLEAN)
a->value.boolean = value ? 0xff : 0;
else
a->value.ptr=value;
- }
+}
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
- {
+{
if (!value || (type == V_ASN1_BOOLEAN))
- {
+ {
void *p = (void *)value;
ASN1_TYPE_set(a, type, p);
- }
+ }
else if (type == V_ASN1_OBJECT)
- {
+ {
ASN1_OBJECT *odup;
odup = OBJ_dup(value);
if (!odup)
return 0;
ASN1_TYPE_set(a, type, odup);
- }
+ }
else
- {
+ {
ASN1_STRING *sdup;
sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
- }
- return 1;
}
+ return 1;
+}
IMPLEMENT_STACK_OF(ASN1_TYPE)
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
- {
+{
int result = -1;
if (!a || !b || a->type != b->type) return -1;
switch (a->type)
- {
+ {
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
(ASN1_STRING *) b->value.ptr);
break;
- }
+ }
return result;
- }
+}
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
- {
+{
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
- }
+}
ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
long length)
- {
+{
ASN1_UTCTIME *ret=NULL;
ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
return(NULL);
- }
+ }
if (!ASN1_UTCTIME_check(ret))
- {
+ {
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
goto err;
- }
+ }
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_UTCTIME_free(ret);
return(NULL);
- }
+}
#endif
int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
- {
+{
static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
static const int max[8]={99,12,31,23,59,59,12,59};
char *a;
if (l < 11) goto err;
for (i=0; i<6; i++)
- {
+ {
if ((i == 5) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
- { i++; break; }
+ { i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if (++o > l) goto err;
if ((n < min[i]) || (n > max[i])) goto err;
- }
+ }
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-'))
- {
+ {
o++;
if (o+4 > l) goto err;
for (i=6; i<8; i++)
- {
+ {
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
o++;
n=(n*10)+ a[o]-'0';
if ((n < min[i]) || (n > max[i])) goto err;
o++;
- }
}
+ }
return(o == l);
err:
return(0);
- }
+}
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
- {
+{
ASN1_UTCTIME t;
t.type=V_ASN1_UTCTIME;
t.length=strlen(str);
t.data=(unsigned char *)str;
if (ASN1_UTCTIME_check(&t))
- {
+ {
if (s != NULL)
- {
+ {
if (!ASN1_STRING_set((ASN1_STRING *)s,
(unsigned char *)str,t.length))
return 0;
s->type = V_ASN1_UTCTIME;
- }
- return(1);
}
+ return(1);
+ }
else
return(0);
- }
+}
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
- {
+{
return ASN1_UTCTIME_adj(s, t, 0, 0);
- }
+}
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
int offset_day, long offset_sec)
- {
+{
char *p;
struct tm *ts;
struct tm data;
return(NULL);
if (offset_day || offset_sec)
- {
+ {
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
return NULL;
- }
+ }
if((ts->tm_year < 50) || (ts->tm_year >= 150))
return NULL;
p=(char *)s->data;
if ((p == NULL) || ((size_t)s->length < len))
- {
+ {
p=malloc(len);
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
if (s->data != NULL)
free(s->data);
s->data=(unsigned char *)p;
- }
+ }
(void) snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
s->length=strlen(p);
s->type=V_ASN1_UTCTIME;
return(s);
- }
+}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
- {
+{
struct tm *tm;
struct tm data;
int offset;
if (s->data[12] == 'Z')
offset=0;
else
- {
+ {
offset = g2(s->data+13)*60+g2(s->data+15);
if (s->data[12] == '-')
offset = -offset;
- }
+ }
t -= offset*60; /* FIXME: may overflow in extreme cases */
#undef return_cmp
return 0;
- }
+}
#if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
- {
+{
struct tm tm;
int offset;
if(s->data[12] == 'Z')
offset=0;
else
- {
+ {
offset=g2(s->data+13)*60+g2(s->data+15);
if(s->data[12] == '-')
offset= -offset;
- }
+ }
#undef g2
return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
* non-standard.
* Also time_t is inappropriate for general
* UTC times because it may a 32 bit type. */
- }
+}
#endif
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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
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))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
- }
+ }
if (mdnid == NID_undef)
- {
+ {
if (!pkey->ameth || !pkey->ameth->item_verify)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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
if (ret != 2)
goto err;
ret = -1;
- }
+ }
else
- {
+ {
const EVP_MD *type;
type=EVP_get_digestbynid(mdnid);
if (type == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
goto err;
- }
+ }
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
ret=0;
goto err;
- }
-
}
+ }
+
inl = ASN1_item_i2d(asn, &buf_in, it);
if (buf_in == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
ret=0;
goto err;
- }
+ }
OPENSSL_cleanse(buf_in,(unsigned int)inl);
free(buf_in);
if (EVP_DigestVerifyFinal(&ctx,signature->data,
(size_t)signature->length) <= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,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)); */
err:
EVP_MD_CTX_cleanup(&ctx);
return(ret);
- }
+}
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
- {
+{
#ifndef OPENSSL_NO_RSA
&rsa_asn1_meths[0],
&rsa_asn1_meths[1],
#endif
&hmac_asn1_meth,
&cmac_asn1_meth
- };
+};
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
#ifdef TEST
void main()
- {
+{
int i;
for (i = 0;
i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
fprintf(stderr, "Number %d id=%d (%s)\n", i,
standard_methods[i]->pkey_id,
OBJ_nid2sn(standard_methods[i]->pkey_id));
- }
+}
#endif
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
const EVP_PKEY_ASN1_METHOD * const *b)
- {
+{
return ((*a)->pkey_id - (*b)->pkey_id);
- }
+}
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
const EVP_PKEY_ASN1_METHOD *, ameth);
int EVP_PKEY_asn1_get_count(void)
- {
+{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (app_methods)
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
return num;
- }
+}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
- {
+{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (idx < 0)
return NULL;
return standard_methods[idx];
idx -= num;
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
+}
static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
- {
+{
EVP_PKEY_ASN1_METHOD tmp;
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
tmp.pkey_id = type;
if (app_methods)
- {
+ {
int idx;
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
if (idx >= 0)
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
- }
+ }
ret = OBJ_bsearch_ameth(&t, standard_methods,
sizeof(standard_methods)
/sizeof(EVP_PKEY_ASN1_METHOD *));
if (!ret || !*ret)
return NULL;
return *ret;
- }
+}
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
* also search through engines and set *pe to a functional reference
*/
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
- {
+{
const EVP_PKEY_ASN1_METHOD *t;
for (;;)
- {
+ {
t = pkey_asn1_find(type);
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
break;
type = t->pkey_base_id;
- }
+ }
if (pe)
- {
+ {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
/* type will contain the final unaliased type */
e = ENGINE_get_pkey_asn1_meth_engine(type);
if (e)
- {
+ {
*pe = e;
return ENGINE_get_pkey_asn1_meth(e, type);
- }
+ }
#endif
*pe = NULL;
- }
- return t;
}
+ return t;
+}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
const char *str, int len)
- {
+{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
if (len == -1)
len = strlen(str);
if (pe)
- {
+ {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
if (ameth)
- {
+ {
/* Convert structural into
* functional reference
*/
ENGINE_free(e);
*pe = e;
return ameth;
- }
+ }
#endif
*pe = NULL;
- }
+ }
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
- {
+ {
ameth = EVP_PKEY_asn1_get0(i);
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
continue;
if (((int)strlen(ameth->pem_str) == len) &&
!strncasecmp(ameth->pem_str, str, len))
return ameth;
- }
- return NULL;
}
+ return NULL;
+}
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (app_methods == NULL)
- {
+ {
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
if (!app_methods)
return 0;
- }
+ }
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
return 0;
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
return 1;
- }
+}
int EVP_PKEY_asn1_add_alias(int to, int from)
- {
+{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
if (!ameth)
return 0;
ameth->pkey_base_id = to;
return EVP_PKEY_asn1_add0(ameth);
- }
+}
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
const char **pinfo, const char **ppem_str,
const EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (!ameth)
return 0;
if (ppkey_id)
if (ppem_str)
*ppem_str = ameth->pem_str;
return 1;
- }
+}
const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
- {
+{
return pkey->ameth;
- }
+}
EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
const char *pem_str, const char *info)
- {
+{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = malloc(sizeof(EVP_PKEY_ASN1_METHOD));
if (!ameth)
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
if (info)
- {
+ {
ameth->info = BUF_strdup(info);
if (!ameth->info)
goto err;
- }
+ }
else
ameth->info = NULL;
if (pem_str)
- {
+ {
ameth->pem_str = BUF_strdup(pem_str);
if (!ameth->pem_str)
goto err;
- }
+ }
else
ameth->pem_str = NULL;
EVP_PKEY_asn1_free(ameth);
return NULL;
- }
+}
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->item_sign = src->item_sign;
dst->item_verify = src->item_verify;
- }
+}
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
- {
+{
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
- {
+ {
if (ameth->pem_str)
free(ameth->pem_str);
if (ameth->info)
free(ameth->info);
free(ameth);
- }
}
+}
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
ASN1_PCTX *pctx),
int (*pkey_size)(const EVP_PKEY *pk),
int (*pkey_bits)(const EVP_PKEY *pk))
- {
+{
ameth->pub_decode = pub_decode;
ameth->pub_encode = pub_encode;
ameth->pub_cmp = pub_cmp;
ameth->pub_print = pub_print;
ameth->pkey_size = pkey_size;
ameth->pkey_bits = pkey_bits;
- }
+}
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
- {
+{
ameth->priv_decode = priv_decode;
ameth->priv_encode = priv_encode;
ameth->priv_print = priv_print;
- }
+}
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
int (*param_decode)(EVP_PKEY *pkey,
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
- {
+{
ameth->param_decode = param_decode;
ameth->param_encode = param_encode;
ameth->param_missing = param_missing;
ameth->param_copy = param_copy;
ameth->param_cmp = param_cmp;
ameth->param_print = param_print;
- }
+}
void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
void (*pkey_free)(EVP_PKEY *pkey))
- {
+{
ameth->pkey_free = pkey_free;
- }
+}
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
long arg1, void *arg2))
- {
+{
ameth->pkey_ctrl = pkey_ctrl;
- }
+}
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
static ERR_STRING_DATA ASN1_str_functs[]=
- {
+{
{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
{ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
{0,NULL}
- };
+};
static ERR_STRING_DATA ASN1_str_reasons[]=
- {
+{
{ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"},
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) ,"asn1 parse error"},
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
{ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"},
{ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"},
{0,NULL}
- };
+};
#endif
void ERR_load_ASN1_strings(void)
- {
+{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
- {
+ {
ERR_load_strings(0,ASN1_str_functs);
ERR_load_strings(0,ASN1_str_reasons);
- }
-#endif
}
+#endif
+}
#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
-#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val}
+#define ASN1_GEN_STR(str,val){str, sizeof(str) - 1, val}
#define ASN1_FLAG_EXP_MAX 20
struct tag_name_st
- {
+{
const char *strnam;
int len;
int tag;
- };
+};
typedef struct
- {
+{
int exp_tag;
int exp_class;
int exp_constructed;
int exp_pad;
long exp_len;
- } tag_exp_type;
+} tag_exp_type;
typedef struct
- {
+{
int imp_tag;
int imp_class;
int utype;
const char *str;
tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
int exp_count;
- } tag_exp_arg;
+} tag_exp_arg;
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
- {
+{
X509V3_CTX cnf;
if (!nconf)
X509V3_set_nconf(&cnf, nconf);
return ASN1_generate_v3(str, &cnf);
- }
+}
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
- {
+{
ASN1_TYPE *ret;
tag_exp_arg asn1_tags;
tag_exp_type *etmp;
return NULL;
if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
- {
+ {
if (!cnf)
- {
+ {
ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
- }
- ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
}
+ ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
+ }
else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
/* Do we need IMPLICIT tagging? */
if (asn1_tags.imp_tag != -1)
- {
+ {
/* If IMPLICIT we will replace the underlying tag */
/* Skip existing tag+len */
r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
* consistent.
*/
if (r & 0x1)
- {
+ {
/* Indefinite length constructed */
hdr_constructed = 2;
hdr_len = 0;
- }
+ }
else
/* Just retain constructed flag */
hdr_constructed = r & V_ASN1_CONSTRUCTED;
* because it will mess up if indefinite length
*/
len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
- }
+ }
else
len = cpy_len;
/* Work out length in any EXPLICIT, starting from end */
for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
- {
+ {
/* Content length: number of content octets + any padding */
len += etmp->exp_pad;
etmp->exp_len = len;
/* Total object length: length including new header */
len = ASN1_object_size(0, len, etmp->exp_tag);
- }
+ }
/* Allocate buffer for new encoding */
/* Output explicit tags first */
for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
- {
+ {
ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
etmp->exp_tag, etmp->exp_class);
if (etmp->exp_pad)
*p++ = 0;
- }
+ }
/* If IMPLICIT, output tag */
if (asn1_tags.imp_tag != -1)
- {
+ {
if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
&& (asn1_tags.imp_tag == V_ASN1_SEQUENCE
|| asn1_tags.imp_tag == V_ASN1_SET) )
hdr_constructed = V_ASN1_CONSTRUCTED;
ASN1_put_object(&p, hdr_constructed, hdr_len,
asn1_tags.imp_tag, asn1_tags.imp_class);
- }
+ }
/* Copy across original encoding */
memcpy(p, cpy_start, cpy_len);
return ret;
- }
+}
static int asn1_cb(const char *elem, int len, void *bitstr)
- {
+{
tag_exp_arg *arg = bitstr;
int i;
int utype;
int tmp_tag, tmp_class;
for(i = 0, p = elem; i < len; p++, i++)
- {
+ {
/* Look for the ':' in name value pairs */
if (*p == ':')
- {
+ {
vstart = p + 1;
vlen = len - (vstart - elem);
len = p - elem;
break;
- }
}
+ }
utype = asn1_str2tag(elem, len);
if (utype == -1)
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
ERR_add_error_data(2, "tag=", elem);
return -1;
- }
+ }
/* If this is not a modifier mark end of string and exit */
if (!(utype & ASN1_GEN_FLAG))
- {
+ {
arg->utype = utype;
arg->str = vstart;
/* If no value and not end of string, error */
if (!vstart && elem[len])
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
return -1;
- }
- return 0;
}
+ return 0;
+ }
switch(utype)
- {
+ {
case ASN1_GEN_FLAG_IMP:
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1)
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
- }
+ }
if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
return -1;
break;
else if (!strncmp(vstart, "BITLIST", 7))
arg->format = ASN1_GEN_FORMAT_BITLIST;
else
- {
+ {
ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT);
return -1;
- }
+ }
break;
- }
+ }
return 1;
- }
+}
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
- {
+{
char erch[2];
long tag_num;
char *eptr;
if (eptr && *eptr && (eptr > vstart + vlen))
return 0;
if (tag_num < 0)
- {
+ {
ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
return 0;
- }
+ }
*ptag = tag_num;
/* If we have non numeric characters, parse them */
if (eptr)
else
vlen = 0;
if (vlen)
- {
+ {
switch (*eptr)
- {
+ {
case 'U':
*pclass = V_ASN1_UNIVERSAL;
return 0;
break;
- }
}
+ }
else
*pclass = V_ASN1_CONTEXT_SPECIFIC;
return 1;
- }
+}
/* Handle multiple types: SET and SEQUENCE */
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
- {
+{
ASN1_TYPE *ret = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL;
if (!sk)
goto bad;
if (section)
- {
+ {
if (!cnf)
goto bad;
sect = X509V3_get_section(cnf, (char *)section);
if (!sect)
goto bad;
for (i = 0; i < sk_CONF_VALUE_num(sect); i++)
- {
+ {
ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf);
if (!typ)
goto bad;
if (!sk_ASN1_TYPE_push(sk, typ))
goto bad;
- }
}
+ }
/* Now we has a STACK of the components, convert to the correct form */
X509V3_section_free(cnf, sect);
return ret;
- }
+}
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok)
- {
+{
tag_exp_type *exp_tmp;
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok)
- {
+ {
ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
- }
+ }
if (arg->exp_count == ASN1_FLAG_EXP_MAX)
- {
+ {
ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
return 0;
- }
+ }
exp_tmp = &arg->exp_list[arg->exp_count++];
* reset implicit tag since it has been used.
*/
if (arg->imp_tag != -1)
- {
+ {
exp_tmp->exp_tag = arg->imp_tag;
exp_tmp->exp_class = arg->imp_class;
arg->imp_tag = -1;
arg->imp_class = -1;
- }
+ }
else
- {
+ {
exp_tmp->exp_tag = exp_tag;
exp_tmp->exp_class = exp_class;
- }
+ }
exp_tmp->exp_constructed = exp_constructed;
exp_tmp->exp_pad = exp_pad;
return 1;
- }
+}
static int asn1_str2tag(const char *tagstr, int len)
- {
+{
unsigned int i;
static const struct tag_name_st *tntmp, tnst [] = {
ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
- };
+};
if (len == -1)
len = strlen(tagstr);
tntmp = tnst;
for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++)
- {
+ {
if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
return tntmp->tag;
- }
+ }
return -1;
- }
+}
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
- {
+{
ASN1_TYPE *atmp = NULL;
CONF_VALUE vtmp;
int no_unused = 1;
if (!(atmp = ASN1_TYPE_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
return NULL;
- }
+ }
if (!str)
str = "";
switch(utype)
- {
+ {
case V_ASN1_NULL:
if (str && *str)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
- }
+ }
break;
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
vtmp.name = NULL;
vtmp.section = NULL;
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
- }
+ }
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
- }
+ }
break;
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
- }
+ }
break;
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
- }
+ }
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
- }
+ }
break;
else if (format == ASN1_GEN_FORMAT_UTF8)
format = MBSTRING_UTF8;
else
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
- }
+ }
if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-1, format, ASN1_tag2bit(utype)) <= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_str;
- }
+ }
break;
case V_ASN1_OCTET_STRING:
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
goto bad_form;
- }
+ }
if (format == ASN1_GEN_FORMAT_HEX)
- {
+ {
if (!(rdata = string_to_hex((char *)str, &rdlen)))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
goto bad_str;
- }
+ }
atmp->value.asn1_string->data = rdata;
atmp->value.asn1_string->length = rdlen;
atmp->value.asn1_string->type = utype;
- }
+ }
else if (format == ASN1_GEN_FORMAT_ASCII)
ASN1_STRING_set(atmp->value.asn1_string, str, -1);
else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING))
- {
+ {
if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
goto bad_str;
- }
+ }
no_unused = 0;
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
- }
+ }
if ((utype == V_ASN1_BIT_STRING) && no_unused)
- {
+ {
atmp->value.asn1_string->flags
&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
atmp->value.asn1_string->flags
|= ASN1_STRING_FLAG_BITS_LEFT;
- }
+ }
break;
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
- }
+ }
atmp->type = utype;
ASN1_TYPE_free(atmp);
return NULL;
- }
+}
static int bitstr_cb(const char *elem, int len, void *bitstr)
- {
+{
long bitnum;
char *eptr;
if (!elem)
if (eptr && *eptr && (eptr != elem + len))
return 0;
if (bitnum < 0)
- {
+ {
ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
return 0;
- }
+ }
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
- {
+ {
ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
return 0;
- }
- return 1;
}
+ return 1;
+}
const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
static int _asn1_check_infinite_end(const unsigned char **p, long len)
- {
+{
/* 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);
}
+ return(0);
+}
int ASN1_check_infinite_end(unsigned char **p, long len)
- {
+{
return _asn1_check_infinite_end((const unsigned char **)p, len);
- }
+}
int ASN1_const_check_infinite_end(const unsigned char **p, long len)
- {
+{
return _asn1_check_infinite_end(p, len);
- }
+}
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;
xclass=(*p&V_ASN1_PRIVATE);
i= *p&V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG)
- { /* high-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;
#endif
if (*plength > (omax - (p - *pp)))
- {
+ {
ASN1err(ASN1_F_ASN1_GET_OBJECT,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:
ASN1err(ASN1_F_ASN1_GET_OBJECT,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 (i > sizeof(long))
return 0;
if (max-- == 0) return(0);
while (i-- > 0)
- {
+ {
ret<<=8L;
ret|= *(p++);
if (max-- == 0) return(0);
- }
}
+ }
else
ret=i;
- }
+ }
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;
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;
}
+ 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;
+ 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);
}
+ return(ret);
+}
static int _asn1_Finish(ASN1_const_CTX *c)
- {
+{
if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
- {
+ {
if (!ASN1_const_check_infinite_end(&c->p,c->slen))
- {
+ {
c->error=ERR_R_MISSING_ASN1_EOS;
return(0);
- }
}
+ }
if ( ((c->slen != 0) && !(c->inf & 1)) ||
((c->slen < 0) && (c->inf & 1)))
- {
+ {
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
return(0);
- }
- return(1);
}
+ return(1);
+}
int asn1_Finish(ASN1_CTX *c)
- {
+{
return _asn1_Finish((ASN1_const_CTX *)c);
- }
+}
int asn1_const_Finish(ASN1_const_CTX *c)
- {
+{
return _asn1_Finish(c);
- }
+}
int asn1_GetSequence(ASN1_const_CTX *c, long *length)
- {
+{
const unsigned char *q;
q=c->p;
c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
*length);
if (c->inf & 0x80)
- {
+ {
c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
return(0);
- }
+ }
if (c->tag != V_ASN1_SEQUENCE)
- {
+ {
c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
return(0);
- }
+ }
(*length)-=(c->p-q);
if (c->max && (*length < 0))
- {
+ {
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
return(0);
- }
+ }
if (c->inf == (1|V_ASN1_CONSTRUCTED))
c->slen= *length+ *(c->pp)-c->p;
c->eos=0;
return(1);
- }
+}
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
- {
+{
if (str == NULL)
return 0;
dst->type = str->type;
return 0;
dst->flags = str->flags;
return 1;
- }
+}
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
- {
+{
ASN1_STRING *ret;
if (!str)
return NULL;
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret,str))
- {
+ {
ASN1_STRING_free(ret);
return NULL;
- }
- return ret;
}
+ return ret;
+}
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
- {
+{
unsigned char *c;
const char *data=_data;
if (len < 0)
- {
+ {
if (data == NULL)
return(0);
else
len=strlen(data);
- }
+ }
if ((str->length < len) || (str->data == NULL))
- {
+ {
c=str->data;
if (c == NULL)
str->data=malloc(len+1);
str->data=realloc(c,len+1);
if (str->data == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
- }
}
+ }
str->length=len;
if (data != NULL)
- {
+ {
memcpy(str->data,data,len);
/* an allowance for strings :-) */
str->data[len]='\0';
- }
- return(1);
}
+ return(1);
+}
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
- {
+{
if (str->data)
free(str->data);
str->data = data;
str->length = len;
- }
+}
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 *ret;
ret=(ASN1_STRING *)malloc(sizeof(ASN1_STRING));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,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 && !(a->flags & ASN1_STRING_FLAG_NDEF))
free(a->data);
free(a);
- }
+}
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
- {
+{
int i;
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);
- }
+}
void asn1_add_error(const unsigned char *address, int offset)
- {
+{
char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
(void) snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
(void) snprintf(buf2,sizeof buf2,"%d",offset);
ERR_add_error_data(4,"address=",buf1," offset=",buf2);
- }
+}
int ASN1_STRING_length(const ASN1_STRING *x)
{ return M_ASN1_STRING_length(x); }
int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
- {
+{
static const char fmt[]="%-18s";
char str[128];
const char *p;
return(1);
err:
return(0);
- }
+}
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
- {
+{
return(asn1_parse2(bp,&pp,len,0,0,indent,0));
- }
+}
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
- {
+{
return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
- }
+}
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
int depth, int indent, int dump)
- {
+{
const unsigned char *p,*ep,*tot,*op,*opp;
long len;
int tag,xclass,ret=0;
tot=p+length;
op=p-1;
while ((p < tot) && (op < p))
- {
+ {
op=p;
j=ASN1_get_object(&p,&len,&tag,&xclass,length);
#ifdef LINT
j=j;
#endif
if (j & 0x80)
- {
+ {
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
goto end;
ret=0;
goto end;
- }
+ }
hl=(p-op);
length-=hl;
/* if j == 0x21 it is a constructed indefinite length object */
<= 0) goto end;
if (j != (V_ASN1_CONSTRUCTED | 1))
- {
+ {
if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
depth,(long)hl,len) <= 0)
goto end;
- }
+ }
else
- {
+ {
if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
depth,(long)hl) <= 0)
goto end;
- }
+ }
if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
goto end;
if (j & V_ASN1_CONSTRUCTED)
- {
+ {
ep=p+len;
if (BIO_write(bp,"\n",1) <= 0) goto end;
if (len > length)
- {
+ {
BIO_printf(bp,
"length is greater than %ld\n",length);
ret=0;
goto end;
- }
+ }
if ((j == 0x21) && (len == 0))
- {
+ {
for (;;)
- {
+ {
r=asn1_parse2(bp,&p,(long)(tot-p),
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
if ((r == 2) || (p >= tot)) break;
- }
}
+ }
else
while (p < ep)
- {
+ {
r=asn1_parse2(bp,&p,(long)len,
offset+(p - *pp),depth+1,
indent,dump);
if (r == 0) { ret=0; goto end; }
- }
- }
+ }
+ }
else if (xclass != 0)
- {
+ {
p+=len;
if (BIO_write(bp,"\n",1) <= 0) goto end;
- }
+ }
else
- {
+ {
nl=0;
if ( (tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) ||
(tag == V_ASN1_GENERALIZEDTIME))
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if ((len > 0) &&
BIO_write(bp,(const char *)p,(int)len)
!= (int)len)
goto end;
- }
+ }
else if (tag == V_ASN1_OBJECT)
- {
+ {
opp=op;
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
i2a_ASN1_OBJECT(bp,o);
- }
+ }
else
- {
+ {
if (BIO_write(bp,":BAD OBJECT",11) <= 0)
goto end;
- }
}
+ }
else if (tag == V_ASN1_BOOLEAN)
- {
+ {
int ii;
opp=op;
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
if (ii < 0)
- {
+ {
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
goto end;
- }
- BIO_printf(bp,":%d",ii);
}
+ BIO_printf(bp,":%d",ii);
+ }
else if (tag == V_ASN1_BMPSTRING)
- {
+ {
/* do the BMP thang */
- }
+ }
else if (tag == V_ASN1_OCTET_STRING)
- {
+ {
int i,printable=1;
opp=op;
os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
if (os != NULL && os->length > 0)
- {
+ {
opp = os->data;
/* testing whether the octet string is
* printable */
for (i=0; i<os->length; i++)
- {
+ {
if (( (opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) ||
(opp[i] > '~'))
- {
+ {
printable=0;
break;
- }
}
+ }
if (printable)
/* printable string */
- {
+ {
if (BIO_write(bp,":",1) <= 0)
goto end;
if (BIO_write(bp,(const char *)opp,
os->length) <= 0)
goto end;
- }
+ }
else if (!dump)
/* not printable => print octet string
* as hex dump */
- {
+ {
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
goto end;
for (i=0; i<os->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X"
, opp[i]) <= 0)
goto end;
- }
}
+ }
else
/* print the normal dump */
- {
+ {
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0)
goto end;
- }
+ }
if (BIO_dump_indent(bp,
(const char *)opp,
((dump == -1 || dump >
dump_indent) <= 0)
goto end;
nl=1;
- }
}
+ }
if (os != NULL)
- {
+ {
M_ASN1_OCTET_STRING_free(os);
os=NULL;
- }
}
+ }
else if (tag == V_ASN1_INTEGER)
- {
+ {
ASN1_INTEGER *bs;
int i;
opp=op;
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
if (bs != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
- }
+ }
if (bs->length == 0)
- {
+ {
if (BIO_write(bp,"00",2) <= 0)
goto end;
- }
}
+ }
else
- {
+ {
if (BIO_write(bp,"BAD INTEGER",11) <= 0)
goto end;
- }
- M_ASN1_INTEGER_free(bs);
}
+ M_ASN1_INTEGER_free(bs);
+ }
else if (tag == V_ASN1_ENUMERATED)
- {
+ {
ASN1_ENUMERATED *bs;
int i;
opp=op;
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
if (bs != NULL)
- {
+ {
if (BIO_write(bp,":",1) <= 0) goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_write(bp,"-",1) <= 0)
goto end;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02X",
bs->data[i]) <= 0)
goto end;
- }
+ }
if (bs->length == 0)
- {
+ {
if (BIO_write(bp,"00",2) <= 0)
goto end;
- }
}
+ }
else
- {
+ {
if (BIO_write(bp,"BAD ENUMERATED",14) <= 0)
goto end;
- }
- M_ASN1_ENUMERATED_free(bs);
}
+ M_ASN1_ENUMERATED_free(bs);
+ }
else if (len > 0 && dump)
- {
+ {
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0)
goto end;
- }
+ }
if (BIO_dump_indent(bp,(const char *)p,
((dump == -1 || dump > len)?len:dump),
dump_indent) <= 0)
goto end;
nl=1;
- }
+ }
if (!nl)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0) goto end;
- }
+ }
p+=len;
if ((tag == V_ASN1_EOC) && (xclass == 0))
- {
+ {
ret=2; /* End of sequence */
goto end;
- }
}
- length-=len;
}
+ length-=len;
+ }
ret=1;
end:
if (o != NULL) ASN1_OBJECT_free(o);
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
*pp=p;
return(ret);
- }
+}
const char *ASN1_tag2str(int tag)
{
"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;
int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const ASN1_ITEM *it)
- {
+{
/* If streaming create stream BIO and copy all content through it */
if (flags & SMIME_STREAM)
- {
+ {
BIO *bio, *tbio;
bio = BIO_new_NDEF(out, val, it);
if (!bio)
- {
+ {
ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM,ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
SMIME_crlf_copy(in, bio, flags);
(void)BIO_flush(bio);
/* Free up successive BIOs until we hit the old output BIO */
do
- {
+ {
tbio = BIO_pop(bio);
BIO_free(bio);
bio = tbio;
- } while (bio != out);
- }
+ } while (bio != out);
+ }
/* else just write out ASN1 structure which will have all content
* stored internally
*/
else
ASN1_item_i2d_bio(it, out, val);
return 1;
- }
+}
/* Base 64 read and write of ASN1 structure */
static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const ASN1_ITEM *it)
- {
+{
BIO *b64;
int r;
b64 = BIO_new(BIO_f_base64());
if(!b64)
- {
+ {
ASN1err(ASN1_F_B64_WRITE_ASN1,ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
/* prepend the b64 BIO so all data is base64 encoded.
*/
out = BIO_push(b64, out);
BIO_pop(out);
BIO_free(b64);
return r;
- }
+}
/* Streaming ASN1 PEM write */
int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
const char *hdr,
const ASN1_ITEM *it)
- {
+{
int r;
BIO_printf(out, "-----BEGIN %s-----\n", hdr);
r = B64_write_ASN1(out, val, in, flags, it);
BIO_printf(out, "-----END %s-----\n", hdr);
return r;
- }
+}
static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
{
if(!(b64 = BIO_new(BIO_f_base64()))) {
ASN1err(ASN1_F_B64_READ_ASN1,ERR_R_MALLOC_FAILURE);
return 0;
- }
+}
bio = BIO_push(b64, bio);
val = ASN1_item_d2i_bio(it, bio, NULL);
if(!val)
/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
- {
+{
const EVP_MD *md;
int i, have_unknown = 0, write_comma, ret = 0, md_nid;
have_unknown = 0;
write_comma = 0;
for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++)
- {
+ {
if (write_comma)
BIO_write(out, ",", 1);
write_comma = 1;
md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
md = EVP_get_digestbynid(md_nid);
if (md && md->md_ctrl)
- {
+ {
int rv;
char *micstr;
rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
if (rv > 0)
- {
+ {
BIO_puts(out, micstr);
free(micstr);
continue;
- }
+ }
if (rv != -2)
goto err;
- }
+ }
switch(md_nid)
- {
+ {
case NID_sha1:
BIO_puts(out, "sha1");
break;
if (have_unknown)
write_comma = 0;
else
- {
+ {
BIO_puts(out, "unknown");
have_unknown = 1;
- }
+ }
break;
- }
}
+ }
ret = 1;
err:
return ret;
- }
+}
/* SMIME sender */
if(c < 10) c += '0';
else c += 'A' - 10;
bound[i] = c;
- }
+ }
bound[32] = 0;
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
BIO_printf(bio, "Content-Type: multipart/signed;");
BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
mime_eol, mime_eol);
return 1;
- }
+}
/* Determine smime-type header */
if (ctype_nid == NID_pkcs7_enveloped)
msg_type = "enveloped-data";
else if (ctype_nid == NID_pkcs7_signed)
- {
+ {
if (econt_nid == NID_id_smime_ct_receipt)
msg_type = "signed-receipt";
else if (sk_X509_ALGOR_num(mdalgs) >= 0)
msg_type = "signed-data";
else
msg_type = "certs-only";
- }
+ }
else if (ctype_nid == NID_id_smime_ct_compressedData)
- {
+ {
msg_type = "compressed-data";
cname = "smime.p7z";
- }
+ }
/* MIME headers */
BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
BIO_printf(bio, "Content-Disposition: attachment;");
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
const ASN1_ITEM *it)
- {
+{
BIO *tmpbio;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
* already set up to finalise when it is written through.
*/
if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST))
- {
+ {
SMIME_crlf_copy(data, out, flags);
return 1;
- }
+ }
if (!aux || !aux->asn1_cb)
- {
+ {
ASN1err(ASN1_F_ASN1_OUTPUT_DATA,
ASN1_R_STREAMING_NOT_SUPPORTED);
return 0;
- }
+ }
sarg.out = out;
sarg.ndef_bio = NULL;
/* Now remove any digests prepended to the BIO */
while (sarg.ndef_bio != out)
- {
+ {
tmpbio = BIO_pop(sarg.ndef_bio);
BIO_free(sarg.ndef_bio);
sarg.ndef_bio = tmpbio;
- }
+ }
return rv;
- }
+}
/* SMIME reader: handle multipart/signed and opaque signing.
* in multipart case the content is placed in a memory BIO
if (!(headers = mime_parse_hdr(bio))) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_PARSE_ERROR);
return NULL;
- }
+}
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
return NULL;
- }
+}
/* Handle multipart/signed */
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
return NULL;
- }
+ }
ret = multi_split(bio, prm->param_value, &parts);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
if(!ret || (sk_BIO_num(parts) != 2) ) {
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
/* Parse the signature piece */
asnin = sk_BIO_value(parts, 1);
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
/* Get content type */
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
return NULL;
- }
+ }
if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
strcmp(hdr->value, "application/pkcs7-signature")) {
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
/* Read in ASN1 */
if(!(val = b64_read_asn1(asnin, it))) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_ASN1_SIG_PARSE_ERROR);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
- }
+ }
if(bcont) {
*bcont = sk_BIO_value(parts, 0);
BIO_free(asnin);
sk_BIO_free(parts);
- } else sk_BIO_pop_free(parts, BIO_vfree);
+ } else sk_BIO_pop_free(parts, BIO_vfree);
return val;
- }
+}
/* OK, if not multipart/signed try opaque signature */
ERR_add_error_data(2, "type: ", hdr->value);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return NULL;
- }
+}
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
if(!(val = b64_read_asn1(bio, it))) {
ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
return NULL;
- }
+}
return val;
}
return 0;
out = BIO_push(bf, out);
if(flags & SMIME_BINARY)
- {
+ {
while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
BIO_write(out, linebuf, len);
- }
+ }
else
- {
+ {
if(flags & SMIME_TEXT)
BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0)
- {
+ {
eol = strip_eol(linebuf, &len);
if (len)
BIO_write(out, linebuf, len);
if(eol) BIO_write(out, "\r\n", 2);
- }
}
+ }
(void)BIO_flush(out);
BIO_pop(out);
BIO_free(bf);
if (!(headers = mime_parse_hdr(in))) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_PARSE_ERROR);
return 0;
- }
+}
if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_MIME_NO_CONTENT_TYPE);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return 0;
- }
+}
if (strcmp (hdr->value, "text/plain")) {
ASN1err(ASN1_F_SMIME_TEXT,ASN1_R_INVALID_MIME_TYPE);
ERR_add_error_data(2, "type: ", hdr->value);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
return 0;
- }
+}
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
BIO_write(out, iobuf, len);
if(state == 1) {
first = 1;
part++;
- } else if(state == 2) {
+ } else if(state == 2) {
sk_BIO_push(parts, bpart);
return 1;
- } else if(part) {
+ } else if(part) {
/* Strip CR+LF from linebuf */
next_eol = strip_eol(linebuf, &len);
if(first) {
if(bpart) sk_BIO_push(parts, bpart);
bpart = BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(bpart, 0);
- } else if (eol)
+ } else if (eol)
BIO_write(bpart, "\r\n", 2);
eol = next_eol;
if (len)
BIO_write(bpart, linebuf, len);
- }
}
+}
return 0;
}
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
- }
+ }
break;
case MIME_TYPE:
ntmp = NULL;
q = p + 1;
state = MIME_NAME;
- } else if(c == '(') {
+ } else if(c == '(') {
save_state = state;
state = MIME_COMMENT;
- }
+ }
break;
case MIME_COMMENT:
if(c == ')') {
state = save_state;
- }
+ }
break;
case MIME_NAME:
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
- }
+ }
break ;
case MIME_VALUE:
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
ntmp = NULL;
q = p + 1;
- } else if (c == '"') {
+ } else if (c == '"') {
mime_debug("Found Quote\n");
state = MIME_QUOTE;
- } else if(c == '(') {
+ } else if(c == '(') {
save_state = state;
state = MIME_COMMENT;
- }
+ }
break;
case MIME_QUOTE:
if(c == '"') {
mime_debug("Found Match Quote\n");
state = MIME_VALUE;
- }
- break;
}
+ break;
}
+}
if(state == MIME_TYPE) {
mhdr = mime_hdr_new(ntmp, strip_ends(q));
sk_MIME_HEADER_push(headers, mhdr);
- } else if(state == MIME_VALUE)
+} else if(state == MIME_VALUE)
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
if(p == linebuf) break; /* Blank line means end of headers */
}
if(p[1]) return p + 1;
/* Else null string */
return NULL;
- }
- if(!isspace((unsigned char)c)) return p;
}
+ if(!isspace((unsigned char)c)) return p;
+}
return NULL;
}
if(p - 1 == name) return NULL;
*p = 0;
return name;
- }
+ }
if(isspace((unsigned char)c)) *p = 0;
else return name;
- }
+}
return NULL;
}
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpname = NULL;
+ }
+} else tmpname = NULL;
if(value) {
if(!(tmpval = BUF_strdup(value))) return NULL;
for(p = tmpval ; *p; p++) {
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpval = NULL;
+ }
+} else tmpval = NULL;
mhdr = (MIME_HEADER *) malloc(sizeof(MIME_HEADER));
if (!mhdr) {
OPENSSL_free(tmpname);
return NULL;
- }
+}
mhdr->name = tmpname;
mhdr->value = tmpval;
if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) {
free(mhdr);
return NULL;
- }
+}
return mhdr;
}
if(isupper(c)) {
c = tolower(c);
*p = c;
- }
}
- } else tmpname = NULL;
+ }
+} else tmpname = NULL;
if(value) {
tmpval = BUF_strdup(value);
if(!tmpval) return 0;
- } else tmpval = NULL;
+} else tmpval = NULL;
/* Parameter values are case sensitive so leave as is */
mparam = (MIME_PARAM *) malloc(sizeof(MIME_PARAM));
if(!mparam) return 0;
if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
if(!strncmp(line + blen + 2, "--", 2)) return 2;
else return 1;
- }
+}
return 0;
}
static int strip_eol(char *linebuf, int *plen)
- {
+{
int len = *plen;
char *p, c;
int is_eol = 0;
p = linebuf + len - 1;
for (p = linebuf + len - 1; len > 0; len--, p--)
- {
+ {
c = *p;
if (c == '\n')
is_eol = 1;
else if (c != '\r')
break;
- }
+ }
*plen = len;
return is_eol;
- }
+}
static int do_create(char *value, char *name);
static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
- {
+{
int i;
const char *oid_section;
STACK_OF(CONF_VALUE) *sktmp;
CONF_VALUE *oval;
oid_section = CONF_imodule_get_value(md);
if(!(sktmp = NCONF_get_section(cnf, oid_section)))
- {
+ {
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
return 0;
- }
+ }
for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
- {
+ {
oval = sk_CONF_VALUE_value(sktmp, i);
if(!do_create(oval->value, oval->name))
- {
+ {
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
return 0;
- }
}
- return 1;
}
+ return 1;
+}
static void oid_module_finish(CONF_IMODULE *md)
- {
+{
OBJ_cleanup();
- }
+}
void ASN1_add_oid_module(void)
- {
+{
CONF_module_add("oid_section", oid_module_init, oid_module_finish);
- }
+}
/* Create an OID based on a name value pair. Accept two formats.
* shortname = 1.2.3.4
static int do_create(char *value, char *name)
- {
+{
int nid;
ASN1_OBJECT *oid;
char *ln, *ostr, *p, *lntmp;
p = strrchr(value, ',');
if (!p)
- {
+ {
ln = name;
ostr = value;
- }
+ }
else
- {
+ {
ln = NULL;
ostr = p + 1;
if (!*ostr)
return 0;
while(isspace((unsigned char)*ostr)) ostr++;
- }
+ }
nid = OBJ_create(ostr, name, ln);
return 0;
if (p)
- {
+ {
ln = value;
while(isspace((unsigned char)*ln)) ln++;
p--;
while(isspace((unsigned char)*p))
- {
+ {
if (p == ln)
return 0;
p--;
- }
+ }
p++;
lntmp = malloc((p - ln) + 1);
if (lntmp == NULL)
lntmp[p - ln] = 0;
oid = OBJ_nid2obj(nid);
oid->ln = lntmp;
- }
+ }
return 1;
- }
+}
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum
- {
+{
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
- } asn1_bio_state_t;
+} asn1_bio_state_t;
typedef struct BIO_ASN1_EX_FUNCS_st
- {
+{
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
- } BIO_ASN1_EX_FUNCS;
+} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_BUF_CTX_t
- {
+{
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
int ex_len;
int ex_pos;
void *ex_arg;
- } BIO_ASN1_BUF_CTX;
+} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf,int num);
asn1_bio_state_t other_state);
static BIO_METHOD methods_asn1=
- {
+{
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_new,
asn1_bio_free,
asn1_bio_callback_ctrl,
- };
+};
BIO_METHOD *BIO_f_asn1(void)
- {
+{
return(&methods_asn1);
- }
+}
static int asn1_bio_new(BIO *b)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
free(ctx);
return 0;
- }
+}
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->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
- }
+}
static int asn1_bio_free(BIO *b)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
b->ptr = NULL;
b->flags = 0;
return 1;
- }
+}
static int asn1_bio_write(BIO *b, const char *in , int inl)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret;
unsigned char *p;
ret = -1;
for(;;)
- {
+ {
switch (ctx->state)
- {
+ {
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (ctx->buflen)
ctx->bufpos += ret;
else
- {
+ {
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
- }
+ }
break;
BIO_clear_retry_flags(b);
return 0;
- }
-
}
+ }
+
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (wrlen > 0) ? wrlen : ret;
- }
+}
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next)
- {
+{
int ret;
if (ctx->ex_len <= 0)
return 1;
for(;;)
- {
+ {
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
ctx->ex_len);
if (ret <= 0)
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else
- {
+ {
if(cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
&ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
- }
}
- return ret;
}
+ return ret;
+}
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state)
- {
+{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
- {
+ {
BIO_clear_retry_flags(b);
return 0;
- }
+ }
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
- }
+}
static int asn1_bio_read(BIO *b, char *in , int inl)
- {
+{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in , inl);
- }
+}
static int asn1_bio_puts(BIO *b, const char *str)
- {
+{
return asn1_bio_write(b, str, strlen(str));
- }
+}
static int asn1_bio_gets(BIO *b, char *str, int size)
- {
+{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str , size);
- }
+}
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
- {
+{
if (b->next_bio == NULL) return(0);
return BIO_callback_ctrl(b->next_bio,cmd,fp);
- }
+}
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
- {
+{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
if (ctx == NULL)
return 0;
switch(cmd)
- {
+ {
case BIO_C_SET_PREFIX:
ex_func = arg2;
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER)
- {
+ {
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
- }
+ }
if (ctx->state == ASN1_STATE_POST_COPY)
- {
+ {
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
- }
+ }
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else
- {
+ {
BIO_clear_retry_flags(b);
return 0;
- }
+ }
break;
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
- }
+ }
return ret;
- }
+}
static int asn1_bio_set_ex(BIO *b, int cmd,
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
- {
+{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
- }
+}
static int asn1_bio_get_ex(BIO *b, int cmd,
asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
- {
+{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0)
- {
+ {
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
- }
- return ret;
}
+ return ret;
+}
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
- {
+{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
- }
+}
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
- {
+{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
- }
+}
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
- {
+{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
- }
+}
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
- {
+{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
- }
+}
/* BIO support data stored in the ASN1 BIO ex_arg */
typedef struct ndef_aux_st
- {
+{
/* ASN1 structure this BIO refers to */
ASN1_VALUE *val;
const ASN1_ITEM *it;
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
- } NDEF_SUPPORT;
+} NDEF_SUPPORT;
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
- {
+{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
if (!aux || !aux->asn1_cb)
- {
+ {
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
- }
+ }
ndef_aux = malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
if (ndef_aux)
free(ndef_aux);
return NULL;
- }
+}
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
*plen = *ndef_aux->boundary - *pbuf;
return 1;
- }
+}
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
if (!parg)
*pbuf = NULL;
*plen = 0;
return 1;
- }
+}
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
if (!ndef_prefix_free(b, pbuf, plen, parg))
return 0;
free(*pndef_aux);
*pndef_aux = NULL;
return 1;
- }
+}
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
- {
+{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
return 1;
- }
+}
EVP_PKEY *d2i_PrivateKey(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)
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_EVP_LIB);
return(NULL);
- }
}
+ }
else
- {
+ {
ret= *a;
#ifndef OPENSSL_NO_ENGINE
if (ret->engine)
- {
+ {
ENGINE_finish(ret->engine);
ret->engine = NULL;
- }
-#endif
}
+#endif
+ }
if (!EVP_PKEY_set_type(ret, type))
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,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;
p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
if (!p8) goto err;
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
- }
+ }
else
- {
+ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
goto err;
- }
- }
+ }
+ }
if (a != NULL) (*a)=ret;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
return(NULL);
- }
+}
/* This works like d2i_PrivateKey() except it automatically works out the type */
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 */
+ { /* 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)
- {
+ {
ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,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);
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)
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
return(NULL);
- }
}
+ }
else ret= *a;
if (!EVP_PKEY_set_type(ret, type))
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,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,
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
(const unsigned char **)pp,length)) /* TMP UGLY CAST */
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if (!o2i_ECPublicKey(&(ret->pkey.ec),
(const unsigned char **)pp, length))
- {
+ {
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
goto err;
- }
+ }
break;
#endif
default:
ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
/* break; */
- }
+ }
if (a != NULL) (*a)=ret;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
return(NULL);
- }
+}
#include <openssl/asn1_mac.h>
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
- {
+{
ASN1_STRING *os;
if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
return(1);
- }
+}
/* int max_len: for returned value */
int ASN1_TYPE_get_octetstring(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))
- {
+ {
ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
return(-1);
- }
+ }
p=M_ASN1_STRING_data(a->value.octet_string);
ret=M_ASN1_STRING_length(a->value.octet_string);
if (ret < max_len)
num=max_len;
memcpy(data,p,num);
return(ret);
- }
+}
int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
int len)
- {
+{
int n,size;
ASN1_OCTET_STRING os,*osp;
ASN1_INTEGER in;
if ((osp=ASN1_STRING_new()) == NULL) return(0);
/* Grow the 'string' */
if (!ASN1_STRING_set(osp,NULL,size))
- {
+ {
ASN1_STRING_free(osp);
return(0);
- }
+ }
M_ASN1_STRING_length_set(osp, size);
p=M_ASN1_STRING_data(osp);
ASN1_TYPE_set(a,V_ASN1_SEQUENCE,osp);
return(1);
- }
+}
/* we return the actual length..., num may be missing, in which
* case, set it to zero */
/* int max_len: for returned value */
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
int max_len)
- {
+{
int ret= -1,n;
ASN1_INTEGER *ai=NULL;
ASN1_OCTET_STRING *os=NULL;
ASN1_const_CTX c;
if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL))
- {
+ {
goto err;
- }
+ }
p=M_ASN1_STRING_data(a->value.sequence);
length=M_ASN1_STRING_length(a->value.sequence);
if (data != NULL)
memcpy(data,M_ASN1_STRING_data(os),n);
if (0)
- {
+ {
err:
ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
- }
+ }
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
if (ai != NULL) M_ASN1_INTEGER_free(ai);
return(ret);
- }
+}
/* Based on a_int.c: equivalent ENUMERATED functions */
int i2a_ASN1_ENUMERATED(BIO *bp, 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;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
again=(buf[i-1] == '\\');
for (j=0; j<i; j++)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
bufp=(unsigned char *)buf;
if (first)
- {
+ {
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
- {
+ {
bufp+=2;
i-=2;
- }
}
+ }
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
sp=(unsigned char *)realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include <openssl/asn1.h>
int i2a_ASN1_INTEGER(BIO *bp, 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;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
again=(buf[i-1] == '\\');
for (j=0; j<i; j++)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
bufp=(unsigned char *)buf;
if (first)
- {
+ {
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
- {
+ {
bufp+=2;
i-=2;
- }
}
+ }
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
else
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_INTEGER,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include <openssl/asn1.h>
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
- {
+{
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,"0",1) != 1) goto err;
n=1;
- }
+ }
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_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
- {
+{
int ret=0;
int i,j,k,m,n,again,bufsize;
unsigned char *s=NULL,*sp;
bufsize=BIO_gets(bp,buf,size);
for (;;)
- {
+ {
if (bufsize < 1)
- {
+ {
if (first)
break;
else
goto err_sl;
- }
+ }
first=0;
i=bufsize;
again=(buf[i-1] == '\\');
for (j=i-1; j>0; j--)
- {
+ {
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
- {
+ {
i=j;
break;
- }
}
+ }
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
k=0;
i-=again;
if (i%2 != 0)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
- }
+ }
i/=2;
if (num+i > slen)
- {
+ {
if (s == NULL)
sp=(unsigned char *)malloc(
(unsigned int)num+i*2);
sp=(unsigned char *)realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
if (s != NULL) free(s);
goto err;
- }
+ }
s=sp;
slen=num+i*2;
- }
+ }
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
- {
+ {
ASN1err(ASN1_F_A2I_ASN1_STRING,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;
ret=1;
err:
if (0)
- {
+ {
err_sl:
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_SHORT_LINE);
- }
- return(ret);
}
+ return(ret);
+}
#include "asn1_locl.h"
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;
- }
+}
ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1);
- }
+}
#endif
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));
default:
ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1);
- }
}
+}
#ifndef OPENSSL_NO_RC4
typedef struct netscape_pkey_st
- {
+{
long version;
X509_ALGOR *algor;
ASN1_OCTET_STRING *private_key;
- } NETSCAPE_PKEY;
+} NETSCAPE_PKEY;
typedef struct netscape_encrypted_pkey_st
- {
+{
ASN1_OCTET_STRING *os;
/* This is the same structure as DigestInfo so use it:
* although this isn't really anything to do with
* digests.
*/
X509_SIG *enckey;
- } NETSCAPE_ENCRYPTED_PKEY;
+} NETSCAPE_ENCRYPTED_PKEY;
ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
int i2d_RSA_NET(const RSA *a, unsigned char **pp,
int (*cb)(char *buf, int len, const char *prompt, int verify),
int sgckey)
- {
+{
int i, j, ret = 0;
int rsalen, pkeylen, olen;
NETSCAPE_PKEY *pkey = NULL;
enckey->enckey->algor->parameter->type=V_ASN1_NULL;
if (pp == NULL)
- {
+ {
olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
NETSCAPE_PKEY_free(pkey);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return olen;
- }
+ }
/* Since its RC4 encrypted length is actual length */
if ((zz=(unsigned char *)malloc(rsalen)) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
pkey->private_key->data = zz;
/* Write out private key encoding */
i2d_RSAPrivateKey(a,&zz);
if ((zz=malloc(pkeylen)) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!ASN1_STRING_set(enckey->os, "private-key", -1))
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
enckey->enckey->digest->data = zz;
i2d_NETSCAPE_PKEY(pkey,&zz);
cb=EVP_read_pw_string;
i=cb((char *)buf,256,"Enter Private Key password:",1);
if (i != 0)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
goto err;
- }
+ }
i = strlen((char *)buf);
/* If the key is used for SGC the algorithm is modified a little. */
if(sgckey) {
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
- }
+}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return(ret);
- }
+}
RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
int (*cb)(char *buf, int len, const char *prompt, int verify),
int sgckey)
- {
+{
RSA *ret=NULL;
const unsigned char *p;
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
if(!enckey) {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
return NULL;
- }
+}
if ((enckey->os->length != 11) || (strncmp("private-key",
(char *)enckey->os->data,11) != 0))
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return NULL;
- }
+ }
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
goto err;
- }
+}
if (cb == NULL)
cb=EVP_read_pw_string;
if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return ret;
- }
+}
static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
int (*cb)(char *buf, int len, const char *prompt,
int verify), int sgckey)
- {
+{
NETSCAPE_PKEY *pkey=NULL;
RSA *ret=NULL;
int i,j;
i=cb((char *)buf,256,"Enter Private Key password:",0);
if (i != 0)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
goto err;
- }
+ }
i = strlen((char *)buf);
if(sgckey){
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
- }
+}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
zz=os->data;
if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
goto err;
- }
+ }
zz=pkey->private_key->data;
if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
- {
+ {
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
goto err;
- }
+ }
err:
EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_PKEY_free(pkey);
return(ret);
- }
+}
#endif /* OPENSSL_NO_RC4 */
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen)
- {
+{
PBEPARAM *pbe=NULL;
ASN1_STRING *pbe_str=NULL;
unsigned char *sstr;
pbe = PBEPARAM_new();
if (!pbe)
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if(iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if (!ASN1_INTEGER_set(pbe->iter, iter))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
sstr = ASN1_STRING_data(pbe->salt);
if (salt)
memcpy(sstr, salt, saltlen);
goto err;
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
PBEPARAM_free(pbe);
pbe = NULL;
if (pbe_str != NULL)
ASN1_STRING_free(pbe_str);
return 0;
- }
+}
/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen)
- {
+{
X509_ALGOR *ret;
ret = X509_ALGOR_new();
if (!ret)
- {
+ {
ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
return NULL;
- }
+ }
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
return ret;
X509_ALGOR_free(ret);
return NULL;
- }
+}
if (key->pkey->value.octet_string)
OPENSSL_cleanse(key->pkey->value.octet_string->data,
key->pkey->value.octet_string->length);
- }
+}
return 1;
}
int version,
int ptype, void *pval,
unsigned char *penc, int penclen)
- {
+{
unsigned char **ppenc = NULL;
if (version >= 0)
- {
+ {
if (!ASN1_INTEGER_set(priv->version, version))
return 0;
- }
+ }
if (penc)
- {
+ {
int pmtype;
ASN1_OCTET_STRING *oct;
oct = ASN1_OCTET_STRING_new();
else
pmtype = V_ASN1_OCTET_STRING;
ASN1_TYPE_set(priv->pkey, pmtype, oct);
- }
+ }
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
- {
+ {
/* If call fails do not swallow 'enc' */
if (ppenc)
*ppenc = NULL;
return 0;
- }
- return 1;
}
+ return 1;
+}
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
PKCS8_PRIV_KEY_INFO *p8)
- {
+{
if (ppkalg)
*ppkalg = p8->pkeyalg->algorithm;
if(p8->pkey->type == V_ASN1_OCTET_STRING)
- {
+ {
p8->broken = PKCS8_OK;
if (pk)
- {
+ {
*pk = p8->pkey->value.octet_string->data;
*ppklen = p8->pkey->value.octet_string->length;
- }
}
+ }
else if (p8->pkey->type == V_ASN1_SEQUENCE)
- {
+ {
p8->broken = PKCS8_NO_OCTET;
if (pk)
- {
+ {
*pk = p8->pkey->value.sequence->data;
*ppklen = p8->pkey->value.sequence->length;
- }
}
+ }
else
return 0;
if (pa)
*pa = p8->pkeyalg;
return 1;
- }
+}
#ifndef OPENSSL_NO_FP_API
int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_CRL_print(b, x);
BIO_free(b);
return(ret);
- }
+}
#endif
int X509_CRL_print(BIO *out, X509_CRL *x)
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)
- {
+{
int n,i;
const char *neg;
if(!BIO_indent(bp,off,128))
return 0;
if (BN_is_zero(num))
- {
+ {
if (BIO_printf(bp, "%s 0\n", number) <= 0)
return 0;
return 1;
- }
+ }
if (BN_num_bytes(num) <= BN_BYTES)
- {
+ {
if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
<= 0) return(0);
- }
+ }
else
- {
+ {
buf[0]=0;
if (BIO_printf(bp,"%s%s",number,
(neg[0] == '-')?" (Negative)":"") <= 0)
else buf++;
for (i=0; i<n; i++)
- {
+ {
if ((i%15) == 0)
- {
+ {
if(BIO_puts(bp,"\n") <= 0
|| !BIO_indent(bp,off+4,128))
return 0;
- }
+ }
if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
<= 0) return(0);
- }
- if (BIO_write(bp,"\n",1) <= 0) return(0);
}
- return(1);
+ if (BIO_write(bp,"\n",1) <= 0) return(0);
}
+ return(1);
+}
#ifndef OPENSSL_NO_FP_API
int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
- {
+{
BIO *b;
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_REQ_PRINT_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_REQ_print(b, x);
BIO_free(b);
return(ret);
- }
+}
#endif
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
- {
+{
unsigned long l;
int i;
const char *neg;
ri=x->req_info;
if(!(cflag & X509_FLAG_NO_HEADER))
- {
+ {
if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VERSION))
- {
+ {
neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
l=0;
for (i=0; i<ri->version->length; i++)
- { l<<=8; l+=ri->version->data[i]; }
+ { l<<=8; l+=ri->version->data[i]; }
if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
l) <= 0)
goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SUBJECT))
{
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
}
if(!(cflag & X509_FLAG_NO_PUBKEY))
- {
+ {
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
goto err;
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
pkey=X509_REQ_get_pubkey(x);
if (pkey == NULL)
- {
+ {
BIO_printf(bp,"%12sUnable to load Public Key\n","");
ERR_print_errors(bp);
- }
+ }
else
- {
+ {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
- }
}
+ }
if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
- {
+ {
/* may not be */
if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
goto err;
sk=x->req_info->attributes;
if (sk_X509_ATTRIBUTE_num(sk) == 0)
- {
+ {
if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
goto err;
- }
+ }
else
- {
+ {
for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
- {
+ {
ASN1_TYPE *at;
X509_ATTRIBUTE *a;
ASN1_BIT_STRING *bs=NULL;
if(BIO_printf(bp,"%12s","") <= 0)
goto err;
if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
- {
+ {
if (a->single)
- {
+ {
t=a->value.single;
type=t->type;
bs=t->value.bit_string;
- }
+ }
else
- {
+ {
ii=0;
count=sk_ASN1_TYPE_num(a->value.set);
get_next:
at=sk_ASN1_TYPE_value(a->value.set,ii);
type=at->type;
bs=at->value.asn1_string;
- }
}
+ }
for (j=25-j; j>0; j--)
if (BIO_write(bp," ",1) != 1) goto err;
if (BIO_puts(bp,":") <= 0) goto err;
if ( (type == V_ASN1_PRINTABLESTRING) ||
(type == V_ASN1_T61STRING) ||
(type == V_ASN1_IA5STRING))
- {
+ {
if (BIO_write(bp,(char *)bs->data,bs->length)
!= bs->length)
goto err;
BIO_puts(bp,"\n");
- }
+ }
else
- {
+ {
BIO_puts(bp,"unable to print attribute\n");
- }
- if (++ii < count) goto get_next;
}
+ if (++ii < count) goto get_next;
}
}
+ }
if(!(cflag & X509_FLAG_NO_EXTENSIONS))
- {
+ {
exts = X509_REQ_get_extensions(x);
if(exts)
- {
+ {
BIO_printf(bp,"%8sRequested Extensions:\n","");
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
- {
+ {
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
int j;
if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
goto err;
if(!X509V3_EXT_print(bp, ex, cflag, 16))
- {
+ {
BIO_printf(bp, "%16s", "");
M_ASN1_OCTET_STRING_print(bp,ex->value);
- }
- if (BIO_write(bp,"\n",1) <= 0) goto err;
}
- sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ if (BIO_write(bp,"\n",1) <= 0) goto err;
}
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
}
+ }
if(!(cflag & X509_FLAG_NO_SIGDUMP))
- {
+ {
if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
- }
+ }
return(1);
err:
X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
return(0);
- }
+}
int X509_REQ_print(BIO *bp, X509_REQ *x)
- {
+{
return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
- }
+}
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
if(!pkey) BIO_printf(out, " Unable to load public key\n");
else
- {
+ {
EVP_PKEY_print_public(out, pkey, 4, NULL);
EVP_PKEY_free(pkey);
- }
+ }
chal = spki->spkac->challenge;
if(chal->length)
BIO_printf(out, " Challenge String: %s\n", chal->data);
n=spki->signature->length;
s=(char *)spki->signature->data;
for (i=0; i<n; i++)
- {
+ {
if ((i%18) == 0) BIO_write(out,"\n ",7);
BIO_printf(out,"%02x%s",(unsigned char)s[i],
((i+1) == n)?"":":");
- }
+ }
BIO_write(out,"\n",1);
return 1;
}
#ifndef OPENSSL_NO_FP_API
int X509_print_fp(FILE *fp, X509 *x)
- {
+{
return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
- }
+}
int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
{
int ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
- {
+ {
X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
return(0);
- }
+ }
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=X509_print_ex(b, x, nmflag, cflag);
BIO_free(b);
}
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
- {
+{
long l;
int ret=0,i;
char *m=NULL,mlch = ' ';
ci=x->cert_info;
if(!(cflag & X509_FLAG_NO_HEADER))
- {
+ {
if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VERSION))
- {
+ {
l=X509_get_version(x);
if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SERIAL))
- {
+ {
if (BIO_write(bp," Serial Number:",22) <= 0) goto err;
bs=X509_get_serialNumber(x);
if (bs->length <= (int)sizeof(long))
- {
+ {
l=ASN1_INTEGER_get(bs);
if (bs->type == V_ASN1_NEG_INTEGER)
- {
+ {
l= -l;
neg="-";
- }
+ }
else
neg="";
if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
goto err;
- }
+ }
else
- {
+ {
neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
for (i=0; i<bs->length; i++)
- {
+ {
if (BIO_printf(bp,"%02x%c",bs->data[i],
((i+1 == bs->length)?'\n':':')) <= 0)
goto err;
- }
}
-
}
+ }
+
if(!(cflag & X509_FLAG_NO_SIGNAME))
- {
+ {
if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
goto err;
#if 0
if (BIO_puts(bp, "\n") <= 0)
goto err;
#endif
- }
+ }
if(!(cflag & X509_FLAG_NO_ISSUER))
- {
+ {
if (BIO_printf(bp," Issuer:%c",mlch) <= 0) goto err;
if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_VALIDITY))
- {
+ {
if (BIO_write(bp," Validity\n",17) <= 0) goto err;
if (BIO_write(bp," Not Before: ",24) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_SUBJECT))
- {
+ {
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
if (BIO_write(bp,"\n",1) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_PUBKEY))
- {
+ {
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
goto err;
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
pkey=X509_get_pubkey(x);
if (pkey == NULL)
- {
+ {
BIO_printf(bp,"%12sUnable to load Public Key\n","");
ERR_print_errors(bp);
- }
+ }
else
- {
+ {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
- }
}
+ }
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
X509V3_extensions_print(bp, "X509v3 extensions",
ci->extensions, cflag, 8);
if(!(cflag & X509_FLAG_NO_SIGDUMP))
- {
+ {
if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
- }
+ }
if(!(cflag & X509_FLAG_NO_AUX))
- {
+ {
if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
- }
+ }
ret=1;
err:
if (m != NULL) free(m);
return(ret);
- }
+}
int X509_ocspid_print (BIO *bp, X509 *x)
- {
+{
unsigned char *der=NULL ;
unsigned char *dertmp;
int derlen;
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
+ {
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
- }
+ }
free (der);
der=NULL;
SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i=0; i < SHA_DIGEST_LENGTH; i++)
- {
+ {
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
goto err;
- }
+ }
BIO_printf(bp,"\n");
return (1);
err:
if (der != NULL) free(der);
return(0);
- }
+}
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
n=sig->length;
s=sig->data;
for (i=0; i<n; i++)
- {
+ {
if ((i%18) == 0)
- {
+ {
if (BIO_write(bp,"\n",1) <= 0) return 0;
if (BIO_indent(bp, indent, indent) <= 0) return 0;
- }
+ }
if (BIO_printf(bp,"%02x%s",s[i],
((i+1) == n)?"":":") <= 0) return 0;
- }
+ }
if (BIO_write(bp,"\n",1) != 1) return 0;
return 1;
sig_nid = OBJ_obj2nid(sigalg->algorithm);
if (sig_nid != NID_undef)
- {
+ {
int pkey_nid, dig_nid;
const EVP_PKEY_ASN1_METHOD *ameth;
if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
- {
+ {
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
if (ameth && ameth->sig_print)
return ameth->sig_print(bp, sigalg, sig, 9, 0);
- }
}
+ }
if (sig)
return X509_signature_dump(bp, sig, 9);
else if (BIO_puts(bp, "\n") <= 0)
}
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
- {
+{
int i,n;
char buf[80];
const char *p;
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]='.';
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)
{
};
int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
- {
+{
char *v;
int gmt=0;
int i;
if (tm->length >= 14 &&
(v[12] >= '0') && (v[12] <= '9') &&
(v[13] >= '0') && (v[13] <= '9'))
- {
+ {
s= (v[12]-'0')*10+(v[13]-'0');
/* Check for fractions of seconds. */
if (tm->length >= 15 && v[14] == '.')
- {
+ {
int l = tm->length;
f = &v[14]; /* The decimal point. */
f_len = 1;
while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
++f_len;
- }
}
+ }
if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
err:
BIO_write(bp,"Bad time value",14);
return(0);
- }
+}
int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
- {
+{
const char *v;
int gmt=0;
int i;
err:
BIO_write(bp,"Bad time value",14);
return(0);
- }
+}
int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
- {
+{
char *s,*c,*b;
int ret=0,l,i;
b=X509_NAME_oneline(name,NULL,0);
if (!*b)
- {
+ {
free(b);
return 1;
- }
+ }
s=b+1; /* skip the first slash */
c=s;
for (;;)
- {
+ {
if ( ((*s == '/') &&
((s[1] >= 'A') && (s[1] <= 'Z') && (
(s[2] == '=') ||
(s[3] == '='))
))) ||
(*s == '\0'))
- {
+ {
i=s-c;
if (BIO_write(bp,c,i) != i) goto err;
c=s+1; /* skip following slash */
if (*s != '\0')
- {
+ {
if (BIO_write(bp,", ",2) != 2) goto err;
- }
- l--;
}
+ l--;
+ }
if (*s == '\0') break;
s++;
l--;
- }
+ }
ret=1;
if (0)
- {
+ {
err:
X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
- }
+ }
free(b);
return(ret);
- }
+}
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)
- {
+{
if ((tag < 0) || (tag > 30)) return 0;
return tag2bit[tag];
- }
+}
/* Macro to initialize and invalidate the cache */
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;
if (!pval)
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval;
return NULL;
- }
+}
int ASN1_template_d2i(ASN1_VALUE **pval,
const unsigned char **in, long len, const ASN1_TEMPLATE *tt)
- {
+{
ASN1_TLC c;
asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c);
- }
+}
/* Decode an item, taking care of IMPLICIT tagging, if any.
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)
- {
+{
const ASN1_TEMPLATE *tt, *errtt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
else asn1_cb = 0;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
- {
+ {
/* tagging or OPTIONAL is currently illegal on an item
* template because the flags can't get passed down.
* In practice this isn't a problem: we include the
* template itself.
*/
if ((tag != -1) || opt)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
goto err;
- }
+ }
return asn1_template_ex_d2i(pval, in, len,
it->templates, opt, ctx);
- }
+ }
return asn1_d2i_ex_primitive(pval, in, len, it,
tag, aclass, opt, ctx);
break;
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
&p, len, -1, 0, 1, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* Must be UNIVERSAL class */
if (oclass != V_ASN1_UNIVERSAL)
- {
+ {
/* If OPTIONAL, assume this is OK */
if (opt) return -1;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
- }
+ }
/* Check tag matches bit map */
if (!(ASN1_tag2bit(otag) & it->utype))
- {
+ {
/* If OPTIONAL, assume this is OK */
if (opt)
return -1;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_MSTRING_WRONG_TAG);
goto err;
- }
+ }
return asn1_d2i_ex_primitive(pval, in, len,
it, otag, 0, 0, ctx);
/* If OPTIONAL see if it is there */
if (opt)
- {
+ {
int exptag;
p = *in;
if (tag == -1)
ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL,
&p, len, exptag, aclass, 1, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if (ret == -1)
return -1;
- }
+ }
/* This is the old style evil hack IMPLICIT handling:
* since the underlying code is expecting a tag and
*/
if (tag != -1)
- {
+ {
wp = *(unsigned char **)in;
imphack = *wp;
if (p == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
| it->utype);
- }
+ }
ptmpval = cf->asn1_d2i(pval, in, len);
/* Allocate structure */
if (!*pval && !ASN1_item_ex_new(pval, it))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* CHOICE type, try each possibility in turn */
p = *in;
for (i = 0, tt=it->templates; i < it->tcount; i++, tt++)
- {
+ {
pchptr = asn1_get_field_ptr(pval, tt);
/* We mark field as OPTIONAL so its absence
* can be recognised.
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
/* Did we fall off the end without reading anything? */
if (i == it->tcount)
- {
+ {
/* If OPTIONAL, this is OK */
if (opt)
- {
+ {
/* Free and zero it */
ASN1_item_ex_free(pval, it);
return -1;
- }
+ }
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_NO_MATCHING_CHOICE_TYPE);
goto err;
- }
+ }
asn1_set_choice_selector(pval, i, it);
*in = p;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if (tag == -1)
- {
+ {
tag = V_ASN1_SEQUENCE;
aclass = V_ASN1_UNIVERSAL;
- }
+ }
/* Get SEQUENCE length and update len, p */
ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
&p, len, tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
if (aux && (aux->flags & ASN1_AFLG_BROKEN))
- {
+ {
len = tmplen - (p - *in);
seq_nolen = 1;
- }
+ }
/* If indefinite we don't do a length check */
else seq_nolen = seq_eoc;
if (!cst)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
goto err;
- }
+ }
if (!*pval && !ASN1_item_ex_new(pval, it))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
/* Get each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
break;
q = p;
if (asn1_check_eoc(&p, len))
- {
+ {
if (!seq_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_UNEXPECTED_EOC);
goto err;
- }
+ }
len -= p - q;
seq_eoc = 0;
q = p;
break;
- }
+ }
/* This determines the OPTIONAL flag value. The field
* cannot be omitted if it is the last of a SEQUENCE
* and there is still data to be read. This isn't
ret = asn1_template_ex_d2i(pseqval, &p, len,
seqtt, isopt, ctx);
if (!ret)
- {
+ {
errtt = seqtt;
goto err;
- }
+ }
else if (ret == -1)
- {
+ {
/* OPTIONAL component absent.
* Free and zero the field.
*/
ASN1_template_free(pseqval, seqtt);
continue;
- }
+ }
/* Update length */
len -= p - q;
- }
+ }
/* Check for EOC if expecting one */
if (seq_eoc && !asn1_check_eoc(&p, len))
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
goto err;
- }
+ }
/* Check all data read */
if (!seq_nolen && len)
- {
+ {
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_SEQUENCE_LENGTH_MISMATCH);
goto err;
- }
+ }
/* If we get here we've got no more data in the SEQUENCE,
* however we may not have read all fields so check all
* remaining are OPTIONAL and clear any that are.
*/
for (; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
goto err;
if (seqtt->flags & ASN1_TFLG_OPTIONAL)
- {
+ {
ASN1_VALUE **pseqval;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
- }
+ }
else
- {
+ {
errtt = seqtt;
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I,
ASN1_R_FIELD_MISSING);
goto err;
- }
}
+ }
/* Save encoding */
if (!asn1_enc_save(pval, *in, p - *in, it))
goto auxerr;
default:
return 0;
- }
+ }
auxerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
err:
else
ERR_add_error_data(2, "Type=", it->sname);
return 0;
- }
+}
/* Templates are handled with two separate functions.
* One handles any EXPLICIT tag and the other handles the rest.
const unsigned char **in, long inlen,
const ASN1_TEMPLATE *tt, char opt,
ASN1_TLC *ctx)
- {
+{
int flags, aclass;
int ret;
long len;
/* Check if EXPLICIT tag expected */
if (flags & ASN1_TFLG_EXPTAG)
- {
+ {
char cst;
/* Need to work out amount of data available to the inner
* content and where it starts: so read in EXPLICIT header to
&p, inlen, tt->tag, aclass, opt, ctx);
q = p;
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
if (!cst)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
return 0;
- }
+ }
/* We've found the field so it can't be OPTIONAL now */
ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
/* We read the field in OK so update length */
len -= p - q;
if (exp_eoc)
- {
+ {
/* If NDEF we must have an EOC here */
if (!asn1_check_eoc(&p, len))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_MISSING_EOC);
goto err;
- }
}
+ }
else
- {
+ {
/* Otherwise we must hit the EXPLICIT tag end or its
* an error */
if (len)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
ASN1_R_EXPLICIT_LENGTH_MISMATCH);
goto err;
- }
}
}
+ }
else
return asn1_template_noexp_d2i(val, in, inlen,
tt, opt, ctx);
err:
ASN1_template_free(val, tt);
return 0;
- }
+}
static int asn1_template_noexp_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_TEMPLATE *tt, char opt,
ASN1_TLC *ctx)
- {
+{
int flags, aclass;
int ret;
const unsigned char *p, *q;
q = p;
if (flags & ASN1_TFLG_SK_MASK)
- {
+ {
/* SET OF, SEQUENCE OF */
int sktag, skaclass;
char sk_eoc;
/* First work out expected inner tag value */
if (flags & ASN1_TFLG_IMPTAG)
- {
+ {
sktag = tt->tag;
skaclass = aclass;
- }
+ }
else
- {
+ {
skaclass = V_ASN1_UNIVERSAL;
if (flags & ASN1_TFLG_SET_OF)
sktag = V_ASN1_SET;
else
sktag = V_ASN1_SEQUENCE;
- }
+ }
/* Get the tag */
ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
&p, len, sktag, skaclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
if (!*val)
*val = (ASN1_VALUE *)sk_new_null();
else
- {
+ {
/* We've got a valid STACK: free up any items present */
STACK_OF(ASN1_VALUE) *sktmp
= (STACK_OF(ASN1_VALUE) *)*val;
ASN1_VALUE *vtmp;
while(sk_ASN1_VALUE_num(sktmp) > 0)
- {
+ {
vtmp = sk_ASN1_VALUE_pop(sktmp);
ASN1_item_ex_free(&vtmp,
ASN1_ITEM_ptr(tt->item));
- }
}
+ }
if (!*val)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
+ }
/* Read as many items as we can */
while(len > 0)
- {
+ {
ASN1_VALUE *skfield;
q = p;
/* See if EOC found */
if (asn1_check_eoc(&p, len))
- {
+ {
if (!sk_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ASN1_R_UNEXPECTED_EOC);
goto err;
- }
+ }
len -= p - q;
sk_eoc = 0;
break;
- }
+ }
skfield = NULL;
if (!ASN1_item_ex_d2i(&skfield, &p, len,
ASN1_ITEM_ptr(tt->item),
-1, 0, 0, ctx))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
skfield))
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
}
+ }
if (sk_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
goto err;
- }
}
+ }
else if (flags & ASN1_TFLG_IMPTAG)
- {
+ {
/* IMPLICIT tagging */
ret = ASN1_item_ex_d2i(val, &p, len,
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
- }
+ }
else
- {
+ {
/* Nothing special */
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
-1, 0, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
ERR_R_NESTED_ASN1_ERROR);
goto err;
- }
+ }
else if (ret == -1)
return -1;
- }
+ }
*in = p;
return 1;
err:
ASN1_template_free(val, tt);
return 0;
- }
+}
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
const unsigned char **in, long inlen,
const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx)
- {
+{
int ret = 0, utype;
long plen;
char cst, inf, free_cont = 0;
const unsigned char *cont = NULL;
long len;
if (!pval)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
return 0; /* Should never happen */
- }
+ }
if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
utype = tag;
tag = -1;
- }
+ }
else
utype = it->utype;
if (utype == V_ASN1_ANY)
- {
+ {
/* If type is ANY need to figure out type from tag */
unsigned char oclass;
if (tag >= 0)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_ILLEGAL_TAGGED_ANY);
return 0;
- }
+ }
if (opt)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_ILLEGAL_OPTIONAL_ANY);
return 0;
- }
+ }
p = *in;
ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
&p, inlen, -1, 0, 0, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
if (oclass != V_ASN1_UNIVERSAL)
utype = V_ASN1_OTHER;
- }
+ }
if (tag == -1)
- {
+ {
tag = utype;
aclass = V_ASN1_UNIVERSAL;
- }
+ }
p = *in;
/* Check header */
ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
&p, inlen, tag, aclass, opt, ctx);
if (!ret)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
else if (ret == -1)
return -1;
ret = 0;
/* SEQUENCE, SET and "OTHER" are left in encoded form */
if ((utype == V_ASN1_SEQUENCE)
|| (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER))
- {
+ {
/* Clear context cache for type OTHER because the auto clear
* 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)
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
- }
+ }
cont = *in;
/* If indefinite length constructed find the real end */
if (inf)
- {
+ {
if (!asn1_find_end(&p, plen, inf))
goto err;
len = p - cont;
- }
+ }
else
- {
+ {
len = p - cont + plen;
p += plen;
buf.data = NULL;
- }
}
+ }
else if (cst)
- {
+ {
buf.length = 0;
buf.max = 0;
buf.data = NULL;
* for UNIVERSAL class and ignore the tag.
*/
if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
- {
+ {
free_cont = 1;
goto err;
- }
+ }
len = buf.length;
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1))
- {
+ {
ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
buf.data[len] = 0;
cont = (const unsigned char *)buf.data;
free_cont = 1;
- }
+ }
else
- {
+ {
cont = 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))
err:
if (free_cont && buf.data) free(buf.data);
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)
- {
+{
ASN1_VALUE **opval = NULL;
ASN1_STRING *stmp;
ASN1_TYPE *typ = NULL;
return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
/* If ANY type clear type and set pointer to internal value */
if (it->utype == V_ASN1_ANY)
- {
+ {
if (!*pval)
- {
+ {
typ = ASN1_TYPE_new();
if (typ == NULL)
goto err;
*pval = (ASN1_VALUE *)typ;
- }
+ }
else
typ = (ASN1_TYPE *)*pval;
ASN1_TYPE_set(typ, utype, NULL);
opval = pval;
pval = &typ->value.asn1_value;
- }
+ }
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
goto err;
case V_ASN1_NULL:
if (len)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_NULL_IS_WRONG_LENGTH);
goto err;
- }
+ }
*pval = (ASN1_VALUE *)1;
break;
case V_ASN1_BOOLEAN:
if (len != 1)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
goto err;
- }
+ }
else
- {
+ {
ASN1_BOOLEAN *tbool;
tbool = (ASN1_BOOLEAN *)pval;
*tbool = *cont;
- }
+ }
break;
case V_ASN1_BIT_STRING:
case V_ASN1_SEQUENCE:
default:
if (utype == V_ASN1_BMPSTRING && (len & 1))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
goto err;
- }
+ }
if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
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)
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ERR_R_MALLOC_FAILURE);
goto err;
- }
- *pval = (ASN1_VALUE *)stmp;
}
+ *pval = (ASN1_VALUE *)stmp;
+ }
else
- {
+ {
stmp = (ASN1_STRING *)*pval;
stmp->type = utype;
- }
+ }
/* If we've already allocated a buffer use it */
if (*free_cont)
- {
+ {
if (stmp->data)
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))
- {
+ {
ASN1err(ASN1_F_ASN1_EX_C2I,
ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
- }
}
- break;
}
+ break;
+ }
/* If ASN1_ANY and NULL type fix up value */
if (typ && (utype == V_ASN1_NULL))
typ->value.ptr = NULL;
ret = 1;
err:
if (!ret)
- {
+ {
ASN1_TYPE_free(typ);
if (opval)
*opval = NULL;
- }
- return ret;
}
+ return ret;
+}
/* This function finds the end of an ASN1 structure when passed its maximum
*/
static int asn1_find_end(const unsigned char **in, long len, char inf)
- {
+{
int expected_eoc;
long plen;
const unsigned char *p = *in, *q;
/* If not indefinite length constructed just add length */
if (inf == 0)
- {
+ {
*in += len;
return 1;
- }
+ }
expected_eoc = 1;
/* Indefinite length constructed form. Find the end when enough EOCs
* are found. If more indefinite length constructed headers
* skip to the end of the data.
*/
while (len > 0)
- {
+ {
if(asn1_check_eoc(&p, len))
- {
+ {
expected_eoc--;
if (expected_eoc == 0)
break;
len -= 2;
continue;
- }
+ }
q = p;
/* Just read in a header: only care about the length */
if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-1, 0, 0, NULL))
- {
+ {
ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
if (inf)
expected_eoc++;
else
p += plen;
len -= p - q;
- }
+ }
if (expected_eoc)
- {
+ {
ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
return 0;
- }
+ }
*in = p;
return 1;
- }
+}
/* This function collects the asn1 data from a constructred string
* type into a buffer. The values of 'in' and 'len' should refer
* to the contents of the constructed type and 'inf' should be set
static int asn1_collect(BUF_MEM *buf, 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 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 */
if (asn1_check_eoc(&p, len))
- {
+ {
/* EOC is illegal outside indefinite length
* constructed form */
if (!inf)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT,
ASN1_R_UNEXPECTED_EOC);
return 0;
- }
+ }
inf = 0;
break;
- }
+ }
if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
len, tag, aclass, 0, NULL))
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
return 0;
- }
+ }
/* If indefinite length constructed update max length */
if (cst)
- {
+ {
if (depth >= ASN1_MAX_STRING_NEST)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT,
ASN1_R_NESTED_ASN1_STRING);
return 0;
- }
+ }
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
depth + 1))
return 0;
- }
+ }
else if (plen && !collect_data(buf, &p, plen))
return 0;
len -= p - q;
- }
+ }
if (inf)
- {
+ {
ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
return 0;
- }
+ }
*in = p;
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))
- {
+ {
ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
return 0;
- }
- memcpy(buf->data + len, *p, plen);
}
+ memcpy(buf->data + len, *p, plen);
+ }
*p += plen;
return 1;
- }
+}
/* Check for ASN1 EOC and swallow it if found */
static int asn1_check_eoc(const unsigned char **in, long len)
- {
+{
const unsigned char *p;
if (len < 2) return 0;
p = *in;
if (!p[0] && !p[1])
- {
+ {
*in += 2;
return 1;
- }
- return 0;
}
+ return 0;
+}
/* Check an ASN1 tag and length: a bit like ASN1_get_object
* but it sets the length for indefinite length constructed
const unsigned char **in, long len,
int exptag, int expclass, char opt,
ASN1_TLC *ctx)
- {
+{
int i;
int ptag, pclass;
long plen;
q = p;
if (ctx && ctx->valid)
- {
+ {
i = ctx->ret;
plen = ctx->plen;
pclass = ctx->pclass;
ptag = ctx->ptag;
p += ctx->hdrlen;
- }
+ }
else
- {
+ {
i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
if (ctx)
- {
+ {
ctx->ret = i;
ctx->plen = plen;
ctx->pclass = pclass;
* header can't exceed total amount of data available.
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
- {
+ {
ASN1err(ASN1_F_ASN1_CHECK_TLEN,
ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
return 0;
- }
}
}
+ }
if (i & 0x80)
- {
+ {
ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
return 0;
- }
+ }
if (exptag >= 0)
- {
+ {
if ((exptag != ptag) || (expclass != pclass))
- {
+ {
/* If type is OPTIONAL, not an error:
* indicate missing type.
*/
asn1_tlc_clear(ctx);
ASN1err(ASN1_F_ASN1_CHECK_TLEN, 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);
- }
+ }
if (i & 1)
plen = len - (p - q);
*in = p;
return 1;
- }
+}
int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it)
- {
+{
return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
- }
+}
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
- {
+{
return asn1_item_flags_i2d(val, out, it, 0);
- }
+}
/* Encode an ASN1 item, this is use by the
* standard 'i2d' function. 'out' points to
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags)
- {
+{
if (out && !*out)
- {
+ {
unsigned char *p, *buf;
int len;
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
*out = buf;
return len;
- }
+ }
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
- }
+}
/* Encode an item, taking care of IMPLICIT tagging (if any).
* This function performs the normal item handling: it can be
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
- {
+{
const ASN1_TEMPLATE *tt = NULL;
unsigned char *p = NULL;
int i, seqcontlen, seqlen, ndef = 1;
asn1_cb = aux->asn1_cb;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
return 0;
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount))
- {
+ {
ASN1_VALUE **pchval;
const ASN1_TEMPLATE *chtt;
chtt = it->templates + i;
pchval = asn1_get_field_ptr(pval, chtt);
return asn1_template_ex_i2d(pchval, out, chtt,
-1, aclass);
- }
+ }
/* Fixme: error condition if selector out of range */
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
seqcontlen = 0;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if (tag == -1)
- {
+ {
tag = V_ASN1_SEQUENCE;
/* Retain any other flags in aclass */
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
| V_ASN1_UNIVERSAL;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
/* First work out sequence content length */
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
/* FIXME: check for errors in enhanced version */
seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-1, aclass);
- }
+ }
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
if (!out)
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
- }
+ }
if (ndef == 2)
ASN1_put_eoc(out);
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
default:
return 0;
- }
- return 0;
}
+ return 0;
+}
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt)
- {
+{
return asn1_template_ex_i2d(pval, out, tt, -1, 0);
- }
+}
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt, int tag, int iclass)
- {
+{
int i, ret, flags, ttag, tclass, ndef;
flags = tt->flags;
/* Work out tag and class to use: tagging may come
* which should be noted and passed down to other levels.
*/
if (flags & ASN1_TFLG_TAG_MASK)
- {
+ {
/* Error if argument and template tagging */
if (tag != -1)
/* FIXME: error code here */
/* Get tagging from template */
ttag = tt->tag;
tclass = flags & ASN1_TFLG_TAG_CLASS;
- }
+ }
else if (tag != -1)
- {
+ {
/* No template tagging, get from arguments */
ttag = tag;
tclass = iclass & ASN1_TFLG_TAG_CLASS;
- }
+ }
else
- {
+ {
ttag = -1;
tclass = 0;
- }
+ }
/*
* Remove any class mask from iflag.
*/
else ndef = 1;
if (flags & ASN1_TFLG_SK_MASK)
- {
+ {
/* SET OF, SEQUENCE OF */
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
int isset, sktag, skaclass;
return 0;
if (flags & ASN1_TFLG_SET_OF)
- {
+ {
isset = 1;
/* 2 means we reorder */
if (flags & ASN1_TFLG_SEQUENCE_OF)
isset = 2;
- }
+ }
else isset = 0;
/* Work out inner tag value: if EXPLICIT
* or no tagging use underlying type.
*/
if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG))
- {
+ {
sktag = ttag;
skaclass = tclass;
- }
+ }
else
- {
+ {
skaclass = V_ASN1_UNIVERSAL;
if (isset)
sktag = V_ASN1_SET;
else sktag = V_ASN1_SEQUENCE;
- }
+ }
/* Determine total length of items */
skcontlen = 0;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
ASN1_ITEM_ptr(tt->item),
-1, iclass);
- }
+ }
sklen = ASN1_object_size(ndef, skcontlen, sktag);
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
isset, iclass);
if (ndef == 2)
- {
+ {
ASN1_put_eoc(out);
if (flags & ASN1_TFLG_EXPTAG)
ASN1_put_eoc(out);
- }
+ }
return ret;
- }
+ }
if (flags & ASN1_TFLG_EXPTAG)
- {
+ {
/* EXPLICIT tagging */
/* Find length of tagged item */
i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item),
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
if (out)
- {
+ {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
-1, iclass);
if (ndef == 2)
ASN1_put_eoc(out);
- }
- return ret;
}
+ return ret;
+ }
/* Either normal or IMPLICIT tagging: combine class and flags */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
} DER_ENC;
static int der_cmp(const void *a, const void *b)
- {
+{
const DER_ENC *d1 = a, *d2 = b;
int cmplen, i;
cmplen = (d1->length < d2->length) ? d1->length : d2->length;
if (i)
return i;
return d1->length - d2->length;
- }
+}
/* Output the content octets of SET OF or SEQUENCE OF */
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item,
int do_sort, int iclass)
- {
+{
int i;
ASN1_VALUE *skitem;
unsigned char *tmpdat = NULL, *p = NULL;
if (sk_ASN1_VALUE_num(sk) < 2)
do_sort = 0;
else
- {
+ {
derlst = malloc(sk_ASN1_VALUE_num(sk)
* sizeof(*derlst));
tmpdat = malloc(skcontlen);
free(derlst);
free(tmpdat);
return 0;
- }
}
+ }
/* If not sorting just output each item */
if (!do_sort)
- {
+ {
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
- }
- return 1;
}
+ return 1;
+ }
p = tmpdat;
/* Doing sort: build up a list of each member's DER encoding */
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
+ {
skitem = sk_ASN1_VALUE_value(sk, i);
tder->data = p;
tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
tder->field = skitem;
- }
+ }
/* Now sort them */
qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
/* Output sorted DER encoding */
p = *out;
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
- {
+ {
memcpy(p, tder->data, tder->length);
p += tder->length;
- }
+ }
*out = p;
/* If do_sort is 2 then reorder the STACK */
if (do_sort == 2)
- {
+ {
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk);
i++, tder++)
(void)sk_ASN1_VALUE_set(sk, i, tder->field);
- }
+ }
free(derlst);
free(tmpdat);
return 1;
- }
+}
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
- {
+{
int len;
int utype;
int usetag;
/* -2 return is special meaning use ndef */
if (len == -2)
- {
+ {
ndef = 2;
len = 0;
- }
+ }
/* If not implicitly tagged get tag from underlying type */
if (tag == -1) tag = utype;
/* Output tag+length followed by content octets */
if (out)
- {
+ {
if (usetag)
ASN1_put_object(out, ndef, len, tag, aclass);
asn1_ex_i2c(pval, *out, &utype, it);
ASN1_put_eoc(out);
else
*out += len;
- }
+ }
if (usetag)
return ASN1_object_size(ndef, len, tag);
return len;
- }
+}
/* Produce content octets from a structure */
int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
const ASN1_ITEM *it)
- {
+{
ASN1_BOOLEAN *tbool = NULL;
ASN1_STRING *strtmp;
ASN1_OBJECT *otmp;
/* Should type be omitted? */
if ((it->itype != ASN1_ITYPE_PRIMITIVE)
|| (it->utype != V_ASN1_BOOLEAN))
- {
+ {
if (!*pval) return -1;
- }
+ }
if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
/* If MSTRING type set the underlying type */
strtmp = (ASN1_STRING *)*pval;
utype = strtmp->type;
*putype = utype;
- }
+ }
else if (it->utype == V_ASN1_ANY)
- {
+ {
/* If ANY set type and pointer to value */
ASN1_TYPE *typ;
typ = (ASN1_TYPE *)*pval;
utype = typ->type;
*putype = utype;
pval = &typ->value.asn1_value;
- }
+ }
else utype = *putype;
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
otmp = (ASN1_OBJECT *)*pval;
cont = otmp->data;
if (*tbool == -1)
return -1;
if (it->utype != V_ASN1_ANY)
- {
+ {
/* Default handling if value == size field then omit */
if (*tbool && (it->size > 0))
return -1;
if (!*tbool && !it->size)
return -1;
- }
+ }
c = (unsigned char)*tbool;
cont = &c;
len = 1;
/* Special handling for NDEF */
if ((it->size == ASN1_TFLG_NDEF)
&& (strtmp->flags & ASN1_STRING_FLAG_NDEF))
- {
+ {
if (cout)
- {
+ {
strtmp->data = cout;
strtmp->length = 0;
- }
+ }
/* Special return code */
return -2;
- }
+ }
cont = strtmp->data;
len = strtmp->length;
break;
- }
+ }
if (cout && len)
memcpy(cout, cont, len);
return len;
- }
+}
/* Free up an ASN1 structure */
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
- {
+{
asn1_item_combine_free(&val, it, 0);
- }
+}
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
asn1_item_combine_free(pval, it, 0);
- }
+}
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
- {
+{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_COMPAT_FUNCS *cf;
asn1_cb = 0;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
- }
+ }
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount))
- {
+ {
ASN1_VALUE **pchval;
tt = it->templates + i;
pchval = asn1_get_field_ptr(pval, tt);
ASN1_template_free(pchval, tt);
- }
+ }
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
- {
+ {
free(*pval);
*pval = NULL;
- }
+ }
break;
case ASN1_ITYPE_COMPAT:
if (asn1_do_lock(pval, -1, it) > 0)
return;
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
- }
+ }
asn1_enc_free(pval, it);
/* If we free up as normal we will invalidate any
* ANY DEFINED BY field and we wont be able to
*/
tt = it->templates + it->tcount - 1;
for (i = 0; i < it->tcount; tt--, i++)
- {
+ {
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 0);
if (!seqtt)
continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
- }
+ }
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine)
- {
+ {
free(*pval);
*pval = NULL;
- }
- break;
}
+ break;
}
+}
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
int i;
if (tt->flags & ASN1_TFLG_SK_MASK)
- {
+ {
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
- {
+ {
ASN1_VALUE *vtmp;
vtmp = sk_ASN1_VALUE_value(sk, i);
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
0);
- }
+ }
sk_ASN1_VALUE_free(sk);
*pval = NULL;
- }
+ }
else
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
tt->flags & ASN1_TFLG_COMBINE);
- }
+}
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int utype;
if (it)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_free)
- {
+ {
pf->prim_free(pval, it);
return;
- }
}
+ }
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
if (!it)
- {
+ {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
- }
+ }
else if (it->itype == ASN1_ITYPE_MSTRING)
- {
+ {
utype = -1;
if (!*pval)
return;
- }
+ }
else
- {
+ {
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
- }
+ }
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
break;
ASN1_STRING_free((ASN1_STRING *)*pval);
*pval = NULL;
break;
- }
- *pval = NULL;
}
+ *pval = NULL;
+}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
- {
+{
ASN1_VALUE *ret = NULL;
if (ASN1_item_ex_new(&ret, it) > 0)
return ret;
return NULL;
- }
+}
/* Allocate an ASN1 structure */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
return asn1_item_ex_combine_new(pval, it, 0);
- }
+}
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine)
- {
+{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
#endif
switch(it->itype)
- {
+ {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_new)
- {
+ {
if (!ef->asn1_ex_new(pval, it))
goto memerr;
- }
+ }
break;
case ASN1_ITYPE_COMPAT:
*pval = cf->asn1_new();
if (!*pval)
goto memerr;
- }
+ }
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
- {
+ {
if (!ASN1_template_new(pval, it->templates))
goto memerr;
- }
+ }
else if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
- {
+ {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
- }
}
+ }
if (!combine)
- {
+ {
*pval = malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
- }
+ }
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i==2)
- {
+ {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
- }
}
+ }
if (!combine)
- {
+ {
*pval = malloc(it->size);
if (!*pval)
goto memerr;
memset(*pval, 0, it->size);
asn1_do_lock(pval, 0, it);
asn1_enc_init(pval, it);
- }
+ }
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
- {
+ {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
- }
+ }
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
- }
+}
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
#endif
#endif
return 0;
- }
+}
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
const ASN1_EXTERN_FUNCS *ef;
switch(it->itype)
- {
+ {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
- }
}
+}
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
int ret;
if (tt->flags & ASN1_TFLG_OPTIONAL)
- {
+ {
asn1_template_clear(pval, tt);
return 1;
- }
+ }
/* If ANY DEFINED BY nothing to do */
if (tt->flags & ASN1_TFLG_ADB_MASK)
- {
+ {
*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;
skval = sk_ASN1_VALUE_new_null();
if (!skval)
- {
+ {
ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
- }
+ }
*pval = (ASN1_VALUE *)skval;
ret = 1;
goto done;
- }
+ }
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
CRYPTO_pop_info();
#endif
return ret;
- }
+}
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
/* If ADB or STACK just NULL the field */
if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
*pval = NULL;
else
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
- }
+}
/* NB: could probably combine most of the real XXX_new() behaviour and junk
*/
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_TYPE *typ;
ASN1_STRING *str;
int utype;
if (it && it->funcs)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
- }
+ }
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
utype = it->utype;
switch(utype)
- {
+ {
case V_ASN1_OBJECT:
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
return 1;
str->flags |= ASN1_STRING_FLAG_MSTRING;
*pval = (ASN1_VALUE *)str;
break;
- }
+ }
if (*pval)
return 1;
return 0;
- }
+}
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int utype;
if (it && it->funcs)
- {
+ {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_clear)
pf->prim_clear(pval, it);
else
*pval = NULL;
return;
- }
+ }
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = -1;
else
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else *pval = NULL;
- }
+}
/* ASN1_PCTX routines */
ASN1_PCTX default_pctx =
- {
+{
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
0, /* cert_flags */
0, /* oid_flags */
0 /* str_flags */
- };
+};
ASN1_PCTX *ASN1_PCTX_new(void)
- {
+{
ASN1_PCTX *ret;
ret = malloc(sizeof(ASN1_PCTX));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_ASN1_PCTX_NEW, 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;
- }
+}
void ASN1_PCTX_free(ASN1_PCTX *p)
- {
+{
free(p);
- }
+}
unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
- {
+{
return p->flags;
- }
+}
void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
- {
+{
return p->nm_flags;
- }
+}
void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->nm_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
- {
+{
return p->cert_flags;
- }
+}
void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->cert_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
- {
+{
return p->oid_flags;
- }
+}
void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->oid_flags = flags;
- }
+}
unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
- {
+{
return p->str_flags;
- }
+}
void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
- {
+{
p->str_flags = flags;
- }
+}
/* Main print routines */
int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
const ASN1_ITEM *it, const ASN1_PCTX *pctx)
- {
+{
const char *sname;
if (pctx == NULL)
pctx = &default_pctx;
sname = it->sname;
return asn1_item_print_ctx(out, &ifld, indent, it,
NULL, sname, 0, pctx);
- }
+}
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_ITEM *it,
const char *fname, const char *sname,
int nohdr, const ASN1_PCTX *pctx)
- {
+{
const ASN1_TEMPLATE *tt;
const ASN1_EXTERN_FUNCS *ef;
ASN1_VALUE **tmpfld;
ASN1_PRINT_ARG parg;
int i;
if (aux && aux->asn1_cb)
- {
+ {
parg.out = out;
parg.indent = indent;
parg.pctx = pctx;
asn1_cb = aux->asn1_cb;
- }
+ }
else asn1_cb = 0;
if(*fld == NULL)
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT)
- {
+ {
if (!nohdr && !asn1_print_fsname(out, indent,
fname, sname, pctx))
return 0;
if (BIO_puts(out, "<ABSENT>\n") <= 0)
return 0;
- }
- return 1;
}
+ return 1;
+ }
switch(it->itype)
- {
+ {
case ASN1_ITYPE_PRIMITIVE:
if(it->templates)
- {
+ {
if (!asn1_template_print_ctx(out, fld, indent,
it->templates, pctx))
return 0;
- }
+ }
/* fall thru */
case ASN1_ITYPE_MSTRING:
if (!asn1_primitive_print(out, fld, it,
/* Use new style print routine if possible */
ef = it->funcs;
if (ef && ef->asn1_ex_print)
- {
+ {
i = ef->asn1_ex_print(out, fld, indent, "", pctx);
if (!i)
return 0;
if ((i == 2) && (BIO_puts(out, "\n") <= 0))
return 0;
return 1;
- }
+ }
else if (sname &&
BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
return 0;
i = asn1_get_choice_selector(fld, it);
/* This should never happen... */
if((i < 0) || (i >= it->tcount))
- {
+ {
if (BIO_printf(out,
"ERROR: selector [%d] invalid\n", i) <= 0)
return 0;
return 1;
- }
+ }
tt = it->templates + i;
tmpfld = asn1_get_field_ptr(fld, tt);
if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (fname || sname)
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_puts(out, " {\n") <= 0)
return 0;
- }
+ }
else
- {
+ {
if (BIO_puts(out, "\n") <= 0)
return 0;
- }
}
+ }
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
- }
+ }
/* Print each field entry */
for(i = 0, tt = it->templates; i < it->tcount; i++, tt++)
- {
+ {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(fld, tt, 1);
tmpfld = asn1_get_field_ptr(fld, seqtt);
if (!asn1_template_print_ctx(out, tmpfld,
indent + 2, seqtt, pctx))
return 0;
- }
+ }
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_printf(out, "%*s}\n", indent, "") < 0)
return 0;
- }
+ }
if (asn1_cb)
- {
+ {
i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
- }
+ }
break;
default:
BIO_printf(out, "Unprocessed type %d\n", it->itype);
return 0;
- }
+ }
return 1;
- }
+}
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
- {
+{
int i, flags;
const char *sname, *fname;
flags = tt->flags;
else
fname = tt->field_name;
if(flags & ASN1_TFLG_SK_MASK)
- {
+ {
char *tname;
ASN1_VALUE *skitem;
STACK_OF(ASN1_VALUE) *stack;
/* SET OF, SEQUENCE OF */
if (fname)
- {
+ {
if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF)
- {
+ {
if(flags & ASN1_TFLG_SET_OF)
tname = "SET";
else
if (BIO_printf(out, "%*s%s OF %s {\n",
indent, "", tname, tt->field_name) <= 0)
return 0;
- }
+ }
else if (BIO_printf(out, "%*s%s:\n", indent, "",
fname) <= 0)
return 0;
- }
+ }
stack = (STACK_OF(ASN1_VALUE) *)*fld;
for(i = 0; i < sk_ASN1_VALUE_num(stack); i++)
- {
+ {
if ((i > 0) && (BIO_puts(out, "\n") <= 0))
return 0;
if (!asn1_item_print_ctx(out, &skitem, indent + 2,
ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, pctx))
return 0;
- }
+ }
if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
return 0;
if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE)
- {
+ {
if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
return 0;
- }
- return 1;
}
+ return 1;
+ }
return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
fname, sname, 0, pctx);
- }
+}
static int asn1_print_fsname(BIO *out, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
- {
+{
static char spaces[] = " ";
const int nspaces = sizeof(spaces) - 1;
#endif
while (indent > nspaces)
- {
+ {
if (BIO_write(out, spaces, nspaces) != nspaces)
return 0;
indent -= nspaces;
- }
+ }
if (BIO_write(out, spaces, indent) != indent)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
if (!sname && !fname)
return 1;
if (fname)
- {
+ {
if (BIO_puts(out, fname) <= 0)
return 0;
- }
+ }
if (sname)
- {
+ {
if (fname)
- {
+ {
if (BIO_printf(out, " (%s)", sname) <= 0)
return 0;
- }
+ }
else
- {
+ {
if (BIO_puts(out, sname) <= 0)
return 0;
- }
}
+ }
if (BIO_write(out, ": ", 2) != 2)
return 0;
return 1;
- }
+}
static int asn1_print_boolean_ctx(BIO *out, int boolval,
const ASN1_PCTX *pctx)
- {
+{
const char *str;
switch (boolval)
- {
+ {
case -1:
str = "BOOL ABSENT";
break;
str = "TRUE";
break;
- }
+ }
if (BIO_puts(out, str) <= 0)
return 0;
return 1;
- }
+}
static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
const ASN1_PCTX *pctx)
- {
+{
char *s;
int ret = 1;
s = i2s_ASN1_INTEGER(NULL, str);
ret = 0;
free(s);
return ret;
- }
+}
static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
const ASN1_PCTX *pctx)
- {
+{
char objbuf[80];
const char *ln;
ln = OBJ_nid2ln(OBJ_obj2nid(oid));
if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
return 0;
return 1;
- }
+}
static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
const ASN1_PCTX *pctx)
- {
+{
if (str->type == V_ASN1_BIT_STRING)
- {
+ {
if (BIO_printf(out, " (%ld unused bits)\n",
str->flags & 0x7) <= 0)
return 0;
- }
+ }
else if (BIO_puts(out, "\n") <= 0)
return 0;
if ((str->length > 0)
indent + 2) <= 0)
return 0;
return 1;
- }
+}
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
const ASN1_ITEM *it, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
- {
+{
long utype;
ASN1_STRING *str;
int ret = 1, needlf = 1;
else
utype = it->utype;
if (utype == V_ASN1_ANY)
- {
+ {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
fld = &atype->value.asn1_value;
pname = NULL;
else
pname = ASN1_tag2str(utype);
- }
+ }
else
- {
+ {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
pname = ASN1_tag2str(utype);
else
pname = NULL;
- }
+ }
if (utype == V_ASN1_NULL)
- {
+ {
if (BIO_puts(out, "NULL\n") <= 0)
return 0;
return 1;
- }
+ }
if (pname)
- {
+ {
if (BIO_puts(out, pname) <= 0)
return 0;
if (BIO_puts(out, ":") <= 0)
return 0;
- }
+ }
switch (utype)
- {
+ {
case V_ASN1_BOOLEAN:
- {
+ {
int boolval = *(int *)fld;
if (boolval == -1)
boolval = it->size;
ret = asn1_print_boolean_ctx(out, boolval, pctx);
- }
+ }
break;
case V_ASN1_INTEGER:
default:
ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
- }
+ }
if (!ret)
return 0;
if (needlf && BIO_puts(out, "\n") <= 0)
return 0;
return 1;
- }
+}
*/
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
int *sel = offset2ptr(*pval, it->utype);
return *sel;
- }
+}
/* Given an ASN1_ITEM CHOICE type set
* the selector value, return old value.
*/
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
- {
+{
int *sel, ret;
sel = offset2ptr(*pval, it->utype);
ret = *sel;
*sel = value;
return ret;
- }
+}
/* Do reference counting. The value 'op' decides what to do.
* if it is +1 then the count is incremented. If op is 0 count is
*/
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
- {
+{
const ASN1_AUX *aux;
int *lck, ret;
if ((it->itype != ASN1_ITYPE_SEQUENCE)
return 0;
lck = offset2ptr(*pval, aux->ref_offset);
if (op == 0)
- {
+ {
*lck = 1;
return 1;
- }
+ }
ret = CRYPTO_add(lck, op, aux->ref_lock);
return ret;
- }
+}
static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
const ASN1_AUX *aux;
if (!pval || !*pval)
return NULL;
if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
return NULL;
return offset2ptr(*pval, aux->enc_offset);
- }
+}
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc)
- {
+ {
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
- }
}
+}
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc)
- {
+ {
if (enc->enc)
free(enc->enc);
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
- }
}
+}
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc)
enc->modified = 0;
return 1;
- }
+}
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
const ASN1_ITEM *it)
- {
+{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc || enc->modified)
return 0;
if (out)
- {
+ {
memcpy(*out, enc->enc, enc->len);
*out += enc->len;
- }
+ }
if (len)
*len = enc->len;
return 1;
- }
+}
/* Given an ASN1_TEMPLATE get a pointer to a field */
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
- {
+{
ASN1_VALUE **pvaltmp;
if (tt->flags & ASN1_TFLG_COMBINE)
return pval;
* (int *).
*/
return pvaltmp;
- }
+}
/* Handle ANY DEFINED BY template, find the selector, look up
* the relevant ASN1_TEMPLATE in the table and return it.
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
int nullerr)
- {
+{
const ASN1_ADB *adb;
const ASN1_ADB_TABLE *atbl;
long selector;
/* Check if NULL */
if (!sfld)
- {
+ {
if (!adb->null_tt)
goto err;
return adb->null_tt;
- }
+ }
/* Convert type to a long:
* NB: don't check for NID_undef here because it
ASN1err(ASN1_F_ASN1_DO_ADB,
ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
- }
+}
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
- {
+{
if (!alg)
return 0;
if (ptype != V_ASN1_UNDEF)
- {
+ {
if (alg->parameter == NULL)
alg->parameter = ASN1_TYPE_new();
if (alg->parameter == NULL)
return 0;
- }
+ }
if (alg)
- {
+ {
if (alg->algorithm)
ASN1_OBJECT_free(alg->algorithm);
alg->algorithm = aobj;
- }
+ }
if (ptype == 0)
return 1;
if (ptype == V_ASN1_UNDEF)
- {
+ {
if (alg->parameter)
- {
+ {
ASN1_TYPE_free(alg->parameter);
alg->parameter = NULL;
- }
}
+ }
else
ASN1_TYPE_set(alg->parameter, ptype, pval);
return 1;
- }
+}
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor)
- {
+{
if (paobj)
*paobj = algor->algorithm;
if (pptype)
- {
+ {
if (algor->parameter == NULL)
- {
+ {
*pptype = V_ASN1_UNDEF;
return;
- }
+ }
else
*pptype = algor->parameter->type;
if (ppval)
*ppval = algor->parameter->value.ptr;
- }
}
+}
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
- {
+{
int param_type;
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
- }
+}
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
- {
+{
X509_ATTRIBUTE *ret=NULL;
ASN1_TYPE *val=NULL;
if (ret != NULL) X509_ATTRIBUTE_free(ret);
if (val != NULL) ASN1_TYPE_free(val);
return(NULL);
- }
+}
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
static X509_CRL_METHOD int_crl_meth =
- {
+{
0,
0,0,
def_crl_lookup,
def_crl_verify
- };
+};
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
case ASN1_OP_D2I_POST:
(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
break;
- }
+}
return 1;
}
*/
static int crl_set_issuers(X509_CRL *crl)
- {
+{
int i, j;
GENERAL_NAMES *gens, *gtmp;
gens = NULL;
for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
- {
+ {
X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
STACK_OF(X509_EXTENSION) *exts;
ASN1_ENUMERATED *reason;
NID_certificate_issuer,
&j, NULL);
if (!gtmp && (j != -1))
- {
+ {
crl->flags |= EXFLAG_INVALID;
return 1;
- }
+ }
if (gtmp)
- {
+ {
gens = gtmp;
if (!crl->issuers)
- {
+ {
crl->issuers = sk_GENERAL_NAMES_new_null();
if (!crl->issuers)
return 0;
- }
+ }
if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
return 0;
- }
+ }
rev->issuer = gens;
reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
&j, NULL);
if (!reason && (j != -1))
- {
+ {
crl->flags |= EXFLAG_INVALID;
return 1;
- }
+ }
if (reason)
- {
+ {
rev->reason = ASN1_ENUMERATED_get(reason);
ASN1_ENUMERATED_free(reason);
- }
+ }
else
rev->reason = CRL_REASON_NONE;
exts = rev->extensions;
for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
- {
+ {
ext = sk_X509_EXTENSION_value(exts, j);
if (ext->critical > 0)
- {
+ {
if (OBJ_obj2nid(ext->object) ==
NID_certificate_issuer)
continue;
crl->flags |= EXFLAG_CRITICAL;
break;
- }
}
+ }
- }
+ }
return 1;
- }
+}
/* The X509_CRL structure needs a bit of customisation. Cache some extensions
* and hash of the whole CRL.
*/
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
- {
+{
X509_CRL *crl = (X509_CRL *)*pval;
STACK_OF(X509_EXTENSION) *exts;
X509_EXTENSION *ext;
int idx;
switch(operation)
- {
+ {
case ASN1_OP_NEW_POST:
crl->idp = NULL;
crl->akid = NULL;
exts = crl->crl->extensions;
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
- {
+ {
int nid;
ext = sk_X509_EXTENSION_value(exts, idx);
nid = OBJ_obj2nid(ext->object);
if (nid == NID_freshest_crl)
crl->flags |= EXFLAG_FRESHEST;
if (ext->critical > 0)
- {
+ {
/* We handle IDP and deltas */
if ((nid == NID_issuing_distribution_point)
|| (nid == NID_delta_crl))
break;;
crl->flags |= EXFLAG_CRITICAL;
break;
- }
}
+ }
if (!crl_set_issuers(crl))
return 0;
if (crl->meth->crl_init)
- {
+ {
if (crl->meth->crl_init(crl) == 0)
return 0;
- }
+ }
break;
case ASN1_OP_FREE_POST:
if (crl->meth->crl_free)
- {
+ {
if (!crl->meth->crl_free(crl))
return 0;
- }
+ }
if (crl->akid)
AUTHORITY_KEYID_free(crl->akid);
if (crl->idp)
ASN1_INTEGER_free(crl->base_crl_number);
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
break;
- }
- return 1;
}
+ return 1;
+}
/* Convert IDP into a more convenient form */
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
- {
+{
int idp_only = 0;
/* Set various flags according to IDP */
crl->idp_flags |= IDP_PRESENT;
if (idp->onlyuser > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYUSER;
- }
+ }
if (idp->onlyCA > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYCA;
- }
+ }
if (idp->onlyattr > 0)
- {
+ {
idp_only++;
crl->idp_flags |= IDP_ONLYATTR;
- }
+ }
if (idp_only > 1)
crl->idp_flags |= IDP_INVALID;
crl->idp_flags |= IDP_INDIRECT;
if (idp->onlysomereasons)
- {
+ {
crl->idp_flags |= IDP_REASONS;
if (idp->onlysomereasons->length > 0)
crl->idp_reasons = idp->onlysomereasons->data[0];
crl->idp_reasons |=
(idp->onlysomereasons->data[1] << 8);
crl->idp_reasons &= CRLDP_ALL_REASONS;
- }
+ }
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
- }
+}
ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b)
- {
+{
return(ASN1_STRING_cmp(
(ASN1_STRING *)(*a)->serialNumber,
(ASN1_STRING *)(*b)->serialNumber));
- }
+}
int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
{
if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
return 0;
- }
+}
inf->enc.modified = 1;
return 1;
}
int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
- {
+{
if (crl->meth->crl_verify)
return crl->meth->crl_verify(crl, r);
return 0;
- }
+}
int X509_CRL_get0_by_serial(X509_CRL *crl,
X509_REVOKED **ret, ASN1_INTEGER *serial)
- {
+{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret, serial, NULL);
return 0;
- }
+}
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
- {
+{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret,
X509_get_serialNumber(x),
X509_get_issuer_name(x));
return 0;
- }
+}
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
- {
+{
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
crl->sig_alg, crl->signature,crl->crl,r));
- }
+}
static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
X509_REVOKED *rev)
- {
+{
int i;
if (!rev->issuer)
- {
+ {
if (!nm)
return 1;
if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
return 1;
return 0;
- }
+ }
if (!nm)
nm = X509_CRL_get_issuer(crl);
for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
- {
+ {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
if (gen->type != GEN_DIRNAME)
continue;
if (!X509_NAME_cmp(nm, gen->d.directoryName))
return 1;
- }
+ }
return 0;
- }
+}
static int def_crl_lookup(X509_CRL *crl,
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
- {
+{
X509_REVOKED rtmp, *rev;
int idx;
rtmp.serialNumber = serial;
* Do this under a lock to avoid race condition.
*/
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
- {
+ {
CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
sk_X509_REVOKED_sort(crl->crl->revoked);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
- }
+ }
idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
if(idx < 0)
return 0;
/* Need to look for matching name */
for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
- {
+ {
rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
return 0;
if (crl_revoked_issuer_match(crl, issuer, rev))
- {
+ {
if (ret)
*ret = rev;
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
return 2;
return 1;
- }
}
- return 0;
}
+ return 0;
+}
void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
- {
+{
if (meth == NULL)
default_crl_method = &int_crl_meth;
else
default_crl_method = meth;
- }
+}
X509_CRL_METHOD *X509_CRL_METHOD_new(
int (*crl_init)(X509_CRL *crl),
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *ser, X509_NAME *issuer),
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
- {
+{
X509_CRL_METHOD *m;
m = malloc(sizeof(X509_CRL_METHOD));
if (!m)
m->crl_verify = crl_verify;
m->flags = X509_CRL_METHOD_DYNAMIC;
return m;
- }
+}
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
- {
+{
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
return;
free(m);
- }
+}
void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
- {
+{
crl->meth_data = dat;
- }
+}
void *X509_CRL_get_meth_data(X509_CRL *crl)
- {
+{
return crl->meth_data;
- }
+}
IMPLEMENT_STACK_OF(X509_REVOKED)
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
#include <openssl/x509.h>
X509_INFO *X509_INFO_new(void)
- {
+{
X509_INFO *ret=NULL;
ret=(X509_INFO *)malloc(sizeof(X509_INFO));
if (ret == NULL)
- {
+ {
ASN1err(ASN1_F_X509_INFO_NEW,ERR_R_MALLOC_FAILURE);
return(NULL);
- }
+ }
ret->enc_cipher.cipher=NULL;
ret->enc_len=0;
ret->crl=NULL;
ret->x_pkey=NULL;
return(ret);
- }
+}
void X509_INFO_free(X509_INFO *x)
- {
+{
int i;
if (x == NULL) return;
if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
if (x->enc_data != NULL) free(x->enc_data);
free(x);
- }
+}
IMPLEMENT_STACK_OF(X509_INFO)
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
int indent, const ASN1_PCTX *pctx)
- {
+{
return BIO_printf(out, "%ld\n", *(long *)pval);
- }
+}
memerr:
ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
if (ret)
- {
+ {
if (ret->entries)
sk_X509_NAME_ENTRY_free(ret->entries);
free(ret);
- }
+ }
return 0;
}
/* need to implement */
int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
- {
+{
return(0);
- }
+}
X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
- {
+{
int i;
M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new);
ret->cipher.cipher=EVP_get_cipherbyname(
OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm)));
if (ret->cipher.cipher == NULL)
- {
+ {
c.error=ASN1_R_UNSUPPORTED_CIPHER;
c.line=__LINE__;
goto err;
- }
+ }
if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING)
- {
+ {
i=ret->enc_algor->parameter->value.octet_string->length;
if (i > EVP_MAX_IV_LENGTH)
- {
+ {
c.error=ASN1_R_IV_TOO_LARGE;
c.line=__LINE__;
goto err;
- }
+ }
memcpy(ret->cipher.iv,
ret->enc_algor->parameter->value.octet_string->data,i);
- }
+ }
else
memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
M_ASN1_D2I_Finish(a,X509_PKEY_free,ASN1_F_D2I_X509_PKEY);
- }
+}
X509_PKEY *X509_PKEY_new(void)
- {
+{
X509_PKEY *ret=NULL;
ASN1_CTX c;
ret->references=1;
return(ret);
M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
- }
+}
void X509_PKEY_free(X509_PKEY *x)
- {
+{
int i;
if (x == NULL) return;
if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
if ((x->key_data != NULL) && (x->key_free)) free(x->key_data);
free(x);
- }
+}
/* Minor tweak to operation: free up EVP_PKEY */
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
- {
+{
if (operation == ASN1_OP_FREE_POST)
- {
+ {
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
EVP_PKEY_free(pubkey->pkey);
- }
- return 1;
}
+ return 1;
+}
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
- {
+{
X509_PUBKEY *pk=NULL;
if (x == NULL) return(0);
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
if (pkey->ameth)
- {
+ {
if (pkey->ameth->pub_encode)
- {
+ {
if (!pkey->ameth->pub_encode(pk, pkey))
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,
X509_R_PUBLIC_KEY_ENCODE_ERROR);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,
X509_R_METHOD_NOT_SUPPORTED);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
goto error;
- }
+ }
if (*x != NULL)
X509_PUBKEY_free(*x);
error:
if (pk != NULL) X509_PUBKEY_free(pk);
return 0;
- }
+}
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
- {
+{
EVP_PKEY *ret=NULL;
if (key == NULL) goto error;
if (key->pkey != NULL)
- {
+ {
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
return key->pkey;
- }
+ }
if (key->public_key == NULL) goto error;
if ((ret = EVP_PKEY_new()) == NULL)
- {
+ {
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
goto error;
- }
+ }
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
- {
+ {
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
goto error;
- }
+ }
if (ret->ameth->pub_decode)
- {
+ {
if (!ret->ameth->pub_decode(ret, key))
- {
+ {
X509err(X509_F_X509_PUBKEY_GET,
X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
- }
}
+ }
else
- {
+ {
X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
goto error;
- }
+ }
/* Check to see if another thread set key->pkey first */
CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
if (key->pkey)
- {
+ {
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
EVP_PKEY_free(ret);
ret = key->pkey;
- }
+ }
else
- {
+ {
key->pkey = ret;
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
- }
+ }
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
return ret;
if (ret != NULL)
EVP_PKEY_free(ret);
return(NULL);
- }
+}
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
* and encode or decode as X509_PUBKEY
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
long length)
- {
+{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
xpk = d2i_X509_PUBKEY(NULL, pp, length);
X509_PUBKEY_free(xpk);
if(!pktmp) return NULL;
if(a)
- {
+ {
EVP_PKEY_free(*a);
*a = pktmp;
- }
- return pktmp;
}
+ return pktmp;
+}
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
- {
+{
X509_PUBKEY *xpk=NULL;
int ret;
if(!a) return 0;
ret = i2d_X509_PUBKEY(xpk, pp);
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)
- {
+{
EVP_PKEY *pkey;
RSA *key;
const unsigned char *q;
if (!key) return NULL;
*pp = q;
if (a)
- {
+ {
RSA_free(*a);
*a = key;
- }
- return key;
}
+ return key;
+}
int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if (!a) return 0;
pktmp = EVP_PKEY_new();
if (!pktmp)
- {
+ {
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
EVP_PKEY_set1_RSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
- }
+}
#endif
#ifndef OPENSSL_NO_DSA
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
long length)
- {
+{
EVP_PKEY *pkey;
DSA *key;
const unsigned char *q;
if (!key) return NULL;
*pp = q;
if (a)
- {
+ {
DSA_free(*a);
*a = key;
- }
- return key;
}
+ return key;
+}
int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if(!a) return 0;
pktmp = EVP_PKEY_new();
if(!pktmp)
- {
+ {
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
return 0;
- }
+ }
EVP_PKEY_set1_DSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
- }
+}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
- {
+{
EVP_PKEY *pkey;
EC_KEY *key;
const unsigned char *q;
if (!key) return(NULL);
*pp = q;
if (a)
- {
+ {
EC_KEY_free(*a);
*a = key;
- }
- return(key);
}
+ return(key);
+}
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
- {
+{
EVP_PKEY *pktmp;
int ret;
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
- {
+ {
ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
return(0);
- }
+ }
EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return(ret);
- }
+}
#endif
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
int ptype, void *pval,
unsigned char *penc, int penclen)
- {
+{
if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
return 0;
if (penc)
- {
+ {
if (pub->public_key->data)
free(pub->public_key->data);
pub->public_key->data = penc;
/* Set number of unused bits to zero */
pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
- }
- return 1;
}
+ return 1;
+}
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
X509_ALGOR **pa,
X509_PUBKEY *pub)
- {
+{
if (ppkalg)
*ppkalg = pub->algor->algorithm;
if (pk)
- {
+ {
*pk = pub->public_key->data;
*ppklen = pub->public_key->length;
- }
+ }
if (pa)
*pa = pub->algor;
return 1;
- }
+}
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
- {
+{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp,
new_func, dup_func, free_func);
- }
+}
int X509_set_ex_data(X509 *r, int idx, void *arg)
- {
+{
return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
- }
+}
void *X509_get_ex_data(X509 *r, int idx)
- {
+{
return(CRYPTO_get_ex_data(&r->ex_data,idx));
- }
+}
/* X509_AUX ASN1 routines. X509_AUX is the name given to
* a certificate with extra info tagged on the end. Since these
{
X509_CERT_AUX *aux;
if (!name)
- {
+ {
if (!x || !x->aux || !x->aux->alias)
return 1;
ASN1_UTF8STRING_free(x->aux->alias);
x->aux->alias = NULL;
return 1;
- }
+ }
if(!(aux = aux_get(x))) return 0;
if(!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) return 0;
return ASN1_STRING_set(aux->alias, name, len);
{
X509_CERT_AUX *aux;
if (!id)
- {
+ {
if (!x || !x->aux || !x->aux->keyid)
return 1;
ASN1_OCTET_STRING_free(x->aux->keyid);
x->aux->keyid = NULL;
return 1;
- }
+ }
if(!(aux = aux_get(x))) return 0;
if(!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) return 0;
return ASN1_STRING_set(aux->keyid, id, len);