diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2005-11-20 13:07:47 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2005-11-20 13:07:47 +0000 |
commit | 452ae49db5444f61fd643507fe71e4ac41ecfb1c (patch) | |
tree | 675545ea2056602925e6feccf4639183eb007303 /crypto/objects | |
parent | 8c5c5b651725916cd690f7fabf04c4f7bfe4afbb (diff) |
Extensive OID code enhancement and fixes.
Diffstat (limited to 'crypto/objects')
-rw-r--r-- | crypto/objects/obj_dat.c | 170 |
1 files changed, 125 insertions, 45 deletions
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index e56f3dea09..9c61829c77 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) |