aboutsummaryrefslogtreecommitdiff
path: root/crypto/objects/obj_dat.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2005-11-20 13:07:47 +0000
committerDr. Stephen Henson <steve@openssl.org>2005-11-20 13:07:47 +0000
commit452ae49db5444f61fd643507fe71e4ac41ecfb1c (patch)
tree675545ea2056602925e6feccf4639183eb007303 /crypto/objects/obj_dat.c
parent8c5c5b651725916cd690f7fabf04c4f7bfe4afbb (diff)
downloadopenssl-452ae49db5444f61fd643507fe71e4ac41ecfb1c.zip
openssl-452ae49db5444f61fd643507fe71e4ac41ecfb1c.tar.gz
openssl-452ae49db5444f61fd643507fe71e4ac41ecfb1c.tar.bz2
Extensive OID code enhancement and fixes.
Diffstat (limited to 'crypto/objects/obj_dat.c')
-rw-r--r--crypto/objects/obj_dat.c170
1 files changed, 125 insertions, 45 deletions
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index e56f3de..9c61829 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -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++;
+ if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
+ {
+ const char *s;
+ s=OBJ_nid2ln(nid);
+ if (s == NULL)
+ s=OBJ_nid2sn(nid);
+ 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;
- for (; idx<len; idx++) {
- l|=p[idx]&0x7f;
- if (!(p[idx] & 0x80)) {
- BIO_snprintf(tbuf,sizeof tbuf,".%lu",l);
- i=strlen(tbuf);
+ 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_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;
- n+=i;
- l=0;
+ }
+ buf_len-=i;
+ n+=i;
+ l=0;
}
- l<<=7L;
}
- } else {
- s=OBJ_nid2ln(nid);
- if (s == NULL)
- s=OBJ_nid2sn(nid);
- BUF_strlcpy(buf,s,buf_len);
- n=strlen(s);
- }
- return(n);
+
+ if (bl)
+ BN_free(bl);
+ return n;
+
+ err:
+ if (bl)
+ BN_free(bl);
+ return -1;
}
int OBJ_txt2nid(const char *s)