- int i,idx=0,n=0,len,nid;
- unsigned long l;
- unsigned char *p;
- const char *s;
- char tbuf[32];
-
- if (buf_len <= 0) return(0);
-
- if ((a == NULL) || (a->data == NULL)) {
- buf[0]='\0';
- return(0);
- }
-
- nid=OBJ_obj2nid(a);
- if ((nid == NID_undef) || no_name) {
- 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);
-
- sprintf(tbuf,"%d.%lu",i,l);
- i=strlen(tbuf);
- strncpy(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)) {
- sprintf(tbuf,".%lu",l);
- i=strlen(tbuf);
- if (buf_len > 0)
- strncpy(buf,tbuf,buf_len);
- buf_len-=i;
- buf+=i;
- n+=i;
- l=0;
- }
- l<<=7L;
- }
- } else {
- s=OBJ_nid2ln(nid);
- if (s == NULL)
- s=OBJ_nid2sn(nid);
- strncpy(buf,s,buf_len);
- n=strlen(s);
- }
- buf[buf_len-1]='\0';
- return(n);
+ int nid = NID_undef;
+ ASN1_OBJECT *op = NULL;
+ unsigned char *buf;
+ unsigned char *p;
+ const unsigned char *cp;
+ int i, j;
+
+ if (!no_name) {
+ if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
+ ((nid = OBJ_ln2nid(s)) != NID_undef))
+ return OBJ_nid2obj(nid);
+ }
+
+ /* Work out size of content octets */
+ i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
+ if (i <= 0) {
+ /* Don't clear the error */
+ /*
+ * ERR_clear_error();
+ */
+ return NULL;
+ }
+ /* Work out total size */
+ j = ASN1_object_size(0, i, V_ASN1_OBJECT);
+
+ if ((buf = OPENSSL_malloc(j)) == NULL)
+ return NULL;
+
+ p = buf;
+ /* Write out tag+length */
+ ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+ /* Write out contents */
+ a2d_ASN1_OBJECT(p, i, s, -1);
+
+ cp = buf;
+ op = d2i_ASN1_OBJECT(NULL, &cp, j);
+ OPENSSL_free(buf);
+ return op;
+}
+
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
+{
+ int i, n = 0, len, nid, first, use_bn;
+ BIGNUM *bl;
+ unsigned long l;
+ const unsigned char *p;
+ char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
+
+ /* Ensure that, at every state, |buf| is NUL-terminated. */
+ if (buf && buf_len > 0)
+ buf[0] = '\0';
+
+ if ((a == NULL) || (a->data == NULL))
+ return (0);
+
+ if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
+ const char *s;
+ s = OBJ_nid2ln(nid);
+ if (s == NULL)
+ s = OBJ_nid2sn(nid);
+ if (s) {
+ if (buf)
+ OPENSSL_strlcpy(buf, s, buf_len);
+ n = strlen(s);
+ 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 == NULL && (bl = BN_new()) == NULL)
+ 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 > 1)) {
+ *buf++ = i + '0';
+ *buf = '\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 > 1) {
+ *buf++ = '.';
+ *buf = '\0';
+ buf_len--;
+ }
+ OPENSSL_strlcpy(buf, bndec, buf_len);
+ if (i > buf_len) {
+ buf += buf_len;
+ buf_len = 0;
+ } else {
+ buf += i;
+ buf_len -= i;
+ }
+ }
+ n++;
+ n += i;
+ OPENSSL_free(bndec);
+ } else {
+ BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
+ i = strlen(tbuf);
+ if (buf && (buf_len > 0)) {
+ OPENSSL_strlcpy(buf, tbuf, buf_len);
+ if (i > buf_len) {
+ buf += buf_len;
+ buf_len = 0;
+ } else {
+ buf += i;
+ buf_len -= i;
+ }
+ }
+ n += i;
+ l = 0;
+ }
+ }
+
+ BN_free(bl);
+ return n;
+
+ err:
+ BN_free(bl);
+ return -1;