예제 #1
1
파일: validate.c 프로젝트: 0neday/xpwn
static int
extract2Certs(const unsigned char *p, long length, X509 **x1, X509 **x2)
{
	const unsigned char *cert1;
	const unsigned char *cert2;

	long len1, len2;
	int j, tag, xclass;

	cert1 = p;
	j = ASN1_get_object(&p, &len1, &tag, &xclass, length);
	if (j != V_ASN1_CONSTRUCTED) {
		return -1;
	}
	p += len1;
	len1 = p - cert1;
	if (len1 >= length) {
		return -1;
	}
	*x1 = d2i_X509(NULL, &cert1, len1);
	if (!*x1) {
		return -1;
	}
	length -= len1;

	cert2 = p;
	j = ASN1_get_object(&p, &len2, &tag, &xclass, length);
	if (j != V_ASN1_CONSTRUCTED) {
		X509_free(*x1);
		return -1;
	}
	p += len2;
	len2 = p - cert2;
	if (len2 > length) {
		X509_free(*x1);
		return -1;
	}
	*x2 = d2i_X509(NULL, &cert2, len2);
	if (!*x2) {
		X509_free(*x1);
		return -1;
	}

	return 0;
}
예제 #2
0
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
	{
	int ret= -1;
	const unsigned char *p;
	long len;
	int inf,tag,xclass;
	int i=0;

	p= *pp;
	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
	if (inf & 0x80)
		{
		i=ASN1_R_BAD_OBJECT_HEADER;
		goto err;
		}

	if (tag != V_ASN1_BOOLEAN)
		{
		i=ASN1_R_EXPECTING_A_BOOLEAN;
		goto err;
		}

	if (len != 1)
		{
		i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
		goto err;
		}
	ret= (int)*(p++);
	if (a != NULL) (*a)=ret;
	*pp=p;
	return(ret);
err:
	ASN1err(ASN1_F_D2I_ASN1_BOOLEAN,i);
	return(ret);
	}
