Support for Signal calls.

Merge in RedPhone

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2015-09-09 13:54:29 -07:00
parent 3d4ae60d81
commit d83a3d71bc
2585 changed files with 803492 additions and 45 deletions

View File

@@ -0,0 +1,248 @@
/* crypto/asn1/a_bitstr.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{ return M_ASN1_BIT_STRING_set(x, d, len); }
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
int ret,j,bits,len;
unsigned char *p,*d;
if (a == NULL) return(0);
len=a->length;
if (len > 0)
{
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
{
bits=(int)a->flags&0x07;
}
else
{
for ( ; len > 0; len--)
{
if (a->data[len-1]) break;
}
j=a->data[len-1];
if (j & 0x01) bits=0;
else if (j & 0x02) bits=1;
else if (j & 0x04) bits=2;
else if (j & 0x08) bits=3;
else if (j & 0x10) bits=4;
else if (j & 0x20) bits=5;
else if (j & 0x40) bits=6;
else if (j & 0x80) bits=7;
else bits=0; /* should not happen */
}
}
else
bits=0;
ret=1+len;
if (pp == NULL) return(ret);
p= *pp;
*(p++)=(unsigned char)bits;
d=a->data;
memcpy(p,d,len);
p+=len;
if (len > 0) p[-1]&=(0xff<<bits);
*pp=p;
return(ret);
}
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
const unsigned char **pp, long len)
{
ASN1_BIT_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
int i;
if (len < 1)
{
i=ASN1_R_STRING_TOO_SHORT;
goto err;
}
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
}
else
ret=(*a);
p= *pp;
i= *(p++);
/* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate
* on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
s=(unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s,p,(int)len);
s[len-1]&=(0xff<<i);
p+=len;
}
else
s=NULL;
ret->length=(int)len;
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->data=s;
ret->type=V_ASN1_BIT_STRING;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_BIT_STRING_free(ret);
return(NULL);
}
/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
*/
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w,v,iv;
unsigned char *c;
w=n/8;
v=1<<(7-(n&0x07));
iv= ~v;
if (!value) v=0;
if (a == NULL)
return 0;
a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
if ((a->length < (w+1)) || (a->data == NULL))
{
if (!value) return(1); /* Don't need to set */
if (a->data == NULL)
c=(unsigned char *)OPENSSL_malloc(w+1);
else
c=(unsigned char *)OPENSSL_realloc_clean(a->data,
a->length,
w+1);
if (c == NULL)
{
ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE);
return 0;
}
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
a->data=c;
a->length=w+1;
}
a->data[w]=((a->data[w])&iv)|v;
while ((a->length > 0) && (a->data[a->length-1] == 0))
a->length--;
return(1);
}
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w,v;
w=n/8;
v=1<<(7-(n&0x07));
if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
return(0);
return((a->data[w]&v) != 0);
}
/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
unsigned char *flags, int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data) return 1;
/* Check each byte of the internal representation of the bit string. */
ok = 1;
for (i = 0; i < a->length && ok; ++i)
{
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}

View File

@@ -0,0 +1,114 @@
/* crypto/asn1/a_bool.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
{
int r;
unsigned char *p;
r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
if (pp == NULL) return(r);
p= *pp;
ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
*(p++)= (unsigned char)a;
*pp=p;
return(r);
}
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
{
int ret= -1;
const unsigned char *p;
long len;
int inf,tag,xclass;
int i=0;
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_BOOLEAN)
{
i=ASN1_R_EXPECTING_A_BOOLEAN;
goto err;
}
if (len != 1)
{
i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
goto err;
}
ret= (int)*(p++);
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
ASN1err(ASN1_F_D2I_ASN1_BOOLEAN,i);
return(ret);
}

View File

@@ -0,0 +1,314 @@
/* crypto/asn1/a_bytes.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
/* type is a 'bitmap' of acceptable string types.
*/
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int type)
{
ASN1_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf,tag,xclass;
int i=0;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80) goto err;
if (tag >= 32)
{
i=ASN1_R_TAG_VALUE_TOO_HIGH;
goto err;
}
if (!(ASN1_tag2bit(tag) & type))
{
i=ASN1_R_WRONG_TYPE;
goto err;
}
/* If a bit-string, exit early */
if (tag == V_ASN1_BIT_STRING)
return(d2i_ASN1_BIT_STRING(a,pp,length));
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
}
else
ret=(*a);
if (len != 0)
{
s=(unsigned char *)OPENSSL_malloc((int)len+1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s,p,(int)len);
s[len]='\0';
p+=len;
}
else
s=NULL;
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->length=(int)len;
ret->data=s;
ret->type=tag;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return(NULL);
}
int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
{
int ret,r,constructed;
unsigned char *p;
if (a == NULL) return(0);
if (tag == V_ASN1_BIT_STRING)
return(i2d_ASN1_BIT_STRING(a,pp));
ret=a->length;
r=ASN1_object_size(0,ret,tag);
if (pp == NULL) return(r);
p= *pp;
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
constructed=1;
else
constructed=0;
ASN1_put_object(&p,constructed,ret,tag,xclass);
memcpy(p,a->data,a->length);
p+=a->length;
*pp= p;
return(r);
}
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int Ptag, int Pclass)
{
ASN1_STRING *ret=NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf,tag,xclass;
int i=0;
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
}
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 != Ptag)
{
i=ASN1_R_WRONG_TAG;
goto err;
}
if (inf & V_ASN1_CONSTRUCTED)
{
ASN1_const_CTX c;
c.pp=pp;
c.p=p;
c.inf=inf;
c.slen=len;
c.tag=Ptag;
c.xclass=Pclass;
c.max=(length == 0)?0:(p+length);
if (!asn1_collate_primitive(ret,&c))
goto err;
else
{
p=c.p;
}
}
else
{
if (len != 0)
{
if ((ret->length < len) || (ret->data == NULL))
{
if (ret->data != NULL) OPENSSL_free(ret->data);
s=(unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL)
{
i=ERR_R_MALLOC_FAILURE;
goto err;
}
}
else
s=ret->data;
memcpy(s,p,(int)len);
s[len] = '\0';
p+=len;
}
else
{
s=NULL;
if (ret->data != NULL) OPENSSL_free(ret->data);
}
ret->length=(int)len;
ret->data=s;
ret->type=Ptag;
}
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
ASN1err(ASN1_F_D2I_ASN1_BYTES,i);
return(NULL);
}
/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
* them into the one structure that is then returned */
/* There have been a few bug fixes for this function from
* Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
{
ASN1_STRING *os=NULL;
BUF_MEM b;
int num;
b.length=0;
b.max=0;
b.data=NULL;
if (a == NULL)
{
c->error=ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
num=0;
for (;;)
{
if (c->inf & 1)
{
c->eos=ASN1_const_check_infinite_end(&c->p,
(long)(c->max-c->p));
if (c->eos) break;
}
else
{
if (c->slen <= 0) break;
}
c->q=c->p;
if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
== NULL)
{
c->error=ERR_R_ASN1_LIB;
goto err;
}
if (!BUF_MEM_grow_clean(&b,num+os->length))
{
c->error=ERR_R_BUF_LIB;
goto err;
}
memcpy(&(b.data[num]),os->data,os->length);
if (!(c->inf & 1))
c->slen-=(c->p-c->q);
num+=os->length;
}
if (!asn1_const_Finish(c)) goto err;
a->length=num;
if (a->data != NULL) OPENSSL_free(a->data);
a->data=(unsigned char *)b.data;
if (os != NULL) ASN1_STRING_free(os);
return(1);
err:
ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE,c->error);
if (os != NULL) ASN1_STRING_free(os);
if (b.data != NULL) OPENSSL_free(b.data);
return(0);
}

View File

@@ -0,0 +1,286 @@
/* crypto/asn1/a_d2i_fp.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <limits.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1_mac.h>
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
#ifndef NO_OLD_ASN1
#ifndef OPENSSL_NO_FP_API
void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
void *ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ASN1err(ASN1_F_ASN1_D2I_FP,ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
ret=ASN1_d2i_bio(xnew,d2i,b,x);
BIO_free(b);
return(ret);
}
#endif
void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret=NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if(len < 0) goto err;
p=(unsigned char *)b->data;
ret=d2i(x,&p,len);
err:
if (b != NULL) BUF_MEM_free(b);
return(ret);
}
#endif
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret=NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if(len < 0) goto err;
p=(const unsigned char *)b->data;
ret=ASN1_item_d2i(x,&p,len, it);
err:
if (b != NULL) BUF_MEM_free(b);
return(ret);
}
#ifndef OPENSSL_NO_FP_API
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
{
BIO *b;
char *ret;
if ((b=BIO_new(BIO_s_file())) == NULL)
{
ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
ret=ASN1_item_d2i_bio(it,b,x);
BIO_free(b);
return(ret);
}
#endif
#define HEADER_SIZE 8
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
int i;
ASN1_const_CTX c;
size_t want=HEADER_SIZE;
int eos=0;
size_t off=0;
size_t len=0;
b=BUF_MEM_new();
if (b == NULL)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
return -1;
}
ERR_clear_error();
for (;;)
{
if (want >= (len-off))
{
want-=(len-off);
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
{
if (len+i < len)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
len+=i;
}
}
/* else data already loaded */
p=(unsigned char *)&(b->data[off]);
c.p=p;
c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
len-off);
if (c.inf & 0x80)
{
unsigned long e;
e=ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
goto err;
else
ERR_clear_error(); /* clear error */
}
i=c.p-p;/* header length */
off+=i; /* end of data */
if (c.inf & 1)
{
/* no data body so go round again */
eos++;
if (eos < 0)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE;
}
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
{
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want=HEADER_SIZE;
}
else
{
/* suck in c.slen bytes of data */
want=c.slen;
if (want > (len-off))
{
want-=(len-off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want))
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0)
{
i=BIO_read(in,&(b->data[len]),want);
if (i <= 0)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/* This can't overflow because
* |len+want| didn't overflow. */
len+=i;
want-=i;
}
}
if (off + c.slen < off)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
if (eos <= 0)
{
break;
}
else
want=HEADER_SIZE;
}
}
if (off > INT_MAX)
{
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
goto err;
}
*pb = b;
return off;
err:
if (b != NULL) BUF_MEM_free(b);
return -1;
}

View File

@@ -0,0 +1,113 @@
/* crypto/asn1/a_digest.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#ifndef NO_ASN1_OLD
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
unsigned char *md, unsigned int *len)
{
int i;
unsigned char *str,*p;
i=i2d(data,NULL);
if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
{
ASN1err(ASN1_F_ASN1_DIGEST,ERR_R_MALLOC_FAILURE);
return(0);
}
p=str;
i2d(data,&p);
if (!EVP_Digest(str, i, md, len, type, NULL))
return 0;
OPENSSL_free(str);
return(1);
}
#endif
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
unsigned char *md, unsigned int *len)
{
int i;
unsigned char *str = NULL;
i=ASN1_item_i2d(asn,&str, it);
if (!str) return(0);
if (!EVP_Digest(str, i, md, len, type, NULL))
return 0;
OPENSSL_free(str);
return(1);
}

View File

@@ -0,0 +1,109 @@
/* crypto/asn1/a_dup.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#ifndef NO_OLD_ASN1
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b,*p;
const unsigned char *p2;
int i;
char *ret;
if (x == NULL) return(NULL);
i=i2d(x,NULL);
b=OPENSSL_malloc(i+10);
if (b == 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);
OPENSSL_free(b);
return(ret);
}
#endif
/* ASN1_ITEM version of dup: this follows the model above except we don't need
* to allocate the buffer. At some point this could be rewritten to directly dup
* the underlying structure instead of doing and encode and decode.
*/
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
{
unsigned char *b = NULL;
const unsigned char *p;
long i;
void *ret;
if (x == NULL) return(NULL);
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
{ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
OPENSSL_free(b);
return(ret);
}

View File

@@ -0,0 +1,182 @@
/* crypto/asn1/a_enum.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/bn.h>
/*
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
* for comments on encoding see a_int.c
*/
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
{
int j,k;
unsigned int i;
unsigned char buf[sizeof(long)+1];
long d;
a->type=V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long)+1))
{
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data=(unsigned char *)OPENSSL_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;
if (a == NULL) return(0L);
i=a->type;
if (i == V_ASN1_NEG_ENUMERATED)
neg=1;
else if (i != V_ASN1_ENUMERATED)
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;
if (ai == NULL)
ret=M_ASN1_ENUMERATED_new();
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=OPENSSL_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->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);
}

View File

@@ -0,0 +1,263 @@
/* crypto/asn1/a_gentm.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME */
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1.h>
#if 0
int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
{
#ifdef CHARSET_EBCDIC
/* KLUDGE! We convert to ascii before writing DER */
int len;
char tmp[24];
ASN1_STRING tmpstr = *(ASN1_STRING *)a;
len = tmpstr.length;
ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
tmpstr.data = tmp;
a = (ASN1_GENERALIZEDTIME *) &tmpstr;
#endif
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);
}
#ifdef CHARSET_EBCDIC
ascii2ebcdic(ret->data, ret->data, ret->length);
#endif
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;
int n,i,l,o;
if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
l=d->length;
a=(char *)d->data;
o=0;
/* GENERALIZEDTIME is similar to UTCTIME except the year is
* represented as YYYY. This stuff treats everything as a two digit
* field so make first two fields 00 to 99
*/
if (l < 13) goto err;
for (i=0; i<7; i++)
{
if ((i == 6) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
{ i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
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++;
if ((a[o] < '0') || (a[o] > '9')) goto err;
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);
}
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;
size_t len = 20;
if (s == NULL)
s=M_ASN1_GENERALIZEDTIME_new();
if (s == NULL)
return(NULL);
ts=OPENSSL_gmtime(&t, &data);
if (ts == NULL)
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=OPENSSL_malloc(len);
if (p == NULL)
{
ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data=(unsigned char *)p;
}
BIO_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;
#ifdef CHARSET_EBCDIC_not
ebcdic2ascii(s->data, s->data, s->length);
#endif
return(s);
}

View File

@@ -0,0 +1,163 @@
/* crypto/asn1/a_i2d_fp.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
#ifndef NO_OLD_ASN1
#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 *)OPENSSL_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;
}
OPENSSL_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;
}
OPENSSL_free(b);
return(ret);
}

View File

@@ -0,0 +1,458 @@
/* crypto/asn1/a_int.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/bn.h>
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
{ 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);
if (neg)
return -ret;
else
return ret;
}
/*
* This converts an ASN1 INTEGER into its content encoding.
* The internal representation is an ASN1_STRING whose data is a big endian
* representation of the value, ignoring the sign. The sign is determined by
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
*
* Positive integers are no problem: they are almost the same as the DER
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
*
* Negative integers are a bit trickier...
* The DER representation of negative integers is in 2s complement form.
* The internal form is converted by complementing each octet and finally
* adding one to the result. This can be done less messily with a little trick.
* If the internal form has trailing zeroes then they will become FF by the
* complement and 0 by the add one (due to carry) so just copy as many trailing
* zeros to the destination as there are in the source. The carry will add one
* to the last none zero octet: so complement this octet and add one and finally
* complement any left over until you get to the start of the string.
*
* Padding is a little trickier too. If the first bytes is > 0x80 then we pad
* with 0xff. However if the first byte is 0x80 and one of the following bytes
* is non-zero we pad with 0xff. The reason for this distinction is that 0x80
* followed by optional zeros isn't padded.
*/
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
int pad=0,ret,i,neg;
unsigned char *p,*n,pb=0;
if (a == NULL) return(0);
neg=a->type & V_ASN1_NEG;
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) {
if(i>128) {
pad=1;
pb=0xFF;
} else if(i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
*/
for(i = 1; i < a->length; i++) if(a->data[i]) {
pad=1;
pb=0xFF;
break;
}
}
}
ret+=pad;
}
if (pp == NULL) return(ret);
p= *pp;
if (pad) *(p++)=pb;
if (a->length == 0) *(p++)=0;
else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
else {
/* Begin at the end of the encoding */
n=a->data + a->length - 1;
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while(!*n) {
*(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);
p= *pp;
pend = p + len;
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)OPENSSL_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 */
{
ret->type=V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
}
i = len;
p += i - 1;
to += i - 1;
while((!*p) && i) {
*(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
* so we just append an extra one and set the first byte to
* a 1. This is treated separately because it is the only case
* where the number of bytes is larger than len.
*/
if(!i) {
*s = 1;
s[len] = 0;
len++;
} else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
}
} else {
ret->type=V_ASN1_INTEGER;
if ((*p == 0) && (len != 1))
{
p++;
len--;
}
memcpy(s,p,(int)len);
}
if (ret->data != NULL) OPENSSL_free(ret->data);
ret->data=s;
ret->length=(int)len;
if (a != NULL) (*a)=ret;
*pp=pend;
return(ret);
err:
ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
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 integers: some broken software can encode a positive INTEGER
* with its MSB set as negative (it doesn't add a padding zero).
*/
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;
long len;
int inf,tag,xclass;
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 OPENSSL_malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s=(unsigned char *)OPENSSL_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) OPENSSL_free(ret->data);
ret->data=s;
ret->length=(int)len;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i);
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];
long d;
a->type=V_ASN1_INTEGER;
if (a->length < (int)(sizeof(long)+1))
{
if (a->data != NULL)
OPENSSL_free(a->data);
if ((a->data=(unsigned char *)OPENSSL_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;
if (a == NULL) return(0L);
i=a->type;
if (i == V_ASN1_NEG_INTEGER)
neg=1;
else if (i != V_ASN1_INTEGER)
return -1;
if (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;
if (ai == NULL)
ret=M_ASN1_INTEGER_new();
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=OPENSSL_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->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)
ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
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)

View File

@@ -0,0 +1,400 @@
/* a_mbstr.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
static int traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg);
static int in_utf8(unsigned long value, void *arg);
static int out_utf8(unsigned long value, void *arg);
static int type_str(unsigned long value, void *arg);
static int cpy_asc(unsigned long value, void *arg);
static int cpy_bmp(unsigned long value, void *arg);
static int cpy_univ(unsigned long value, void *arg);
static int cpy_utf8(unsigned long value, void *arg);
static int is_printable(unsigned long value);
/* These functions take a string in UTF8, ASCII or multibyte form and
* a mask of permissible ASN1 string types. It then works out the minimal
* type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
* and creates a string of the correct type with the supplied data.
* Yes this is horrible: it has to be :-(
* The 'ncopy' form checks minimum and maximum size limits too.
*/
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask)
{
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
}
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask,
long minsize, long maxsize)
{
int str_type;
int ret;
char free_out;
int outform, outlen = 0;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
char strbuf[32];
int (*cpyfunc)(unsigned long,void *) = NULL;
if(len == -1) len = strlen((const char *)in);
if(!mask) mask = DIRSTRING_TYPE;
/* First do a string check and work out the number of characters */
switch(inform) {
case MBSTRING_BMP:
if(len & 1) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
break;
case MBSTRING_UNIV:
if(len & 3) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
break;
case MBSTRING_UTF8:
nchar = 0;
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
case MBSTRING_ASC:
nchar = len;
break;
default:
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if((minsize > 0) && (nchar < minsize)) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if((maxsize > 0) && (nchar > maxsize)) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
}
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
/* Now work out output format and string type */
outform = MBSTRING_ASC;
if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
else if(mask & B_ASN1_BMPSTRING) {
str_type = V_ASN1_BMPSTRING;
outform = MBSTRING_BMP;
} else if(mask & B_ASN1_UNIVERSALSTRING) {
str_type = V_ASN1_UNIVERSALSTRING;
outform = MBSTRING_UNIV;
} else {
str_type = V_ASN1_UTF8STRING;
outform = MBSTRING_UTF8;
}
if(!out) return str_type;
if(*out) {
free_out = 0;
dest = *out;
if(dest->data) {
dest->length = 0;
OPENSSL_free(dest->data);
dest->data = NULL;
}
dest->type = str_type;
} else {
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
}
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
}
/* Work out how much space the destination will need */
switch(outform) {
case MBSTRING_ASC:
outlen = nchar;
cpyfunc = cpy_asc;
break;
case MBSTRING_BMP:
outlen = nchar << 1;
cpyfunc = cpy_bmp;
break;
case MBSTRING_UNIV:
outlen = nchar << 2;
cpyfunc = cpy_univ;
break;
case MBSTRING_UTF8:
outlen = 0;
traverse_string(in, len, inform, out_utf8, &outlen);
cpyfunc = cpy_utf8;
break;
}
if(!(p = OPENSSL_malloc(outlen + 1))) {
if(free_out) ASN1_STRING_free(dest);
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
dest->data = p;
p[outlen] = 0;
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
}
/* This function traverses a string and passes the value of each character
* to an optional function along with a void * argument.
*/
static int traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg)
{
unsigned long value;
int ret;
while(len) {
if(inform == MBSTRING_ASC) {
value = *p++;
len--;
} else if(inform == MBSTRING_BMP) {
value = *p++ << 8;
value |= *p++;
len -= 2;
} else if(inform == MBSTRING_UNIV) {
value = ((unsigned long)*p++) << 24;
value |= ((unsigned long)*p++) << 16;
value |= *p++ << 8;
value |= *p++;
len -= 4;
} else {
ret = UTF8_getc(p, len, &value);
if(ret < 0) return -1;
len -= ret;
p += ret;
}
if(rfunc) {
ret = rfunc(value, arg);
if(ret <= 0) return ret;
}
}
return 1;
}
/* Various utility functions for traverse_string */
/* Just count number of characters */
static int in_utf8(unsigned long value, void *arg)
{
int *nchar;
nchar = arg;
(*nchar)++;
return 1;
}
/* Determine size of output as a UTF8 String */
static int out_utf8(unsigned long value, void *arg)
{
int *outlen;
outlen = arg;
*outlen += UTF8_putc(NULL, -1, value);
return 1;
}
/* Determine the "type" of a string: check each character against a
* supplied "mask".
*/
static int type_str(unsigned long value, void *arg)
{
unsigned long types;
types = *((unsigned long *)arg);
if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
types &= ~B_ASN1_PRINTABLESTRING;
if((types & B_ASN1_IA5STRING) && (value > 127))
types &= ~B_ASN1_IA5STRING;
if((types & B_ASN1_T61STRING) && (value > 0xff))
types &= ~B_ASN1_T61STRING;
if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
types &= ~B_ASN1_BMPSTRING;
if(!types) return -1;
*((unsigned long *)arg) = types;
return 1;
}
/* Copy one byte per character ASCII like strings */
static int cpy_asc(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q = (unsigned char) value;
(*p)++;
return 1;
}
/* Copy two byte per character BMPStrings */
static int cpy_bmp(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char) ((value >> 8) & 0xff);
*q = (unsigned char) (value & 0xff);
*p += 2;
return 1;
}
/* Copy four byte per character UniversalStrings */
static int cpy_univ(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (unsigned char) ((value >> 24) & 0xff);
*q++ = (unsigned char) ((value >> 16) & 0xff);
*q++ = (unsigned char) ((value >> 8) & 0xff);
*q = (unsigned char) (value & 0xff);
*p += 4;
return 1;
}
/* Copy to a UTF8String */
static int cpy_utf8(unsigned long value, void *arg)
{
unsigned char **p;
int ret;
p = arg;
/* We already know there is enough room so pass 0xff as the length */
ret = UTF8_putc(*p, 0xff, value);
*p += ret;
return 1;
}
/* Return 1 if the character is permitted in a PrintableString */
static int is_printable(unsigned long value)
{
int ch;
if(value > 0x7f) return 0;
ch = (int) value;
/* Note: we can't use 'isalnum' because certain accented
* characters may count as alphanumeric in some environments.
*/
#ifndef CHARSET_EBCDIC
if((ch >= 'a') && (ch <= 'z')) return 1;
if((ch >= 'A') && (ch <= 'Z')) return 1;
if((ch >= '0') && (ch <= '9')) return 1;
if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
#else /*CHARSET_EBCDIC*/
if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
#endif /*CHARSET_EBCDIC*/
return 0;
}

View File

