Extensive OID code enhancement and fixes.
This commit is contained in:
parent
8c5c5b6517
commit
452ae49db5
3 changed files with 209 additions and 60 deletions
6
CHANGES
6
CHANGES
|
@ -73,6 +73,12 @@
|
|||
|
||||
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
|
||||
under VC++ build system.
|
||||
[Steve Henson]
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
@ -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 i,first,len=0,c;
|
||||
char tmp[24];
|
||||
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);
|
||||
|
@ -98,7 +101,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
|
|||
num--;
|
||||
if ((c >= '0') && (c <= '2'))
|
||||
{
|
||||
first=(c-'0')*40;
|
||||
first= c-'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -122,6 +125,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
|
|||
goto err;
|
||||
}
|
||||
l=0;
|
||||
use_bn = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (num <= 0) break;
|
||||
|
@ -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);
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
goto err;
|
||||
}
|
||||
l+=(long)first;
|
||||
if (use_bn)
|
||||
{
|
||||
if (!BN_add_word(bl, first * 40))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
l+=(long)first*40;
|
||||
}
|
||||
i=0;
|
||||
for (;;)
|
||||
if (use_bn)
|
||||
{
|
||||
tmp[i++]=(unsigned char)l&0x7f;
|
||||
l>>=7L;
|
||||
if (l == 0L) break;
|
||||
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++] = BN_div_word(bl, 0x80L);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (;;)
|
||||
{
|
||||
tmp[i++]=(unsigned char)l&0x7f;
|
||||
l>>=7L;
|
||||
if (l == 0L) break;
|
||||
}
|
||||
|
||||
}
|
||||
if (out != NULL)
|
||||
{
|
||||
|
@ -166,8 +213,16 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
char buf[80];
|
||||
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)) i=sizeof buf;
|
||||
BIO_write(bp,buf,i);
|
||||
if (i > (int)(sizeof(buf) - 1))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
@ -413,8 +414,8 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
|
|||
/* Work out size of content octets */
|
||||
i=a2d_ASN1_OBJECT(NULL,0,s,-1);
|
||||
if (i <= 0) {
|
||||
/* Clear the error */
|
||||
ERR_clear_error();
|
||||
/* Don't clear the error */
|
||||
/*ERR_clear_error();*/
|
||||
return NULL;
|
||||
}
|
||||
/* Work out total size */
|
||||
|
@ -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 i,idx=0,n=0,len,nid;
|
||||
int i,n=0,len,nid, first, use_bn;
|
||||
BIGNUM *bl;
|
||||
unsigned long l;
|
||||
unsigned char *p;
|
||||
const char *s;
|
||||
char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
|
||||
|
||||
if (buf_len <= 0) return(0);
|
||||
|
||||
if ((a == NULL) || (a->data == NULL)) {
|
||||
buf[0]='\0';
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (no_name || (nid=OBJ_obj2nid(a)) == NID_undef) {
|
||||
len=a->length;
|
||||
p=a->data;
|
||||
|
||||
idx=0;
|
||||
l=0;
|
||||
while (idx < a->length) {
|
||||
l|=(p[idx]&0x7f);
|
||||
if (!(p[idx] & 0x80)) break;
|
||||
l<<=7L;
|
||||
idx++;
|
||||
}
|
||||
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;
|
||||
|
||||
l=0;
|
||||
for (; idx<len; idx++) {
|
||||
l|=p[idx]&0x7f;
|
||||
if (!(p[idx] & 0x80)) {
|
||||
BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
|
||||
i=strlen(tbuf);
|
||||
if (buf_len > 0)
|
||||
BUF_strlcpy(buf,tbuf,buf_len);
|
||||
buf_len-=i;
|
||||
buf+=i;
|
||||
n+=i;
|
||||
l=0;
|
||||
}
|
||||
l<<=7L;
|
||||
}
|
||||
} else {
|
||||
if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
|
||||
{
|
||||
const char *s;
|
||||
s=OBJ_nid2ln(nid);
|
||||
if (s == NULL)
|
||||
s=OBJ_nid2sn(nid);
|
||||
BUF_strlcpy(buf,s,buf_len);
|
||||
if (buf)
|
||||
BUF_strlcpy(buf,s,buf_len);
|
||||
n=strlen(s);
|
||||
}
|
||||
return(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
len=a->length;
|
||||
p=a->data;
|
||||
|
||||
first = 1;
|
||||
bl = NULL;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
l=0;
|
||||
use_bn = 0;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char c = *p++;
|
||||
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)
|
||||
{
|
||||
*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_len-=i;
|
||||
n+=i;
|
||||
l=0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return n;
|
||||
|
||||
err:
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int OBJ_txt2nid(const char *s)
|
||||
|
|
Loading…
Reference in a new issue