예제 #3
0
ASN1_OBJECT *
d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length)
{
	const unsigned char *p;
	long len;
	int tag, xclass;
	int inf, i;
	ASN1_OBJECT *ret = NULL;

	p = *pp;
	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
	if (inf & 0x80) {
		i = ASN1_R_BAD_OBJECT_HEADER;
		goto err;
	}

	if (tag != V_ASN1_OBJECT) {
		i = ASN1_R_EXPECTING_AN_OBJECT;
		goto err;
	}
	ret = c2i_ASN1_OBJECT(a, &p, len);
	if (ret)
		*pp = p;
	return ret;

err:
	ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
	return (NULL);
}
예제 #4
0
ASN1_INTEGER *
d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
{
	ASN1_INTEGER *ret = NULL;
	const unsigned char *p;
	unsigned char *s;
	long len;
	int inf, tag, xclass;
	int i;

	if ((a == NULL) || ((*a) == NULL)) {
		if ((ret = M_ASN1_INTEGER_new()) == NULL)
			return (NULL);
		ret->type = V_ASN1_INTEGER;
	} else
		ret = (*a);

	p = *pp;
	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
	if (inf & 0x80) {
		i = ASN1_R_BAD_OBJECT_HEADER;
		goto err;
	}

	if (tag != V_ASN1_INTEGER) {
		i = ASN1_R_EXPECTING_AN_INTEGER;
		goto err;
	}

	/* We must malloc stuff, even for 0 bytes otherwise it
	 * signifies a missing NULL parameter. */
	s = malloc((int)len + 1);
	if (s == NULL) {
		i = ERR_R_MALLOC_FAILURE;
		goto err;
	}
	ret->type = V_ASN1_INTEGER;
	if (len) {
		if ((*p == 0) && (len != 1)) {
			p++;
			len--;
		}
		memcpy(s, p, len);
		p += len;
	}

	free(ret->data);
	ret->data = s;
	ret->length = (int)len;
	if (a != NULL)
		(*a) = ret;
	*pp = p;
	return (ret);

err:
	ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
	if (a == NULL || *a != ret)
		M_ASN1_INTEGER_free(ret);
	return (NULL);
}
예제 #5
0
static size_t
get_extension_by_object (X509 *x509, ASN1_OBJECT *obj, char **output)
{
	int pos = X509_get_ext_by_OBJ (x509, obj, -1);
	if (pos < 0) {
		return 0;
	}
	X509_EXTENSION *ext = X509_get_ext (x509, pos);

	int tag;
	long len;
	int tc;
	const unsigned char *p = ext->value->data;

	ASN1_get_object (&p, &len, &tag, &tc, ext->value->length);

	size_t size;
	switch (tag) {
		case V_ASN1_UTF8STRING:
			{
				ASN1_UTF8STRING *str =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_UTF8STRING));
				*output = strndup ((const char *)
						   ASN1_STRING_data (str),
						   str->length);
				size = str->length;
				ASN1_UTF8STRING_free (str);
				return size;
			}
		case V_ASN1_OCTET_STRING:
			{
				ASN1_OCTET_STRING *octstr =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_OCTET_STRING));
				*output = malloc (octstr->length);
				memcpy (*output, octstr->data, octstr->length);
				size = octstr->length;
				ASN1_OCTET_STRING_free (octstr);
				return size;
			}
		default:
			{
				BIO *bio = BIO_new (BIO_s_mem ());
				X509V3_EXT_print (bio, ext, 0, 0);

				size_t size = BIO_ctrl_pending (bio);
				char *buf = malloc (sizeof (char) * size);
				BIO_read (bio, buf, size);
				*output = buf;
				BIO_free (bio);
				return size;
			}
	}
}
예제 #6
0
int findoffset(char *dbname)
{
    DB *db;
    DBT dkey, dvalue;
    int result;
    int offset = 0;
    char *p;
    int ptag = 0, pclass, plen;
    X509 *mycert;

    if((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
    {
        fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
        exit(1);
    }
    while((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0)
    {
        if((dvalue.size) > 520)
        {
            while(offset < dvalue.size)
            {
                p = (char *)dvalue.data + offset - 1;
                ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
                if(ptag == V_ASN1_SEQUENCE)
                { /* ok, it might be a cert then. */
                    /* include length of object header junk */
                    plen += p - ((char *)dvalue.data + offset - 1);
                    mycert = NULL;
                    p = (char *)dvalue.data + offset - 1;
                    d2i_X509(&mycert, (unsigned char **)&p, plen);
                    if(mycert == NULL)
                    { /* must be garbage after all */
                        offset++;
                        continue;
                    }
                    break;
                }
                else
                    offset++;
            }
            if(offset > 0)
                break; /* found it, let's quit */
        }
    }
    db->close(db);
    return (offset);
}
예제 #7
0
파일: a_d2i_fp.c 프로젝트: 4ker/openssl
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
    BUF_MEM *b;
    unsigned char *p;
    int i;
    size_t want = HEADER_SIZE;
    int eos = 0;
    size_t off = 0;
    size_t len = 0;

    const unsigned char *q;
    long slen;
    int inf, tag, xclass;

    b = BUF_MEM_new();
    if (b == NULL) {
        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
        return -1;
    }

    ERR_clear_error();
    for (;;) {
        if (want >= (len - off)) {
            want -= (len - off);

            if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            i = BIO_read(in, &(b->data[len]), want);
            if ((i < 0) && ((len - off) == 0)) {
                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
                goto err;
            }
            if (i > 0) {
                if (len + i < len) {
                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
                    goto err;
                }
                len += i;
            }
        }
        /* else data already loaded */

        p = (unsigned char *)&(b->data[off]);
        q = p;
        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
        if (inf & 0x80) {
            unsigned long e;

            e = ERR_GET_REASON(ERR_peek_error());
            if (e != ASN1_R_TOO_LONG)
                goto err;
            else
                ERR_clear_error(); /* clear error */
        }
        i = q - p;            /* header length */
        off += i;               /* end of data */

        if (inf & 1) {
            /* no data body so go round again */
            eos++;
            if (eos < 0) {
                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
                goto err;
            }
            want = HEADER_SIZE;
        } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
            /* eos value, so go back and read another header */
            eos--;
            if (eos <= 0)
                break;
            else
                want = HEADER_SIZE;
        } else {
            /* suck in slen bytes of data */
            want = slen;
            if (want > (len - off)) {
                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;

                want -= (len - off);
                if (want > INT_MAX /* BIO_read takes an int length */  ||
                    len + want < len) {
                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
                    goto err;
                }
                while (want > 0) {
                    /*
                     * Read content in chunks of increasing size
                     * so we can return an error for EOF without
                     * having to allocate the entire content length
                     * in one go.
                     */
                    size_t chunk = want > chunk_max ? chunk_max : want;

                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
                        goto err;
                    }
                    want -= chunk;
                    while (chunk > 0) {
                        i = BIO_read(in, &(b->data[len]), chunk);
                        if (i <= 0) {
                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
                                    ASN1_R_NOT_ENOUGH_DATA);
                            goto err;
                        }
                    /*
                     * This can't overflow because |len+want| didn't
                     * overflow.
                     */
                        len += i;
                        chunk -= i;
                    }
                    if (chunk_max < INT_MAX/2)
                        chunk_max *= 2;
                }
            }
            if (off + slen < off) {
                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
                goto err;
            }
            off += slen;
            if (eos <= 0) {
                break;
            } else
                want = HEADER_SIZE;
        }
    }

    if (off > INT_MAX) {
        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
        goto err;
    }

    *pb = b;
    return off;
 err:
    BUF_MEM_free(b);
    return -1;
}
예제 #8
0
파일: ossl_asn1.c 프로젝트: DocPsy/MacRuby
static VALUE
ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
		  int once, int yield)
{
    unsigned char *start, *p;
    const unsigned char *p0;
    long len, off = *offset;
    int hlen, tag, tc, j;
    VALUE ary, asn1data, value, tag_class;

    ary = rb_ary_new();
    p = *pp;
    while(length > 0){
	start = p;
	p0 = p;
	j = ASN1_get_object(&p0, &len, &tag, &tc, length);
	p = (unsigned char *)p0;
	if(j & 0x80) ossl_raise(eASN1Error, NULL);
	hlen = p - start;
	if(yield){
	    VALUE arg = rb_ary_new();
	    rb_ary_push(arg, LONG2NUM(depth));
	    rb_ary_push(arg, LONG2NUM(off));
	    rb_ary_push(arg, LONG2NUM(hlen));
	    rb_ary_push(arg, LONG2NUM(len));
	    rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
	    rb_ary_push(arg, ossl_asn1_class2sym(tc));
	    rb_ary_push(arg, INT2NUM(tag));
	    rb_yield(arg);
	}
	length -= hlen;
	off += hlen;
	if(len > length) ossl_raise(eASN1Error, "value is too short");
	if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
	    tag_class = sPRIVATE;
	else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
	    tag_class = sCONTEXT_SPECIFIC;
	else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
	    tag_class = sAPPLICATION;
	else
	    tag_class = sUNIVERSAL;
	if(j & V_ASN1_CONSTRUCTED){
	    /* TODO: if j == 0x21 it is indefinite length object. */
	    if((j == 0x21) && (len == 0)){
		long lastoff = off;
		value = ossl_asn1_decode0(&p, length, &off, depth+1, 0, yield);
		len = off - lastoff;
	    }
	    else value = ossl_asn1_decode0(&p, len, &off, depth+1, 0, yield);
	}
	else{
	    value = rb_str_new((const char *)p, len);
	    p += len;
	    off += len;
	}
	if(tag_class == sUNIVERSAL &&
	   tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass){
	    VALUE klass = *ossl_asn1_info[tag].klass;
	    long flag = 0;
	    if(!rb_obj_is_kind_of(value, rb_cArray)){
		switch(tag){
		case V_ASN1_BOOLEAN:
		    value = decode_bool(start, hlen+len);
		    break;
		case V_ASN1_INTEGER:
		    value = decode_int(start, hlen+len);
		    break;
		case V_ASN1_BIT_STRING:
		    value = decode_bstr(start, hlen+len, &flag);
		    break;
		case V_ASN1_NULL:
		    value = decode_null(start, hlen+len);
		    break;
		case V_ASN1_ENUMERATED:
		    value = decode_enum(start, hlen+len);
		    break;
		case V_ASN1_OBJECT:
		    value = decode_obj(start, hlen+len);
		    break;
		case V_ASN1_UTCTIME:           /* FALLTHROUGH */
		case V_ASN1_GENERALIZEDTIME:
		    value = decode_time(start, hlen+len);
		    break;
		default:
		    /* use original value */
		    break;
		}
	    }
	    asn1data = rb_funcall(klass, rb_intern("new"), 1, value);
	    if(tag == V_ASN1_BIT_STRING){
		rb_iv_set(asn1data, "@unused_bits", LONG2NUM(flag));
	    }
	}
	else{
	    asn1data = rb_funcall(cASN1Data, rb_intern("new"), 3,
				  value, INT2NUM(tag), ID2SYM(tag_class));
	}
	rb_ary_push(ary, asn1data);
	length -= len;
        if(once) break;
    }
    *pp = p;
    *offset = off;

    return ary;
}
예제 #9
0
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
	{
	BUF_MEM *b;
	unsigned char *p;
	int i;
	int ret=-1;
	ASN1_const_CTX c;
	int want=HEADER_SIZE;
	int eos=0;
#if defined(__GNUC__) && defined(__ia64)
	/* pathetic compiler bug in all known versions as of Nov. 2002 */
	long off=0;
#else
	int off=0;
#endif
	int len=0;

	b=BUF_MEM_new();
	if (b == NULL)
		{
		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
		return -1;
		}

	ERR_clear_error();
	for (;;)
		{
		if (want >= (len-off))
			{
			want-=(len-off);

			if (!BUF_MEM_grow_clean(b,len+want))
				{
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
				goto err;
				}
			i=BIO_read(in,&(b->data[len]),want);
			if ((i < 0) && ((len-off) == 0))
				{
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
				goto err;
				}
			if (i > 0)
				len+=i;
			}
		/* else data already loaded */

		p=(unsigned char *)&(b->data[off]);
		c.p=p;
		c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
			len-off);
		if (c.inf & 0x80)
			{
			unsigned long e;

			e=ERR_GET_REASON(ERR_peek_error());
			if (e != ASN1_R_TOO_LONG)
				goto err;
			else
				ERR_clear_error(); /* clear error */
			}
		i=(int)(c.p-p);/* header length */
		off+=i;	/* end of data */

		if (c.inf & 1)
			{
			/* no data body so go round again */
			eos++;
			want=HEADER_SIZE;
			}
		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
			{
			/* eos value, so go back and read another header */
			eos--;
			if (eos <= 0)
				break;
			else
				want=HEADER_SIZE;
			}
		else 
			{
			/* suck in c.slen bytes of data */
			want=(int)c.slen;
			if (want > (len-off))
				{
				want-=(len-off);
				if (!BUF_MEM_grow_clean(b,len+want))
					{
					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
					goto err;
					}
				while (want > 0)
					{
					i=BIO_read(in,&(b->data[len]),want);
					if (i <= 0)
						{
						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
						    ASN1_R_NOT_ENOUGH_DATA);
						goto err;
						}
					len+=i;
					want -= i;
					}
				}
			off+=(int)c.slen;
			if (eos <= 0)
				{
				break;
				}
			else
				want=HEADER_SIZE;
			}
		}

	*pb = b;
	return off;