@@ -0,0 +1,403 @@
/* crypto/asn1/a_object.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <limits.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/bn.h>
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
if ((a == NULL) || (a->data == NULL)) return(0);
objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
if (pp == NULL) return objsize;
p= *pp;
ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
memcpy(p,a->data,a->length);
p+=a->length;
*pp=p;
return(objsize);
}
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
int i,first,len=0,c, use_bn;
char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p;
unsigned long l;
BIGNUM *bl = NULL;
if (num == 0)
return(0);
else if (num == -1)
num=strlen(buf);
p=buf;
c= *(p++);
num--;
if ((c >= '0') && (c <= '2'))
{
first= c-'0';
}
else
{
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)
OPENSSL_free(tmp);
tmpsize = blsize + 32;
tmp = OPENSSL_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)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(len);
err:
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(0);
}
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
{
char buf[80], *p = buf;
int i;
if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp,"NULL",4));
i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
if (i > (int)(sizeof(buf) - 1))
{
p = OPENSSL_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)
OPENSSL_free(p);
return(i);
}
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
long length)
{
const unsigned char *p;
long len;
int tag,xclass;
int inf,i;
ASN1_OBJECT *ret = NULL;
p= *pp;
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
if (inf & 0x80)
{
i=ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_OBJECT)
{
i=ASN1_R_EXPECTING_AN_OBJECT;
goto err;
}
ret = c2i_ASN1_OBJECT(a, &p, len);
if(ret) *pp = p;
return ret;
err:
ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
return(NULL);
}
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;
int i;
/* Sanity check OID encoding: can't have leading 0x80 in
* 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;
/* detach data from object */
data = (unsigned char *)ret->data;
ret->data = NULL;
/* once detached we can change it */
if ((data == NULL) || (ret->length < len))
{
ret->length=0;
if (data != NULL) OPENSSL_free(data);
data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
if (data == NULL)
{ 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;
ret->length=(int)len;
ret->sn=NULL;
ret->ln=NULL;
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
p+=len;
if (a != NULL) (*a)=ret;
*pp=p;
return(ret);
err:
ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
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 *)OPENSSL_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->sn=NULL;
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) OPENSSL_free((void *)a->sn);
if (a->ln != NULL) OPENSSL_free((void *)a->ln);
#endif
a->sn=a->ln=NULL;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
{
if (a->data != NULL) OPENSSL_free((void *)a->data);
a->data=NULL;
a->length=0;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
OPENSSL_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.ln=ln;
o.data=data;
o.nid=nid;
o.length=len;
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)

View File

@@ -0,0 +1,71 @@
/* crypto/asn1/a_octet.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
{ return M_ASN1_OCTET_STRING_dup(x); }
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
{ return M_ASN1_OCTET_STRING_cmp(a, b); }
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{ return M_ASN1_OCTET_STRING_set(x, d, len); }

View File

@@ -0,0 +1,127 @@
/* crypto/asn1/a_print.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
{
int c;
int ia5=0;
int t61=0;
if (len <= 0) len= -1;
if (s == NULL) return(V_ASN1_PRINTABLESTRING);
while ((*s) && (len-- != 0))
{
c= *(s++);
#ifndef CHARSET_EBCDIC
if (!( ((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
(c == ' ') ||
((c >= '0') && (c <= '9')) ||
(c == ' ') || (c == '\'') ||
(c == '(') || (c == ')') ||
(c == '+') || (c == ',') ||
(c == '-') || (c == '.') ||
(c == '/') || (c == ':') ||
(c == '=') || (c == '?')))
ia5=1;
if (c&0x80)
t61=1;
#else
if (!isalnum(c) && (c != ' ') &&
strchr("'()+,-./:=?", c) == NULL)
ia5=1;
if (os_toascii[c] & 0x80)
t61=1;
#endif
}
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->type != V_ASN1_UNIVERSALSTRING) return(0);
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);
}

View File

@@ -0,0 +1,241 @@
/* crypto/asn1/a_set.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1_mac.h>
#ifndef NO_ASN1_OLD
typedef struct
{
unsigned char *pbData;
int cbData;
} MYBLOB;
/* SetBlobCmp
* This function compares two elements of SET_OF block
*/
static int SetBlobCmp(const void *elem1, const void *elem2 )
{
const MYBLOB *b1 = (const MYBLOB *)elem1;
const MYBLOB *b2 = (const MYBLOB *)elem2;
int r;
r = memcmp(b1->pbData, b2->pbData,
b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
if(r != 0)
return r;
return b1->cbData-b2->cbData;
}
/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
i2d_of_void *i2d, int ex_tag, int ex_class,
int is_set)
{
int ret=0,r;
int i;
unsigned char *p;
unsigned char *pStart, *pTempMem;
MYBLOB *rgSetBlob;
int totSize;
if (a == NULL) return(0);
for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
r=ASN1_object_size(1,ret,ex_tag);
if (pp == NULL) return(r);
p= *pp;
ASN1_put_object(&p,1,ret,ex_tag,ex_class);
/* Modified by gp@nsj.co.jp */
/* And then again by Ben */
/* And again by Steve */
if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
{
for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
*pp=p;
return(r);
}
pStart = p; /* Catch the beg of Setblobs*/
/* In this array we will store the SET blobs */
rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
if (rgSetBlob == NULL)
{
ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
return(0);
}
for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
{
rgSetBlob[i].pbData = p; /* catch each set encode blob */
i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
SetBlob
*/
}
*pp=p;
totSize = p - pStart; /* This is the total size of all set blobs */
/* Now we have to sort the blobs. I am using a simple algo.
*Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
if (!(pTempMem = OPENSSL_malloc(totSize)))
{
ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
return(0);
}
/* Copy to temp mem */
p = pTempMem;
for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
{
memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
p += rgSetBlob[i].cbData;
}
/* Copy back to user mem*/
memcpy(pStart, pTempMem, totSize);
OPENSSL_free(pTempMem);
OPENSSL_free(rgSetBlob);
return(r);
}
STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
const unsigned char **pp,
long length, d2i_of_void *d2i,
void (*free_func)(OPENSSL_BLOCK), int ex_tag,
int ex_class)
{
ASN1_const_CTX c;
STACK_OF(OPENSSL_BLOCK) *ret=NULL;
if ((a == NULL) || ((*a) == NULL))
{
if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
{
ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
goto err;
}
}
else
ret=(*a);
c.p= *pp;
c.max=(length == 0)?0:(c.p+length);
c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,c.max-c.p);
if (c.inf & 0x80) goto err;
if (ex_class != c.xclass)
{
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);
goto err;
}
if (ex_tag != c.tag)
{
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);
goto err;
}
if ((c.slen+c.p) > c.max)
{
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);
goto err;
}
/* check for infinite constructed - it can be as long
* as the amount of data passed to us */
if (c.inf == (V_ASN1_CONSTRUCTED+1))
c.slen=length+ *pp-c.p;
c.max=c.p+c.slen;
while (c.p < c.max)
{
char *s;
if (M_ASN1_D2I_end_sequence()) break;
/* XXX: This was called with 4 arguments, incorrectly, it seems
if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */
if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
{
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
asn1_add_error(*pp,(int)(c.p- *pp));
goto err;
}
if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
}
if (a != NULL) (*a)=ret;
*pp=c.p;
return(ret);
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
{
if (free_func != NULL)
sk_OPENSSL_BLOCK_pop_free(ret,free_func);
else
sk_OPENSSL_BLOCK_free(ret);
}
return(NULL);
}
#endif

View File

@@ -0,0 +1,333 @@
/* crypto/asn1/a_sign.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include "asn1_locl.h"
#ifndef NO_ASN1_OLD
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
const EVP_MD *type)
{
EVP_MD_CTX ctx;
unsigned char *p,*buf_in=NULL,*buf_out=NULL;
int i,inl=0,outl=0,outll=0;
X509_ALGOR *a;
EVP_MD_CTX_init(&ctx);
for (i=0; i<2; i++)
{
if (i == 0)
a=algor1;
else
a=algor2;
if (a == NULL) continue;
if (type->pkey_type == NID_dsaWithSHA1)
{
/* special case: RFC 2459 tells us to omit 'parameters'
* with id-dsa-with-sha1 */
ASN1_TYPE_free(a->parameter);
a->parameter = NULL;
}
else if ((a->parameter == NULL) ||
(a->parameter->type != V_ASN1_NULL))
{
ASN1_TYPE_free(a->parameter);
if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
a->parameter->type=V_ASN1_NULL;
}
ASN1_OBJECT_free(a->algorithm);
a->algorithm=OBJ_nid2obj(type->pkey_type);
if (a->algorithm == NULL)
{
ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
goto err;
}
if (a->algorithm->length == 0)
{
ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
goto err;
}
}
inl=i2d(data,NULL);
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
outll=outl=EVP_PKEY_size(pkey);
buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
if ((buf_in == NULL) || (buf_out == NULL))
{
outl=0;
ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
goto err;
}
p=buf_in;
i2d(data,&p);
if (!EVP_SignInit_ex(&ctx,type, NULL)
|| !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
|| !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
(unsigned int *)&outl,pkey))
{
outl=0;
ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
goto err;
}
if (signature->data != NULL) OPENSSL_free(signature->data);
signature->data=buf_out;
buf_out=NULL;
signature->length=outl;
/* In the interests of compatibility, I'll make sure that
* the bit string has a 'not-used bits' value of 0
*/
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
EVP_MD_CTX_cleanup(&ctx);
if (buf_in != NULL)
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
if (buf_out != NULL)
{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
return(outl);
}
#endif
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
const EVP_MD *type)
{
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
{
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
}
int ASN1_item_sign_ctx(const ASN1_ITEM *it,
X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
{
const EVP_MD *type;
EVP_PKEY *pkey;
unsigned char *buf_in=NULL,*buf_out=NULL;
size_t inl=0,outl=0,outll=0;
int signid, paramtype;
int rv;
type = EVP_MD_CTX_md(ctx);
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!type || !pkey)
{
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)
outl = signature->length;
/* Return value meanings:
* <=0: error.
* 1: method does everything.
* 2: carry on as normal.
* 3: ASN1 method sets algorithm identifiers: just sign.
*/
if (rv <= 0)
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 (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
paramtype = V_ASN1_NULL;
else
paramtype = V_ASN1_UNDEF;
if (algor1)
X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
if (algor2)
X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
}
inl=ASN1_item_i2d(asn,&buf_in, it);
outll=outl=EVP_PKEY_size(pkey);
buf_out=OPENSSL_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) OPENSSL_free(signature->data);
signature->data=buf_out;
buf_out=NULL;
signature->length=outl;
/* In the interests of compatibility, I'll make sure that
* the bit string has a 'not-used bits' value of 0
*/
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
EVP_MD_CTX_cleanup(ctx);
if (buf_in != NULL)
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
if (buf_out != NULL)
{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
return(outl);
}

View File

@@ -0,0 +1,575 @@
/* a_strex.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include "charmap.h"
/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
* Enhanced string and name printing routines handling
* multibyte characters, RFC2253 and a host of other
* options.
*/
#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
ASN1_STRFLGS_ESC_QUOTE | \
ASN1_STRFLGS_ESC_CTRL | \
ASN1_STRFLGS_ESC_MSB)
/* Three IO functions for sending data to memory, a BIO and
* and a FILE pointer.
*/
#if 0 /* never used */
static int send_mem_chars(void *arg, const void *buf, int len)
{
unsigned char **out = arg;
if(!out) return 1;
memcpy(*out, buf, len);
*out += len;
return 1;
}
#endif
static int send_bio_chars(void *arg, const void *buf, int len)
{
if(!arg) return 1;
if(BIO_write(arg, buf, len) != len) return 0;
return 1;
}
static int send_fp_chars(void *arg, const void *buf, int len)
{
if(!arg) return 1;
if(fwrite(buf, 1, len, arg) != (unsigned int)len) return 0;
return 1;
}
typedef int char_io(void *arg, const void *buf, int len);
/* This function handles display of
* strings, one character at a time.
* It is passed an unsigned long for each
* character because it could come from 2 or even
* 4 byte forms.
*/
static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg)
{
unsigned char chflgs, chtmp;
char tmphex[HEX_SIZE(long)+3];
if(c > 0xffffffffL)
return -1;
if(c > 0xffff) {
BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
if(!io_ch(arg, tmphex, 10)) return -1;
return 10;
}
if(c > 0xff) {
BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
if(!io_ch(arg, tmphex, 6)) return -1;
return 6;
}
chtmp = (unsigned char)c;
if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
else chflgs = char_type[chtmp] & flags;
if(chflgs & CHARTYPE_BS_ESC) {
/* If we don't escape with quotes, signal we need quotes */
if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
if(do_quotes) *do_quotes = 1;
if(!io_ch(arg, &chtmp, 1)) return -1;
return 1;
}
if(!io_ch(arg, "\\", 1)) return -1;
if(!io_ch(arg, &chtmp, 1)) return -1;
return 2;
}
if(chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
if(!io_ch(arg, tmphex, 3)) return -1;
return 3;
}
/* If we get this far and do any escaping at all must escape
* the escape character itself: backslash.
*/
if (chtmp == '\\' && flags & ESC_FLAGS) {
if(!io_ch(arg, "\\\\", 2)) return -1;
return 2;
}
if(!io_ch(arg, &chtmp, 1)) return -1;
return 1;
}
#define BUF_TYPE_WIDTH_MASK 0x7
#define BUF_TYPE_CONVUTF8 0x8
/* This function sends each character in a buffer to
* do_esc_char(). It interprets the content formats
* and converts to or from UTF8 as appropriate.
*/
static int do_buf(unsigned char *buf, int buflen,
int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
{
int i, outlen, len;
unsigned char orflags, *p, *q;
unsigned long c;
p = buf;
q = buf + buflen;
outlen = 0;
while(p != q) {
if(p == buf && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_FIRST_ESC_2253;
else orflags = 0;
switch(type & BUF_TYPE_WIDTH_MASK) {
case 4:
c = ((unsigned long)*p++) << 24;
c |= ((unsigned long)*p++) << 16;
c |= ((unsigned long)*p++) << 8;
c |= *p++;
break;
case 2:
c = ((unsigned long)*p++) << 8;
c |= *p++;
break;
case 1:
c = *p++;
break;
case 0:
i = UTF8_getc(p, buflen, &c);
if(i < 0) return -1; /* Invalid UTF8String */
p += i;
break;
default:
return -1; /* invalid width */
}
if (p == q && flags & ASN1_STRFLGS_ESC_2253) orflags = CHARTYPE_LAST_ESC_2253;
if(type & BUF_TYPE_CONVUTF8) {
unsigned char utfbuf[6];
int utflen;
utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
for(i = 0; i < utflen; i++) {
/* We don't need to worry about setting orflags correctly
* because if utflen==1 its value will be correct anyway
* otherwise each character will be > 0x7f and so the
* character will never be escaped on first and last.
*/
len = do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
if(len < 0) return -1;
outlen += len;
}
} else {
len = do_esc_char(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
if(len < 0) return -1;
outlen += len;
}
}
return outlen;
}
/* This function hex dumps a buffer of characters */
static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
{
static const char hexdig[] = "0123456789ABCDEF";
unsigned char *p, *q;
char hextmp[2];
if(arg) {
p = buf;
q = buf + buflen;
while(p != q) {
hextmp[0] = hexdig[*p >> 4];
hextmp[1] = hexdig[*p & 0xf];
if(!io_ch(arg, hextmp, 2)) return -1;
p++;
}
}
return buflen << 1;
}
/* "dump" a string. This is done when the type is unknown,
* or the flags request it. We can either dump the content
* octets or the entire DER encoding. This uses the RFC2253
* #01234 format.
*/
static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
{
/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
* the DER encoding to readily obtained
*/
ASN1_TYPE t;
unsigned char *der_buf, *p;
int outlen, der_len;
if(!io_ch(arg, "#", 1)) return -1;
/* If we don't dump DER encoding just dump content octets */
if(!(lflags & ASN1_STRFLGS_DUMP_DER)) {
outlen = do_hex_dump(io_ch, arg, str->data, str->length);
if(outlen < 0) return -1;
return outlen + 1;
}
t.type = str->type;
t.value.ptr = (char *)str;
der_len = i2d_ASN1_TYPE(&t, NULL);
der_buf = OPENSSL_malloc(der_len);
if(!der_buf) return -1;
p = der_buf;
i2d_ASN1_TYPE(&t, &p);
outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
OPENSSL_free(der_buf);
if(outlen < 0) return -1;
return outlen + 1;
}
/* Lookup table to convert tags to character widths,
* 0 = UTF8 encoded, -1 is used for non string types
* otherwise it is the number of bytes per character
*/
static const signed char tag2nbyte[] = {
-1, -1, -1, -1, -1, /* 0-4 */
-1, -1, -1, -1, -1, /* 5-9 */
-1, -1, 0, -1, /* 10-13 */
-1, -1, -1, -1, /* 15-17 */
-1, 1, 1, /* 18-20 */
-1, 1, 1, 1, /* 21-24 */
-1, 1, -1, /* 25-27 */
4, -1, 2 /* 28-30 */
};
/* This is the main function, print out an
* ASN1_STRING taking note of various escape
* and display options. Returns number of
* characters written or -1 if an error
* occurred.
*/
static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
{
int outlen, len;
int type;
char quotes;
unsigned char flags;
quotes = 0;
/* Keep a copy of escape flags */
flags = (unsigned char)(lflags & ESC_FLAGS);
type = str->type;
outlen = 0;
if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
const char *tagname;
tagname = ASN1_tag2str(type);
outlen += strlen(tagname);
if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1;
outlen++;
}
/* Decide what to do with type, either dump content or display it */
/* Dump everything */
if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
/* Ignore the string type */
else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
else {
/* Else determine width based on type */
if((type > 0) && (type < 31)) type = tag2nbyte[type];
else type = -1;
if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
}
if(type == -1) {
len = do_dump(lflags, io_ch, arg, str);
if(len < 0) return -1;
outlen += len;
return outlen;
}
if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
/* Note: if string is UTF8 and we want
* to convert to UTF8 then we just interpret
* it as 1 byte per character to avoid converting
* twice.
*/
if(!type) type = 1;
else type |= BUF_TYPE_CONVUTF8;
}
len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
if(len < 0) return -1;
outlen += len;
if(quotes) outlen += 2;
if(!arg) return outlen;
if(quotes && !io_ch(arg, "\"", 1)) return -1;
if(do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
return -1;
if(quotes && !io_ch(arg, "\"", 1)) return -1;
return outlen;
}
/* Used for line indenting: print 'indent' spaces */
static int do_indent(char_io *io_ch, void *arg, int indent)
{
int i;
for(i = 0; i < indent; i++)
if(!io_ch(arg, " ", 1)) return 0;
return 1;
}
#define FN_WIDTH_LN 25
#define FN_WIDTH_SN 10
static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n,
int indent, unsigned long flags)
{
int i, prev = -1, orflags, cnt;
int fn_opt, fn_nid;
ASN1_OBJECT *fn;
ASN1_STRING *val;
X509_NAME_ENTRY *ent;
char objtmp[80];
const char *objbuf;
int outlen, len;
char *sep_dn, *sep_mv, *sep_eq;
int sep_dn_len, sep_mv_len, sep_eq_len;
if(indent < 0) indent = 0;
outlen = indent;
if(!do_indent(io_ch, arg, indent)) return -1;
switch (flags & XN_FLAG_SEP_MASK)
{
case XN_FLAG_SEP_MULTILINE:
sep_dn = "\n";
sep_dn_len = 1;
sep_mv = " + ";
sep_mv_len = 3;
break;
case XN_FLAG_SEP_COMMA_PLUS:
sep_dn = ",";
sep_dn_len = 1;
sep_mv = "+";
sep_mv_len = 1;
indent = 0;
break;
case XN_FLAG_SEP_CPLUS_SPC:
sep_dn = ", ";
sep_dn_len = 2;
sep_mv = " + ";
sep_mv_len = 3;
indent = 0;
break;
case XN_FLAG_SEP_SPLUS_SPC:
sep_dn = "; ";
sep_dn_len = 2;
sep_mv = " + ";
sep_mv_len = 3;
indent = 0;
break;
default:
return -1;
}
if(flags & XN_FLAG_SPC_EQ) {
sep_eq = " = ";
sep_eq_len = 3;
} else {
sep_eq = "=";
sep_eq_len = 1;
}
fn_opt = flags & XN_FLAG_FN_MASK;
cnt = X509_NAME_entry_count(n);
for(i = 0; i < cnt; i++) {
if(flags & XN_FLAG_DN_REV)
ent = X509_NAME_get_entry(n, cnt - i - 1);
else ent = X509_NAME_get_entry(n, i);
if(prev != -1) {
if(prev == ent->set) {
if(!io_ch(arg, sep_mv, sep_mv_len)) return -1;
outlen += sep_mv_len;
} else {
if(!io_ch(arg, sep_dn, sep_dn_len)) return -1;
outlen += sep_dn_len;
if(!do_indent(io_ch, arg, indent)) return -1;
outlen += indent;
}
}
prev = ent->set;
fn = X509_NAME_ENTRY_get_object(ent);
val = X509_NAME_ENTRY_get_data(ent);
fn_nid = OBJ_obj2nid(fn);
if(fn_opt != XN_FLAG_FN_NONE) {
int objlen, fld_len;
if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
fld_len = 0; /* XXX: what should this be? */
objbuf = objtmp;
} else {
if(fn_opt == XN_FLAG_FN_SN) {
fld_len = FN_WIDTH_SN;
objbuf = OBJ_nid2sn(fn_nid);
} else if(fn_opt == XN_FLAG_FN_LN) {
fld_len = FN_WIDTH_LN;
objbuf = OBJ_nid2ln(fn_nid);
} else {
fld_len = 0; /* XXX: what should this be? */
objbuf = "";
}
}
objlen = strlen(objbuf);
if(!io_ch(arg, objbuf, objlen)) return -1;
if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
if (!do_indent(io_ch, arg, fld_len - objlen)) return -1;
outlen += fld_len - objlen;
}
if(!io_ch(arg, sep_eq, sep_eq_len)) return -1;
outlen += objlen + sep_eq_len;
}
/* If the field name is unknown then fix up the DER dump
* flag. We might want to limit this further so it will
* DER dump on anything other than a few 'standard' fields.
*/
if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
orflags = ASN1_STRFLGS_DUMP_ALL;
else orflags = 0;
len = do_print_ex(io_ch, arg, flags | orflags, val);
if(len < 0) return -1;
outlen += len;
}
return outlen;
}
/* Wrappers round the main functions */
int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
{
if(flags == XN_FLAG_COMPAT)
return X509_NAME_print(out, nm, indent);
return do_name_ex(send_bio_chars, out, nm, indent, flags);
}
#ifndef OPENSSL_NO_FP_API
int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
{
if(flags == XN_FLAG_COMPAT)
{
BIO *btmp;
int ret;
btmp = BIO_new_fp(fp, BIO_NOCLOSE);
if(!btmp) return -1;
ret = X509_NAME_print(btmp, nm, indent);
BIO_free(btmp);
return ret;
}
return do_name_ex(send_fp_chars, fp, nm, indent, flags);
}
#endif
int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
{
return do_print_ex(send_bio_chars, out, flags, str);
}
#ifndef OPENSSL_NO_FP_API
int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
{
return do_print_ex(send_fp_chars, fp, flags, str);
}
#endif
/* Utility function: convert any string type to UTF8, returns number of bytes
* in output string or a negative error code
*/
int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
{
ASN1_STRING stmp, *str = &stmp;
int mbflag, type, ret;
if(!in) return -1;
type = in->type;
if((type < 0) || (type > 30)) return -1;
mbflag = tag2nbyte[type];
if(mbflag == -1) return -1;
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
if(ret < 0) return ret;
*out = stmp.data;
return stmp.length;
}

View File

