提交 452ae49d 编写于 作者: D Dr. Stephen Henson

Extensive OID code enhancement and fixes.

上级 8c5c5b65
...@@ -73,6 +73,12 @@ ...@@ -73,6 +73,12 @@
Changes between 0.9.8a and 0.9.8b [XX xxx XXXX] Changes between 0.9.8a and 0.9.8b [XX xxx XXXX]
*) Several fixes and enhancements to the OID generation code. The old code
sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
handle numbers larger than ULONG_MAX, truncated printing and had a
non standard OBJ_obj2txt() behaviour.
[Steve Henson]
*) Add support for building of engines under engine/ as shared libraries *) Add support for building of engines under engine/ as shared libraries
under VC++ build system. under VC++ build system.
[Steve Henson] [Steve Henson]
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <limits.h>
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/buffer.h> #include <openssl/buffer.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
...@@ -83,10 +84,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) ...@@ -83,10 +84,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{ {
int i,first,len=0,c; int i,first,len=0,c, use_bn;
char tmp[24]; char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p; const char *p;
unsigned long l; unsigned long l;
BIGNUM *bl = NULL;
if (num == 0) if (num == 0)
return(0); return(0);
...@@ -98,7 +101,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ...@@ -98,7 +101,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
num--; num--;
if ((c >= '0') && (c <= '2')) if ((c >= '0') && (c <= '2'))
{ {
first=(c-'0')*40; first= c-'0';
} }
else else
{ {
...@@ -122,6 +125,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ...@@ -122,6 +125,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
goto err; goto err;
} }
l=0; l=0;
use_bn = 0;
for (;;) for (;;)
{ {
if (num <= 0) break; if (num <= 0) break;
...@@ -134,7 +138,22 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ...@@ -134,7 +138,22 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
goto err; goto err;
} }
l=l*10L+(long)(c-'0'); if (!use_bn && l > (ULONG_MAX / 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 (len == 0)
{ {
...@@ -143,14 +162,42 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ...@@ -143,14 +162,42 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE); ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err; goto err;
} }
l+=(long)first; if (use_bn)
{
if (!BN_add_word(bl, first * 40))
goto err;
}
else
l+=(long)first*40;
} }
i=0; i=0;
for (;;) if (use_bn)
{ {
tmp[i++]=(unsigned char)l&0x7f; int blsize;
l>>=7L; blsize = BN_num_bits(bl);
if (l == 0L) break; 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++] = BN_div_word(bl, 0x80L);
}
else
{
for (;;)
{
tmp[i++]=(unsigned char)l&0x7f;
l>>=7L;
if (l == 0L) break;
}
} }
if (out != NULL) if (out != NULL)
{ {
...@@ -166,8 +213,16 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) ...@@ -166,8 +213,16 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
else else
len+=i; len+=i;
} }
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(len); return(len);
err: err:
if (tmp != ftmp)
OPENSSL_free(tmp);
if (bl)
BN_free(bl);
return(0); return(0);
} }
...@@ -178,14 +233,22 @@ int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) ...@@ -178,14 +233,22 @@ int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
{ {
char buf[80]; char buf[80], *p = buf;
int i; int i;
if ((a == NULL) || (a->data == NULL)) if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp,"NULL",4)); return(BIO_write(bp,"NULL",4));
i=i2t_ASN1_OBJECT(buf,sizeof buf,a); i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
if (i > (int)sizeof(buf)) i=sizeof buf; if (i > (int)(sizeof(buf) - 1))
BIO_write(bp,buf,i); {
p = OPENSSL_malloc(i + 1);
if (!p)
return -1;
i2t_ASN1_OBJECT(p,i + 1,a);
}
BIO_write(bp,p,i);
if (p != buf)
OPENSSL_free(p);
return(i); return(i);
} }
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h>
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/lhash.h> #include <openssl/lhash.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
...@@ -413,8 +414,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) ...@@ -413,8 +414,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
/* Work out size of content octets */ /* Work out size of content octets */
i=a2d_ASN1_OBJECT(NULL,0,s,-1); i=a2d_ASN1_OBJECT(NULL,0,s,-1);
if (i <= 0) { if (i <= 0) {
/* Clear the error */ /* Don't clear the error */
ERR_clear_error(); /*ERR_clear_error();*/
return NULL; return NULL;
} }
/* Work out total size */ /* Work out total size */
...@@ -436,66 +437,145 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) ...@@ -436,66 +437,145 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
{ {
int i,idx=0,n=0,len,nid; int i,n=0,len,nid, first, use_bn;
BIGNUM *bl;
unsigned long l; unsigned long l;
unsigned char *p; unsigned char *p;
const char *s;
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2]; char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
if (buf_len <= 0) return(0);
if ((a == NULL) || (a->data == NULL)) { if ((a == NULL) || (a->data == NULL)) {
buf[0]='\0'; buf[0]='\0';
return(0); return(0);
} }
if (no_name || (nid=OBJ_obj2nid(a)) == NID_undef) {
len=a->length;
p=a->data;
idx=0; if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
l=0; {
while (idx < a->length) { const char *s;
l|=(p[idx]&0x7f); s=OBJ_nid2ln(nid);
if (!(p[idx] & 0x80)) break; if (s == NULL)
l<<=7L; s=OBJ_nid2sn(nid);
idx++; if (buf)
BUF_strlcpy(buf,s,buf_len);
n=strlen(s);
return n;
} }
idx++;
i=(int)(l/40);
if (i > 2) i=2;
l-=(long)(i*40);
BIO_snprintf(tbuf,sizeof tbuf,"%d.%lu",i,l);
i=strlen(tbuf);
BUF_strlcpy(buf,tbuf,buf_len);
buf_len-=i;
buf+=i;
n+=i;
len=a->length;
p=a->data;
first = 1;
bl = NULL;
while (len > 0)
{
l=0; l=0;
for (; idx<len; idx++) { use_bn = 0;
l|=p[idx]&0x7f; for (;;)
if (!(p[idx] & 0x80)) { {
BIO_snprintf(tbuf,sizeof tbuf,".%lu",l); unsigned char c = *p++;
i=strlen(tbuf); len--;
if ((len == 0) && (c & 0x80))
goto err;
if (use_bn)
{
if (!BN_add_word(bl, c & 0x7f))
goto err;
}
else
l |= c & 0x7f;
if (!(c & 0x80))
break;
if (!use_bn && (l > (ULONG_MAX >> 7L)))
{
if (!bl && !(bl = BN_new()))
goto err;
if (!BN_set_word(bl, l))
goto err;
use_bn = 1;
}
if (use_bn)
{
if (!BN_lshift(bl, bl, 7))
goto err;
}
else
l<<=7L;
}
if (first)
{
first = 0;
if (l >= 80)
{
i = 2;
if (use_bn)
{
if (!BN_sub_word(bl, 80))
goto err;
}
else
l -= 80;
}
else
{
i=(int)(l/40);
l-=(long)(i*40);
}
if (buf && (buf_len > 0))
{
*buf++ = i + '0';
buf_len--;
}
n++;
}
if (use_bn)
{
char *bndec;
bndec = BN_bn2dec(bl);
if (!bndec)
goto err;
i = strlen(bndec);
if (buf)
{
if (buf_len > 0) if (buf_len > 0)
BUF_strlcpy(buf,tbuf,buf_len); {
buf_len-=i; *buf++ = '.';
buf_len--;
}
BUF_strlcpy(buf,bndec,buf_len);
buf += i;
}
n++;
n += i;
buf_len -= i;
OPENSSL_free(bndec);
}
else
{
BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
i=strlen(tbuf);
if (buf && (buf_len > 0))
{
BUF_strlcpy(buf,tbuf,buf_len);
buf+=i; buf+=i;
n+=i; }
l=0; buf_len-=i;
n+=i;
l=0;
} }
l<<=7L;
} }
} else {
s=OBJ_nid2ln(nid); if (bl)
if (s == NULL) BN_free(bl);
s=OBJ_nid2sn(nid); return n;
BUF_strlcpy(buf,s,buf_len);
n=strlen(s); err:
} if (bl)
return(n); BN_free(bl);
return -1;
} }
int OBJ_txt2nid(const char *s) int OBJ_txt2nid(const char *s)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册