err:
	if (b != NULL) BUF_MEM_free(b);
	return(ret);
	}
예제 #10
0
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
	{
	ASN1_TYPE *ret;
	tag_exp_arg asn1_tags;
	tag_exp_type *etmp;

	int i, len;

	unsigned char *orig_der = NULL, *new_der = NULL;
	const unsigned char *cpy_start;
	unsigned char *p;
	const unsigned char *cp;
	int cpy_len;
	long hdr_len;
	int hdr_constructed = 0, hdr_tag, hdr_class;
	int r;

	asn1_tags.imp_tag = -1;
	asn1_tags.imp_class = -1;
	asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
	asn1_tags.exp_count = 0;
	if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
		return NULL;

	if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET))
		{
		if (!cnf)
			{
			ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
			return NULL;
			}
		ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
		}
	else
		ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);

	if (!ret)
		return NULL;

	/* If no tagging return base type */
	if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
		return ret;

	/* Generate the encoding */
	cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
	ASN1_TYPE_free(ret);
	ret = NULL;
	/* Set point to start copying for modified encoding */
	cpy_start = orig_der;

	/* Do we need IMPLICIT tagging? */
	if (asn1_tags.imp_tag != -1)
		{
		/* If IMPLICIT we will replace the underlying tag */
		/* Skip existing tag+len */
		r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len);
		if (r & 0x80)
			goto err;
		/* Update copy length */
		cpy_len -= (int)(cpy_start - orig_der);
		/* For IMPLICIT tagging the length should match the
		 * original length and constructed flag should be
		 * consistent.
		 */
		if (r & 0x1)
			{
			/* Indefinite length constructed */
			hdr_constructed = 2;
			hdr_len = 0;
			}
		else
			/* Just retain constructed flag */
			hdr_constructed = r & V_ASN1_CONSTRUCTED;
		/* Work out new length with IMPLICIT tag: ignore constructed
		 * because it will mess up if indefinite length
		 */
		len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
		}
	else
		len = cpy_len;

	/* Work out length in any EXPLICIT, starting from end */

	for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--)
		{
		/* Content length: number of content octets + any padding */
		len += etmp->exp_pad;
		etmp->exp_len = len;
		/* Total object length: length including new header */
		len = ASN1_object_size(0, len, etmp->exp_tag);
		}

	/* Allocate buffer for new encoding */

	new_der = OPENSSL_malloc(len);

	/* Generate tagged encoding */

	p = new_der;

	/* Output explicit tags first */

	for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++)
		{
		ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
					etmp->exp_tag, etmp->exp_class);
		if (etmp->exp_pad)
			*p++ = 0;
		}

	/* If IMPLICIT, output tag */

	if (asn1_tags.imp_tag != -1)
		ASN1_put_object(&p, hdr_constructed, hdr_len,
					asn1_tags.imp_tag, asn1_tags.imp_class);

	/* Copy across original encoding */
	memcpy(p, cpy_start, cpy_len);

	cp = new_der;

	/* Obtain new ASN1_TYPE structure */
	ret = d2i_ASN1_TYPE(NULL, &cp, len);

	err:
	if (orig_der)
		OPENSSL_free(orig_der);
	if (new_der)
		OPENSSL_free(new_der);

	return ret;

	}