@@ -0,0 +1,290 @@
/* a_strnid.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static void st_free(ASN1_STRING_TABLE *tbl);
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
const ASN1_STRING_TABLE * const *b);
/* This is the global mask for the mbstring functions: this is use to
* mask out certain types (such as BMPString and UTF8String) because
* certain software (e.g. Netscape) has problems with them.
*/
static unsigned long global_mask = B_ASN1_UTF8STRING;
void ASN1_STRING_set_default_mask(unsigned long mask)
{
global_mask = mask;
}
unsigned long ASN1_STRING_get_default_mask(void)
{
return global_mask;
}
/* This function sets the default to various "flavours" of configuration.
* based on an ASCII string. Currently this is:
* MASK:XXXX : a numerical mask value.
* nobmp : Don't use BMPStrings (just Printable, T61).
* pkix : PKIX recommendation in RFC2459.
* utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
* default: the default value, Printable, T61, BMP.
*/
int ASN1_STRING_set_default_mask_asc(const char *p)
{
unsigned long mask;
char *end;
if(!strncmp(p, "MASK:", 5)) {
if(!p[5]) return 0;
mask = strtoul(p + 5, &end, 0);
if(*end) return 0;
} else if(!strcmp(p, "nombstr"))
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
else if(!strcmp(p, "pkix"))
mask = ~((unsigned long)B_ASN1_T61STRING);
else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
else if(!strcmp(p, "default"))
mask = 0xFFFFFFFFL;
else return 0;
ASN1_STRING_set_default_mask(mask);
return 1;
}
/* The following function generates an ASN1_STRING based on limits in a table.
* Frequently the types and length of an ASN1_STRING are restricted by a
* corresponding OID. For example certificates and certificate requests.
*/
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
int inlen, int inform, int nid)
{
ASN1_STRING_TABLE *tbl;
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if(!out) out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if(tbl) {
mask = tbl->mask;
if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
if(ret <= 0) return NULL;
return *out;
}
/* Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
#define ub_name 32768
#define ub_common_name 64
#define ub_locality_name 128
#define ub_state_name 128
#define ub_organization_name 64
#define ub_organization_unit_name 64
#define ub_title 64
#define ub_email_address 128
#define ub_serial_number 64
/* This table must be kept in NID order */
static const ASN1_STRING_TABLE tbl_standard[] = {
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
};
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
const ASN1_STRING_TABLE * const *b)
{
return (*a)->nid - (*b)->nid;
}
DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
{
return a->nid - b->nid;
}
IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
{
int idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
if(ttmp) return ttmp;
if(!stable) return NULL;
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
if(idx < 0) return NULL;
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
int ASN1_STRING_TABLE_add(int nid,
long minsize, long maxsize, unsigned long mask,
unsigned long flags)
{
ASN1_STRING_TABLE *tmp;
char new_nid = 0;
flags &= ~STABLE_FLAGS_MALLOC;
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if(!stable) {
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if(!tmp) {
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
new_nid = 1;
} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
if(minsize != -1) tmp->minsize = minsize;
if(maxsize != -1) tmp->maxsize = maxsize;
tmp->mask = mask;
if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
return 1;
}
void ASN1_STRING_TABLE_cleanup(void)
{
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if(!tmp) return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
}
static void st_free(ASN1_STRING_TABLE *tbl)
{
if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
}
IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
#ifdef STRING_TABLE_TEST
main()
{
ASN1_STRING_TABLE *tmp;
int i, last_nid = -1;
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
{
if (tmp->nid < last_nid)
{
last_nid = 0;
break;
}
last_nid = tmp->nid;
}
if (last_nid != 0)
{
printf("Table order OK\n");
exit(0);
}
for (tmp = tbl_standard, i = 0;
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
OBJ_nid2ln(tmp->nid));
}
#endif

View File

@@ -0,0 +1,198 @@
/* crypto/asn1/a_time.c */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* This is an implementation of the ASN1 Time structure which is:
* Time ::= CHOICE {
* utcTime UTCTime,
* generalTime GeneralizedTime }
* written by Steve Henson.
*/
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1t.h>
IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
#if 0
int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
{
#ifdef CHARSET_EBCDIC
/* KLUDGE! We convert to ascii before writing DER */
char tmp[24];
ASN1_STRING tmpstr;
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
int len;
tmpstr = *(ASN1_STRING *)a;
len = tmpstr.length;
ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
tmpstr.data = tmp;
a = (ASN1_GENERALIZEDTIME *) &tmpstr;
}
#endif
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))
return NULL;
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
/* Work out the century and prepend */
if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
else BUF_strlcpy(str, "20", newlen);
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.data = (unsigned char *)str;
t.flags = 0;
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;
}

View File

@@ -0,0 +1,159 @@
/* crypto/asn1/a_type.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#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;
}
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;
case V_ASN1_NULL:
result = 0; /* They do not have content. */
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_OTHER:
default:
result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
(ASN1_STRING *) b->value.ptr);
break;
}
return result;
}

View File

@@ -0,0 +1,318 @@
/* crypto/asn1/a_utctm.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include "o_time.h"
#include <openssl/asn1.h>
#if 0
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
{
#ifndef CHARSET_EBCDIC
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
#else
/* KLUDGE! We convert to ascii before writing DER */
int len;
char tmp[24];
ASN1_STRING x = *(ASN1_STRING *)a;
len = x.length;
ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
x.data = tmp;
return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
#endif
}
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);
}
#ifdef CHARSET_EBCDIC
ascii2ebcdic(ret->data, ret->data, ret->length);
#endif
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;
int n,i,l,o;
if (d->type != V_ASN1_UTCTIME) return(0);
l=d->length;
a=(char *)d->data;
o=0;
if (l < 11) goto err;
for (i=0; i<6; i++)
{
if ((i == 5) && ((a[o] == 'Z') ||
(a[o] == '+') || (a[o] == '-')))
{ i++; break; }
if ((a[o] < '0') || (a[o] > '9')) goto err;
n= a[o]-'0';
if (++o > l) goto err;
if ((a[o] < '0') || (a[o] > '9')) goto err;
n=(n*10)+ a[o]-'0';
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++;
if ((a[o] < '0') || (a[o] > '9')) goto err;
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);
}
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;
size_t len = 20;
if (s == NULL)
s=M_ASN1_UTCTIME_new();
if (s == NULL)
return(NULL);
ts=OPENSSL_gmtime(&t, &data);
if (ts == NULL)
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=OPENSSL_malloc(len);
if (p == NULL)
{
ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
OPENSSL_free(s->data);
s->data=(unsigned char *)p;
}
BIO_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;
#ifdef CHARSET_EBCDIC_not
ebcdic2ascii(s->data, s->data, s->length);
#endif
return(s);
}
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
{
struct tm *tm;
struct tm data;
int offset;
int year;
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
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 */
tm = OPENSSL_gmtime(&t, &data);
#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
year = g2(s->data);
if (year < 50)
year += 100;
return_cmp(year, tm->tm_year);
return_cmp(g2(s->data+2) - 1, tm->tm_mon);
return_cmp(g2(s->data+4), tm->tm_mday);
return_cmp(g2(s->data+6), tm->tm_hour);
return_cmp(g2(s->data+8), tm->tm_min);
return_cmp(g2(s->data+10), tm->tm_sec);
#undef g2
#undef return_cmp
return 0;
}
#if 0
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
{
struct tm tm;
int offset;
memset(&tm,'\0',sizeof tm);
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
tm.tm_year=g2(s->data);
if(tm.tm_year < 50)
tm.tm_year+=100;
tm.tm_mon=g2(s->data+2)-1;
tm.tm_mday=g2(s->data+4);
tm.tm_hour=g2(s->data+6);
tm.tm_min=g2(s->data+8);
tm.tm_sec=g2(s->data+10);
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
* instead of UTC, and unless we rewrite OpenSSL
* in Lisp we cannot locally change the timezone
* without possibly interfering with other parts
* of the program. timegm, which uses UTC, is
* non-standard.
* Also time_t is inappropriate for general
* UTC times because it may a 32 bit type. */
}
#endif

View File

@@ -0,0 +1,211 @@
/* crypto/asn1/a_utf8.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
/* UTF8 utilities */
/* This parses a UTF8 string one character at a time. It is passed a pointer
* to the string and the length of the string. It sets 'value' to the value of
* the current character. It returns the number of characters read or a
* negative error code:
* -1 = string too short
* -2 = illegal character
* -3 = subsequent characters not of the form 10xxxxxx
* -4 = character encoded incorrectly (not minimal length).
*/
int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
{
const unsigned char *p;
unsigned long value;
int ret;
if(len <= 0) return 0;
p = str;
/* Check syntax and work out the encoded value (if correct) */
if((*p & 0x80) == 0) {
value = *p++ & 0x7f;
ret = 1;
} else if((*p & 0xe0) == 0xc0) {
if(len < 2) return -1;
if((p[1] & 0xc0) != 0x80) return -3;
value = (*p++ & 0x1f) << 6;
value |= *p++ & 0x3f;
if(value < 0x80) return -4;
ret = 2;
} else if((*p & 0xf0) == 0xe0) {
if(len < 3) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80) ) return -3;
value = (*p++ & 0xf) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x800) return -4;
ret = 3;
} else if((*p & 0xf8) == 0xf0) {
if(len < 4) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x7)) << 18;
value |= (*p++ & 0x3f) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x10000) return -4;
ret = 4;
} else if((*p & 0xfc) == 0xf8) {
if(len < 5) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x3)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x200000) return -4;
ret = 5;
} else if((*p & 0xfe) == 0xfc) {
if(len < 6) return -1;
if( ((p[1] & 0xc0) != 0x80)
|| ((p[2] & 0xc0) != 0x80)
|| ((p[3] & 0xc0) != 0x80)
|| ((p[4] & 0xc0) != 0x80)
|| ((p[5] & 0xc0) != 0x80) ) return -3;
value = ((unsigned long)(*p++ & 0x1)) << 30;
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if(value < 0x4000000) return -4;
ret = 6;
} else return -2;
*val = value;
return ret;
}
/* This takes a character 'value' and writes the UTF8 encoded value in
* 'str' where 'str' is a buffer containing 'len' characters. Returns
* the number of characters written or -1 if 'len' is too small. 'str' can
* be set to NULL in which case it just returns the number of characters.
* It will need at most 6 characters.
*/
int UTF8_putc(unsigned char *str, int len, unsigned long value)
{
if(!str) len = 6; /* Maximum we will need */
else if(len <= 0) return -1;
if(value < 0x80) {
if(str) *str = (unsigned char)value;
return 1;
}
if(value < 0x800) {
if(len < 2) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 2;
}
if(value < 0x10000) {
if(len < 3) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 3;
}
if(value < 0x200000) {
if(len < 4) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 4;
}
if(value < 0x4000000) {
if(len < 5) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 5;
}
if(len < 6) return -1;
if(str) {
*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
*str = (unsigned char)((value & 0x3f) | 0x80);
}
return 6;
}

View File

@@ -0,0 +1,234 @@
/* crypto/asn1/a_verify.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include "asn1_locl.h"
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#ifndef NO_ASN1_OLD
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
char *data, EVP_PKEY *pkey)
{
EVP_MD_CTX ctx;
const EVP_MD *type;
unsigned char *p,*buf_in=NULL;
int ret= -1,i,inl;
EVP_MD_CTX_init(&ctx);
i=OBJ_obj2nid(a->algorithm);
type=EVP_get_digestbyname(OBJ_nid2sn(i));
if (type == NULL)
{
ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err;
}
inl=i2d(data,NULL);
buf_in=OPENSSL_malloc((unsigned int)inl);
if (buf_in == NULL)
{
ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE);
goto err;
}
p=buf_in;
i2d(data,&p);
if (!EVP_VerifyInit_ex(&ctx,type, NULL)
|| !EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl))
{
ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
ret=0;
goto err;
}
OPENSSL_cleanse(buf_in,(unsigned int)inl);
OPENSSL_free(buf_in);
if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
(unsigned int)signature->length,pkey) <= 0)
{
ASN1err(ASN1_F_ASN1_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)); */
ret=1;
err:
EVP_MD_CTX_cleanup(&ctx);
return(ret);
}
#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
* exit straight away: either a fatal error of the underlying
* verification routine handles all verification.
*/
if (ret != 2)
goto err;
ret = -1;
}
else
{
const EVP_MD *type;
type=EVP_get_digestbynid(mdnid);
if (type == NULL)
{
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);
OPENSSL_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)); */
ret=1;
err:
EVP_MD_CTX_cleanup(&ctx);
return(ret);
}

View File

@@ -0,0 +1,460 @@
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_locl.h"
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
/* 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
#ifndef OPENSSL_NO_DH
&dh_asn1_meth,
#endif
#ifndef OPENSSL_NO_DSA
&dsa_asn1_meths[0],
&dsa_asn1_meths[1],
&dsa_asn1_meths[2],
&dsa_asn1_meths[3],
&dsa_asn1_meths[4],
#endif
#ifndef OPENSSL_NO_EC
&eckey_asn1_meth,
#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)
static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
#ifdef TEST
void main()
{
int i;
for (i = 0;
i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
i++)
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 *,
const EVP_PKEY_ASN1_METHOD *, ameth);
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;
if (idx < num)
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
* to the engine implementing 'type' or NULL if no engine implements
* it.
*/
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;
}
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
*/
if (!ENGINE_init(e))
ameth = NULL;
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;
}
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)
*ppkey_id = ameth->pkey_id;
if (ppkey_base_id)
*ppkey_base_id = ameth->pkey_base_id;
if (ppkey_flags)
*ppkey_flags = ameth->pkey_flags;
if (pinfo)
*pinfo = ameth->info;
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 = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
if (!ameth)
return NULL;
memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
ameth->pkey_id = id;
ameth->pkey_base_id = id;
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;
ameth->pub_decode = 0;
ameth->pub_encode = 0;
ameth->pub_cmp = 0;
ameth->pub_print = 0;
ameth->priv_decode = 0;
ameth->priv_encode = 0;
ameth->priv_print = 0;
ameth->old_priv_encode = 0;
ameth->old_priv_decode = 0;
ameth->item_verify = 0;
ameth->item_sign = 0;
ameth->pkey_size = 0;
ameth->pkey_bits = 0;
ameth->param_decode = 0;
ameth->param_encode = 0;
ameth->param_missing = 0;
ameth->param_copy = 0;
ameth->param_cmp = 0;
ameth->param_print = 0;
ameth->pkey_free = 0;
ameth->pkey_ctrl = 0;
return ameth;
err:
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->pub_cmp = src->pub_cmp;
dst->pub_print = src->pub_print;
dst->priv_decode = src->priv_decode;
dst->priv_encode = src->priv_encode;
dst->priv_print = src->priv_print;
dst->old_priv_encode = src->old_priv_encode;
dst->old_priv_decode = src->old_priv_decode;
dst->pkey_size = src->pkey_size;
dst->pkey_bits = src->pkey_bits;
dst->param_decode = src->param_decode;
dst->param_encode = src->param_encode;
dst->param_missing = src->param_missing;
dst->param_copy = src->param_copy;
dst->param_cmp = src->param_cmp;
dst->param_print = src->param_print;
dst->pkey_free = src->pkey_free;
dst->pkey_ctrl = src->pkey_ctrl;
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)
OPENSSL_free(ameth->pem_str);
if (ameth->info)
OPENSSL_free(ameth->info);
OPENSSL_free(ameth);
}
}
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
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,
const unsigned char **pder, int derlen),
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
int (*param_missing)(const EVP_PKEY *pk),
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,332 @@
/* crypto/asn1/asn1_err.c */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
#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_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
{ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"},
{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
{ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"},
{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"},
{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"},
{ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"},
{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"},
{ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"},
{ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
{ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"},
{ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"},
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
{ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
{ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"},
{ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"},
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
{ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"},
{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"},
{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
{ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
{ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"},
{ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"},
{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
{ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
{ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"},
{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
{ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"},
{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"},
{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"},
{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_AUX_ERROR) ,"aux error"},
{ERR_REASON(ASN1_R_BAD_CLASS) ,"bad class"},
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"},
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ) ,"bad password read"},
{ERR_REASON(ASN1_R_BAD_TAG) ,"bad tag"},
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"},
{ERR_REASON(ASN1_R_BN_LIB) ,"bn lib"},
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"},
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
{ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"},
{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"},
{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"},
{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
{ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"},
{ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"},
{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),"error parsing set element"},
{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),"error setting cipher params"},
{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) ,"expecting an integer"},
{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT) ,"expecting an object"},
{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN) ,"expecting a boolean"},
{ERR_REASON(ASN1_R_EXPECTING_A_TIME) ,"expecting a time"},
{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH),"explicit length mismatch"},
{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),"explicit tag not constructed"},
{ERR_REASON(ASN1_R_FIELD_MISSING) ,"field missing"},
{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE) ,"first num too large"},
{ERR_REASON(ASN1_R_HEADER_TOO_LONG) ,"header too long"},
{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT),"illegal bitstring format"},
{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN) ,"illegal boolean"},
{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS) ,"illegal characters"},
{ERR_REASON(ASN1_R_ILLEGAL_FORMAT) ,"illegal format"},
{ERR_REASON(ASN1_R_ILLEGAL_HEX) ,"illegal hex"},
{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) ,"illegal implicit tag"},
{ERR_REASON(ASN1_R_ILLEGAL_INTEGER) ,"illegal integer"},
{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING),"illegal nested tagging"},
{ERR_REASON(ASN1_R_ILLEGAL_NULL) ,"illegal null"},
{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE) ,"illegal null value"},
{ERR_REASON(ASN1_R_ILLEGAL_OBJECT) ,"illegal object"},
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) ,"illegal optional any"},
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),"illegal options on item template"},
{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY) ,"illegal tagged any"},
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
{ERR_REASON(ASN1_R_INVALID_UTF8STRING) ,"invalid utf8string"},
{ERR_REASON(ASN1_R_IV_TOO_LARGE) ,"iv too large"},
{ERR_REASON(ASN1_R_LENGTH_ERROR) ,"length error"},
{ERR_REASON(ASN1_R_LIST_ERROR) ,"list error"},
{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"},
{ERR_REASON(ASN1_R_MIME_PARSE_ERROR) ,"mime parse error"},
{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"},
{ERR_REASON(ASN1_R_MISSING_EOC) ,"missing eoc"},
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
{ERR_REASON(ASN1_R_MISSING_VALUE) ,"missing value"},
{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"},
{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG) ,"mstring wrong tag"},
{ERR_REASON(ASN1_R_NESTED_ASN1_STRING) ,"nested asn1 string"},
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"},
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"},
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"},
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"},
{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST) ,"no default digest"},
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) ,"odd number of chars"},
{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),"private key header missing"},
{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE),"second number too large"},
{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH),"sequence length mismatch"},
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
{ERR_REASON(ASN1_R_SHORT_LINE) ,"short line"},
{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"},
{ERR_REASON(ASN1_R_STRING_TOO_LONG) ,"string too long"},
{ERR_REASON(ASN1_R_STRING_TOO_SHORT) ,"string too short"},
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) ,"tag value too high"},
{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
{ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},
{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"},
{ERR_REASON(ASN1_R_UNKNOWN_FORMAT) ,"unknown format"},
{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"},
{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"},
{ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unknown format"},
{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"},
{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
{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
}

View File

@@ -0,0 +1,854 @@
/* asn1_gen.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2002.
*/
/* ====================================================================
* Copyright (c) 2002 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/x509v3.h>
#define ASN1_GEN_FLAG 0x10000
#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
#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_FLAG_EXP_MAX 20
/* Input formats */
/* ASCII: default */
#define ASN1_GEN_FORMAT_ASCII 1
/* UTF8 */
#define ASN1_GEN_FORMAT_UTF8 2
/* Hex */
#define ASN1_GEN_FORMAT_HEX 3
/* List of bits */
#define ASN1_GEN_FORMAT_BITLIST 4
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;
typedef struct
{
int imp_tag;
int imp_class;
int utype;
int format;
const char *str;
tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
int exp_count;
} 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 append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok);
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
{
X509V3_CTX cnf;
if (!nconf)
return ASN1_generate_v3(str, NULL);
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;
int i, len;
unsigned char *orig_der = NULL, *new_der = NULL;
const unsigned char *cpy_start;
unsigned char *p;
const unsigned char *cp;
int cpy_len;
long hdr_len;
int hdr_constructed = 0, hdr_tag, hdr_class;
int r;
asn1_tags.imp_tag = -1;
asn1_tags.imp_class = -1;
asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
asn1_tags.exp_count = 0;
if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
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);
}
else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
if (!ret)
return NULL;
/* If no tagging return base type */
if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
return ret;
/* Generate the encoding */
cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
ASN1_TYPE_free(ret);
ret = NULL;
/* Set point to start copying for modified encoding */
cpy_start = orig_der;
/* 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);
if (r & 0x80)
goto err;
/* Update copy length */
cpy_len -= cpy_start - orig_der;
/* For IMPLICIT tagging the length should match the
* original length and constructed flag should be
* consistent.
*/
if (r & 0x1)
{
/* Indefinite length constructed */
hdr_constructed = 2;
hdr_len = 0;
}
else
/* Just retain constructed flag */
hdr_constructed = r & V_ASN1_CONSTRUCTED;
/* Work out new length with IMPLICIT tag: ignore 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 */
new_der = OPENSSL_malloc(len);
if (!new_der)
goto err;
/* Generate tagged encoding */
p = new_der;
/* 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);
cp = new_der;
/* Obtain new ASN1_TYPE structure */
ret = d2i_ASN1_TYPE(NULL, &cp, len);
err:
if (orig_der)
OPENSSL_free(orig_der);
if (new_der)
OPENSSL_free(new_der);
return ret;
}
static int asn1_cb(const char *elem, int len, void *bitstr)
{
tag_exp_arg *arg = bitstr;
int i;
int utype;
int vlen = 0;
const char *p, *vstart = NULL;
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;
}
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;
case ASN1_GEN_FLAG_EXP:
if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
return -1;
if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
return -1;
break;
case ASN1_GEN_FLAG_SEQWRAP:
if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_SETWRAP:
if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_BITWRAP:
if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
return -1;
break;
case ASN1_GEN_FLAG_OCTWRAP:
if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_FORMAT:
if (!strncmp(vstart, "ASCII", 5))
arg->format = ASN1_GEN_FORMAT_ASCII;
else if (!strncmp(vstart, "UTF8", 4))
arg->format = ASN1_GEN_FORMAT_UTF8;
else if (!strncmp(vstart, "HEX", 3))
arg->format = ASN1_GEN_FORMAT_HEX;
else if (!strncmp(vstart, "BITLIST", 3))
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 (!vstart)
return 0;
tag_num = strtoul(vstart, &eptr, 10);
/* Check we haven't gone past max length: should be impossible */
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)
vlen -= eptr - vstart;
else
vlen = 0;
if (vlen)
{
switch (*eptr)
{
case 'U':
*pclass = V_ASN1_UNIVERSAL;
break;
case 'A':
*pclass = V_ASN1_APPLICATION;
break;
case 'P':
*pclass = V_ASN1_PRIVATE;
break;
case 'C':
*pclass = V_ASN1_CONTEXT_SPECIFIC;
break;
default:
erch[0] = *eptr;
erch[1] = 0;
ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
ERR_add_error_data(2, "Char=", erch);
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;
unsigned char *der = NULL;
int derlen;
int i;
sk = sk_ASN1_TYPE_new_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 */
if (utype == V_ASN1_SET)
derlen = i2d_ASN1_SET_ANY(sk, &der);
else
derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
if (derlen < 0)
goto bad;
if (!(ret = ASN1_TYPE_new()))
goto bad;
if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
goto bad;
ret->type = utype;
ret->value.asn1_string->data = der;
ret->value.asn1_string->length = derlen;
der = NULL;
bad:
if (der)
OPENSSL_free(der);
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
if (sect)
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++];
/* If IMPLICIT set tag to implicit value then
* 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("BOOLEAN", V_ASN1_BOOLEAN),
ASN1_GEN_STR("NULL", V_ASN1_NULL),
ASN1_GEN_STR("INT", V_ASN1_INTEGER),
ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
ASN1_GEN_STR("OID", V_ASN1_OBJECT),
ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("T61", V_ASN1_T61STRING),
ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
/* Special cases */
ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SET", V_ASN1_SET),
/* type modifiers */
/* Explicit tag */
ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
/* Implicit tag */
ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
/* OCTET STRING wrapper */
ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
/* SEQUENCE wrapper */
ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
/* SET wrapper */
ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
/* BIT STRING wrapper */
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;
unsigned char *rdata;
long rdlen;
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;
case V_ASN1_BMPSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_IA5STRING:
case V_ASN1_T61STRING:
case V_ASN1_UTF8STRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_NUMERICSTRING:
if (format == ASN1_GEN_FORMAT_ASCII)
format = MBSTRING_ASC;
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_BIT_STRING:
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;
default:
ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
}
atmp->type = utype;
return atmp;
bad_str:
ERR_add_error_data(2, "string=", str);
bad_form:
ASN1_TYPE_free(atmp);
return NULL;
}
static int bitstr_cb(const char *elem, int len, void *bitstr)
{
long bitnum;
char *eptr;
if (!elem)
return 0;
bitnum = strtoul(elem, &eptr, 10);
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;
}

View File

@@ -0,0 +1,482 @@
/* crypto/asn1/asn1_lib.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <limits.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1_mac.h>
static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
static void asn1_put_length(unsigned char **pp, int length);
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);
}
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;
int tag,xclass,inf;
long max=omax;
if (!max) goto err;
ret=(*p&V_ASN1_CONSTRUCTED);
xclass=(*p&V_ASN1_PRIVATE);
i= *p&V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG)
{ /* high-tag */
p++;
if (--max == 0) goto err;
l=0;
while (*p&0x80)
{
l<<=7L;
l|= *(p++)&0x7f;
if (--max == 0) goto err;
if (l > (INT_MAX >> 7L)) goto err;
}
l<<=7L;
l|= *(p++)&0x7f;
tag=(int)l;
if (--max == 0) goto err;
}
else
{
tag=i;
p++;
if (--max == 0) goto err;
}
*ptag=tag;
*pclass=xclass;
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
#if 0
fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
(int)(omax+ *pp));
#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;
i=(constructed)?V_ASN1_CONSTRUCTED:0;
i|=(xclass&V_ASN1_PRIVATE);
if (tag < 31)
*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
else
{
*(p++)=i|V_ASN1_PRIMITIVE_TAG;
for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
ttag = i;
while(i-- > 0)
{
p[i] = tag & 0x7f;
if(i != (ttag - 1)) p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++)=0x80;
else
asn1_put_length(&p,length);
*pp=p;
}
int ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p= *pp;
int i,l;
if (length <= 127)
*(p++)=(unsigned char)length;
else
{
l=length;
for (i=0; l > 0; i++)
l>>=8;
*(p++)=i|0x80;
l=i;
while (i-- > 0)
{
p[i]=length&0xff;
length>>=8;
}
p+=l;
}
*pp=p;
}
int ASN1_object_size(int constructed, int length, int tag)
{
int ret;
ret=length;
ret++;
if (tag >= 31)
{
while (tag > 0)
{
tag>>=7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127)
{
while (length > 0)
{
length>>=8;
ret++;
}
}
return(ret);
}
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);
}
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;
if (!ASN1_STRING_set(dst,str->data,str->length))
return 0;
dst->flags = str->flags;
return 1;
}
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
{
ASN1_STRING *ret;
if (!str)
return NULL;
ret=ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret,str))
{
ASN1_STRING_free(ret);
return NULL;
}
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=OPENSSL_malloc(len+1);
else
str->data=OPENSSL_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);
}
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
if (str->data)
OPENSSL_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 *)OPENSSL_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))
OPENSSL_free(a->data);
OPENSSL_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];
BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
BIO_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); }
void ASN1_STRING_length_set(ASN1_STRING *x, int len)
{ M_ASN1_STRING_length_set(x, len); return; }
int ASN1_STRING_type(ASN1_STRING *x)
{ return M_ASN1_STRING_type(x); }
unsigned char * ASN1_STRING_data(ASN1_STRING *x)
{ return M_ASN1_STRING_data(x); }

