Loading crypto/asn1/tasn_dec.c +637 −355 File changed.Preview size limit exceeded, changes collapsed. Show changes crypto/asn1/tasn_enc.c +188 −118 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -79,7 +79,8 @@ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, * to use indefinite length constructed encoding, where appropriate */ int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); } Loading @@ -98,15 +99,19 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) * allocated and populated with the encoding. */ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags) static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags) { if (out && !*out) { if(out && !*out) { unsigned char *p, *buf; int len; len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); if(len <= 0) return len; if (len <= 0) return len; buf = OPENSSL_malloc(len); if(!buf) return -1; if (!buf) return -1; p = buf; ASN1_item_ex_i2d(&val, &p, it, -1, flags); *out = buf; Loading Loading @@ -138,7 +143,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; switch(it->itype) { switch(it->itype) { case ASN1_ITYPE_PRIMITIVE: if (it->templates) Loading @@ -154,7 +160,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; i = asn1_get_choice_selector(pval, it); if((i >= 0) && (i < it->tcount)) { if ((i >= 0) && (i < it->tcount)) { ASN1_VALUE **pchval; const ASN1_TEMPLATE *chtt; chtt = it->templates + i; Loading @@ -175,7 +182,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, case ASN1_ITYPE_COMPAT: /* old style hackery... */ cf = it->funcs; if(out) p = *out; if (out) p = *out; i = cf->asn1_i2d(*pval, out); /* Fixup for IMPLICIT tag: note this messes up for tags > 30, * but so did the old code. Tags > 30 are very rare anyway. Loading @@ -192,13 +200,16 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, case ASN1_ITYPE_SEQUENCE: i = asn1_enc_restore(&seqcontlen, out, pval, it); /* An error occurred */ if(i < 0) return 0; if (i < 0) return 0; /* We have a valid cached encoding... */ if(i > 0) return seqcontlen; if (i > 0) return seqcontlen; /* Otherwise carry on */ seqcontlen = 0; /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ if(tag == -1) { if (tag == -1) { tag = V_ASN1_SEQUENCE; /* Retain any other flags in aclass */ aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) Loading @@ -207,46 +218,56 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; /* First work out sequence content length */ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); if(!seqtt) return 0; if (!seqtt) return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); } seqlen = ASN1_object_size(ndef, seqcontlen, tag); if(!out) return seqlen; if (!out) return seqlen; /* Output SEQUENCE header */ ASN1_put_object(out, ndef, seqcontlen, tag, aclass); for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); if(!seqtt) return 0; if (!seqtt) return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); } if (ndef == 2) ASN1_put_eoc(out); if (ndef == 2) ASN1_put_eoc(out); if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) return 0; return seqlen; default: return 0; } return 0; } int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) { return asn1_template_ex_i2d(pval, out, tt, -1, 0); } static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass) static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass) { int i, ret, flags, ttag, tclass, ndef; flags = tt->flags; Loading Loading @@ -292,36 +313,46 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS ndef = 2; else ndef = 1; if(flags & ASN1_TFLG_SK_MASK) { if (flags & ASN1_TFLG_SK_MASK) { /* SET OF, SEQUENCE OF */ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; int isset, sktag, skaclass; int skcontlen, sklen; ASN1_VALUE *skitem; if(!*pval) return 0; if (!*pval) return 0; if(flags & ASN1_TFLG_SET_OF) { if (flags & ASN1_TFLG_SET_OF) { isset = 1; /* 2 means we reorder */ if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; } else isset = 0; if (flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; } else isset = 0; /* Work out inner tag value: if EXPLICIT * or no tagging use underlying type. */ if((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { sktag = ttag; skaclass = tclass; } else { } else { skaclass = V_ASN1_UNIVERSAL; if(isset) sktag = V_ASN1_SET; if (isset) sktag = V_ASN1_SET; else sktag = V_ASN1_SEQUENCE; } /* Determine total length of items */ skcontlen = 0; for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { skitem = sk_ASN1_VALUE_value(sk, i); skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), Loading @@ -333,7 +364,8 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS ret = ASN1_object_size(ndef, sklen, ttag); else ret = sklen; if(!out) return ret; if (!out) return ret; /* Now encode this lot... */ /* EXPLICIT tag */ Loading @@ -344,7 +376,8 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS /* And the stuff itself */ asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset, iclass); if (ndef == 2) { if (ndef == 2) { ASN1_put_eoc(out); if (flags & ASN1_TFLG_EXPTAG) ASN1_put_eoc(out); Loading @@ -353,20 +386,24 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS return ret; } if(flags & ASN1_TFLG_EXPTAG) { if (flags & ASN1_TFLG_EXPTAG) { /* EXPLICIT tagging */ /* Find length of tagged item */ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); if(!i) return 0; if (!i) return 0; /* Find length of EXPLICIT tag */ ret = ASN1_object_size(ndef, i, ttag); if(out) { if (out) { /* Output tag and item */ ASN1_put_object(out, ndef, i, ttag, tclass); ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); if (ndef == 2) ASN1_put_eoc(out); if (ndef == 2) ASN1_put_eoc(out); } return ret; } Loading @@ -391,7 +428,8 @@ static int der_cmp(const void *a, const void *b) int cmplen, i; cmplen = (d1->length < d2->length) ? d1->length : d2->length; i = memcmp(d1->data, d2->data, cmplen); if(i) return i; if (i) return i; return d1->length - d2->length; } Loading @@ -405,43 +443,56 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, ASN1_VALUE *skitem; unsigned char *tmpdat = NULL, *p = NULL; DER_ENC *derlst = NULL, *tder; if(do_sort) { if (do_sort) { /* Don't need to sort less than 2 items */ if(sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; else { derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); if (sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; else { derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); tmpdat = OPENSSL_malloc(skcontlen); if(!derlst || !tmpdat) return 0; if (!derlst || !tmpdat) return 0; } } /* If not sorting just output each item */ if(!do_sort) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { if (!do_sort) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { skitem = sk_ASN1_VALUE_value(sk, i); ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); } return 1; } p = tmpdat; /* Doing sort: build up a list of each member's DER encoding */ for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { skitem = sk_ASN1_VALUE_value(sk, i); tder->data = p; tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); tder->field = skitem; } /* Now sort them */ qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); /* Output sorted DER encoding */ p = *out; for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { memcpy(p, tder->data, tder->length); p += tder->length; } *out = p; /* If do_sort is 2 then reorder the STACK */ if(do_sort == 2) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) if (do_sort == 2) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) sk_ASN1_VALUE_set(sk, i, tder->field); } OPENSSL_free(derlst); Loading @@ -449,7 +500,8 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, return 1; } static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) { int len; int utype; Loading Loading @@ -491,8 +543,10 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A if (tag == -1) tag = utype; /* Output tag+length followed by content octets */ if(out) { if(usetag) ASN1_put_object(out, ndef, len, tag, aclass); if (out) { if (usetag) ASN1_put_object(out, ndef, len, tag, aclass); asn1_ex_i2c(pval, *out, &utype, it); if (ndef) ASN1_put_eoc(out); Loading @@ -500,13 +554,15 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A *out += len; } if(usetag) return ASN1_object_size(ndef, len, tag); if (usetag) return ASN1_object_size(ndef, len, tag); return len; } /* Produce content octets from a structure */ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) { ASN1_BOOLEAN *tbool = NULL; ASN1_STRING *strtmp; Loading @@ -516,28 +572,36 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ int len; const ASN1_PRIMITIVE_FUNCS *pf; pf = it->funcs; if(pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); if (pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); /* Should type be omitted? */ if((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { if (!*pval) return -1; } if(it->itype == ASN1_ITYPE_MSTRING) { if (it->itype == ASN1_ITYPE_MSTRING) { /* If MSTRING type set the underlying type */ strtmp = (ASN1_STRING *)*pval; utype = strtmp->type; *putype = utype; } else if(it->utype == V_ASN1_ANY) { } else if (it->utype == V_ASN1_ANY) { /* If ANY set type and pointer to value */ ASN1_TYPE *typ; typ = (ASN1_TYPE *)*pval; utype = typ->type; *putype = utype; pval = (ASN1_VALUE **)&typ->value.ptr; } else utype = *putype; } else utype = *putype; switch(utype) { switch(utype) { case V_ASN1_OBJECT: otmp = (ASN1_OBJECT *)*pval; cont = otmp->data; Loading @@ -551,17 +615,21 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ case V_ASN1_BOOLEAN: tbool = (ASN1_BOOLEAN *)pval; if(*tbool == -1) return -1; if (*tbool == -1) return -1; /* Default handling if value == size field then omit */ if(*tbool && (it->size > 0)) return -1; if(!*tbool && !it->size) return -1; if (*tbool && (it->size > 0)) return -1; if (!*tbool && !it->size) return -1; c = (unsigned char)*tbool; cont = &c; len = 1; break; case V_ASN1_BIT_STRING: return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); break; case V_ASN1_INTEGER: Loading @@ -571,7 +639,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ /* These are all have the same content format * as ASN1_INTEGER */ return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); break; case V_ASN1_OCTET_STRING: Loading Loading @@ -611,6 +680,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ break; } if(cout && len) memcpy(cout, cont, len); if (cout && len) memcpy(cout, cont, len); return len; } Loading
crypto/asn1/tasn_dec.c +637 −355 File changed.Preview size limit exceeded, changes collapsed. Show changes
crypto/asn1/tasn_enc.c +188 −118 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ * project 2000. */ /* ==================================================================== * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions Loading Loading @@ -79,7 +79,8 @@ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, * to use indefinite length constructed encoding, where appropriate */ int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) { return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); } Loading @@ -98,15 +99,19 @@ int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) * allocated and populated with the encoding. */ static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags) static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it, int flags) { if (out && !*out) { if(out && !*out) { unsigned char *p, *buf; int len; len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); if(len <= 0) return len; if (len <= 0) return len; buf = OPENSSL_malloc(len); if(!buf) return -1; if (!buf) return -1; p = buf; ASN1_item_ex_i2d(&val, &p, it, -1, flags); *out = buf; Loading Loading @@ -138,7 +143,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; switch(it->itype) { switch(it->itype) { case ASN1_ITYPE_PRIMITIVE: if (it->templates) Loading @@ -154,7 +160,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; i = asn1_get_choice_selector(pval, it); if((i >= 0) && (i < it->tcount)) { if ((i >= 0) && (i < it->tcount)) { ASN1_VALUE **pchval; const ASN1_TEMPLATE *chtt; chtt = it->templates + i; Loading @@ -175,7 +182,8 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, case ASN1_ITYPE_COMPAT: /* old style hackery... */ cf = it->funcs; if(out) p = *out; if (out) p = *out; i = cf->asn1_i2d(*pval, out); /* Fixup for IMPLICIT tag: note this messes up for tags > 30, * but so did the old code. Tags > 30 are very rare anyway. Loading @@ -192,13 +200,16 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, case ASN1_ITYPE_SEQUENCE: i = asn1_enc_restore(&seqcontlen, out, pval, it); /* An error occurred */ if(i < 0) return 0; if (i < 0) return 0; /* We have a valid cached encoding... */ if(i > 0) return seqcontlen; if (i > 0) return seqcontlen; /* Otherwise carry on */ seqcontlen = 0; /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ if(tag == -1) { if (tag == -1) { tag = V_ASN1_SEQUENCE; /* Retain any other flags in aclass */ aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) Loading @@ -207,46 +218,56 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it)) return 0; /* First work out sequence content length */ for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); if(!seqtt) return 0; if (!seqtt) return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); } seqlen = ASN1_object_size(ndef, seqcontlen, tag); if(!out) return seqlen; if (!out) return seqlen; /* Output SEQUENCE header */ ASN1_put_object(out, ndef, seqcontlen, tag, aclass); for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; ASN1_VALUE **pseqval; seqtt = asn1_do_adb(pval, tt, 1); if(!seqtt) return 0; if (!seqtt) return 0; pseqval = asn1_get_field_ptr(pval, seqtt); /* FIXME: check for errors in enhanced version */ asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); } if (ndef == 2) ASN1_put_eoc(out); if (ndef == 2) ASN1_put_eoc(out); if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it)) return 0; return seqlen; default: return 0; } return 0; } int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt) { return asn1_template_ex_i2d(pval, out, tt, -1, 0); } static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass) static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int iclass) { int i, ret, flags, ttag, tclass, ndef; flags = tt->flags; Loading Loading @@ -292,36 +313,46 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS ndef = 2; else ndef = 1; if(flags & ASN1_TFLG_SK_MASK) { if (flags & ASN1_TFLG_SK_MASK) { /* SET OF, SEQUENCE OF */ STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; int isset, sktag, skaclass; int skcontlen, sklen; ASN1_VALUE *skitem; if(!*pval) return 0; if (!*pval) return 0; if(flags & ASN1_TFLG_SET_OF) { if (flags & ASN1_TFLG_SET_OF) { isset = 1; /* 2 means we reorder */ if(flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; } else isset = 0; if (flags & ASN1_TFLG_SEQUENCE_OF) isset = 2; } else isset = 0; /* Work out inner tag value: if EXPLICIT * or no tagging use underlying type. */ if((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { sktag = ttag; skaclass = tclass; } else { } else { skaclass = V_ASN1_UNIVERSAL; if(isset) sktag = V_ASN1_SET; if (isset) sktag = V_ASN1_SET; else sktag = V_ASN1_SEQUENCE; } /* Determine total length of items */ skcontlen = 0; for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { skitem = sk_ASN1_VALUE_value(sk, i); skcontlen += ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), Loading @@ -333,7 +364,8 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS ret = ASN1_object_size(ndef, sklen, ttag); else ret = sklen; if(!out) return ret; if (!out) return ret; /* Now encode this lot... */ /* EXPLICIT tag */ Loading @@ -344,7 +376,8 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS /* And the stuff itself */ asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset, iclass); if (ndef == 2) { if (ndef == 2) { ASN1_put_eoc(out); if (flags & ASN1_TFLG_EXPTAG) ASN1_put_eoc(out); Loading @@ -353,20 +386,24 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const AS return ret; } if(flags & ASN1_TFLG_EXPTAG) { if (flags & ASN1_TFLG_EXPTAG) { /* EXPLICIT tagging */ /* Find length of tagged item */ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); if(!i) return 0; if (!i) return 0; /* Find length of EXPLICIT tag */ ret = ASN1_object_size(ndef, i, ttag); if(out) { if (out) { /* Output tag and item */ ASN1_put_object(out, ndef, i, ttag, tclass); ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); if (ndef == 2) ASN1_put_eoc(out); if (ndef == 2) ASN1_put_eoc(out); } return ret; } Loading @@ -391,7 +428,8 @@ static int der_cmp(const void *a, const void *b) int cmplen, i; cmplen = (d1->length < d2->length) ? d1->length : d2->length; i = memcmp(d1->data, d2->data, cmplen); if(i) return i; if (i) return i; return d1->length - d2->length; } Loading @@ -405,43 +443,56 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, ASN1_VALUE *skitem; unsigned char *tmpdat = NULL, *p = NULL; DER_ENC *derlst = NULL, *tder; if(do_sort) { if (do_sort) { /* Don't need to sort less than 2 items */ if(sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; else { derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); if (sk_ASN1_VALUE_num(sk) < 2) do_sort = 0; else { derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*derlst)); tmpdat = OPENSSL_malloc(skcontlen); if(!derlst || !tmpdat) return 0; if (!derlst || !tmpdat) return 0; } } /* If not sorting just output each item */ if(!do_sort) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { if (!do_sort) { for(i = 0; i < sk_ASN1_VALUE_num(sk); i++) { skitem = sk_ASN1_VALUE_value(sk, i); ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); } return 1; } p = tmpdat; /* Doing sort: build up a list of each member's DER encoding */ for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { skitem = sk_ASN1_VALUE_value(sk, i); tder->data = p; tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); tder->field = skitem; } /* Now sort them */ qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); /* Output sorted DER encoding */ p = *out; for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { memcpy(p, tder->data, tder->length); p += tder->length; } *out = p; /* If do_sort is 2 then reorder the STACK */ if(do_sort == 2) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) if (do_sort == 2) { for(i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) sk_ASN1_VALUE_set(sk, i, tder->field); } OPENSSL_free(derlst); Loading @@ -449,7 +500,8 @@ static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, return 1; } static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass) { int len; int utype; Loading Loading @@ -491,8 +543,10 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A if (tag == -1) tag = utype; /* Output tag+length followed by content octets */ if(out) { if(usetag) ASN1_put_object(out, ndef, len, tag, aclass); if (out) { if (usetag) ASN1_put_object(out, ndef, len, tag, aclass); asn1_ex_i2c(pval, *out, &utype, it); if (ndef) ASN1_put_eoc(out); Loading @@ -500,13 +554,15 @@ static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const A *out += len; } if(usetag) return ASN1_object_size(ndef, len, tag); if (usetag) return ASN1_object_size(ndef, len, tag); return len; } /* Produce content octets from a structure */ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ITEM *it) { ASN1_BOOLEAN *tbool = NULL; ASN1_STRING *strtmp; Loading @@ -516,28 +572,36 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ int len; const ASN1_PRIMITIVE_FUNCS *pf; pf = it->funcs; if(pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); if (pf && pf->prim_i2c) return pf->prim_i2c(pval, cout, putype, it); /* Should type be omitted? */ if((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) { if (!*pval) return -1; } if(it->itype == ASN1_ITYPE_MSTRING) { if (it->itype == ASN1_ITYPE_MSTRING) { /* If MSTRING type set the underlying type */ strtmp = (ASN1_STRING *)*pval; utype = strtmp->type; *putype = utype; } else if(it->utype == V_ASN1_ANY) { } else if (it->utype == V_ASN1_ANY) { /* If ANY set type and pointer to value */ ASN1_TYPE *typ; typ = (ASN1_TYPE *)*pval; utype = typ->type; *putype = utype; pval = (ASN1_VALUE **)&typ->value.ptr; } else utype = *putype; } else utype = *putype; switch(utype) { switch(utype) { case V_ASN1_OBJECT: otmp = (ASN1_OBJECT *)*pval; cont = otmp->data; Loading @@ -551,17 +615,21 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ case V_ASN1_BOOLEAN: tbool = (ASN1_BOOLEAN *)pval; if(*tbool == -1) return -1; if (*tbool == -1) return -1; /* Default handling if value == size field then omit */ if(*tbool && (it->size > 0)) return -1; if(!*tbool && !it->size) return -1; if (*tbool && (it->size > 0)) return -1; if (!*tbool && !it->size) return -1; c = (unsigned char)*tbool; cont = &c; len = 1; break; case V_ASN1_BIT_STRING: return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL); break; case V_ASN1_INTEGER: Loading @@ -571,7 +639,8 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ /* These are all have the same content format * as ASN1_INTEGER */ return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); break; case V_ASN1_OCTET_STRING: Loading Loading @@ -611,6 +680,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, const ASN1_ break; } if(cout && len) memcpy(cout, cont, len); if (cout && len) memcpy(cout, cont, len); return len; }