예제 #11
0
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, dump_cont = 0;

    if (depth > ASN1_PARSE_MAXDEPTH) {
            BIO_puts(bp, "BAD RECURSION DEPTH\n");
            return 0;
    }

    dump_indent = 6;            /* Because we know BIO_dump_indent() */
    p = *pp;
    tot = p + length;
    while (length > 0) {
        op = p;
        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
        if (j & 0x80) {
            if (BIO_write(bp, "Error in encoding\n", 18) <= 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) {
            const unsigned char *sp = p;

            ep = p + len;
            if (BIO_write(bp, "\n", 1) <= 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)) {
                        len = p - sp;
                        break;
                    }
                }
            } else {
                long tmp = len;

                while (p < ep) {
                    sp = p;
                    r = asn1_parse2(bp, &p, tmp,
                                    offset + (p - *pp), depth + 1,
                                    indent, dump);
                    if (r == 0) {
                        ret = 0;
                        goto end;
                    }
                    tmp -= p - sp;
                }
            }
        } else if (xclass != 0) {
            p += len;
            if (BIO_write(bp, "\n", 1) <= 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_write(bp, ":", 1) <= 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_write(bp, ":", 1) <= 0)
                        goto end;
                    i2a_ASN1_OBJECT(bp, o);
                } else {
                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
                        goto end;
                    dump_cont = 1;
                }
            } else if (tag == V_ASN1_BOOLEAN) {
                if (len != 1) {
                    if (BIO_puts(bp, ":BAD BOOLEAN") <= 0)
                        goto end;
                    dump_cont = 1;
                }
                if (len > 0)
                    BIO_printf(bp, ":%u", p[0]);
            } 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_write(bp, ":", 1) <= 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_write(bp, "[HEX DUMP]:", 11) <= 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_write(bp, "\n", 1) <= 0)
                                goto end;
                        }
                        if (BIO_dump_indent(bp,
                                            (const char *)opp,
                                            ((dump == -1 || dump >
                                              os->
                                              length) ? os->length : dump),
                                            dump_indent) <= 0)
                            goto end;
                        nl = 1;
                    }
                }
                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_write(bp, ":", 1) <= 0)
                        goto end;
                    if (bs->type == V_ASN1_NEG_INTEGER)
                        if (BIO_write(bp, "-", 1) <= 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_write(bp, "00", 2) <= 0)
                            goto end;
                    }
                } else {
                    if (BIO_puts(bp, ":BAD INTEGER") <= 0)
                        goto end;
                    dump_cont = 1;
                }
                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_write(bp, ":", 1) <= 0)
                        goto end;
                    if (bs->type == V_ASN1_NEG_ENUMERATED)
                        if (BIO_write(bp, "-", 1) <= 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_write(bp, "00", 2) <= 0)
                            goto end;
                    }
                } else {
                    if (BIO_puts(bp, ":BAD ENUMERATED") <= 0)
                        goto end;
                    dump_cont = 1;
                }
                ASN1_ENUMERATED_free(bs);
            } else if (len > 0 && dump) {
                if (!nl) {
                    if (BIO_write(bp, "\n", 1) <= 0)
                        goto end;
                }
                if (BIO_dump_indent(bp, (const char *)p,
                                    ((dump == -1 || dump > len) ? len : dump),
                                    dump_indent) <= 0)
                    goto end;
                nl = 1;
            }
            if (dump_cont) {
                int i;
                const unsigned char *tmp = op + hl;
                if (BIO_puts(bp, ":[") <= 0)
                    goto end;
                for (i = 0; i < len; i++) {
                    if (BIO_printf(bp, "%02X", tmp[i]) <= 0)
                        goto end;
                }
                if (BIO_puts(bp, "]") <= 0)
                    goto end;
            }

            if (!nl) {
                if (BIO_write(bp, "\n", 1) <= 0)
                    goto end;
            }
            p += len;
            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
                ret = 2;        /* End of sequence */
                goto end;
            }
        }
        length -= len;
    }
    ret = 1;
 end:
    ASN1_OBJECT_free(o);
    ASN1_OCTET_STRING_free(os);
    *pp = p;
    return (ret);
}
예제 #12
0
파일: a_set.c 프로젝트: imgits/rkanalyzer
STACK *d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
		    d2i_of_void *d2i, void (*free_func)(void *), int ex_tag,
		    int ex_class)
	{
	ASN1_const_CTX c;
	STACK *ret=NULL;

	if ((a == NULL) || ((*a) == NULL))
		{
		if ((ret=sk_new_null()) == NULL)
			{
			ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		}
	else
		ret=(*a);

	c.p= *pp;
	c.max=(length == 0)?0:(c.p+length);

	c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,(long)(c.max-c.p));
	if (c.inf & 0x80) goto err;
	if (ex_class != c.xclass)
		{
		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);
		goto err;
		}
	if (ex_tag != c.tag)
		{
		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);
		goto err;
		}
	if ((c.slen+c.p) > c.max)
		{
		ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);
		goto err;
		}
	/* check for infinite constructed - it can be as long
	 * as the amount of data passed to us */
	if (c.inf == (V_ASN1_CONSTRUCTED+1))
		c.slen=(long)(length+ *pp-c.p);
	c.max=c.p+c.slen;

	while (c.p < c.max)
		{
		char *s;

		if (M_ASN1_D2I_end_sequence()) break;
		/* XXX: This was called with 4 arguments, incorrectly, it seems
		   if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */
		if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
			{
			ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
			asn1_add_error(*pp,(int)(c.q- *pp));
			goto err;
			}
		if (!sk_push(ret,s)) goto err;
		}
	if (a != NULL) (*a)=ret;
	*pp=c.p;
	return(ret);