View File

@@ -0,0 +1,145 @@
/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Internal ASN1 structures and functions: not for application use */
/* ASN1 print context structure */
struct asn1_pctx_st
{
unsigned long flags;
unsigned long nm_flags;
unsigned long cert_flags;
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */;
/* ASN1 public key method structure */
struct evp_pkey_asn1_method_st
{
int pkey_id;
int pkey_base_id;
unsigned long pkey_flags;
char *pem_str;
char *info;
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
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);
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
int (*param_decode)(EVP_PKEY *pkey,
const unsigned char **pder, int derlen);
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
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);
int (*sig_print)(BIO *out,
const X509_ALGOR *sigalg, const ASN1_STRING *sig,
int indent, ASN1_PCTX *pctx);
void (*pkey_free)(EVP_PKEY *pkey);
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
/* Legacy functions for old PEM */
int (*old_priv_decode)(EVP_PKEY *pkey,
const unsigned char **pder, int derlen);
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
/* Custom ASN1 signature verification */
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *a, ASN1_BIT_STRING *sig,
EVP_PKEY *pkey);
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
ASN1_BIT_STRING *sig);
} /* EVP_PKEY_ASN1_METHOD */;
/* Method to handle CRL access.
* In general a CRL could be very large (several Mb) and can consume large
* amounts of resources if stored in memory by multiple processes.
* This method allows general CRL operations to be redirected to more
* efficient callbacks: for example a CRL entry database.
*/
#define X509_CRL_METHOD_DYNAMIC 1
struct x509_crl_method_st
{
int flags;
int (*crl_init)(X509_CRL *crl);
int (*crl_free)(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);
};

View File

@@ -0,0 +1,578 @@
/* crypto/asn1/asn1_mac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_ASN1_MAC_H
#define HEADER_ASN1_MAC_H
#include <openssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ASN1_MAC_ERR_LIB
#define ASN1_MAC_ERR_LIB ERR_LIB_ASN1
#endif
#define ASN1_MAC_H_err(f,r,line) \
ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
#define M_ASN1_D2I_vars(a,type,func) \
ASN1_const_CTX c; \
type ret=NULL; \
\
c.pp=(const unsigned char **)pp; \
c.q= *(const unsigned char **)pp; \
c.error=ERR_R_NESTED_ASN1_ERROR; \
if ((a == NULL) || ((*a) == NULL)) \
{ if ((ret=(type)func()) == NULL) \
{ c.line=__LINE__; goto err; } } \
else ret=(*a);
#define M_ASN1_D2I_Init() \
c.p= *(const unsigned char **)pp; \
c.max=(length == 0)?0:(c.p+length);
#define M_ASN1_D2I_Finish_2(a) \
if (!asn1_const_Finish(&c)) \
{ c.line=__LINE__; goto err; } \
*(const unsigned char **)pp=c.p; \
if (a != NULL) (*a)=ret; \
return(ret);
#define M_ASN1_D2I_Finish(a,func,e) \
M_ASN1_D2I_Finish_2(a); \
err:\
ASN1_MAC_H_err((e),c.error,c.line); \
asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
return(NULL)
#define M_ASN1_D2I_start_sequence() \
if (!asn1_GetSequence(&c,&length)) \
{ c.line=__LINE__; goto err; }
/* Begin reading ASN1 without a surrounding sequence */
#define M_ASN1_D2I_begin() \
c.slen = length;
/* End reading ASN1 with no check on length */
#define M_ASN1_D2I_Finish_nolen(a, func, e) \
*pp=c.p; \
if (a != NULL) (*a)=ret; \
return(ret); \
err:\
ASN1_MAC_H_err((e),c.error,c.line); \
asn1_add_error(*pp,(int)(c.q- *pp)); \
if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
return(NULL)
#define M_ASN1_D2I_end_sequence() \
(((c.inf&1) == 0)?(c.slen <= 0): \
(c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
/* Don't use this with d2i_ASN1_BOOLEAN() */
#define M_ASN1_D2I_get(b, func) \
c.q=c.p; \
if (func(&(b),&c.p,c.slen) == NULL) \
{c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
/* Don't use this with d2i_ASN1_BOOLEAN() */
#define M_ASN1_D2I_get_x(type,b,func) \
c.q=c.p; \
if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
{c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
/* use this instead () */
#define M_ASN1_D2I_get_int(b,func) \
c.q=c.p; \
if (func(&(b),&c.p,c.slen) < 0) \
{c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_opt(b,func,type) \
if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
== (V_ASN1_UNIVERSAL|(type)))) \
{ \
M_ASN1_D2I_get(b,func); \
}
#define M_ASN1_D2I_get_int_opt(b,func,type) \
if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
== (V_ASN1_UNIVERSAL|(type)))) \
{ \
M_ASN1_D2I_get_int(b,func); \
}
#define M_ASN1_D2I_get_imp(b,func, type) \
M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
c.q=c.p; \
if (func(&(b),&c.p,c.slen) == NULL) \
{c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
c.slen-=(c.p-c.q);\
M_ASN1_next_prev=_tmp;
#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
{ \
unsigned char _tmp = M_ASN1_next; \
M_ASN1_D2I_get_imp(b,func, type);\
}
#define M_ASN1_D2I_get_set(r,func,free_func) \
M_ASN1_D2I_get_imp_set(r,func,free_func, \
V_ASN1_SET,V_ASN1_UNIVERSAL);
#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
V_ASN1_SET,V_ASN1_UNIVERSAL);
#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
{ M_ASN1_D2I_get_set(r,func,free_func); }
#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
{ M_ASN1_D2I_get_set_type(type,r,func,free_func); }
#define M_ASN1_I2D_len_SET_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
M_ASN1_I2D_len_SET(a,f);
#define M_ASN1_I2D_put_SET_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
M_ASN1_I2D_put_SET(a,f);
#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
M_ASN1_I2D_put_SEQUENCE(a,f);
#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
if ((c.slen != 0) && \
(M_ASN1_next == \
(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
{ \
M_ASN1_D2I_get_imp_set(b,func,free_func,\
tag,V_ASN1_CONTEXT_SPECIFIC); \
}
#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
if ((c.slen != 0) && \
(M_ASN1_next == \
(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
{ \
M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
tag,V_ASN1_CONTEXT_SPECIFIC); \
}
#define M_ASN1_D2I_get_seq(r,func,free_func) \
M_ASN1_D2I_get_imp_set(r,func,free_func,\
V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
{ M_ASN1_D2I_get_seq(r,func,free_func); }
#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
M_ASN1_D2I_get_imp_set(r,func,free_func,\
x,V_ASN1_CONTEXT_SPECIFIC);
#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
x,V_ASN1_CONTEXT_SPECIFIC);
#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
c.q=c.p; \
if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
(void (*)())free_func,a,b) == NULL) \
{ c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
c.q=c.p; \
if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
free_func,a,b) == NULL) \
{ c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
c.q=c.p; \
if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
{ c.line=__LINE__; goto err; } \
c.slen-=(c.p-c.q);
#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
if ((c.slen != 0L) && (M_ASN1_next == \
(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
{ \
int Tinf,Ttag,Tclass; \
long Tlen; \
\
c.q=c.p; \
Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
if (Tinf & 0x80) \
{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
Tlen = c.slen - (c.p - c.q) - 2; \
if (func(&(r),&c.p,Tlen) == NULL) \
{ c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
Tlen = c.slen - (c.p - c.q); \
if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
{ c.error=ERR_R_MISSING_ASN1_EOS; \
c.line=__LINE__; goto err; } \
}\
c.slen-=(c.p-c.q); \
}
#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
if ((c.slen != 0) && (M_ASN1_next == \
(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
{ \
int Tinf,Ttag,Tclass; \
long Tlen; \
\
c.q=c.p; \
Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
if (Tinf & 0x80) \
{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
Tlen = c.slen - (c.p - c.q) - 2; \
if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
(void (*)())free_func, \
b,V_ASN1_UNIVERSAL) == NULL) \
{ c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
Tlen = c.slen - (c.p - c.q); \
if(!ASN1_check_infinite_end(&c.p, Tlen)) \
{ c.error=ERR_R_MISSING_ASN1_EOS; \
c.line=__LINE__; goto err; } \
}\
c.slen-=(c.p-c.q); \
}
#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
if ((c.slen != 0) && (M_ASN1_next == \
(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
{ \
int Tinf,Ttag,Tclass; \
long Tlen; \
\
c.q=c.p; \
Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
if (Tinf & 0x80) \
{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
Tlen = c.slen - (c.p - c.q) - 2; \
if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
free_func,b,V_ASN1_UNIVERSAL) == NULL) \
{ c.line=__LINE__; goto err; } \
if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
Tlen = c.slen - (c.p - c.q); \
if(!ASN1_check_infinite_end(&c.p, Tlen)) \
{ c.error=ERR_R_MISSING_ASN1_EOS; \
c.line=__LINE__; goto err; } \
}\
c.slen-=(c.p-c.q); \
}
/* New macros */
#define M_ASN1_New_Malloc(ret,type) \
if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
{ c.line=__LINE__; goto err2; }
#define M_ASN1_New(arg,func) \
if (((arg)=func()) == NULL) return(NULL)
#define M_ASN1_New_Error(a) \
/* err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
return(NULL);*/ \
err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
return(NULL)
/* BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately,
some macros that use ASN1_const_CTX still insist on writing in the input
stream. ARGH! ARGH! ARGH! Let's get rid of this macro package.
Please? -- Richard Levitte */
#define M_ASN1_next (*((unsigned char *)(c.p)))
#define M_ASN1_next_prev (*((unsigned char *)(c.q)))
/*************************************************/
#define M_ASN1_I2D_vars(a) int r=0,ret=0; \
unsigned char *p; \
if (a == NULL) return(0)
/* Length Macros */
#define M_ASN1_I2D_len(a,f) ret+=f(a,NULL)
#define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f)
#define M_ASN1_I2D_len_SET(a,f) \
ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
#define M_ASN1_I2D_len_SET_type(type,a,f) \
ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
V_ASN1_UNIVERSAL,IS_SET);
#define M_ASN1_I2D_len_SEQUENCE(a,f) \
ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
IS_SEQUENCE);
#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
V_ASN1_UNIVERSAL,IS_SEQUENCE)
#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
M_ASN1_I2D_len_SEQUENCE(a,f);
#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
V_ASN1_CONTEXT_SPECIFIC,IS_SET);
#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
IS_SET);
#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
V_ASN1_CONTEXT_SPECIFIC,IS_SET);
#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
IS_SEQUENCE);
#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
IS_SEQUENCE);
#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
V_ASN1_CONTEXT_SPECIFIC, \
IS_SEQUENCE);
#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
if (a != NULL)\
{ \
v=f(a,NULL); \
ret+=ASN1_object_size(1,v,mtag); \
}
#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0))\
{ \
v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
ret+=ASN1_object_size(1,v,mtag); \
}
#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0))\
{ \
v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
IS_SEQUENCE); \
ret+=ASN1_object_size(1,v,mtag); \
}
#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
if ((a != NULL) && (sk_##type##_num(a) != 0))\
{ \
v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
V_ASN1_UNIVERSAL, \
IS_SEQUENCE); \
ret+=ASN1_object_size(1,v,mtag); \
}
/* Put Macros */
#define M_ASN1_I2D_put(a,f) f(a,&p)
#define M_ASN1_I2D_put_IMP_opt(a,f,t) \
if (a != NULL) \
{ \
unsigned char *q=p; \
f(a,&p); \
*q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
}
#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
V_ASN1_UNIVERSAL,IS_SET)
#define M_ASN1_I2D_put_SET_type(type,a,f) \
i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
V_ASN1_CONTEXT_SPECIFIC,IS_SET)
#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
V_ASN1_UNIVERSAL,IS_SEQUENCE)
#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
IS_SEQUENCE)
#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
if ((a != NULL) && (sk_num(a) != 0)) \
M_ASN1_I2D_put_SEQUENCE(a,f);
#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
IS_SET); }
#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
V_ASN1_CONTEXT_SPECIFIC, \
IS_SET); }
#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
if ((a != NULL) && (sk_num(a) != 0)) \
{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
IS_SEQUENCE); }
#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
V_ASN1_CONTEXT_SPECIFIC, \
IS_SEQUENCE); }
#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
if (a != NULL) \
{ \
ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
f(a,&p); \
}
#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0)) \
{ \
ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
}
#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
if ((a != NULL) && (sk_num(a) != 0)) \
{ \
ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
}
#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
if ((a != NULL) && (sk_##type##_num(a) != 0)) \
{ \
ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
IS_SEQUENCE); \
}
#define M_ASN1_I2D_seq_total() \
r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
if (pp == NULL) return(r); \
p= *pp; \
ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
#define M_ASN1_I2D_INF_seq_start(tag,ctx) \
*(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
*(p++)=0x80
#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
#define M_ASN1_I2D_finish() *pp=p; \
return(r);
int asn1_GetSequence(ASN1_const_CTX *c, long *length);
void asn1_add_error(const unsigned char *address,int offset);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,437 @@
/* crypto/asn1/asn1_par.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include <openssl/asn1.h>
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
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;
if (constructed & V_ASN1_CONSTRUCTED)
p="cons: ";
else
p="prim: ";
if (BIO_write(bp,p,6) < 6) goto err;
BIO_indent(bp,indent,128);
p=str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
else if (tag > 30)
BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
else
p = ASN1_tag2str(tag);
if (BIO_printf(bp,fmt,p) <= 0)
goto err;
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;
int nl,hl,j,r;
ASN1_OBJECT *o=NULL;
ASN1_OCTET_STRING *os=NULL;
/* ASN1_BMPSTRING *bmp=NULL;*/
int dump_indent;
#if 0
dump_indent = indent;
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
p= *pp;
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 */
if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
<= 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_IA5STRING) ||
(tag == V_ASN1_VISIBLESTRING) ||
(tag == V_ASN1_NUMERICSTRING) ||
(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);
}
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 >
os->length)?os->length: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);
}
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",11) <= 0)
goto end;
}
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;
}
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)
{
static const char * const tag2str[] = {
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
};
if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
tag &= ~0x100;
if(tag < 0 || tag > 30) return "(unknown)";
return tag2str[tag];
}

View File

