/* * DER to Ruby converters */ static VALUE decode_bool(unsigned char* der, int length) { int val; const unsigned char *p; p = der; if((val = d2i_ASN1_BOOLEAN(NULL, &p, length)) < 0) ossl_raise(eASN1Error, NULL); return val ? Qtrue : Qfalse; }
X509_EXTENSION *d2i_X509_EXTENSION(X509_EXTENSION **a, unsigned char **pp, long length) { int i; M_ASN1_D2I_vars(a,X509_EXTENSION *,X509_EXTENSION_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); M_ASN1_D2I_get(ret->object,d2i_ASN1_OBJECT); ret->netscape_hack=0; if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL|V_ASN1_BOOLEAN))) { c.q=c.p; if (d2i_ASN1_BOOLEAN(&i,&c.p,c.slen) < 0) goto err; ret->critical=i; c.slen-=(c.p-c.q); if (ret->critical == 0) ret->netscape_hack=1; } M_ASN1_D2I_get(ret->value,d2i_ASN1_OCTET_STRING); M_ASN1_D2I_Finish(a,X509_EXTENSION_free,ASN1_F_D2I_X509_EXTENSION); }
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump) { const unsigned char *p, *ep, *tot, *op, *opp; long len; int tag, xclass, ret = 0; int nl, hl, j, r; ASN1_OBJECT *o = NULL; ASN1_OCTET_STRING *os = NULL; /* ASN1_BMPSTRING *bmp=NULL; */ int dump_indent; #if 0 dump_indent = indent; #else dump_indent = 6; /* Because we know BIO_dump_indent() */ #endif if (depth > ASN1_PARSE_MAXDEPTH) { BIO_puts(bp, "BAD RECURSION DEPTH\n"); return 0; } p = *pp; tot = p + length; op = p - 1; while ((p < tot) && (op < p)) { op = p; j = ASN1_get_object(&p, &len, &tag, &xclass, length); #ifdef LINT j = j; #endif if (j & 0x80) { if (BIO_puts(bp, "Error in encoding\n") <= 0) goto end; ret = 0; goto end; } hl = (p - op); length -= hl; /* * if j == 0x21 it is a constructed indefinite length object */ if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) <= 0) goto end; if (j != (V_ASN1_CONSTRUCTED | 1)) { if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", depth, (long)hl, len) <= 0) goto end; } else { if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) goto end; } if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) goto end; if (j & V_ASN1_CONSTRUCTED) { ep = p + len; if (BIO_puts(bp, "\n") <= 0) goto end; if (len > length) { BIO_printf(bp, "length is greater than %ld\n", length); ret = 0; goto end; } if ((j == 0x21) && (len == 0)) { for (;;) { r = asn1_parse2(bp, &p, (long)(tot - p), offset + (p - *pp), depth + 1, indent, dump); if (r == 0) { ret = 0; goto end; } if ((r == 2) || (p >= tot)) break; } } else while (p < ep) { r = asn1_parse2(bp, &p, (long)len, offset + (p - *pp), depth + 1, indent, dump); if (r == 0) { ret = 0; goto end; } } } else if (xclass != 0) { p += len; if (BIO_puts(bp, "\n") <= 0) goto end; } else { nl = 0; if ((tag == V_ASN1_PRINTABLESTRING) || (tag == V_ASN1_T61STRING) || (tag == V_ASN1_IA5STRING) || (tag == V_ASN1_VISIBLESTRING) || (tag == V_ASN1_NUMERICSTRING) || (tag == V_ASN1_UTF8STRING) || (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) { if (BIO_puts(bp, ":") <= 0) goto end; if ((len > 0) && BIO_write(bp, (const char *)p, (int)len) != (int)len) goto end; } else if (tag == V_ASN1_OBJECT) { opp = op; if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) { if (BIO_puts(bp, ":") <= 0) goto end; i2a_ASN1_OBJECT(bp, o); } else { if (BIO_puts(bp, ":BAD OBJECT") <= 0) goto end; } } else if (tag == V_ASN1_BOOLEAN) { int ii; opp = op; ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl); if (ii < 0) { if (BIO_puts(bp, "Bad boolean\n") <= 0) goto end; } BIO_printf(bp, ":%d", ii); } else if (tag == V_ASN1_BMPSTRING) { /* do the BMP thang */ } else if (tag == V_ASN1_OCTET_STRING) { int i, printable = 1; opp = op; os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl); if (os != NULL && os->length > 0) { opp = os->data; /* * testing whether the octet string is printable */ for (i = 0; i < os->length; i++) { if (((opp[i] < ' ') && (opp[i] != '\n') && (opp[i] != '\r') && (opp[i] != '\t')) || (opp[i] > '~')) { printable = 0; break; } } if (printable) /* printable string */ { if (BIO_puts(bp, ":") <= 0) goto end; if (BIO_write(bp, (const char *)opp, os->length) <= 0) goto end; } else if (!dump) /* * not printable => print octet string as hex dump */ { if (BIO_puts(bp, "[HEX DUMP]:") <= 0) goto end; for (i = 0; i < os->length; i++) { if (BIO_printf(bp, "%02X", opp[i]) <= 0) goto end; } } else /* print the normal dump */ { if (!nl) { if (BIO_puts(bp, "\n") <= 0) goto end; } if (!BIO_hexdump(bp, opp, ((dump == -1 || dump > os->length) ? os->length : dump), dump_indent)) goto end; nl = 1; } } if (os != NULL) { M_ASN1_OCTET_STRING_free(os); os = NULL; } } else if (tag == V_ASN1_INTEGER) { ASN1_INTEGER *bs; int i; opp = op; bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); if (bs != NULL) { if (BIO_puts(bp, ":") <= 0) goto end; if (bs->type == V_ASN1_NEG_INTEGER) if (BIO_puts(bp, "-") <= 0) goto end; for (i = 0; i < bs->length; i++) { if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) goto end; } if (bs->length == 0) { if (BIO_puts(bp, "00") <= 0) goto end; } } else { if (BIO_puts(bp, "BAD INTEGER") <= 0) goto end; } M_ASN1_INTEGER_free(bs); } else if (tag == V_ASN1_ENUMERATED) { ASN1_ENUMERATED *bs; int i; opp = op; bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); if (bs != NULL) { if (BIO_puts(bp, ":") <= 0) goto end; if (bs->type == V_ASN1_NEG_ENUMERATED) if (BIO_puts(bp, "-") <= 0) goto end; for (i = 0; i < bs->length; i++) { if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) goto end; } if (bs->length == 0) { if (BIO_puts(bp, "00") <= 0) goto end; } } else { if (BIO_puts(bp, "BAD ENUMERATED") <= 0) goto end; } M_ASN1_ENUMERATED_free(bs); } else if (len > 0 && dump) { if (!nl) { if (BIO_puts(bp, "\n") <= 0) goto end; } if (!BIO_hexdump(bp, p, ((dump == -1 || dump > len) ? len : dump), dump_indent)) goto end; nl = 1; } if (!nl) { if (BIO_puts(bp, "\n") <= 0) goto end; } p += len; if ((tag == V_ASN1_EOC) && (xclass == 0)) { ret = 2; /* End of sequence */ goto end; } } length -= len; } ret = 1; end: if (o != NULL) ASN1_OBJECT_free(o); if (os != NULL) M_ASN1_OCTET_STRING_free(os); *pp = p; return (ret); }