err:
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
		{
		if (free_func != NULL)
			sk_pop_free(ret,free_func);
		else
			sk_free(ret);
		}
	return(NULL);
	}
예제 #13
0
static int GRSTasn1Parse2(BIO *bp, unsigned char **pp, long length, int offset,
	     int depth, int indent, int dump, char *treecoords,
	     struct GRSTasn1TagList taglist[], int maxtag, int *lasttag)
	{
        int sibling = 0;
        char sibtreecoords[512];

	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;
	int dump_indent;


	dump_indent = 6;	/* Because we know BIO_dump_indent() */
	p= *pp;
	tot=p+length;
	op=p-1;
	while ((p < tot) && (op < p))
		{
		op=p;
		j=ASN1_get_object(&p,&len,&tag,&xclass,length);

		if (j & 0x80)
			{
			if ((bp != NULL) && 
			    (BIO_write(bp,"Error in encoding\n",18) <= 0))
				goto end;
			ret=0;
			goto end;
			}
		hl=(p-op);
		length-=hl;

		++sibling;
		sprintf(sibtreecoords, "%s-%d", treecoords, sibling);

                GRSTasn1AddToTaglist(taglist, maxtag, lasttag, sibtreecoords,
                               (int)offset+(int)(op - *pp),
                               (int) hl, len, tag);
                               
		if (bp != NULL)
		  {
		    BIO_printf(bp, "  %s %ld %ld %d %d ", sibtreecoords,
		           (long)offset+(long)(op - *pp), hl, len, tag);

		    GRSTasn1PrintPrintable(bp, p,
//		                   &((*pp)[(long)offset+(long)(op - *pp)+hl]),
		                           (len > 30) ? 30 : len);

		    BIO_printf(bp, "\n");
		 }


		/* if j == 0x21 it is a constructed indefinite length object */
		if ((bp != NULL) &&
		    (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
			<= 0)) goto end;

		if (j != (V_ASN1_CONSTRUCTED | 1))
			{
			if ((bp != NULL) && 
			    (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
				depth,(long)hl,len) <= 0))
				goto end;
			}
		else
			{
			if ((bp != NULL) &&
			    (BIO_printf(bp,"d=%-2d hl=%ld l=inf  ",
				depth,(long)hl) <= 0))
				goto end;
			}
		if ((bp != NULL) && 
		    !asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
			goto end;
		if (j & V_ASN1_CONSTRUCTED)
			{
			ep=p+len;
			if ((bp != NULL) &&
			    (BIO_write(bp,"\n",1) <= 0)) goto end;
			if (len > length)
				{
				if (bp != NULL) BIO_printf(bp,
					"length is greater than %ld\n",length);
				ret=0;
				goto end;
				}
			if ((j == 0x21) && (len == 0))
				{
				for (;;)
					{
					r=GRSTasn1Parse2(bp,&p,(long)(tot-p),
						offset+(p - *pp),depth+1,
						indent,dump,sibtreecoords,
						taglist, maxtag, lasttag);
					if (r == 0) { ret=0; goto end; }
					if ((r == 2) || (p >= tot)) break;
					}
				}
			else
				while (p < ep)
					{
					r=GRSTasn1Parse2(bp,&p,(long)len,
						offset+(p - *pp),depth+1,
						indent,dump,sibtreecoords,
						taglist, maxtag, lasttag);
					if (r == 0) { ret=0; goto end; }
					}
			}
		else if (xclass != 0)
			{
			p+=len;
			if ((bp != NULL) && 
			    (BIO_write(bp,"\n",1) <= 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_UTCTIME) ||
				(tag == V_ASN1_GENERALIZEDTIME))
				{
				if ((bp != NULL) &&
				    (BIO_write(bp,":",1) <= 0)) goto end;
				if ((len > 0) && (bp != NULL) &&
					BIO_write(bp,(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 (bp != NULL)
					  {
					    if (BIO_write(bp,":",1) <= 0) goto end;
					    i2a_ASN1_OBJECT(bp,o);
					  }
					}
				else
					{
					if ((bp != NULL) && 
					    (BIO_write(bp,":BAD OBJECT",11) <= 0))
						goto end;
					}
				}
			else if (tag == V_ASN1_BOOLEAN)
				{
				int ii;

				ii = (int)*p;
				if (ii < 0 || (int)len != 1)
				{
				  if ((bp != NULL) &&
				      (BIO_write(bp,"Bad boolean\n",12)))
						goto end;
				}
				if (bp != NULL) BIO_printf(bp,":%d",ii);
				}
			else if (tag == V_ASN1_BMPSTRING)
				{
				/* do the BMP thang */
				}
			else if (tag == V_ASN1_OCTET_STRING)
				{
				int i;

				opp=op;
				os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
				if (os != NULL)
					{
					opp=os->data;

					if (os->length > 0)
					  {
					    if ((bp != NULL) &&
						    (BIO_write(bp,":",1) <= 0))
							goto end;
					    if ((bp != NULL) &&
					        (GRSTasn1PrintPrintable(bp,
					                opp,
							os->length) <= 0))
							goto end;
					  }

					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 ((bp != NULL) &&
					    (BIO_write(bp,":",1) <= 0)) goto end;
					if (bs->type == V_ASN1_NEG_INTEGER)
						if ((bp != NULL) &&
						    (BIO_write(bp,"-",1) <= 0))
							goto end;
					for (i=0; i<bs->length; i++)
						{
						if ((bp != NULL) &&
						    (BIO_printf(bp,"%02X",
							bs->data[i]) <= 0))
							goto end;
						}
					if (bs->length == 0)
						{
						if ((bp != NULL) && 
						    (BIO_write(bp,"00",2) <= 0))
							goto end;
						}
					}
				else
					{
					if ((bp != NULL) && 
					    (BIO_write(bp,"BAD INTEGER",11) <= 0))
						goto end;
					}
				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 ((bp != NULL) &&
					    (BIO_write(bp,":",1) <= 0)) goto end;
					if (bs->type == V_ASN1_NEG_ENUMERATED)
						if ((bp != NULL) &&
						    (BIO_write(bp,"-",1) <= 0))
							goto end;
					for (i=0; i<bs->length; i++)
						{
						if ((bp != NULL) &&
						    (BIO_printf(bp,"%02X",
							bs->data[i]) <= 0))
							goto end;
						}
					if (bs->length == 0)
						{
						if ((bp != NULL) &&
						    (BIO_write(bp,"00",2) <= 0))
							goto end;
						}
					}
				else
					{
					if ((bp != NULL) &&
					    (BIO_write(bp,"BAD ENUMERATED",11) <= 0))
						goto end;
					}
				ASN1_ENUMERATED_free(bs);
				}
			else if (len > 0 && dump)
				{
				if (!nl) 
					{
					if ((bp != NULL) &&
					    (BIO_write(bp,"\n",1) <= 0))
						goto end;
					}
				if ((bp != NULL) &&
				    (BIO_dump_indent(bp,(char *)p,
					((dump == -1 || dump > len)?len:dump),
					dump_indent) <= 0))
					goto end;
				nl=1;
				}

			if (!nl) 
				{
				if ((bp != NULL) &&
				    (BIO_write(bp,"\n",1) <= 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) ASN1_OCTET_STRING_free(os);
	*pp=p;
	return(ret);
	}
예제 #14
0
/* type is a 'bitmap' of acceptable string types.
 */
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
	     long length, int type)
	{
	ASN1_STRING *ret=NULL;
	const unsigned char *p;
	unsigned char *s;
	long len;
	int inf,tag,xclass;
	int i=0;

	p= *pp;
	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
	if (inf & 0x80) goto err;

	if (tag >= 32)
		{
		i=ASN1_R_TAG_VALUE_TOO_HIGH;
		goto err;
		}
	if (!(ASN1_tag2bit(tag) & type))
		{
		i=ASN1_R_WRONG_TYPE;
		goto err;
		}

	/* If a bit-string, exit early */
	if (tag == V_ASN1_BIT_STRING)
		return(d2i_ASN1_BIT_STRING(a,pp,length));

	if ((a == NULL) || ((*a) == NULL))
		{
		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
		}
	else
		ret=(*a);

	if (len != 0)
		{
		s=(unsigned char *)OPENSSL_malloc((int)len+1);
		if (s == NULL)
			{
			i=ERR_R_MALLOC_FAILURE;
			goto err;
			}
		memcpy(s,p,(int)len);
		s[len]='\0';
		p+=len;
		}
	else
		s=NULL;

	if (ret->data != NULL) OPENSSL_free(ret->data);
	ret->length=(int)len;
	ret->data=s;
	ret->type=tag;
	if (a != NULL) (*a)=ret;
	*pp=p;
	return(ret);
err:
	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i);
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
		ASN1_STRING_free(ret);
	return(NULL);
	}
예제 #15
0
int main(int argc, char **argv)
{
    char *dbname;
    DB *db;
    int j;
    int offset;
    DBT dkey, dvalue;
    int result;
    char oname[40];
    int fout;
    int find;
    char *p;
    int ptag = 0, pclass, plen;
    X509 *mycert;
    char *shortname;
    char byte1, byte2;

    if(argc != 2)
    {
        fprintf(stderr, "usage: %s /path/to/netscape/cert.db\n", argv[0]);
        exit(1);
    }

    dbname = argv[1];
    offset = findoffset(dbname);
    if(offset == 0)
    {
        fprintf(stderr, "Couldn't determine cert offset in DB file '%s'\n", dbname);
        exit(1);
    }
    else
    {
        fprintf(stderr, "Ok: certificates are at offset %d\n", offset);
    }

    if((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
    {
        fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
        exit(1);
    }
    if((find = open("cert.index", O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1)
    {
        fprintf(stderr, "Failed to open Index file '%s': %s\n", "cert-index", strerror(errno));
        exit(1);
    }
    j = 0;
    byte1 = -1;
    byte2 = -1;
    while((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0)
    {
        if(dvalue.size > offset && ((dvalue.size) - offset) > 500)
        {
            p = (char *)dvalue.data + offset - 1;
            if(byte1 != -1 && byte2 != -1)
                if(byte1 != p[0] || byte2 != p[1])
                    continue;
            ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
            if(ptag == V_ASN1_SEQUENCE)
            { /* ok, it might be a cert then. */
                if(byte1 == -1 && byte2 == -1)
                {
                    byte1 = p[0];
                    byte2 = p[1];
                }
                /* include length of object header junk */
                plen += p - ((char *)dvalue.data + offset - 1);
                mycert = NULL;
                p = (char *)dvalue.data + offset - 1;
                d2i_X509(&mycert, (unsigned char **)&p, plen);
                if(mycert == NULL)
                { /* must be garbage after all */
                    continue;
                }
                j++;
                sprintf(oname, "cert.%02d.der", j);
                if((fout = open(oname, O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1)
                {
                    fprintf(stderr, "couldn't open %s\n", oname);
                    continue;
                }
                write(fout, (char *)dvalue.data + offset - 1, plen);
                close(fout);
                write(find, oname, strlen(oname));
                write(find, ": ", 2);
                shortname = (char *)dvalue.data + offset - 1 + plen;
                write(find, shortname, dvalue.size - plen - offset);
                write(find, "\n", 1);
                fprintf(stderr, "Extracted: %s (", oname);
                write(fileno(stderr), shortname, dvalue.size - plen - offset);
                fprintf(stderr, ")\n");
            }
            else
            {
                /* fprintf(stderr, "Hmmm... ptag is %d, plen is %d\n", ptag, plen); */
            }
        }
    }
    close(find);
    db->close(db);

    return (0);
}
static int asn1_parse2(BIO *bp, unsigned char **pp, long length, int offset,
	     int depth, int indent, int dump)
	{
	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
	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_write(bp,"Error in encoding\n",18) <= 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_write(bp,"\n",1) <= 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_write(bp,"\n",1) <= 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_UTCTIME) ||
				(tag == V_ASN1_GENERALIZEDTIME))
				{
				if (BIO_write(bp,":",1) <= 0) goto end;
				if ((len > 0) &&
					BIO_write(bp,(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_write(bp,":",1) <= 0) goto end;
					i2a_ASN1_OBJECT(bp,o);
					}
				else
					{
					if (BIO_write(bp,":BAD OBJECT",11) <= 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_write(bp,"Bad boolean\n",12))
						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)
					{
					opp=os->data;
					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 && (os->length > 0))
						{
						if (BIO_write(bp,":",1) <= 0)
							goto end;
						if (BIO_write(bp,(char *)opp,
							os->length) <= 0)
							goto end;
						}
					if (!printable && (os->length > 0)
						&& dump)
						{
						if (!nl) 
							{
							if (BIO_write(bp,"\n",1) <= 0)
								goto end;
							}
						if (BIO_dump_indent(bp,(char *)opp,
							((dump == -1 || dump > os->length)?os->length:dump),
							dump_indent) <= 0)
							goto end;
						nl=1;
						}
					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_write(bp,":",1) <= 0) goto end;
					if (bs->type == V_ASN1_NEG_INTEGER)
						if (BIO_write(bp,"-",1) <= 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_write(bp,"00",2) <= 0)
							goto end;
						}
					}
				else
					{
					if (BIO_write(bp,"BAD INTEGER",11) <= 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_write(bp,":",1) <= 0) goto end;
					if (bs->type == V_ASN1_NEG_ENUMERATED)
						if (BIO_write(bp,"-",1) <= 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_write(bp,"00",2) <= 0)
							goto end;
						}
					}
				else
					{
					if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
						goto end;
					}
				M_ASN1_ENUMERATED_free(bs);
				}
			else if (len > 0 && dump)
				{
				if (!nl) 
					{
					if (BIO_write(bp,"\n",1) <= 0)
						goto end;
					}
				if (BIO_dump_indent(bp,(char *)p,
					((dump == -1 || dump > len)?len:dump),
					dump_indent) <= 0)
					goto end;
				nl=1;
				}

			if (!nl) 
				{
				if (BIO_write(bp,"\n",1) <= 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);
	}
예제 #17
0
파일: validate.c 프로젝트: 0neday/xpwn
static int
asn1_parse2(const unsigned char **pp, long length, long offset, int depth)
{
	const unsigned char *p, *ep, *tot, *op;
	long len, hl;
	int j, tag, xclass, r, ret = 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);
		if (j & 0x80) {
			XLOG(0, "Error in encoding\n");
			goto end;
		}
		hl = p - op;
		length -= hl;
		/* if j == 0x21 it is a constructed indefinite length object */

		if (j & V_ASN1_CONSTRUCTED) {
			ep = p + len;
			if (len > length) {
				XLOG(0, "length is greater than %ld\n", length);
				goto end;
			}
			if (j == 0x21 && len == 0) {
				for (;;) {
					r = asn1_parse2(&p, tot - p, offset + (p - *pp), depth + 1);
					if (r == 0) {
						goto end;
					}
					if (r == 2 || p >= tot) {
						break;
					}
				}
			} else {
				if (depth == 1 && !xclass && tag == V_ASN1_SET) save_tuple(&theset, op, hl + len);
				if (depth == 1 && (xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) save_tuple(&apcert, p, len);
				while (p < ep) {
					r = asn1_parse2(&p, len, offset + (p - *pp), depth + 1);
					if (r == 0) {
						goto end;
					}
				}
			}
		} else if (xclass != 0) {
			if (show_cont(xclass, op + hl, len)) goto end;
			p += len;
		} else {
			/* DECODE HERE */
			if (depth == 1 && tag == V_ASN1_OCTET_STRING) save_tuple(&rsasig, p, len);
			/* DECODE HERE */
			p += len;
			if (tag == V_ASN1_EOC && xclass == 0) {
				ret = 2;	/* End of sequence */
				goto end;
			}
		}
		length -= len;
	}
	ret = 1;
    end:
	if (!ret) {
		free(contarray);
		contarray = NULL;
	}
	*pp = p;
	return ret;
}
예제 #18
0
파일: a_d2i_fp.c 프로젝트: benwh4/libressl
static int
asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
	BUF_MEM *b;
	unsigned char *p;
	int i;
	ASN1_const_CTX c;
	size_t want = HEADER_SIZE;
	int eos = 0;
	size_t off = 0;
	size_t len = 0;

	b = BUF_MEM_new();
	if (b == NULL) {
		ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
		return -1;
	}

	ERR_clear_error();
	for (;;) {
		if (want >= (len - off)) {
			want -= (len - off);

			if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
				goto err;
			}
			i = BIO_read(in, &(b->data[len]), want);
			if ((i < 0) && ((len - off) == 0)) {
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
				goto err;
			}
			if (i > 0) {
				if (len + i < len) {
					ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
					goto err;
				}
				len += i;
			}
		}
		/* else data already loaded */

		p = (unsigned char *) & (b->data[off]);
		c.p = p;
		c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag),
		    &(c.xclass), len - off);
		if (c.inf & 0x80) {
			unsigned long e;

			e = ERR_GET_REASON(ERR_peek_error());
			if (e != ASN1_R_TOO_LONG)
				goto err;
			else
				ERR_clear_error(); /* clear error */
		}
		i = c.p - p;	/* header length */
		off += i;	/* end of data */

		if (c.inf & 1) {
			/* no data body so go round again */
			eos++;
			if (eos < 0) {
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
				goto err;
			}
			want = HEADER_SIZE;
		} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
			/* eos value, so go back and read another header */
			eos--;
			if (eos <= 0)
				break;
			else
				want = HEADER_SIZE;
		} else {
			/* suck in c.slen bytes of data */
			want = c.slen;
			if (want > (len - off)) {
				want -= (len - off);
				if (want > INT_MAX /* BIO_read takes an int length */ ||
				    len+want < len) {
					ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
					goto err;
				}
				if (!BUF_MEM_grow_clean(b, len + want)) {
					ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
					goto err;
				}
				while (want > 0) {
					i = BIO_read(in, &(b->data[len]), want);
					if (i <= 0) {
						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
						    ASN1_R_NOT_ENOUGH_DATA);
						goto err;
					}
					/* This can't overflow because
					 * |len+want| didn't overflow. */
					len += i;
					want -= i;
				}
			}
			if (off + c.slen < off) {
				ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
				goto err;
			}
			off += c.slen;
			if (eos <= 0) {
				break;
			} else
				want = HEADER_SIZE;
		}
	}

	if (off > INT_MAX) {
		ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
		goto err;
	}

	*pb = b;
	return off;

err:
	if (b != NULL)
		BUF_MEM_free(b);
	return -1;
}
예제 #19
0
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
	     long length, int Ptag, int Pclass)
	{
	ASN1_STRING *ret=NULL;
	const unsigned char *p;
	unsigned char *s;
	long len;
	int inf,tag,xclass;
	int i=0;

	if ((a == NULL) || ((*a) == NULL))
		{
		if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
		}
	else
		ret=(*a);

	p= *pp;
	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
	if (inf & 0x80)
		{
		i=ASN1_R_BAD_OBJECT_HEADER;
		goto err;
		}

	if (tag != Ptag)
		{
		i=ASN1_R_WRONG_TAG;
		goto err;
		}

	if (inf & V_ASN1_CONSTRUCTED)
		{
		ASN1_const_CTX c;

		c.pp=pp;
		c.p=p;
		c.inf=inf;
		c.slen=len;
		c.tag=Ptag;
		c.xclass=Pclass;
		c.max=(length == 0)?0:(p+length);
		if (!asn1_collate_primitive(ret,&c)) 
			goto err; 
		else
			{
			p=c.p;
			}
		}
	else
		{
		if (len != 0)
			{
			if ((ret->length < len) || (ret->data == NULL))
				{
				if (ret->data != NULL) OPENSSL_free(ret->data);
				s=(unsigned char *)OPENSSL_malloc((int)len + 1);
				if (s == NULL)
					{
					i=ERR_R_MALLOC_FAILURE;
					goto err;
					}
				}
			else
				s=ret->data;
			memcpy(s,p,(int)len);
			s[len] = '\0';
			p+=len;
			}
		else
			{
			s=NULL;
			if (ret->data != NULL) OPENSSL_free(ret->data);
			}

		ret->length=(int)len;
		ret->data=s;
		ret->type=Ptag;
		}

	if (a != NULL) (*a)=ret;
	*pp=p;
	return(ret);
err:
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
		ASN1_STRING_free(ret);
	OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_bytes, i);
	return(NULL);
	}