@@ -0,0 +1,960 @@
/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_ASN1T_H
#define HEADER_ASN1T_H
#include <stddef.h>
#include <openssl/e_os2.h>
#include <openssl/asn1.h>
#ifdef OPENSSL_BUILD_SHLIBCRYPTO
# undef OPENSSL_EXTERN
# define OPENSSL_EXTERN OPENSSL_EXPORT
#endif
/* ASN1 template defines, structures and functions */
#ifdef __cplusplus
extern "C" {
#endif
#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
/* Macros for start and end of ASN1_ITEM definition */
#define ASN1_ITEM_start(itname) \
OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
#define ASN1_ITEM_end(itname) \
};
#else
/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
/* Macros for start and end of ASN1_ITEM definition */
#define ASN1_ITEM_start(itname) \
const ASN1_ITEM * itname##_it(void) \
{ \
static const ASN1_ITEM local_it = {
#define ASN1_ITEM_end(itname) \
}; \
return &local_it; \
}
#endif
/* Macros to aid ASN1 template writing */
#define ASN1_ITEM_TEMPLATE(tname) \
static const ASN1_TEMPLATE tname##_item_tt
#define ASN1_ITEM_TEMPLATE_END(tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_PRIMITIVE,\
-1,\
&tname##_item_tt,\
0,\
NULL,\
0,\
#tname \
ASN1_ITEM_end(tname)
/* This is a ASN1 type which just embeds a template */
/* This pair helps declare a SEQUENCE. We can do:
*
* ASN1_SEQUENCE(stname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END(stname)
*
* This will produce an ASN1_ITEM called stname_it
* for a structure called stname.
*
* If you want the same structure but a different
* name then use:
*
* ASN1_SEQUENCE(itname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END_name(stname, itname)
*
* This will create an item called itname_it using
* a structure called stname.
*/
#define ASN1_SEQUENCE(tname) \
static const ASN1_TEMPLATE tname##_seq_tt[]
#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
#define ASN1_SEQUENCE_END_name(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_NDEF_SEQUENCE(tname) \
ASN1_SEQUENCE(tname)
#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
ASN1_SEQUENCE_cb(tname, cb)
#define ASN1_SEQUENCE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_BROKEN_SEQUENCE(tname) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_ref(tname, cb, lck) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_enc(tname, enc, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
ASN1_SEQUENCE(tname)
#define ASN1_NDEF_SEQUENCE_END(tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(tname),\
#tname \
ASN1_ITEM_end(tname)
#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
#define ASN1_SEQUENCE_END_ref(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
/* This pair helps declare a CHOICE type. We can do:
*
* ASN1_CHOICE(chname) = {
* ... CHOICE options ...
* ASN1_CHOICE_END(chname)
*
* This will produce an ASN1_ITEM called chname_it
* for a structure called chname. The structure
* definition must look like this:
* typedef struct {
* int type;
* union {
* ASN1_SOMETHING *opt1;
* ASN1_SOMEOTHER *opt2;
* } value;
* } chname;
*
* the name of the selector must be 'type'.
* to use an alternative selector name use the
* ASN1_CHOICE_END_selector() version.
*/
#define ASN1_CHOICE(tname) \
static const ASN1_TEMPLATE tname##_ch_tt[]
#define ASN1_CHOICE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
ASN1_CHOICE(tname)
#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
#define ASN1_CHOICE_END_selector(stname, tname, selname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_CHOICE,\
offsetof(stname,selname) ,\
tname##_ch_tt,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_CHOICE_END_cb(stname, tname, selname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_CHOICE,\
offsetof(stname,selname) ,\
tname##_ch_tt,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
/* This helps with the template wrapper form of ASN1_ITEM */
#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
(flags), (tag), 0,\
#name, ASN1_ITEM_ref(type) }
/* These help with SEQUENCE or CHOICE components */
/* used to declare other types */
#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
(flags), (tag), offsetof(stname, field),\
#field, ASN1_ITEM_ref(type) }
/* used when the structure is combined with the parent */
#define ASN1_EX_COMBINE(flags, tag, type) { \
(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
/* implicit and explicit helper macros */
#define ASN1_IMP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
#define ASN1_EXP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
/* Any defined by macros: the field used is in the table itself */
#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
#else
#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
#endif
/* Plain simple type */
#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
/* OPTIONAL simple type */
#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* IMPLICIT tagged simple type */
#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
/* IMPLICIT tagged OPTIONAL simple type */
#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
/* Same as above but EXPLICIT */
#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
/* SEQUENCE OF type */
#define ASN1_SEQUENCE_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
/* OPTIONAL SEQUENCE OF */
#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Same as above but for SET OF */
#define ASN1_SET_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
#define ASN1_SET_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
#define ASN1_IMP_SET_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
#define ASN1_EXP_SET_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
/* EXPLICIT using indefinite length constructed form */
#define ASN1_NDEF_EXP(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
/* EXPLICIT OPTIONAL using indefinite length constructed form */
#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
/* Macros for the ASN1_ADB structure */
#define ASN1_ADB(name) \
static const ASN1_ADB_TABLE name##_adbtbl[]
#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
;\
static const ASN1_ADB name##_adb = {\
flags,\
offsetof(name, field),\
app_table,\
name##_adbtbl,\
sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
def,\
none\
}
#else
#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
;\
static const ASN1_ITEM *name##_adb(void) \
{ \
static const ASN1_ADB internal_adb = \
{\
flags,\
offsetof(name, field),\
app_table,\
name##_adbtbl,\
sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
def,\
none\
}; \
return (const ASN1_ITEM *) &internal_adb; \
} \
void dummy_function(void)
#endif
#define ADB_ENTRY(val, template) {val, template}
#define ASN1_ADB_TEMPLATE(name) \
static const ASN1_TEMPLATE name##_tt
/* This is the ASN1 template structure that defines
* a wrapper round the actual type. It determines the
* actual position of the field in the value structure,
* various flags such as OPTIONAL and the field name.
*/
struct ASN1_TEMPLATE_st {
unsigned long flags; /* Various flags */
long tag; /* tag, not used if no tagging */
unsigned long offset; /* Offset of this field in structure */
#ifndef NO_ASN1_FIELD_NAMES
const char *field_name; /* Field name */
#endif
ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */
};
/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
#define ASN1_TEMPLATE_item(t) (t->item_ptr)
#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
typedef struct ASN1_ADB_st ASN1_ADB;
struct ASN1_ADB_st {
unsigned long flags; /* Various flags */
unsigned long offset; /* Offset of selector field */
STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
const ASN1_ADB_TABLE *tbl; /* Table of possible types */
long tblcount; /* Number of entries in tbl */
const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
};
struct ASN1_ADB_TABLE_st {
long value; /* NID for an object or value for an int */
const ASN1_TEMPLATE tt; /* item for this value */
};
/* template flags */
/* Field is optional */
#define ASN1_TFLG_OPTIONAL (0x1)
/* Field is a SET OF */
#define ASN1_TFLG_SET_OF (0x1 << 1)
/* Field is a SEQUENCE OF */
#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)
/* Special case: this refers to a SET OF that
* will be sorted into DER order when encoded *and*
* the corresponding STACK will be modified to match
* the new order.
*/
#define ASN1_TFLG_SET_ORDER (0x3 << 1)
/* Mask for SET OF or SEQUENCE OF */
#define ASN1_TFLG_SK_MASK (0x3 << 1)
/* These flags mean the tag should be taken from the
* tag field. If EXPLICIT then the underlying type
* is used for the inner tag.
*/
/* IMPLICIT tagging */
#define ASN1_TFLG_IMPTAG (0x1 << 3)
/* EXPLICIT tagging, inner tag from underlying type */
#define ASN1_TFLG_EXPTAG (0x2 << 3)
#define ASN1_TFLG_TAG_MASK (0x3 << 3)
/* context specific IMPLICIT */
#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
/* context specific EXPLICIT */
#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
/* If tagging is in force these determine the
* type of tag to use. Otherwise the tag is
* determined by the underlying type. These
* values reflect the actual octet format.
*/
/* Universal tag */
#define ASN1_TFLG_UNIVERSAL (0x0<<6)
/* Application tag */
#define ASN1_TFLG_APPLICATION (0x1<<6)
/* Context specific tag */
#define ASN1_TFLG_CONTEXT (0x2<<6)
/* Private tag */
#define ASN1_TFLG_PRIVATE (0x3<<6)
#define ASN1_TFLG_TAG_CLASS (0x3<<6)
/* These are for ANY DEFINED BY type. In this case
* the 'item' field points to an ASN1_ADB structure
* which contains a table of values to decode the
* relevant type
*/
#define ASN1_TFLG_ADB_MASK (0x3<<8)
#define ASN1_TFLG_ADB_OID (0x1<<8)
#define ASN1_TFLG_ADB_INT (0x1<<9)
/* This flag means a parent structure is passed
* instead of the field: this is useful is a
* SEQUENCE is being combined with a CHOICE for
* example. Since this means the structure and
* item name will differ we need to use the
* ASN1_CHOICE_END_name() macro for example.
*/
#define ASN1_TFLG_COMBINE (0x1<<10)
/* This flag when present in a SEQUENCE OF, SET OF
* or EXPLICIT causes indefinite length constructed
* encoding to be used if required.
*/
#define ASN1_TFLG_NDEF (0x1<<11)
/* This is the actual ASN1 item itself */
struct ASN1_ITEM_st {
char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */
long utype; /* underlying type */
const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */
long tcount; /* Number of templates if SEQUENCE or CHOICE */
const void *funcs; /* functions that handle this type */
long size; /* Structure size (usually)*/
#ifndef NO_ASN1_FIELD_NAMES
const char *sname; /* Structure name */
#endif
};
/* These are values for the itype field and
* determine how the type is interpreted.
*
* For PRIMITIVE types the underlying type
* determines the behaviour if items is NULL.
*
* Otherwise templates must contain a single
* template and the type is treated in the
* same way as the type specified in the template.
*
* For SEQUENCE types the templates field points
* to the members, the size field is the
* structure size.
*
* For CHOICE types the templates field points
* to each possible member (typically a union)
* and the 'size' field is the offset of the
* selector.
*
* The 'funcs' field is used for application
* specific functions.
*
* For COMPAT types the funcs field gives a
* set of functions that handle this type, this
* supports the old d2i, i2d convention.
*
* The EXTERN type uses a new style d2i/i2d.
* The new style should be used where possible
* because it avoids things like the d2i IMPLICIT
* hack.
*
* MSTRING is a multiple string type, it is used
* for a CHOICE of character strings where the
* actual strings all occupy an ASN1_STRING
* structure. In this case the 'utype' field
* has a special meaning, it is used as a mask
* of acceptable types using the B_ASN1 constants.
*
* NDEF_SEQUENCE is the same as SEQUENCE except
* that it will use indefinite length constructed
* encoding if requested.
*
*/
#define ASN1_ITYPE_PRIMITIVE 0x0
#define ASN1_ITYPE_SEQUENCE 0x1
#define ASN1_ITYPE_CHOICE 0x2
#define ASN1_ITYPE_COMPAT 0x3
#define ASN1_ITYPE_EXTERN 0x4
#define ASN1_ITYPE_MSTRING 0x5
#define ASN1_ITYPE_NDEF_SEQUENCE 0x6
/* Cache for ASN1 tag and length, so we
* don't keep re-reading it for things
* like CHOICE
*/
struct ASN1_TLC_st{
char valid; /* Values below are valid */
int ret; /* return value */
long plen; /* length */
int ptag; /* class value */
int pclass; /* class value */
int hdrlen; /* header length */
};
/* Typedefs for ASN1 function pointers */
typedef ASN1_VALUE * ASN1_new_func(void);
typedef void ASN1_free_func(ASN1_VALUE *a);
typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx);
typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
int indent, const char *fname,
const ASN1_PCTX *pctx);
typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
typedef struct ASN1_COMPAT_FUNCS_st {
ASN1_new_func *asn1_new;
ASN1_free_func *asn1_free;
ASN1_d2i_func *asn1_d2i;
ASN1_i2d_func *asn1_i2d;
} ASN1_COMPAT_FUNCS;
typedef struct ASN1_EXTERN_FUNCS_st {
void *app_data;
ASN1_ex_new_func *asn1_ex_new;
ASN1_ex_free_func *asn1_ex_free;
ASN1_ex_free_func *asn1_ex_clear;
ASN1_ex_d2i *asn1_ex_d2i;
ASN1_ex_i2d *asn1_ex_i2d;
ASN1_ex_print_func *asn1_ex_print;
} ASN1_EXTERN_FUNCS;
typedef struct ASN1_PRIMITIVE_FUNCS_st {
void *app_data;
unsigned long flags;
ASN1_ex_new_func *prim_new;
ASN1_ex_free_func *prim_free;
ASN1_ex_free_func *prim_clear;
ASN1_primitive_c2i *prim_c2i;
ASN1_primitive_i2c *prim_i2c;
ASN1_primitive_print *prim_print;
} ASN1_PRIMITIVE_FUNCS;
/* This is the ASN1_AUX structure: it handles various
* miscellaneous requirements. For example the use of
* reference counts and an informational callback.
*
* The "informational callback" is called at various
* points during the ASN1 encoding and decoding. It can
* be used to provide minor customisation of the structures
* used. This is most useful where the supplied routines
* *almost* do the right thing but need some extra help
* at a few points. If the callback returns zero then
* it is assumed a fatal error has occurred and the
* main operation should be abandoned.
*
* If major changes in the default behaviour are required
* then an external type is more appropriate.
*/
typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
void *exarg);
typedef struct ASN1_AUX_st {
void *app_data;
int flags;
int ref_offset; /* Offset of reference value */
int ref_lock; /* Lock type to use */
ASN1_aux_cb *asn1_cb;
int enc_offset; /* Offset of ASN1_ENCODING structure */
} ASN1_AUX;
/* For print related callbacks exarg points to this structure */
typedef struct ASN1_PRINT_ARG_st {
BIO *out;
int indent;
const ASN1_PCTX *pctx;
} ASN1_PRINT_ARG;
/* For streaming related callbacks exarg points to this structure */
typedef struct ASN1_STREAM_ARG_st {
/* BIO to stream through */
BIO *out;
/* BIO with filters appended */
BIO *ndef_bio;
/* Streaming I/O boundary */
unsigned char **boundary;
} ASN1_STREAM_ARG;
/* Flags in ASN1_AUX */
/* Use a reference count */
#define ASN1_AFLG_REFCOUNT 1
/* Save the encoding of structure (useful for signatures) */
#define ASN1_AFLG_ENCODING 2
/* The Sequence length is invalid */
#define ASN1_AFLG_BROKEN 4
/* operation values for asn1_cb */
#define ASN1_OP_NEW_PRE 0
#define ASN1_OP_NEW_POST 1
#define ASN1_OP_FREE_PRE 2
#define ASN1_OP_FREE_POST 3
#define ASN1_OP_D2I_PRE 4
#define ASN1_OP_D2I_POST 5
#define ASN1_OP_I2D_PRE 6
#define ASN1_OP_I2D_POST 7
#define ASN1_OP_PRINT_PRE 8
#define ASN1_OP_PRINT_POST 9
#define ASN1_OP_STREAM_PRE 10
#define ASN1_OP_STREAM_POST 11
#define ASN1_OP_DETACHED_PRE 12
#define ASN1_OP_DETACHED_POST 13
/* Macro to implement a primitive type */
#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
ASN1_ITEM_start(itname) \
ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
ASN1_ITEM_end(itname)
/* Macro to implement a multi string type */
#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
ASN1_ITEM_start(itname) \
ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
ASN1_ITEM_end(itname)
/* Macro to implement an ASN1_ITEM in terms of old style funcs */
#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
static const ASN1_COMPAT_FUNCS sname##_ff = { \
(ASN1_new_func *)sname##_new, \
(ASN1_free_func *)sname##_free, \
(ASN1_d2i_func *)d2i_##sname, \
(ASN1_i2d_func *)i2d_##sname, \
}; \
ASN1_ITEM_start(sname) \
ASN1_ITYPE_COMPAT, \
tag, \
NULL, \
0, \
&sname##_ff, \
0, \
#sname \
ASN1_ITEM_end(sname)
#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
ASN1_ITEM_start(sname) \
ASN1_ITYPE_EXTERN, \
tag, \
NULL, \
0, \
&fptrs, \
0, \
#sname \
ASN1_ITEM_end(sname)
/* Macro to implement standard functions in terms of ASN1_ITEM structures */
#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
pre stname *fname##_new(void) \
{ \
return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
} \
pre void fname##_free(stname *a) \
{ \
ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
}
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
stname *fname##_new(void) \
{ \
return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
} \
void fname##_free(stname *a) \
{ \
ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
}
#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
{ \
return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
} \
int i2d_##fname(stname *a, unsigned char **out) \
{ \
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
}
#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
{ \
return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
}
/* This includes evil casts to remove const: they will go away when full
* ASN1 constification is done.
*/
#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
{ \
return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
} \
int i2d_##fname(const stname *a, unsigned char **out) \
{ \
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
}
#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
stname * stname##_dup(stname *x) \
{ \
return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
}
#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
int fname##_print_ctx(BIO *out, stname *x, int indent, \
const ASN1_PCTX *pctx) \
{ \
return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
ASN1_ITEM_rptr(itname), pctx); \
}
#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
/* external definitions for primitive types */
DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
DECLARE_ASN1_ITEM(CBIGNUM)
DECLARE_ASN1_ITEM(BIGNUM)
DECLARE_ASN1_ITEM(LONG)
DECLARE_ASN1_ITEM(ZLONG)
DECLARE_STACK_OF(ASN1_VALUE)
/* Functions used internally by the ASN1 code */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx);
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,951 @@
/* asn_mime.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include "asn1_locl.h"
/* Generalised MIME like utilities for streaming ASN1. Although many
* have a PKCS7/CMS like flavour others are more general purpose.
*/
/* MIME format structures
* Note that all are translated to lower case apart from
* parameter values. Quotes are stripped off
*/
typedef struct {
char *param_name; /* Param name e.g. "micalg" */
char *param_value; /* Param value e.g. "sha1" */
} MIME_PARAM;
DECLARE_STACK_OF(MIME_PARAM)
IMPLEMENT_STACK_OF(MIME_PARAM)
typedef struct {
char *name; /* Name of line e.g. "content-type" */
char *value; /* Value of line e.g. "text/plain" */
STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
} MIME_HEADER;
DECLARE_STACK_OF(MIME_HEADER)
IMPLEMENT_STACK_OF(MIME_HEADER)
static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
const ASN1_ITEM *it);
static char * strip_ends(char *name);
static char * strip_start(char *name);
static char * strip_end(char *name);
static MIME_HEADER *mime_hdr_new(char *name, char *value);
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
static int mime_hdr_cmp(const MIME_HEADER * const *a,
const MIME_HEADER * const *b);
static int mime_param_cmp(const MIME_PARAM * const *a,
const MIME_PARAM * const *b);
static void mime_param_free(MIME_PARAM *param);
static int mime_bound_check(char *line, int linelen, char *bound, int blen);
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
static int strip_eol(char *linebuf, int *plen);
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
static void mime_hdr_free(MIME_HEADER *hdr);
#define MAX_SMLEN 1024
#define mime_debug(x) /* x */
/* Output an ASN1 structure in BER format streaming if necessary */
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);
}
/* 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);
r = i2d_ASN1_bio_stream(out, val, in, flags, it);
(void)BIO_flush(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)
{
BIO *b64;
ASN1_VALUE *val;
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)
ASN1err(ASN1_F_B64_READ_ASN1,ASN1_R_DECODE_ERROR);
(void)BIO_flush(bio);
bio = BIO_pop(bio);
BIO_free(b64);
return 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);
OPENSSL_free(micstr);
continue;
}
if (rv != -2)
goto err;
}
switch(md_nid)
{
case NID_sha1:
BIO_puts(out, "sha1");
break;
case NID_md5:
BIO_puts(out, "md5");
break;
case NID_sha256:
BIO_puts(out, "sha-256");
break;
case NID_sha384:
BIO_puts(out, "sha-384");
break;
case NID_sha512:
BIO_puts(out, "sha-512");
break;
case NID_id_GostR3411_94:
BIO_puts(out, "gostr3411-94");
goto err;
break;
default:
if (have_unknown)
write_comma = 0;
else
{
BIO_puts(out, "unknown");
have_unknown = 1;
}
break;
}
}
ret = 1;
err:
return ret;
}
/* SMIME sender */
int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
int ctype_nid, int econt_nid,
STACK_OF(X509_ALGOR) *mdalgs,
const ASN1_ITEM *it)
{
char bound[33], c;
int i;
const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
const char *msg_type=NULL;
if (flags & SMIME_OLDMIME)
mime_prefix = "application/x-pkcs7-";
else
mime_prefix = "application/pkcs7-";
if (flags & SMIME_CRLFEOL)
mime_eol = "\r\n";
else
mime_eol = "\n";
if((flags & SMIME_DETACHED) && data) {
/* We want multipart/signed */
/* Generate a random boundary */
RAND_pseudo_bytes((unsigned char *)bound, 32);
for(i = 0; i < 32; i++) {
c = bound[i] & 0xf;
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, " protocol=\"%ssignature\";", mime_prefix);
BIO_puts(bio, " micalg=\"");
asn1_write_micalg(bio, mdalgs);
BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
bound, mime_eol, mime_eol);
BIO_printf(bio, "This is an S/MIME signed message%s%s",
mime_eol, mime_eol);
/* Now write out the first part */
BIO_printf(bio, "------%s%s", bound, mime_eol);
if (!asn1_output_data(bio, data, val, flags, it))
return 0;
BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
/* Headers for signature */
BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
mime_eol);
BIO_printf(bio, "Content-Disposition: attachment;");
BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
mime_eol, mime_eol);
B64_write_ASN1(bio, val, NULL, 0, it);
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;");
BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
if (msg_type)
BIO_printf(bio, " smime-type=%s;", msg_type);
BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
mime_eol, mime_eol);
if (!B64_write_ASN1(bio, val, data, flags, it))
return 0;
BIO_printf(bio, "%s", mime_eol);
return 1;
}
/* Handle output of ASN1 data */
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;
int rv = 1;
/* If data is not deteched or resigning then the output BIO is
* 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;
sarg.boundary = NULL;
/* Let ASN1 code prepend any needed BIOs */
if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
return 0;
/* Copy data across, passing through filter BIOs for processing */
SMIME_crlf_copy(data, sarg.ndef_bio, flags);
/* Finalize structure */
if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
rv = 0;
/* 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
* pointed to by "bcont". In opaque this is set to NULL
*/
ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
{
BIO *asnin;
STACK_OF(MIME_HEADER) *headers = NULL;
STACK_OF(BIO) *parts = NULL;
MIME_HEADER *hdr;
MIME_PARAM *prm;
ASN1_VALUE *val;
int ret;
if(bcont) *bcont = NULL;
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 */
if(!strcmp(hdr->value, "multipart/signed")) {
/* Split into two parts */
prm = mime_param_find(hdr, "boundary");
if(!prm || !prm->param_value) {
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);
if (!(headers = mime_parse_hdr(asnin))) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_MIME_SIG_PARSE_ERROR);
sk_BIO_pop_free(parts, BIO_vfree);
return NULL;
}
/* Get content type */
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_SIG_CONTENT_TYPE);
return NULL;
}
if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
strcmp(hdr->value, "application/pkcs7-signature")) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_SIG_INVALID_MIME_TYPE);
ERR_add_error_data(2, "type: ", hdr->value);
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);
return val;
}
/* OK, if not multipart/signed try opaque signature */
if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
strcmp (hdr->value, "application/pkcs7-mime")) {
ASN1err(ASN1_F_SMIME_READ_ASN1,ASN1_R_INVALID_MIME_TYPE);
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;
}
/* Copy text from one BIO to another making the output CRLF at EOL */
int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
{
BIO *bf;
char eol;
int len;
char linebuf[MAX_SMLEN];
/* Buffer output so we don't write one line at a time. This is
* useful when streaming as we don't end up with one OCTET STRING
* per line.
*/
bf = BIO_new(BIO_f_buffer());
if (!bf)
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);
return 1;
}
/* Strip off headers if they are text/plain */
int SMIME_text(BIO *in, BIO *out)
{
char iobuf[4096];
int len;
STACK_OF(MIME_HEADER) *headers;
MIME_HEADER *hdr;
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 (len < 0)
return 0;
return 1;
}
/* Split a multipart/XXX message body into component parts: result is
* canonical parts in a STACK of bios
*/
static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
{
char linebuf[MAX_SMLEN];
int len, blen;
int eol = 0, next_eol = 0;
BIO *bpart = NULL;
STACK_OF(BIO) *parts;
char state, part, first;
blen = strlen(bound);
part = 0;
state = 0;
first = 1;
parts = sk_BIO_new_null();
*ret = parts;
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
state = mime_bound_check(linebuf, len, bound, blen);
if(state == 1) {
first = 1;
part++;
} else if(state == 2) {
sk_BIO_push(parts, bpart);
return 1;
} else if(part) {
/* Strip CR+LF from linebuf */
next_eol = strip_eol(linebuf, &len);
if(first) {
first = 0;
if(bpart) sk_BIO_push(parts, bpart);
bpart = BIO_new(BIO_s_mem());
BIO_set_mem_eof_return(bpart, 0);
} else if (eol)
BIO_write(bpart, "\r\n", 2);
eol = next_eol;
if (len)
BIO_write(bpart, linebuf, len);
}
}
return 0;
}
/* This is the big one: parse MIME header lines up to message body */
#define MIME_INVALID 0
#define MIME_START 1
#define MIME_TYPE 2
#define MIME_NAME 3
#define MIME_VALUE 4
#define MIME_QUOTE 5
#define MIME_COMMENT 6
static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
{
char *p, *q, c;
char *ntmp;
char linebuf[MAX_SMLEN];
MIME_HEADER *mhdr = NULL;
STACK_OF(MIME_HEADER) *headers;
int len, state, save_state = 0;
headers = sk_MIME_HEADER_new(mime_hdr_cmp);
while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
/* If whitespace at line start then continuation line */
if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
else state = MIME_START;
ntmp = NULL;
/* Go through all characters */
for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
/* State machine to handle MIME headers
* if this looks horrible that's because it *is*
*/
switch(state) {
case MIME_START:
if(c == ':') {
state = MIME_TYPE;
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
}
break;
case MIME_TYPE:
if(c == ';') {
mime_debug("Found End Value\n");
*p = 0;
mhdr = mime_hdr_new(ntmp, strip_ends(q));
sk_MIME_HEADER_push(headers, mhdr);
ntmp = NULL;
q = p + 1;
state = MIME_NAME;
} else if(c == '(') {
save_state = state;
state = MIME_COMMENT;
}
break;
case MIME_COMMENT:
if(c == ')') {
state = save_state;
}
break;
case MIME_NAME:
if(c == '=') {
state = MIME_VALUE;
*p = 0;
ntmp = strip_ends(q);
q = p + 1;
}
break ;
case MIME_VALUE:
if(c == ';') {
state = MIME_NAME;
*p = 0;
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
ntmp = NULL;
q = p + 1;
} else if (c == '"') {
mime_debug("Found Quote\n");
state = MIME_QUOTE;
} 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;
}
}
if(state == MIME_TYPE) {
mhdr = mime_hdr_new(ntmp, strip_ends(q));
sk_MIME_HEADER_push(headers, mhdr);
} else if(state == MIME_VALUE)
mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
if(p == linebuf) break; /* Blank line means end of headers */
}
return headers;
}
static char *strip_ends(char *name)
{
return strip_end(strip_start(name));
}
/* Strip a parameter of whitespace from start of param */
static char *strip_start(char *name)
{
char *p, c;
/* Look for first non white space or quote */
for(p = name; (c = *p) ;p++) {
if(c == '"') {
/* Next char is start of string if non null */
if(p[1]) return p + 1;
/* Else null string */
return NULL;
}
if(!isspace((unsigned char)c)) return p;
}
return NULL;
}
/* As above but strip from end of string : maybe should handle brackets? */
static char *strip_end(char *name)
{
char *p, c;
if(!name) return NULL;
/* Look for first non white space or quote */
for(p = name + strlen(name) - 1; p >= name ;p--) {
c = *p;
if(c == '"') {
if(p - 1 == name) return NULL;
*p = 0;
return name;
}
if(isspace((unsigned char)c)) *p = 0;
else return name;
}
return NULL;
}
static MIME_HEADER *mime_hdr_new(char *name, char *value)
{
MIME_HEADER *mhdr;
char *tmpname, *tmpval, *p;
int c;
if(name) {
if(!(tmpname = BUF_strdup(name))) return NULL;
for(p = tmpname ; *p; p++) {
c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
}
}
} else tmpname = NULL;
if(value) {
if(!(tmpval = BUF_strdup(value))) return NULL;
for(p = tmpval ; *p; p++) {
c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
}
}
} else tmpval = NULL;
mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
if(!mhdr) return NULL;
mhdr->name = tmpname;
mhdr->value = tmpval;
if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
return mhdr;
}
static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
{
char *tmpname, *tmpval, *p;
int c;
MIME_PARAM *mparam;
if(name) {
tmpname = BUF_strdup(name);
if(!tmpname) return 0;
for(p = tmpname ; *p; p++) {
c = (unsigned char)*p;
if(isupper(c)) {
c = tolower(c);
*p = c;
}
}
} else tmpname = NULL;
if(value) {
tmpval = BUF_strdup(value);
if(!tmpval) return 0;
} else tmpval = NULL;
/* Parameter values are case sensitive so leave as is */
mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
if(!mparam) return 0;
mparam->param_name = tmpname;
mparam->param_value = tmpval;
sk_MIME_PARAM_push(mhdr->params, mparam);
return 1;
}
static int mime_hdr_cmp(const MIME_HEADER * const *a,
const MIME_HEADER * const *b)
{
if (!(*a)->name || !(*b)->name)
return !!(*a)->name - !!(*b)->name;
return(strcmp((*a)->name, (*b)->name));
}
static int mime_param_cmp(const MIME_PARAM * const *a,
const MIME_PARAM * const *b)
{
if (!(*a)->param_name || !(*b)->param_name)
return !!(*a)->param_name - !!(*b)->param_name;
return(strcmp((*a)->param_name, (*b)->param_name));
}
/* Find a header with a given name (if possible) */
static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
{
MIME_HEADER htmp;
int idx;
htmp.name = name;
idx = sk_MIME_HEADER_find(hdrs, &htmp);
if(idx < 0) return NULL;
return sk_MIME_HEADER_value(hdrs, idx);
}
static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
{
MIME_PARAM param;
int idx;
param.param_name = name;
idx = sk_MIME_PARAM_find(hdr->params, &param);
if(idx < 0) return NULL;
return sk_MIME_PARAM_value(hdr->params, idx);
}
static void mime_hdr_free(MIME_HEADER *hdr)
{
if(hdr->name) OPENSSL_free(hdr->name);
if(hdr->value) OPENSSL_free(hdr->value);
if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
OPENSSL_free(hdr);
}
static void mime_param_free(MIME_PARAM *param)
{
if(param->param_name) OPENSSL_free(param->param_name);
if(param->param_value) OPENSSL_free(param->param_value);
OPENSSL_free(param);
}
/* Check for a multipart boundary. Returns:
* 0 : no boundary
* 1 : part boundary
* 2 : final boundary
*/
static int mime_bound_check(char *line, int linelen, char *bound, int blen)
{
if(linelen == -1) linelen = strlen(line);
if(blen == -1) blen = strlen(bound);
/* Quickly eliminate if line length too short */
if(blen + 2 > linelen) return 0;
/* Check for part boundary */
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;
}

View File

@@ -0,0 +1,160 @@
/* asn_moid.c */
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
/* ====================================================================
* Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <ctype.h>
#include <openssl/crypto.h>
#include "cryptlib.h"
#include <openssl/conf.h>
#include <openssl/dso.h>
#include <openssl/x509.h>
/* Simple ASN1 OID module: add all objects in a given section */
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;
}
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
* shortname = some long name, 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);
if (nid == NID_undef)
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 = OPENSSL_malloc((p - ln) + 1);
if (lntmp == NULL)
return 0;
memcpy(lntmp, ln, p - ln);
lntmp[p - ln] = 0;
oid = OBJ_nid2obj(nid);
oid->ln = lntmp;
}
return 1;
}

View File

@@ -0,0 +1,191 @@
/* asn_pack.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#ifndef NO_ASN1_OLD
/* ASN1 packing and unpacking functions */
/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
{
STACK_OF(OPENSSL_BLOCK) *sk;
const unsigned char *pbuf;
pbuf = buf;
if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR);
return sk;
}
/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
* OPENSSL_malloc'ed buffer
*/
unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
unsigned char **buf, int *len)
{
int safelen;
unsigned char *safe, *p;
if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!(safe = OPENSSL_malloc (safelen))) {
ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE);
return NULL;
}
p = safe;
i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
IS_SEQUENCE);
if (len) *len = safelen;
if (buf) *buf = safe;
return safe;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
{
const unsigned char *p;
char *ret;
p = oct->data;
if(!(ret = d2i(NULL, &p, oct->length)))
ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
return ret;
}
/* Pack an ASN1 object into an ASN1_STRING */
ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
{
unsigned char *p;
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
} else octmp = *oct;
if (!(octmp->length = i2d(obj, NULL))) {
ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!(p = OPENSSL_malloc (octmp->length))) {
ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
return NULL;
}
octmp->data = p;
i2d (obj, &p);
return octmp;
}
#endif
/* ASN1_ITEM versions of the above */
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
{
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
} else octmp = *oct;
if(octmp->data) {
OPENSSL_free(octmp->data);
octmp->data = NULL;
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
ASN1err(ASN1_F_ASN1_ITEM_PACK,ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
{
const unsigned char *p;
void *ret;
p = oct->data;
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
ASN1err(ASN1_F_ASN1_ITEM_UNPACK,ASN1_R_DECODE_ERROR);
return ret;
}

View File

@@ -0,0 +1,495 @@
/* bio_asn1.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* Experimental ASN1 BIO. When written through the data is converted
* to an ASN1 string type: default is OCTET STRING. Additional functions
* can be provided to add prefix and suffix data.
*/
#include <string.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum
{
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_HEADER_COPY,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
} 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;
typedef struct BIO_ASN1_BUF_CTX_t
{
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
unsigned char *buf;
/* Size of buffer */
int bufsize;
/* Current position in buffer */
int bufpos;
/* Current buffer length */
int buflen;
/* Amount of data to copy */
int copylen;
/* Class and tag to use */
int asn1_class, asn1_tag;
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
/* Extra buffer for prefix and suffix data */
unsigned char *ex_buf;
int ex_len;
int ex_pos;
void *ex_arg;
} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf,int num);
static int asn1_bio_read(BIO *h, char *buf, int size);
static int asn1_bio_puts(BIO *h, const char *str);
static int asn1_bio_gets(BIO *h, char *str, int size);
static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int asn1_bio_new(BIO *h);
static int asn1_bio_free(BIO *data);
static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state);
static BIO_METHOD methods_asn1=
{
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_read,
asn1_bio_puts,
asn1_bio_gets,
asn1_bio_ctrl,
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 = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
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 = OPENSSL_malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = 0;
ctx->ex_pos = 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)
return 0;
if (ctx->buf)
OPENSSL_free(ctx->buf);
OPENSSL_free(ctx);
b->init = 0;
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;
if (!in || (inl < 0) || (b->next_bio == NULL))
return 0;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
wrlen = 0;
ret = -1;
for(;;)
{
switch (ctx->state)
{
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
return 0;
break;
/* Copy any pre data first */
case ASN1_STATE_PRE_COPY:
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
ASN1_STATE_HEADER);
if (ret <= 0)
goto done;
break;
case ASN1_STATE_HEADER:
ctx->buflen =
ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
OPENSSL_assert(ctx->buflen <= ctx->bufsize);
p = ctx->buf;
ASN1_put_object(&p, 0, inl,
ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
ctx->state = ASN1_STATE_HEADER_COPY;
break;
case ASN1_STATE_HEADER_COPY:
ret = BIO_write(b->next_bio,
ctx->buf + ctx->bufpos, ctx->buflen);
if (ret <= 0)
goto done;
ctx->buflen -= ret;
if (ctx->buflen)
ctx->bufpos += ret;
else
{
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
}
break;
case ASN1_STATE_DATA_COPY:
if (inl > ctx->copylen)
wrmax = ctx->copylen;
else
wrmax = inl;
ret = BIO_write(b->next_bio, in, wrmax);
if (ret <= 0)
break;
wrlen += ret;
ctx->copylen -= ret;
in += ret;
inl -= ret;
if (ctx->copylen == 0)
ctx->state = ASN1_STATE_HEADER;
if (inl == 0)
goto done;
break;
default:
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)
break;
ctx->ex_len -= ret;
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;
}
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;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
switch(cmd)
{
case BIO_C_SET_PREFIX:
ex_func = arg2;
ctx->prefix = ex_func->ex_func;
ctx->prefix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_PREFIX:
ex_func = arg2;
ex_func->ex_func = ctx->prefix;
ex_func->ex_free_func = ctx->prefix_free;
break;
case BIO_C_SET_SUFFIX:
ex_func = arg2;
ctx->suffix = ex_func->ex_func;
ctx->suffix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_SUFFIX:
ex_func = arg2;
ex_func->ex_func = ctx->suffix;
ex_func->ex_free_func = ctx->suffix_free;
break;
case BIO_C_SET_EX_ARG:
ctx->ex_arg = arg2;
break;
case BIO_C_GET_EX_ARG:
*(void **)arg2 = ctx->ex_arg;
break;
case BIO_CTRL_FLUSH:
if (!b->next_bio)
return 0;
/* 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;
default:
if (!b->next_bio)
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;
}
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);
}

View File

@@ -0,0 +1,243 @@
/* bio_ndef.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <stdio.h>
/* Experimental NDEF ASN1 BIO support routines */
/* The usage is quite simple, initialize an ASN1 structure,
* get a BIO from it then any data written through the BIO
* will end up translated to approptiate format on the fly.
* The data is streamed out and does *not* need to be
* all held in memory at once.
*
* When the BIO is flushed the output is finalized and any
* signatures etc written out.
*
* The BIO is a 'proper' BIO and can handle non blocking I/O
* correctly.
*
* The usage is simple. The implementation is *not*...
*/
/* 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;
/* Top of the BIO chain */
BIO *ndef_bio;
/* Output BIO */
BIO *out;
/* Boundary where content is inserted */
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
} 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(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 = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
/* ASN1 bio needs to be next to output BIO */
out = BIO_push(asn_bio, out);
if (!ndef_aux || !asn_bio || !out)
goto err;
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
/* Now let callback prepend any digest, cipher etc BIOs
* ASN1 structure needs.
*/
sarg.out = out;
sarg.ndef_bio = NULL;
sarg.boundary = NULL;
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
goto err;
ndef_aux->val = val;
ndef_aux->it = it;
ndef_aux->ndef_bio = sarg.ndef_bio;
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
return sarg.ndef_bio;
err:
if (asn_bio)
BIO_free(asn_bio);
if (ndef_aux)
OPENSSL_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;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
*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)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
if (ndef_aux->derbuf)
OPENSSL_free(ndef_aux->derbuf);
ndef_aux->derbuf = NULL;
*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;
OPENSSL_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;
const ASN1_AUX *aux;
ASN1_STREAM_ARG sarg;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
aux = ndef_aux->it->funcs;
/* Finalize structures */
sarg.ndef_bio = ndef_aux->ndef_bio;
sarg.out = ndef_aux->out;
sarg.boundary = ndef_aux->boundary;
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
return 0;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
*pbuf = *ndef_aux->boundary;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
return 1;
}

View File

@@ -0,0 +1,15 @@
/* Auto generated with chartype.pl script.
* Mask of various character properties
*/
static const unsigned char char_type[] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
};

View File

@@ -0,0 +1,80 @@
#!/usr/local/bin/perl -w
use strict;
my ($i, @arr);
# Set up an array with the type of ASCII characters
# Each set bit represents a character property.
# RFC2253 character properties
my $RFC2253_ESC = 1; # Character escaped with \
my $ESC_CTRL = 2; # Escaped control character
# These are used with RFC1779 quoting using "
my $NOESC_QUOTE = 8; # Not escaped if quoted
my $PSTRING_CHAR = 0x10; # Valid PrintableString character
my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character
my $RFC2253_LAST_ESC = 0x40; # Escaped with \ if last character
for($i = 0; $i < 128; $i++) {
# Set the RFC2253 escape characters (control)
$arr[$i] = 0;
if(($i < 32) || ($i > 126)) {
$arr[$i] |= $ESC_CTRL;
}
# Some PrintableString characters
if( ( ( $i >= ord("a")) && ( $i <= ord("z")) )
|| ( ( $i >= ord("A")) && ( $i <= ord("Z")) )
|| ( ( $i >= ord("0")) && ( $i <= ord("9")) ) ) {
$arr[$i] |= $PSTRING_CHAR;
}
}
# Now setup the rest
# Remaining RFC2253 escaped characters
$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC;
$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC;
$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC;
$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC;
$arr[ord("\"")] |= $RFC2253_ESC;
$arr[ord("\\")] |= $RFC2253_ESC;
$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC;
$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC;
$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC;
# Remaining PrintableString characters
$arr[ord(" ")] |= $PSTRING_CHAR;
$arr[ord("'")] |= $PSTRING_CHAR;
$arr[ord("(")] |= $PSTRING_CHAR;
$arr[ord(")")] |= $PSTRING_CHAR;
$arr[ord("+")] |= $PSTRING_CHAR;
$arr[ord(",")] |= $PSTRING_CHAR;
$arr[ord("-")] |= $PSTRING_CHAR;
$arr[ord(".")] |= $PSTRING_CHAR;
$arr[ord("/")] |= $PSTRING_CHAR;
$arr[ord(":")] |= $PSTRING_CHAR;
$arr[ord("=")] |= $PSTRING_CHAR;
$arr[ord("?")] |= $PSTRING_CHAR;
# Now generate the C code
print <<EOF;
/* Auto generated with chartype.pl script.
* Mask of various character properties
*/
static unsigned char char_type[] = {
EOF
for($i = 0; $i < 128; $i++) {
print("\n") if($i && (($i % 16) == 0));
printf("%2d", $arr[$i]);
print(",") if ($i != 127);
}
print("\n};\n\n");

View File

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

View File

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

View File

@@ -0,0 +1,189 @@
/* crypto/asn1/evp_asn1.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#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=ret;
else
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;
unsigned char *p;
unsigned char buf[32]; /* when they have 256bit longs,
* I'll be in trouble */
in.data=buf;
in.length=32;
os.data=data;
os.type=V_ASN1_OCTET_STRING;
os.length=len;
ASN1_INTEGER_set(&in,num);
n = i2d_ASN1_INTEGER(&in,NULL);
n+=M_i2d_ASN1_OCTET_STRING(&os,NULL);
size=ASN1_object_size(1,n,V_ASN1_SEQUENCE);
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_put_object(&p,1,n,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
i2d_ASN1_INTEGER(&in,&p);
M_i2d_ASN1_OCTET_STRING(&os,&p);
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;
const unsigned char *p;
long length;
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);
c.pp= &p;
c.p=p;
c.max=p+length;
c.error=ASN1_R_DATA_IS_WRONG;
M_ASN1_D2I_start_sequence();
c.q=c.p;
if ((ai=d2i_ASN1_INTEGER(NULL,&c.p,c.slen)) == NULL) goto err;
c.slen-=(c.p-c.q);
c.q=c.p;
if ((os=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) goto err;
c.slen-=(c.p-c.q);
if (!M_ASN1_D2I_end_sequence()) goto err;
if (num != NULL)
*num=ASN1_INTEGER_get(ai);
ret=M_ASN1_STRING_length(os);
if (max_len > ret)
n=ret;
else
n=max_len;
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);
}

View File

@@ -0,0 +1,207 @@
/* crypto/asn1/f_enum.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
/* 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;
unsigned char *bufp;
int num=0,slen=0,first=1;
bs->type=V_ASN1_ENUMERATED;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
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 */
if (i < 2) goto err_sl;
bufp=(unsigned char *)buf;
if (first)
{
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
{
bufp+=2;
i-=2;
}
}
k=0;
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 *)OPENSSL_malloc(
(unsigned int)num+i*2);
else
sp=(unsigned char *)OPENSSL_realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
{
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_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 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);
}

View File

@@ -0,0 +1,219 @@
/* crypto/asn1/f_int.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#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;
unsigned char *bufp;
int num=0,slen=0,first=1;
bs->type=V_ASN1_INTEGER;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1) goto err_sl;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
again=(buf[i-1] == '\\');
for (j=0; j<i; j++)
{
#ifndef CHARSET_EBCDIC
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
#else
/* This #ifdef is not strictly necessary, since
* the characters A...F a...f 0...9 are contiguous
* (yes, even in EBCDIC - but not the whole alphabet).
* Nevertheless, isxdigit() is faster.
*/
if (!isxdigit(buf[j]))
#endif
{
i=j;
break;
}
}
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2) goto err_sl;
bufp=(unsigned char *)buf;
if (first)
{
first=0;
if ((bufp[0] == '0') && (buf[1] == '0'))
{
bufp+=2;
i-=2;
}
}
k=0;
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 *)OPENSSL_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) OPENSSL_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 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);
}

View File

@@ -0,0 +1,212 @@
/* crypto/asn1/f_string.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#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;
unsigned char *bufp;
int num=0,slen=0,first=1;
bufsize=BIO_gets(bp,buf,size);
for (;;)
{
if (bufsize < 1)
{
if (first)
break;
else
goto err_sl;
}
first=0;
i=bufsize;
if (buf[i-1] == '\n') buf[--i]='\0';
if (i == 0) goto err_sl;
if (buf[i-1] == '\r') buf[--i]='\0';
if (i == 0) goto err_sl;
again=(buf[i-1] == '\\');
for (j=i-1; j>0; j--)
{
#ifndef CHARSET_EBCDIC
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
#else
/* This #ifdef is not strictly necessary, since
* the characters A...F a...f 0...9 are contiguous
* (yes, even in EBCDIC - but not the whole alphabet).
* Nevertheless, isxdigit() is faster.
*/
if (!isxdigit(buf[j]))
#endif
{
i=j;
break;
}
}
buf[i]='\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2) goto err_sl;
bufp=(unsigned char *)buf;
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 *)OPENSSL_malloc(
(unsigned int)num+i*2);
else
sp=(unsigned char *)OPENSSL_realloc(s,
(unsigned int)num+i*2);
if (sp == NULL)
{
ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
if (s != NULL) OPENSSL_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 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);
}

View File

@@ -0,0 +1,80 @@
/* crypto/asn1/i2d_pr.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/x509.h>
#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);
}

View File

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

View File

@@ -0,0 +1,353 @@
/* crypto/asn1/n_pkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#include <openssl/objects.h>
#include <openssl/asn1t.h>
#include <openssl/asn1_mac.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RC4
typedef struct netscape_pkey_st
{
long version;
X509_ALGOR *algor;
ASN1_OCTET_STRING *private_key;
} 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;
ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
ASN1_SEQUENCE(NETSCAPE_PKEY) = {
ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(NETSCAPE_PKEY)
DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
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);
int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
int (*cb)(char *buf, int len, const char *prompt,
int verify))
{
return i2d_RSA_NET(a, pp, cb, 0);
}
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;
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
unsigned char buf[256],*zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
if (a == NULL) return(0);
if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
if ((enckey=NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) goto err;
pkey->version = 0;
pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
pkey->algor->parameter->type=V_ASN1_NULL;
rsalen = i2d_RSAPrivateKey(a, NULL);
/* Fake some octet strings just for the initial length
* calculation.
*/
pkey->private_key->length=rsalen;
pkeylen=i2d_NETSCAPE_PKEY(pkey,NULL);
enckey->enckey->digest->length = pkeylen;
enckey->os->length = 11; /* "private-key" */
enckey->enckey->algor->algorithm=OBJ_nid2obj(NID_rc4);
if ((enckey->enckey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
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 *)OPENSSL_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=OPENSSL_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);
/* Wipe the private key encoding */
OPENSSL_cleanse(pkey->private_key->data, rsalen);
if (cb == NULL)
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) {
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
OPENSSL_cleanse(buf,256);
/* Encrypt private key in place */
zz = enckey->enckey->digest->data;
if (!EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL))
goto err;
if (!EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen))
goto err;
if (!EVP_EncryptFinal_ex(&ctx,zz + i,&j))
goto err;
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
err:
EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return(ret);
}
RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
int (*cb)(char *buf, int len, const char *prompt,
int verify))
{
return d2i_RSA_NET(a, pp, length, cb, 0);
}
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;
p = *pp;
enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
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;
*pp = p;
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;
unsigned char buf[256];
const unsigned char *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
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){
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
goto err;
OPENSSL_cleanse(buf,256);
if (!EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL))
goto err;
if (!EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length))
goto err;
if (!EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j))
goto err;
os->length=i+j;
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 */
#else /* !OPENSSL_NO_RSA */
# if PEDANTIC
static void *dummy=&dummy;
# endif
#endif

View File

@@ -0,0 +1,83 @@
/* nsseq.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
{
if(operation == ASN1_OP_NEW_POST) {
NETSCAPE_CERT_SEQUENCE *nsseq;
nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
}
return 1;
}
/* Netscape certificate sequence structure */
ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)

View File

@@ -0,0 +1,148 @@
/* p5_pbe.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
/* PKCS#5 password based encryption structure */
ASN1_SEQUENCE(PBEPARAM) = {
ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
} ASN1_SEQUENCE_END(PBEPARAM)
IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
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);
else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
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 (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
return 1;
err:
if (pbe != NULL)
PBEPARAM_free(pbe);
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;
}

View File

@@ -0,0 +1,280 @@
/* p5_pbev2.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999-2004.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
/* PKCS#5 v2.0 password based encryption structures */
ASN1_SEQUENCE(PBE2PARAM) = {
ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
} ASN1_SEQUENCE_END(PBE2PARAM)
IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
ASN1_SEQUENCE(PBKDF2PARAM) = {
ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
} ASN1_SEQUENCE_END(PBKDF2PARAM)
IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
* yes I know this is horrible!
*
* Extended version to allow application supplied PRF NID and IV.
*/
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid)
{
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
int alg_nid, keylen;
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
PBE2PARAM *pbe2 = NULL;
ASN1_OBJECT *obj;
alg_nid = EVP_CIPHER_type(cipher);
if(alg_nid == NID_undef) {
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
obj = OBJ_nid2obj(alg_nid);
if(!(pbe2 = PBE2PARAM_new())) goto merr;
/* Setup the AlgorithmIdentifier for the encryption scheme */
scheme = pbe2->encryption;
scheme->algorithm = obj;
if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
/* Create random IV */
if (EVP_CIPHER_iv_length(cipher))
{
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
goto err;
}
EVP_CIPHER_CTX_init(&ctx);
/* Dummy cipherinit to just setup the IV, and PRF */
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
goto err;
if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
EVP_CIPHER_CTX_cleanup(&ctx);
goto err;
}
/* If prf NID unspecified see if cipher has a preference.
* An error is OK here: just means use default PRF.
*/
if ((prf_nid == -1) &&
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
{
ERR_clear_error();
prf_nid = NID_hmacWithSHA1;
}
EVP_CIPHER_CTX_cleanup(&ctx);
/* If its RC2 then we'd better setup the key length */
if(alg_nid == NID_rc2_cbc)
keylen = EVP_CIPHER_key_length(cipher);
else
keylen = -1;
/* Setup keyfunc */
X509_ALGOR_free(pbe2->keyfunc);
pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
if (!pbe2->keyfunc)
goto merr;
/* Now set up top level AlgorithmIdentifier */
if(!(ret = X509_ALGOR_new())) goto merr;
if(!(ret->parameter = ASN1_TYPE_new())) goto merr;
ret->algorithm = OBJ_nid2obj(NID_pbes2);
/* Encode PBE2PARAM into parameter */
if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
&ret->parameter->value.sequence)) goto merr;
ret->parameter->type = V_ASN1_SEQUENCE;
PBE2PARAM_free(pbe2);
pbe2 = NULL;
return ret;
merr:
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
X509_ALGOR_free(kalg);
X509_ALGOR_free(ret);
return NULL;
}
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen)
{
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
}
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen)
{
X509_ALGOR *keyfunc = NULL;
PBKDF2PARAM *kdf = NULL;
ASN1_OCTET_STRING *osalt = NULL;
if(!(kdf = PBKDF2PARAM_new()))
goto merr;
if(!(osalt = M_ASN1_OCTET_STRING_new()))
goto merr;
kdf->salt->value.octet_string = osalt;
kdf->salt->type = V_ASN1_OCTET_STRING;
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!(osalt->data = OPENSSL_malloc (saltlen)))
goto merr;
osalt->length = saltlen;
if (salt)
memcpy (osalt->data, salt, saltlen);
else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0)
goto merr;
if(iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if(!ASN1_INTEGER_set(kdf->iter, iter))
goto merr;
/* If have a key len set it up */
if(keylen > 0)
{
if(!(kdf->keylength = M_ASN1_INTEGER_new()))
goto merr;
if(!ASN1_INTEGER_set (kdf->keylength, keylen))
goto merr;
}
/* prf can stay NULL if we are using hmacWithSHA1 */
if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1)
{
kdf->prf = X509_ALGOR_new();
if (!kdf->prf)
goto merr;
X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
V_ASN1_NULL, NULL);
}
/* Finally setup the keyfunc structure */
keyfunc = X509_ALGOR_new();
if (!keyfunc)
goto merr;
keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
/* Encode PBKDF2PARAM into parameter of pbe2 */
if(!(keyfunc->parameter = ASN1_TYPE_new()))
goto merr;
if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
&keyfunc->parameter->value.sequence))
goto merr;
keyfunc->parameter->type = V_ASN1_SEQUENCE;
PBKDF2PARAM_free(kdf);
return keyfunc;
merr:
ASN1err(ASN1_F_PKCS5_PBKDF2_SET,ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);
return NULL;
}

View File

@@ -0,0 +1,155 @@
/* p8_pkey.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
/* Minor tweak to operation: zero private key data */
static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
{
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
if(operation == ASN1_OP_FREE_PRE) {
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
if (key->pkey->value.octet_string)
OPENSSL_cleanse(key->pkey->value.octet_string->data,
key->pkey->value.octet_string->length);
}
return 1;
}
ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
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();
if (!oct)
return 0;
oct->data = penc;
ppenc = &oct->data;
oct->length = penclen;
if (priv->broken == PKCS8_NO_OCTET)
pmtype = V_ASN1_SEQUENCE;
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;
}
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;
}

View File