예제 #20
0
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
				char *inf, char *cst,
				const unsigned char **in, long len,
				int exptag, int expclass, char opt,
				ASN1_TLC *ctx)
	{
	int i;
	int ptag, pclass;
	long plen;
	const unsigned char *p, *q;
	p = *in;
	q = p;

	if (ctx && ctx->valid)
		{
		i = ctx->ret;
		plen = ctx->plen;
		pclass = ctx->pclass;
		ptag = ctx->ptag;
		p += ctx->hdrlen;
		}
	else
		{
		i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
		if (ctx)
			{
			ctx->ret = i;
			ctx->plen = plen;
			ctx->pclass = pclass;
			ctx->ptag = ptag;
			ctx->hdrlen = p - q;
			ctx->valid = 1;
			/* If definite length, and no error, length +
			 * header can't exceed total amount of data available. 
			 */
			if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
				{
				ASN1err(ASN1_F_ASN1_CHECK_TLEN,
							ASN1_R_TOO_LONG);
				asn1_tlc_clear(ctx);
				return 0;
				}
			}
		}

	if (i & 0x80)
		{
		ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
		asn1_tlc_clear(ctx);
		return 0;
		}
	if (exptag >= 0)
		{
		if ((exptag != ptag) || (expclass != pclass))
			{
			/* If type is OPTIONAL, not an error:
			 * indicate missing type.
			 */
			if (opt) return -1;
			asn1_tlc_clear(ctx);
			ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
			return 0;
			}
		/* We have a tag and class match:
		 * assume we are going to do something with it */
		asn1_tlc_clear(ctx);
		}

	if (i & 1)
		plen = len - (p - q);

	if (inf)
		*inf = i & 1;

	if (cst)
		*cst = i & V_ASN1_CONSTRUCTED;

	if (olen)
		*olen = plen;

	if (oclass)
		*oclass = pclass;

	if (otag)
		*otag = ptag;

	*in = p;
	return 1;
	}