@@ -0,0 +1,102 @@
/* t_bitst.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/conf.h>
#include <openssl/x509v3.h>
int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
BIT_STRING_BITNAME *tbl, int indent)
{
BIT_STRING_BITNAME *bnam;
char first = 1;
BIO_printf(out, "%*s", indent, "");
for(bnam = tbl; bnam->lname; bnam++) {
if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
if(!first) BIO_puts(out, ", ");
BIO_puts(out, bnam->lname);
first = 0;
}
}
BIO_puts(out, "\n");
return 1;
}
int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
BIT_STRING_BITNAME *tbl)
{
int bitnum;
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
if(bitnum < 0) return 0;
if(bs) {
if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
return 0;
}
return 1;
}
int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
{
BIT_STRING_BITNAME *bnam;
for(bnam = tbl; bnam->lname; bnam++) {
if(!strcmp(bnam->sname, name) ||
!strcmp(bnam->lname, name) ) return bnam->bitnum;
}
return -1;
}

View File

@@ -0,0 +1,132 @@
/* t_crl.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#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)
{
STACK_OF(X509_REVOKED) *rev;
X509_REVOKED *r;
long l;
int i;
char *p;
BIO_printf(out, "Certificate Revocation List (CRL):\n");
l = X509_CRL_get_version(x);
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
i = OBJ_obj2nid(x->sig_alg->algorithm);
X509_signature_print(out, x->sig_alg, NULL);
p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
BIO_printf(out,"%8sIssuer: %s\n","",p);
OPENSSL_free(p);
BIO_printf(out,"%8sLast Update: ","");
ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
BIO_printf(out,"\n%8sNext Update: ","");
if (X509_CRL_get_nextUpdate(x))
ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
else BIO_printf(out,"NONE");
BIO_printf(out,"\n");
X509V3_extensions_print(out, "CRL extensions",
x->crl->extensions, 0, 8);
rev = X509_CRL_get_REVOKED(x);
if(sk_X509_REVOKED_num(rev) > 0)
BIO_printf(out, "Revoked Certificates:\n");
else BIO_printf(out, "No Revoked Certificates.\n");
for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
r = sk_X509_REVOKED_value(rev, i);
BIO_printf(out," Serial Number: ");
i2a_ASN1_INTEGER(out,r->serialNumber);
BIO_printf(out,"\n Revocation Date: ");
ASN1_TIME_print(out,r->revocationDate);
BIO_printf(out,"\n");
X509V3_extensions_print(out, "CRL entry extensions",
r->extensions, 0, 8);
}
X509_signature_print(out, x->sig_alg, x->signature);
return 1;
}

View File

@@ -0,0 +1,114 @@
/* crypto/asn1/t_pkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/bn.h>
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)
{
int n,i;
const char *neg;
if (num == NULL) return(1);
neg = (BN_is_negative(num))?"-":"";
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)
return(0);
n=BN_bn2bin(num,&buf[1]);
if (buf[1] & 0x80)
n++;
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);
}

View File

@@ -0,0 +1,266 @@
/* crypto/asn1/t_req.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#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;
X509_REQ_INFO *ri;
EVP_PKEY *pkey;
STACK_OF(X509_ATTRIBUTE) *sk;
STACK_OF(X509_EXTENSION) *exts;
char mlch = ' ';
int nmindent = 0;
if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
nmindent = 12;
}
if(nmflags == X509_FLAG_COMPAT)
nmindent = 16;
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]; }
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 (X509_NAME_print_ex(bp,ri->subject,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)
goto err;
if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
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;
ASN1_TYPE *t;
int j,type=0,count=1,ii=0;
a=sk_X509_ATTRIBUTE_value(sk,i);
if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
continue;
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(!(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;
ex=sk_X509_EXTENSION_value(exts, i);
if (BIO_printf(bp,"%12s","") <= 0) goto err;
obj=X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp,obj);
j=X509_EXTENSION_get_critical(ex);
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(!(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);
}

View File

@@ -0,0 +1,107 @@
/* t_spki.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#include <openssl/bn.h>
/* Print out an SPKI */
int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
{
EVP_PKEY *pkey;
ASN1_IA5STRING *chal;
int i, n;
char *s;
BIO_printf(out, "Netscape SPKI:\n");
i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
BIO_printf(out," Public Key Algorithm: %s\n",
(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
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);
i=OBJ_obj2nid(spki->sig_algor->algorithm);
BIO_printf(out," Signature Algorithm: %s",
(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
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;
}

View File

@@ -0,0 +1,528 @@
/* crypto/asn1/t_x509.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/bn.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "asn1_locl.h"
#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)
{
BIO *b;
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);
return(ret);
}
#endif
int X509_print(BIO *bp, X509 *x)
{
return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
{
long l;
int ret=0,i;
char *m=NULL,mlch = ' ';
int nmindent = 0;
X509_CINF *ci;
ASN1_INTEGER *bs;
EVP_PKEY *pkey=NULL;
const char *neg;
if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
nmindent = 12;
}
if(nmflags == X509_FLAG_COMPAT)
nmindent = 16;
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_printf(bp,"%8sSignature Algorithm: ","") <= 0)
goto err;
if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
goto err;
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)
goto err;
if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
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) OPENSSL_free(m);
return(ret);
}
int X509_ocspid_print (BIO *bp, X509 *x)
{
unsigned char *der=NULL ;
unsigned char *dertmp;
int derlen;
int i;
unsigned char SHA1md[SHA_DIGEST_LENGTH];
/* display the hash of the subject as it would appear
in OCSP requests */
if (BIO_printf(bp," Subject OCSP hash: ") <= 0)
goto err;
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
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;
}
OPENSSL_free (der);
der=NULL;
/* display the hash of the public key as it would appear
in OCSP requests */
if (BIO_printf(bp,"\n Public key OCSP hash: ") <= 0)
goto err;
if (!EVP_Digest(x->cert_info->key->public_key->data,
x->cert_info->key->public_key->length,
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) OPENSSL_free(der);
return(0);
}
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
const unsigned char *s;
int i, n;
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;
}
int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
{
int sig_nid;
if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0;
if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
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)
return 0;
return 1;
}
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
{
int i,n;
char buf[80];
const char *p;
if (v == NULL) return(0);
n=0;
p=(const char *)v->data;
for (i=0; i<v->length; i++)
{
if ((p[i] > '~') || ((p[i] < ' ') &&
(p[i] != '\n') && (p[i] != '\r')))
buf[n]='.';
else
buf[n]=p[i];
n++;
if (n >= 80)
{
if (BIO_write(bp,buf,n) <= 0)
return(0);
n=0;
}
}
if (n > 0)
if (BIO_write(bp,buf,n) <= 0)
return(0);
return(1);
}
int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
{
if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
if(tm->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_print(bp, tm);
BIO_write(bp,"Bad time value",14);
return(0);
}
static const char *mon[12]=
{
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"
};
int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
{
char *v;
int gmt=0;
int i;
int y=0,M=0,d=0,h=0,m=0,s=0;
char *f = NULL;
int f_len = 0;
i=tm->length;
v=(char *)tm->data;
if (i < 12) goto err;
if (v[i-1] == 'Z') gmt=1;
for (i=0; i<12; i++)
if ((v[i] > '9') || (v[i] < '0')) goto err;
y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
M= (v[4]-'0')*10+(v[5]-'0');
if ((M > 12) || (M < 1)) goto err;
d= (v[6]-'0')*10+(v[7]-'0');
h= (v[8]-'0')*10+(v[9]-'0');
m= (v[10]-'0')*10+(v[11]-'0');
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)
return(0);
else
return(1);
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;
int y=0,M=0,d=0,h=0,m=0,s=0;
i=tm->length;
v=(const char *)tm->data;
if (i < 10) goto err;
if (v[i-1] == 'Z') gmt=1;
for (i=0; i<10; i++)
if ((v[i] > '9') || (v[i] < '0')) goto err;
y= (v[0]-'0')*10+(v[1]-'0');
if (y < 50) y+=100;
M= (v[2]-'0')*10+(v[3]-'0');
if ((M > 12) || (M < 1)) goto err;
d= (v[4]-'0')*10+(v[5]-'0');
h= (v[6]-'0')*10+(v[7]-'0');
m= (v[8]-'0')*10+(v[9]-'0');
if (tm->length >=12 &&
(v[10] >= '0') && (v[10] <= '9') &&
(v[11] >= '0') && (v[11] <= '9'))
s= (v[10]-'0')*10+(v[11]-'0');
if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
return(0);
else
return(1);
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;
l=80-2-obase;
b=X509_NAME_oneline(name,NULL,0);
if (!*b)
{
OPENSSL_free(b);
return 1;
}
s=b+1; /* skip the first slash */
c=s;
for (;;)
{
#ifndef CHARSET_EBCDIC
if ( ((*s == '/') &&
((s[1] >= 'A') && (s[1] <= 'Z') && (
(s[2] == '=') ||
((s[2] >= 'A') && (s[2] <= 'Z') &&
(s[3] == '='))
))) ||
(*s == '\0'))
#else
if ( ((*s == '/') &&
(isupper(s[1]) && (
(s[2] == '=') ||
(isupper(s[2]) &&
(s[3] == '='))
))) ||
(*s == '\0'))
#endif
{
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--;
}
if (*s == '\0') break;
s++;
l--;
}
ret=1;
if (0)
{
err:
X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
}
OPENSSL_free(b);
return(ret);
}

View File

@@ -0,0 +1,110 @@
/* t_x509a.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
/* X509_CERT_AUX and string set routines
*/
int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
{
char oidstr[80], first;
int i;
if(!aux) return 1;
if(aux->trust) {
first = 1;
BIO_printf(out, "%*sTrusted Uses:\n%*s",
indent, "", indent + 2, "");
for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
if(!first) BIO_puts(out, ", ");
else first = 0;
OBJ_obj2txt(oidstr, sizeof oidstr,
sk_ASN1_OBJECT_value(aux->trust, i), 0);
BIO_puts(out, oidstr);
}
BIO_puts(out, "\n");
} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
if(aux->reject) {
first = 1;
BIO_printf(out, "%*sRejected Uses:\n%*s",
indent, "", indent + 2, "");
for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
if(!first) BIO_puts(out, ", ");
else first = 0;
OBJ_obj2txt(oidstr, sizeof oidstr,
sk_ASN1_OBJECT_value(aux->reject, i), 0);
BIO_puts(out, oidstr);
}
BIO_puts(out, "\n");
} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
aux->alias->data);
if(aux->keyid) {
BIO_printf(out, "%*sKey Id: ", indent, "");
for(i = 0; i < aux->keyid->length; i++)
BIO_printf(out, "%s%02X",
i ? ":" : "",
aux->keyid->data[i]);
BIO_write(out,"\n",1);
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,691 @@
/* tasn_enc.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <string.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it,
int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item,
int do_sort, int iclass);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt,
int tag, int aclass);
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags);
/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
* to use indefinite length constructed encoding, where appropriate
*/
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
* a buffer to output the data to.
*
* The new i2d has one additional feature. If the output
* buffer is NULL (i.e. *out == NULL) then a buffer is
* allocated and populated with the encoding.
*/
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);
if (len <= 0)
return len;
buf = OPENSSL_malloc(len);
if (!buf)
return -1;
p = buf;
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
* used in external types.
*/
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;
const ASN1_COMPAT_FUNCS *cf;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb = 0;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return 0;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
switch(it->itype)
{
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
return asn1_template_ex_i2d(pval, out, it->templates,
tag, aclass);
return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
break;
case ASN1_ITYPE_MSTRING:
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
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;
break;
case ASN1_ITYPE_EXTERN:
/* If new style i2d it does all the work */
ef = it->funcs;
return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
case ASN1_ITYPE_COMPAT:
/* old style hackery... */
cf = it->funcs;
if (out)
p = *out;
i = cf->asn1_i2d(*pval, out);
/* Fixup for IMPLICIT tag: note this messes up for tags > 30,
* but so did the old code. Tags > 30 are very rare anyway.
*/
if (out && (tag != -1))
*p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
return i;
case ASN1_ITYPE_NDEF_SEQUENCE:
/* Use indefinite length constructed if requested */
if (aclass & ASN1_TFLG_NDEF) ndef = 2;
/* fall through */
case ASN1_ITYPE_SEQUENCE:
i = asn1_enc_restore(&seqcontlen, out, pval, it);
/* An error occurred */
if (i < 0)
return 0;
/* We have a valid cached encoding... */
if (i > 0)
return seqcontlen;
/* Otherwise carry on */
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);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* 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)
return seqlen;
/* 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);
if (!seqtt)
return 0;
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))
return 0;
return seqlen;
default:
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
* either from the template or the arguments, not both
* because this would create ambiguity. Additionally
* the iclass argument may contain some additional flags
* 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 */
return -1;
/* 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.
*/
iclass &= ~ASN1_TFLG_TAG_CLASS;
/* At this point 'ttag' contains the outer tag to use,
* 'tclass' is the class and iclass is any flags passed
* to this function.
*/
/* if template and arguments require ndef, use it */
if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
ndef = 2;
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;
int skcontlen, sklen;
ASN1_VALUE *skitem;
if (!*pval)
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)
ret = ASN1_object_size(ndef, sklen, ttag);
else ret = sklen;
if (!out)
return ret;
/* Now encode this lot... */
/* EXPLICIT tag */
if (flags & ASN1_TFLG_EXPTAG)
ASN1_put_object(out, ndef, sklen, ttag, tclass);
/* SET or SEQUENCE and IMPLICIT tag */
ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
/* And the stuff itself */
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),
-1, iclass);
if (!i)
return 0;
/* 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;
}
/* Either normal or IMPLICIT tagging: combine class and flags */
return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
ttag, tclass | iclass);
}
/* Temporary structure used to hold DER encoding of items for SET OF */
typedef struct {
unsigned char *data;
int length;
ASN1_VALUE *field;
} 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;
i = memcmp(d1->data, d2->data, cmplen);
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;
DER_ENC *derlst = NULL, *tder;
if (do_sort)
{
/* Don't need to sort less than 2 items */
if (sk_ASN1_VALUE_num(sk) < 2)
do_sort = 0;
else
{
derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
* sizeof(*derlst));
tmpdat = OPENSSL_malloc(skcontlen);
if (!derlst || !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;
}
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);
}
OPENSSL_free(derlst);
OPENSSL_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;
int ndef = 0;
utype = it->utype;
/* Get length of content octets and maybe find
* out the underlying type.
*/
len = asn1_ex_i2c(pval, NULL, &utype, it);
/* If SEQUENCE, SET or OTHER then header is
* included in pseudo content octets so don't
* include tag+length. We need to check here
* because the call to asn1_ex_i2c() could change
* utype.
*/
if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
(utype == V_ASN1_OTHER))
usetag = 0;
else usetag = 1;
/* -1 means omit type */
if (len == -1)
return 0;
/* -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);
if (ndef)
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;
int utype;
const unsigned char *cont;
unsigned char c;
int len;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_i2c)
return pf->prim_i2c(pval, cout, putype, it);
/* 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;
len = otmp->length;
break;
case V_ASN1_NULL:
cont = NULL;
len = 0;
break;
case V_ASN1_BOOLEAN:
tbool = (ASN1_BOOLEAN *)pval;
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;
break;
case V_ASN1_BIT_STRING:
return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
cout ? &cout : NULL);
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
/* These are all have the same content format
* as ASN1_INTEGER
*/
return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
cout ? &cout : NULL);
break;
case V_ASN1_OCTET_STRING:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
default:
/* All based on ASN1_STRING and handled the same */
strtmp = (ASN1_STRING *)*pval;
/* 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;
}

View File

@@ -0,0 +1,266 @@
/* tasn_fre.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
/* 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;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
int i;
if (!pval)
return;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
switch(it->itype)
{
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
ASN1_template_free(pval, it->templates);
else
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_MSTRING:
ASN1_primitive_free(pval, it);
break;
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)
{
OPENSSL_free(*pval);
*pval = NULL;
}
break;
case ASN1_ITYPE_COMPAT:
cf = it->funcs;
if (cf && cf->asn1_free)
cf->asn1_free(*pval);
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_free)
ef->asn1_ex_free(pval, it);
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
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
* determine the type of the field it defines. So
* free up in reverse order.
*/
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)
{
OPENSSL_free(*pval);
*pval = NULL;
}
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;
case V_ASN1_BOOLEAN:
if (it)
*(ASN1_BOOLEAN *)pval = it->size;
else
*(ASN1_BOOLEAN *)pval = -1;
return;
case V_ASN1_NULL:
break;
case V_ASN1_ANY:
ASN1_primitive_free(pval, NULL);
OPENSSL_free(*pval);
break;
default:
ASN1_STRING_free((ASN1_STRING *)*pval);
*pval = NULL;
break;
}
*pval = NULL;
}

View File

@@ -0,0 +1,396 @@
/* tasn_new.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#include <openssl/asn1t.h>
#include <string.h>
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
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;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
ASN1_VALUE **pseqval;
int i;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
else
asn1_cb = 0;
if (!combine) *pval = NULL;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
#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:
cf = it->funcs;
if (cf && cf->asn1_new) {
*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_MSTRING:
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 = OPENSSL_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;
break;
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 = OPENSSL_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
return 1;
memerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
#endif
return 0;
auxerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
#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;
if (ef && ef->asn1_ex_clear)
ef->asn1_ex_clear(pval, it);
else *pval = NULL;
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
asn1_template_clear(pval, it->templates);
else
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_MSTRING:
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_COMPAT:
case ASN1_ITYPE_CHOICE:
case ASN1_ITYPE_SEQUENCE:
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:
#ifdef CRYPTO_MDEBUG
if (it->sname)
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
* all the old functions.
*/
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;
case V_ASN1_BOOLEAN:
*(ASN1_BOOLEAN *)pval = it->size;
return 1;
case V_ASN1_NULL:
*pval = (ASN1_VALUE *)1;
return 1;
case V_ASN1_ANY:
typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
if (!typ)
return 0;
typ->value.ptr = NULL;
typ->type = -1;
*pval = (ASN1_VALUE *)typ;
break;
default:
str = ASN1_STRING_type_new(utype);
if (it->itype == ASN1_ITYPE_MSTRING && str)
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
utype = it->utype;
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else *pval = NULL;
}

View File

@@ -0,0 +1,627 @@
/* tasn_prn.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#include "asn1_locl.h"
/* Print routines.
*/
/* 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 = OPENSSL_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)
{
OPENSSL_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 */
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);
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
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);
static int asn1_print_fsname(BIO *out, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx);
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;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;
else
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;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
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;
}
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,
indent, fname, sname,pctx))
return 0;
break;
case ASN1_ITYPE_EXTERN:
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
/* 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;
break;
case ASN1_ITYPE_CHOICE:
#if 0
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
#endif
/* CHOICE type, get selector */
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))
return 0;
break;
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
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;
if(pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
sname = ASN1_ITEM_ptr(tt->item)->sname;
else
sname = NULL;
if(pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
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
tname = "SEQUENCE";
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;
skitem = sk_ASN1_VALUE_value(stack, i);
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 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;
#if 0
if (!sname && !fname)
return 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)
sname = NULL;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
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;
case 0:
str = "FALSE";
break;
default:
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);
if (BIO_puts(out, s) <= 0)
ret = 0;
OPENSSL_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(!ln)
ln = "";
OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
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)
&& BIO_dump_indent(out, (char *)str->data, str->length,
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;
const char *pname;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (pf && pf->prim_print)
return pf->prim_print(out, fld, it, indent, pctx);
str = (ASN1_STRING *)*fld;
if (it->itype == ASN1_ITYPE_MSTRING)
utype = str->type & ~V_ASN1_NEG;
else
utype = it->utype;
if (utype == V_ASN1_ANY)
{
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
fld = &atype->value.asn1_value;
str = (ASN1_STRING *)*fld;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
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:
case V_ASN1_ENUMERATED:
ret = asn1_print_integer_ctx(out, str, pctx);
break;
case V_ASN1_UTCTIME:
ret = ASN1_UTCTIME_print(out, str);
break;
case V_ASN1_GENERALIZEDTIME:
ret = ASN1_GENERALIZEDTIME_print(out, str);
break;
case V_ASN1_OBJECT:
ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
break;
case V_ASN1_OCTET_STRING:
case V_ASN1_BIT_STRING:
ret = asn1_print_obstring_ctx(out, str, indent, pctx);
needlf = 0;
break;
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_OTHER:
if (BIO_puts(out, "\n") <= 0)
return 0;
if (ASN1_parse_dump(out, str->data, str->length,
indent, 0) <= 0)
ret = 0;
needlf = 0;
break;
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;
}

View File

@@ -0,0 +1,148 @@
/* tasn_typ.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
/* Declarations for string types */
IMPLEMENT_ASN1_TYPE(ASN1_INTEGER)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER)
IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED)
IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING)
IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
IMPLEMENT_ASN1_TYPE(ASN1_NULL)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING)
IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
IMPLEMENT_ASN1_TYPE(ASN1_T61STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING)
IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING)
IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME)
IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING)
IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING)
IMPLEMENT_ASN1_TYPE(ASN1_ANY)
/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
/* Multistring types */
IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
/* Special, OCTET STRING with indefinite length constructed support */
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)

View File

@@ -0,0 +1,279 @@
/* tasn_utl.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/err.h>
/* Utility functions for manipulating fields and offsets */
/* Add 'offset' to 'addr' */
#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
/* Given an ASN1_ITEM CHOICE type return
* the selector value
*/
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
* set to 1. If op is -1 count is decremented and the return value
* is the current refrence count or 0 if no reference count exists.
*/
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)
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
return 0;
aux = it->funcs;
if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
return 0;
lck = offset2ptr(*pval, aux->ref_offset);
if (op == 0)
{
*lck = 1;
return 1;
}
ret = CRYPTO_add(lck, op, aux->ref_lock);
#ifdef REF_PRINT
fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
#endif
#ifdef REF_CHECK
if (ret < 0)
fprintf(stderr, "%s, bad reference count\n", it->sname);
#endif
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;
aux = it->funcs;
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)
OPENSSL_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)
return 1;
if (enc->enc)
OPENSSL_free(enc->enc);
enc->enc = OPENSSL_malloc(inlen);
if (!enc->enc)
return 0;
memcpy(enc->enc, in, inlen);
enc->len = inlen;
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;
pvaltmp = offset2ptr(*pval, tt->offset);
/* NOTE for BOOLEAN types the field is just a plain
* int so we can't return int **, so settle for
* (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;
ASN1_VALUE **sfld;
int i;
if (!(tt->flags & ASN1_TFLG_ADB_MASK))
return tt;
/* Else ANY DEFINED BY ... get the table */
adb = ASN1_ADB_ptr(tt->item);
/* Get the selector field */
sfld = offset2ptr(*pval, adb->offset);
/* 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
* might be a legitimate value in the table
*/
if (tt->flags & ASN1_TFLG_ADB_OID)
selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
else
selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
/* Try to find matching entry in table
* Maybe should check application types first to
* allow application override? Might also be useful
* to have a flag which indicates table is sorted and
* we can do a binary search. For now stick to a
* linear search.
*/
for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
if (atbl->value == selector)
return &atbl->tt;
/* FIXME: need to search application table too */
/* No match, return default type */
if (!adb->default_tt)
goto err;
return adb->default_tt;
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr)
ASN1err(ASN1_F_ASN1_DO_ADB,
ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
}

View File

@@ -0,0 +1,144 @@
/* x_algor.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
ASN1_SEQUENCE(X509_ALGOR) = {
ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
} ASN1_SEQUENCE_END(X509_ALGOR)
ASN1_ITEM_TEMPLATE(X509_ALGORS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
IMPLEMENT_STACK_OF(X509_ALGOR)
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)
param_type = V_ASN1_UNDEF;
else
param_type = V_ASN1_NULL;
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}

View File

@@ -0,0 +1,118 @@
/* crypto/asn1/x_attrib.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/objects.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
/* X509_ATTRIBUTE: this has the following form:
*
* typedef struct x509_attributes_st
* {
* ASN1_OBJECT *object;
* int single;
* union {
* char *ptr;
* STACK_OF(ASN1_TYPE) *set;
* ASN1_TYPE *single;
* } value;
* } X509_ATTRIBUTE;
*
* this needs some extra thought because the CHOICE type is
* merged with the main structure and because the value can
* be anything at all we *must* try the SET OF first because
* the ASN1_ANY type will swallow anything including the whole
* SET OF structure.
*/
ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
ASN1_SEQUENCE(X509_ATTRIBUTE) = {
ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
/* CHOICE type merged with parent */
ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
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=X509_ATTRIBUTE_new()) == NULL)
return(NULL);
ret->object=OBJ_nid2obj(nid);
ret->single=0;
if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
if ((val=ASN1_TYPE_new()) == NULL) goto err;
if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
ASN1_TYPE_set(val,atrtype,value);
return(ret);
err:
if (ret != NULL) X509_ATTRIBUTE_free(ret);
if (val != NULL) ASN1_TYPE_free(val);
return(NULL);
}

View File

@@ -0,0 +1,139 @@
/* x_bignum.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/bn.h>
/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
* BIGNUM directly. Currently it ignores the sign which isn't a problem since all
* BIGNUMs used are non negative and anything that looks negative is normally due
* to an encoding error.
*/
#define BN_SENSITIVE 1
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
bn_new,
bn_free,
0,
bn_c2i,
bn_i2c
};
ASN1_ITEM_start(BIGNUM)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
ASN1_ITEM_end(BIGNUM)
ASN1_ITEM_start(CBIGNUM)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
ASN1_ITEM_end(CBIGNUM)
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*pval = (ASN1_VALUE *)BN_new();
if(*pval) return 1;
else return 0;
}
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if(!*pval) return;
if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
else BN_free((BIGNUM *)*pval);
*pval = NULL;
}
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
{
BIGNUM *bn;
int pad;
if(!*pval) return -1;
bn = (BIGNUM *)*pval;
/* If MSB set in an octet we need a padding byte */
if(BN_num_bits(bn) & 0x7) pad = 0;
else pad = 1;
if(cont) {
if(pad) *cont++ = 0;
BN_bn2bin(bn, cont);
}
return pad + BN_num_bytes(bn);
}
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
if(!*pval) bn_new(pval, it);
bn = (BIGNUM *)*pval;
if(!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
return 0;
}
return 1;
}

View File

@@ -0,0 +1,527 @@
/* crypto/asn1/x_crl.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include "asn1_locl.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b);
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
ASN1_SEQUENCE(X509_REVOKED) = {
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
} ASN1_SEQUENCE_END(X509_REVOKED)
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
static int def_crl_lookup(X509_CRL *crl,
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;
/* The X509_CRL_INFO structure needs a bit of customisation.
* Since we cache the original encoding the signature wont be affected by
* reordering of the revoked field.
*/
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
{
X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
if(!a || !a->revoked) return 1;
switch(operation) {
/* Just set cmp function here. We don't sort because that
* would affect the output of X509_CRL_print().
*/
case ASN1_OP_D2I_POST:
(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
break;
}
return 1;
}
ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
/* Set CRL entry issuer according to CRL certificate issuer extension.
* Check for unhandled critical CRL entry extensions.
*/
static int crl_set_issuers(X509_CRL *crl)
{
int i, j;
GENERAL_NAMES *gens, *gtmp;
STACK_OF(X509_REVOKED) *revoked;
revoked = X509_CRL_get_REVOKED(crl);
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;
X509_EXTENSION *ext;
gtmp = X509_REVOKED_get_ext_d2i(rev,
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;
/* Check for critical CRL entry extensions */
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;
crl->flags = 0;
crl->idp_flags = 0;
crl->idp_reasons = CRLDP_ALL_REASONS;
crl->meth = default_crl_method;
crl->meth_data = NULL;
crl->issuers = NULL;
crl->crl_number = NULL;
crl->base_crl_number = NULL;
break;
case ASN1_OP_D2I_POST:
#ifndef OPENSSL_NO_SHA
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
#endif
crl->idp = X509_CRL_get_ext_d2i(crl,
NID_issuing_distribution_point, NULL, NULL);
if (crl->idp)
setup_idp(crl, crl->idp);
crl->akid = X509_CRL_get_ext_d2i(crl,
NID_authority_key_identifier, NULL, NULL);
crl->crl_number = X509_CRL_get_ext_d2i(crl,
NID_crl_number, NULL, NULL);
crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
NID_delta_crl, NULL, NULL);
/* Delta CRLs must have CRL number */
if (crl->base_crl_number && !crl->crl_number)
crl->flags |= EXFLAG_INVALID;
/* See if we have any unhandled critical CRL extensions and
* indicate this in a flag. We only currently handle IDP so
* anything else critical sets the flag.
*
* This code accesses the X509_CRL structure directly:
* applications shouldn't do this.
*/
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)
ISSUING_DIST_POINT_free(crl->idp);
ASN1_INTEGER_free(crl->crl_number);
ASN1_INTEGER_free(crl->base_crl_number);
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
break;
}
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;
if (idp->indirectCRL > 0)
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];
if (idp->onlysomereasons->length > 1)
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),
ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
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)
{
X509_CRL_INFO *inf;
inf = crl->crl;
if(!inf->revoked)
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
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;
/* Sort revoked into serial number order if not already sorted.
* 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;
}
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_free)(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 = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
if (!m)
return NULL;
m->crl_init = crl_init;
m->crl_free = crl_free;
m->crl_lookup = crl_lookup;
m->crl_verify = crl_verify;
m->flags = X509_CRL_METHOD_DYNAMIC;
return m;
}
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
{
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
return;
OPENSSL_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)
IMPLEMENT_STACK_OF(X509_CRL)
IMPLEMENT_ASN1_SET_OF(X509_CRL)

View File

@@ -0,0 +1,76 @@
/* x_exten.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
ASN1_SEQUENCE(X509_EXTENSION) = {
ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(X509_EXTENSION)
ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)

View File

@@ -0,0 +1,114 @@
/* crypto/asn1/x_info.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
X509_INFO *X509_INFO_new(void)
{
X509_INFO *ret=NULL;
ret=(X509_INFO *)OPENSSL_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->enc_data=NULL;
ret->references=1;
ret->x509=NULL;
ret->crl=NULL;
ret->x_pkey=NULL;
return(ret);
}
void X509_INFO_free(X509_INFO *x)
{
int i;
if (x == NULL) return;
i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
#ifdef REF_PRINT
REF_PRINT("X509_INFO",x);
#endif
if (i > 0) return;
#ifdef REF_CHECK
if (i < 0)
{
fprintf(stderr,"X509_INFO_free, bad reference count\n");
abort();
}
#endif
if (x->x509 != NULL) X509_free(x->x509);
if (x->crl != NULL) X509_CRL_free(x->crl);
if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
OPENSSL_free(x);
}
IMPLEMENT_STACK_OF(X509_INFO)

View File

@@ -0,0 +1,179 @@
/* x_long.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/bn.h>
/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
* and a long directly.
*/
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
static ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
long_i2c,
long_print
};
ASN1_ITEM_start(LONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
ASN1_ITEM_end(LONG)
ASN1_ITEM_start(ZLONG)
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
ASN1_ITEM_end(ZLONG)
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
return 1;
}
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
}
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
{
long ltmp;
unsigned long utmp;
int clen, pad, i;
/* this exists to bypass broken gcc optimization */
char *cp = (char *)pval;
/* use memcpy, because we may not be long aligned */
memcpy(&ltmp, cp, sizeof(long));
if(ltmp == it->size) return -1;
/* Convert the long to positive: we subtract one if negative so
* we can cleanly handle the padding if only the MSB of the leading
* octet is set.
*/
if(ltmp < 0) utmp = -ltmp - 1;
else utmp = ltmp;
clen = BN_num_bits_word(utmp);
/* If MSB of leading octet set we need to pad */
if(!(clen & 0x7)) pad = 1;
else pad = 0;
/* Convert number of bits to number of octets */
clen = (clen + 7) >> 3;
if(cont) {
if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
for(i = clen - 1; i >= 0; i--) {
cont[i] = (unsigned char)(utmp & 0xff);
if(ltmp < 0) cont[i] ^= 0xff;
utmp >>= 8;
}
}
return clen + pad;
}
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
int neg, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
if(len > (int)sizeof(long)) {
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
if(len && (cont[0] & 0x80)) neg = 1;
else neg = 0;
utmp = 0;
for(i = 0; i < len; i++) {
utmp <<= 8;
if(neg) utmp |= cont[i] ^ 0xff;
else utmp |= cont[i];
}
ltmp = (long)utmp;
if(neg) {
ltmp++;
ltmp = -ltmp;
}
if(ltmp == it->size) {
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
return 1;
}
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);
}

View File

@@ -0,0 +1,519 @@
/* crypto/asn1/x_name.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
static int x509_name_ex_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx);
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
static int x509_name_encode(X509_NAME *a);
static int x509_name_canon(X509_NAME *a);
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
unsigned char **in);
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
int indent,
const char *fname,
const ASN1_PCTX *pctx);
ASN1_SEQUENCE(X509_NAME_ENTRY) = {
ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
* so declare two template wrappers for this
*/
ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
/* Normally that's where it would end: we'd have two nested STACK structures
* representing the ASN1. Unfortunately X509_NAME uses a completely different
* form and caches encodings so we have to process the internal form and convert
* to the external form.
*/
const ASN1_EXTERN_FUNCS x509_name_ff = {
NULL,
x509_name_ex_new,
x509_name_ex_free,
0, /* Default clear behaviour is OK */
x509_name_ex_d2i,
x509_name_ex_i2d,
x509_name_ex_print
};
IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
{
X509_NAME *ret = NULL;
ret = OPENSSL_malloc(sizeof(X509_NAME));
if(!ret) goto memerr;
if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
goto memerr;
if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
ret->canon_enc = NULL;
ret->canon_enclen = 0;
ret->modified=1;
*val = (ASN1_VALUE *)ret;
return 1;
memerr:
ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
if (ret)
{
if (ret->entries)
sk_X509_NAME_ENTRY_free(ret->entries);
OPENSSL_free(ret);
}
return 0;
}
static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
X509_NAME *a;
if(!pval || !*pval)
return;
a = (X509_NAME *)*pval;
BUF_MEM_free(a->bytes);
sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
if (a->canon_enc)
OPENSSL_free(a->canon_enc);
OPENSSL_free(a);
*pval = NULL;
}
static int x509_name_ex_d2i(ASN1_VALUE **val,
const unsigned char **in, long len, const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx)
{
const unsigned char *p = *in, *q;
union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a; } intname = {NULL};
union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
int i, j, ret;
STACK_OF(X509_NAME_ENTRY) *entries;
X509_NAME_ENTRY *entry;
q = p;
/* Get internal representation of Name */
ret = ASN1_item_ex_d2i(&intname.a,
&p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
tag, aclass, opt, ctx);
if(ret <= 0) return ret;
if(*val) x509_name_ex_free(val, NULL);
if(!x509_name_ex_new(&nm.a, NULL)) goto err;
/* We've decoded it: now cache encoding */
if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
memcpy(nm.x->bytes->data, q, p - q);
/* Convert internal representation to X509_NAME structure */
for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
entry = sk_X509_NAME_ENTRY_value(entries, j);
entry->set = i;
if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
goto err;
}
sk_X509_NAME_ENTRY_free(entries);
}
sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
ret = x509_name_canon(nm.x);
if (!ret)
goto err;
nm.x->modified = 0;
*val = nm.a;
*in = p;
return ret;
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
return 0;
}
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
{
int ret;
X509_NAME *a = (X509_NAME *)*val;
if(a->modified) {
ret = x509_name_encode(a);
if(ret < 0)
return ret;
ret = x509_name_canon(a);
if(ret < 0)
return ret;
}
ret = a->bytes->length;
if(out != NULL) {
memcpy(*out,a->bytes->data,ret);
*out+=ret;
}
return ret;
}
static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
sk_X509_NAME_ENTRY_free(ne);
}
static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}
static int x509_name_encode(X509_NAME *a)
{
union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a; } intname = {NULL};
int len;
unsigned char *p;
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
X509_NAME_ENTRY *entry;
int i, set = -1;
intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
if(!intname.s) goto memerr;
for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
if(entry->set != set) {
entries = sk_X509_NAME_ENTRY_new_null();
if(!entries) goto memerr;
if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
entries))
goto memerr;
set = entry->set;
}
if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
}
len = ASN1_item_ex_i2d(&intname.a, NULL,
ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
p=(unsigned char *)a->bytes->data;
ASN1_item_ex_i2d(&intname.a,
&p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
a->modified = 0;
return len;
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
return -1;
}
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
int indent,
const char *fname,
const ASN1_PCTX *pctx)
{
if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
indent, pctx->nm_flags) <= 0)
return 0;
return 2;
}
/* This function generates the canonical encoding of the Name structure.
* In it all strings are converted to UTF8, leading, trailing and
* multiple spaces collapsed, converted to lower case and the leading
* SEQUENCE header removed.
*
* In future we could also normalize the UTF8 too.
*
* By doing this comparison of Name structures can be rapidly
* perfomed by just using memcmp() of the canonical encoding.
* By omitting the leading SEQUENCE name constraints of type
* dirName can also be checked with a simple memcmp().
*/
static int x509_name_canon(X509_NAME *a)
{
unsigned char *p;
STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
X509_NAME_ENTRY *entry, *tmpentry = NULL;
int i, set = -1, ret = 0;
if (a->canon_enc)
{
OPENSSL_free(a->canon_enc);
a->canon_enc = NULL;
}
/* Special case: empty X509_NAME => null encoding */
if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
{
a->canon_enclen = 0;
return 1;
}
intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
if(!intname)
goto err;
for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
{
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
if(entry->set != set)
{
entries = sk_X509_NAME_ENTRY_new_null();
if(!entries)
goto err;
if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
goto err;
set = entry->set;
}
tmpentry = X509_NAME_ENTRY_new();
tmpentry->object = OBJ_dup(entry->object);
if (!asn1_string_canon(tmpentry->value, entry->value))
goto err;
if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
goto err;
tmpentry = NULL;
}
/* Finally generate encoding */
a->canon_enclen = i2d_name_canon(intname, NULL);
p = OPENSSL_malloc(a->canon_enclen);
if (!p)
goto err;
a->canon_enc = p;
i2d_name_canon(intname, &p);
ret = 1;
err:
if (tmpentry)
X509_NAME_ENTRY_free(tmpentry);
if (intname)
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
local_sk_X509_NAME_ENTRY_pop_free);
return ret;
}
/* Bitmap of all the types of string that will be canonicalized. */
#define ASN1_MASK_CANON \
(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
| B_ASN1_VISIBLESTRING)
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
{
unsigned char *to, *from;
int len, i;
/* If type not in bitmask just copy string across */
if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
{
if (!ASN1_STRING_copy(out, in))
return 0;
return 1;
}
out->type = V_ASN1_UTF8STRING;
out->length = ASN1_STRING_to_UTF8(&out->data, in);
if (out->length == -1)
return 0;
to = out->data;
from = to;
len = out->length;
/* Convert string in place to canonical form.
* Ultimately we may need to handle a wider range of characters
* but for now ignore anything with MSB set and rely on the
* isspace() and tolower() functions.
*/
/* Ignore leading spaces */
while((len > 0) && !(*from & 0x80) && isspace(*from))
{
from++;
len--;
}
to = from + len - 1;
/* Ignore trailing spaces */
while ((len > 0) && !(*to & 0x80) && isspace(*to))
{
to--;
len--;
}
to = out->data;
i = 0;
while(i < len)
{
/* If MSB set just copy across */
if (*from & 0x80)
{
*to++ = *from++;
i++;
}
/* Collapse multiple spaces */
else if (isspace(*from))
{
/* Copy one space across */
*to++ = ' ';
/* Ignore subsequent spaces. Note: don't need to
* check len here because we know the last
* character is a non-space so we can't overflow.
*/
do
{
from++;
i++;
}
while(!(*from & 0x80) && isspace(*from));
}
else
{
*to++ = tolower(*from);
from++;
i++;
}
}
out->length = to - out->data;
return 1;
}
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
unsigned char **in)
{
int i, len, ltmp;
ASN1_VALUE *v;
STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
len = 0;
for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
{
v = sk_ASN1_VALUE_value(intname, i);
ltmp = ASN1_item_ex_i2d(&v, in,
ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
if (ltmp < 0)
return ltmp;
len += ltmp;
}
return len;
}
int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
{
X509_NAME *in;
if (!xn || !name) return(0);
if (*xn != name)
{
in=X509_NAME_dup(name);
if (in != NULL)
{
X509_NAME_free(*xn);
*xn=in;
}
}
return(*xn != NULL);
}
IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)

View File

@@ -0,0 +1,72 @@
/* x_nx509.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2005.
*/
/* ====================================================================
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
/* Old netscape certificate wrapper format */
ASN1_SEQUENCE(NETSCAPE_X509) = {
ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
ASN1_OPT(NETSCAPE_X509, cert, X509)
} ASN1_SEQUENCE_END(NETSCAPE_X509)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)

View File

@@ -0,0 +1,151 @@
/* crypto/asn1/x_pkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/asn1_mac.h>
#include <openssl/x509.h>
/* 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);
M_ASN1_D2I_Init();
M_ASN1_D2I_start_sequence();
M_ASN1_D2I_get_x(X509_ALGOR,ret->enc_algor,d2i_X509_ALGOR);
M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->enc_pkey,d2i_ASN1_OCTET_STRING);
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;
M_ASN1_New_Malloc(ret,X509_PKEY);
ret->version=0;
M_ASN1_New(ret->enc_algor,X509_ALGOR_new);
M_ASN1_New(ret->enc_pkey,M_ASN1_OCTET_STRING_new);
ret->dec_pkey=NULL;
ret->key_length=0;
ret->key_data=NULL;
ret->key_free=0;
ret->cipher.cipher=NULL;
memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
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;
i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
#ifdef REF_PRINT
REF_PRINT("X509_PKEY",x);
#endif
if (i > 0) return;
#ifdef REF_CHECK
if (i < 0)
{
fprintf(stderr,"X509_PKEY_free, bad reference count\n");
abort();
}
#endif
if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
OPENSSL_free(x);
}

View File

@@ -0,0 +1,385 @@
/* crypto/asn1/x_pubkey.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
/* 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;
}
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
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);
*x=pk;
return 1;
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;
error:
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);
if(!xpk) return NULL;
pktmp = X509_PUBKEY_get(xpk);
X509_PUBKEY_free(xpk);
if(!pktmp) return NULL;
if(a)
{
EVP_PKEY_free(*a);
*a = pktmp;
}
return pktmp;
}
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
{
X509_PUBKEY *xpk=NULL;
int ret;
if(!a) return 0;
if(!X509_PUBKEY_set(&xpk, 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;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return NULL;
key = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (!key) return NULL;
*pp = q;
if (a)
{
RSA_free(*a);
*a = key;
}
return key;
}
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;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return NULL;
key = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
if (!key) return NULL;
*pp = q;
if (a)
{
DSA_free(*a);
*a = key;
}
return key;
}
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;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey) return(NULL);
key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (!key) return(NULL);
*pp = q;
if (a)
{
EC_KEY_free(*a);
*a = key;
}
return(key);
}
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)
OPENSSL_free(pub->public_key->data);
pub->public_key->data = penc;
pub->public_key->length = penclen;
/* 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;
}
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;
}

View File

@@ -0,0 +1,113 @@
/* crypto/asn1/x_req.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
/* X509_REQ_INFO is handled in an unusual way to get round
* invalid encodings. Some broken certificate requests don't
* encode the attributes field if it is empty. This is in
* violation of PKCS#10 but we need to tolerate it. We do
* this by making the attributes field OPTIONAL then using
* the callback to initialise it to an empty STACK.
*
* This means that the field will be correctly encoded unless
* we NULL out the field.
*
* As a result we no longer need the req_kludge field because
* the information is now contained in the attributes field:
* 1. If it is NULL then it's the invalid omission.
* 2. If it is empty it is the correct encoding.
* 3. If it is not empty then some attributes are present.
*
*/
static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
{
X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
if(operation == ASN1_OP_NEW_POST) {
rinf->attributes = sk_X509_ATTRIBUTE_new_null();
if(!rinf->attributes) return 0;
}
return 1;
}
ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
/* This isn't really OPTIONAL but it gets round invalid
* encodings
*/
ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)

View File

@@ -0,0 +1,69 @@
/* crypto/asn1/x_sig.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
ASN1_SEQUENCE(X509_SIG) = {
ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(X509_SIG)
IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)

View File

@@ -0,0 +1,81 @@
/* crypto/asn1/x_spki.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* This module was send to me my Pat Richards <patr@x509.com> who
* wrote it. It is under my Copyright with his permission
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
#include <openssl/asn1t.h>
ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
ASN1_SEQUENCE(NETSCAPE_SPKI) = {
ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)

View File

@@ -0,0 +1,69 @@
/* crypto/asn1/x_val.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
ASN1_SEQUENCE(X509_VAL) = {
ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
} ASN1_SEQUENCE_END(X509_VAL)
IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)

View File

@@ -0,0 +1,194 @@
/* crypto/asn1/x_x509.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER),
ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR),
ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
ASN1_SIMPLE(X509_CINF, validity, X509_VAL),
ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
/* X509 top level structure needs a bit of customisation */
extern void policy_cache_free(X509_POLICY_CACHE *cache);
static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg)
{
X509 *ret = (X509 *)*pval;
switch(operation) {
case ASN1_OP_NEW_POST:
ret->valid=0;
ret->name = NULL;
ret->ex_flags = 0;
ret->ex_pathlen = -1;
ret->skid = NULL;
ret->akid = NULL;
#ifndef OPENSSL_NO_RFC3779
ret->rfc3779_addr = NULL;
ret->rfc3779_asid = NULL;
#endif
ret->aux = NULL;
ret->crldp = NULL;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
case ASN1_OP_D2I_POST:
if (ret->name != NULL) OPENSSL_free(ret->name);
ret->name=X509_NAME_oneline(ret->cert_info->subject,NULL,0);
break;
case ASN1_OP_FREE_POST:
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
X509_CERT_AUX_free(ret->aux);
ASN1_OCTET_STRING_free(ret->skid);
AUTHORITY_KEYID_free(ret->akid);
CRL_DIST_POINTS_free(ret->crldp);
policy_cache_free(ret->policy_cache);
GENERAL_NAMES_free(ret->altname);
NAME_CONSTRAINTS_free(ret->nc);
#ifndef OPENSSL_NO_RFC3779
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
ASIdentifiers_free(ret->rfc3779_asid);
#endif
if (ret->name != NULL) OPENSSL_free(ret->name);
break;
}
return 1;
}
ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = {
ASN1_SIMPLE(X509, cert_info, X509_CINF),
ASN1_SIMPLE(X509, sig_alg, X509_ALGOR),
ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING)
} ASN1_SEQUENCE_END_ref(X509, X509)
IMPLEMENT_ASN1_FUNCTIONS(X509)
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
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
* functions set how a certificate is trusted they should only
* be used when the certificate comes from a reliable source
* such as local storage.
*
*/
X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
{
const unsigned char *q;
X509 *ret;
/* Save start position */
q = *pp;
ret = d2i_X509(a, pp, length);
/* If certificate unreadable then forget it */
if(!ret) return NULL;
/* update length */
length -= *pp - q;
if(!length) return ret;
if(!d2i_X509_CERT_AUX(&ret->aux, pp, length)) goto err;
return ret;
err:
X509_free(ret);
return NULL;
}
int i2d_X509_AUX(X509 *a, unsigned char **pp)
{
int length;
length = i2d_X509(a, pp);
if(a) length += i2d_X509_CERT_AUX(a->aux, pp);
return length;
}

View File

@@ -0,0 +1,180 @@
/* a_x509a.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
/* X509_CERT_AUX routines. These are used to encode additional
* user modifiable data about a certificate. This data is
* appended to the X509 encoding when the *_X509_AUX routines
* are used. This means that the "traditional" X509 routines
* will simply ignore the extra data.
*/
static X509_CERT_AUX *aux_get(X509 *x);
ASN1_SEQUENCE(X509_CERT_AUX) = {
ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
} ASN1_SEQUENCE_END(X509_CERT_AUX)
IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
static X509_CERT_AUX *aux_get(X509 *x)
{
if(!x) return NULL;
if(!x->aux && !(x->aux = X509_CERT_AUX_new())) return NULL;
return x->aux;
}
int X509_alias_set1(X509 *x, unsigned char *name, int len)
{
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);
}
int X509_keyid_set1(X509 *x, unsigned char *id, int 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);
}
unsigned char *X509_alias_get0(X509 *x, int *len)
{
if(!x->aux || !x->aux->alias) return NULL;
if(len) *len = x->aux->alias->length;
return x->aux->alias->data;
}
unsigned char *X509_keyid_get0(X509 *x, int *len)
{
if(!x->aux || !x->aux->keyid) return NULL;
if(len) *len = x->aux->keyid->length;
return x->aux->keyid->data;
}
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
X509_CERT_AUX *aux;
ASN1_OBJECT *objtmp;
if(!(objtmp = OBJ_dup(obj))) return 0;
if(!(aux = aux_get(x))) return 0;
if(!aux->trust
&& !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
return sk_ASN1_OBJECT_push(aux->trust, objtmp);
}
int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
{
X509_CERT_AUX *aux;
ASN1_OBJECT *objtmp;
if(!(objtmp = OBJ_dup(obj))) return 0;
if(!(aux = aux_get(x))) return 0;
if(!aux->reject
&& !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
return sk_ASN1_OBJECT_push(aux->reject, objtmp);
}
void X509_trust_clear(X509 *x)
{
if(x->aux && x->aux->trust) {
sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
x->aux->trust = NULL;
}
}
void X509_reject_clear(X509 *x)
{
if(x->aux && x->aux->reject) {
sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
x->aux->reject = NULL;
}
}
ASN1_SEQUENCE(X509_CERT_PAIR) = {
ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0),
ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1)
} ASN1_SEQUENCE_END(X509_CERT_PAIR)
IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR)