Ejemplo n.º 1
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                              unsigned char *salt, int saltlen,
                              unsigned char *aiv, int prf_nid)
{
    X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
    int alg_nid, keylen;
    EVP_CIPHER_CTX ctx;
    unsigned char iv[EVP_MAX_IV_LENGTH];
    PBE2PARAM *pbe2 = NULL;
    ASN1_OBJECT *obj;

    alg_nid = EVP_CIPHER_type(cipher);
    if (alg_nid == NID_undef) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
        goto err;
    }
    obj = OBJ_nid2obj(alg_nid);

    if (!(pbe2 = PBE2PARAM_new()))
        goto merr;

    /* Setup the AlgorithmIdentifier for the encryption scheme */
    scheme = pbe2->encryption;

    scheme->algorithm = obj;
    if (!(scheme->parameter = ASN1_TYPE_new()))
        goto merr;

    /* Create random IV */
    if (EVP_CIPHER_iv_length(cipher)) {
        if (aiv)
            sgx_memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
        else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
            goto err;
    }

    EVP_CIPHER_CTX_init(&ctx);

    /* Dummy cipherinit to just setup the IV, and PRF */
    if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
        goto err;
    if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
        EVP_CIPHER_CTX_cleanup(&ctx);
        goto err;
    }
    /*
     * If prf NID unspecified see if cipher has a preference. An error is OK
     * here: just means use default PRF.
     */
    if ((prf_nid == -1) &&
        EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
        ERR_clear_error();
        prf_nid = NID_hmacWithSHA1;
    }
    EVP_CIPHER_CTX_cleanup(&ctx);

    /* If its RC2 then we'd better setup the key length */

    if (alg_nid == NID_rc2_cbc)
        keylen = EVP_CIPHER_key_length(cipher);
    else
        keylen = -1;

    /* Setup keyfunc */

    X509_ALGOR_free(pbe2->keyfunc);

    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);

    if (!pbe2->keyfunc)
        goto merr;

    /* Now set up top level AlgorithmIdentifier */

    if (!(ret = X509_ALGOR_new()))
        goto merr;
    if (!(ret->parameter = ASN1_TYPE_new()))
        goto merr;

    ret->algorithm = OBJ_nid2obj(NID_pbes2);

    /* Encode PBE2PARAM into parameter */

    if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
                        &ret->parameter->value.sequence))
         goto merr;
    ret->parameter->type = V_ASN1_SEQUENCE;

    PBE2PARAM_free(pbe2);
    pbe2 = NULL;

    return ret;

 merr:
    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);

 err:
    PBE2PARAM_free(pbe2);
    /* Note 'scheme' is freed as part of pbe2 */
    X509_ALGOR_free(kalg);
    X509_ALGOR_free(ret);

    return NULL;

}
Ejemplo n.º 2
0
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
{
    ASN1_TYPE *atmp = NULL;

    CONF_VALUE vtmp;

    unsigned char *rdata;
    long rdlen;

    int no_unused = 1;

    if (!(atmp = ASN1_TYPE_new())) {
        ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (!str)
        str = "";

    switch (utype) {

    case V_ASN1_NULL:
        if (str && *str) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
            goto bad_form;
        }
        break;

    case V_ASN1_BOOLEAN:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        vtmp.name = NULL;
        vtmp.section = NULL;
        vtmp.value = (char *)str;
        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
            goto bad_str;
        }
        break;

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
            goto bad_str;
        }
        break;

    case V_ASN1_OBJECT:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
            goto bad_str;
        }
        break;

    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }
        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }
        atmp->value.asn1_string->type = utype;
        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
            goto bad_str;
        }

        break;

    case V_ASN1_BMPSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_T61STRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_NUMERICSTRING:

        if (format == ASN1_GEN_FORMAT_ASCII)
            format = MBSTRING_ASC;
        else if (format == ASN1_GEN_FORMAT_UTF8)
            format = MBSTRING_UTF8;
        else {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
            goto bad_form;
        }

        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
                               -1, format, ASN1_tag2bit(utype)) <= 0) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }

        break;

    case V_ASN1_BIT_STRING:

    case V_ASN1_OCTET_STRING:

        if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_form;
        }

        if (format == ASN1_GEN_FORMAT_HEX) {

            if (!(rdata = string_to_hex((char *)str, &rdlen))) {
                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
                goto bad_str;
            }

            atmp->value.asn1_string->data = rdata;
            atmp->value.asn1_string->length = rdlen;
            atmp->value.asn1_string->type = utype;

        } else if (format == ASN1_GEN_FORMAT_ASCII)
            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
        else if ((format == ASN1_GEN_FORMAT_BITLIST)
                 && (utype == V_ASN1_BIT_STRING)) {
            if (!CONF_parse_list
                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
                goto bad_str;
            }
            no_unused = 0;

        } else {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
            goto bad_form;
        }

        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
            atmp->value.asn1_string->flags
                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        }

        break;

    default:
        ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
        goto bad_str;
    }

    atmp->type = utype;
    return atmp;

 bad_str:
    ERR_add_error_data(2, "string=", str);
 bad_form:

    ASN1_TYPE_free(atmp);
    return NULL;

}
Ejemplo n.º 3
0
int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
{
    int ret = 0;
    int i, j, k, m, n, again, bufsize;
    unsigned char *s = NULL, *sp;
    unsigned char *bufp;
    int num = 0, slen = 0, first = 1;

    bufsize = BIO_gets(bp, buf, size);
    for (;;) {
        if (bufsize < 1) {
            if (first)
                break;
            else
                goto err_sl;
        }
        first = 0;

        i = bufsize;
        if (buf[i - 1] == '\n')
            buf[--i] = '\0';
        if (i == 0)
            goto err_sl;
        if (buf[i - 1] == '\r')
            buf[--i] = '\0';
        if (i == 0)
            goto err_sl;
        again = (buf[i - 1] == '\\');

        for (j = i - 1; j > 0; j--) {
#ifndef CHARSET_EBCDIC
            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                  ((buf[j] >= 'A') && (buf[j] <= 'F'))))
#else
            /*
             * This #ifdef is not strictly necessary, since the characters
             * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
             * not the whole alphabet). Nevertheless, isxdigit() is faster.
             */
            if (!isxdigit(buf[j]))
#endif
            {
                i = j;
                break;
            }
        }
        buf[i] = '\0';
        /*
         * We have now cleared all the crap off the end of the line
         */
        if (i < 2)
            goto err_sl;

        bufp = (unsigned char *)buf;

        k = 0;
        i -= again;
        if (i % 2 != 0) {
            ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
            goto err;
        }
        i /= 2;
        if (num + i > slen) {
            if (s == NULL)
                sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
                                                     i * 2);
            else
                sp = (unsigned char *)OPENSSL_realloc(s,
                                                      (unsigned int)num +
                                                      i * 2);
            if (sp == NULL) {
                ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            s = sp;
            slen = num + i * 2;
        }
        for (j = 0; j < i; j++, k += 2) {
            for (n = 0; n < 2; n++) {
                m = bufp[k + n];
                if ((m >= '0') && (m <= '9'))
                    m -= '0';
                else if ((m >= 'a') && (m <= 'f'))
                    m = m - 'a' + 10;
                else if ((m >= 'A') && (m <= 'F'))
                    m = m - 'A' + 10;
                else {
                    ASN1err(ASN1_F_A2I_ASN1_STRING,
                            ASN1_R_NON_HEX_CHARACTERS);
                    goto err;
                }
                s[num + j] <<= 4;
                s[num + j] |= m;
            }
        }
        num += i;
        if (again)
            bufsize = BIO_gets(bp, buf, size);
        else
            break;
    }
    bs->length = num;
    bs->data = s;
    ret = 1;
 err:
    if (0) {
 err_sl:
        ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
    }
    if (ret != 1)
        OPENSSL_free(s);
    return (ret);
}
Ejemplo n.º 4
0
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBKDF2PARAM *kdf = NULL;
	PBE2PARAM *pbe2 = NULL;
	ASN1_OCTET_STRING *osalt = NULL;
	ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_type(cipher);
	if(alg_nid == NID_undef) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET,
				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (EVP_CIPHER_iv_length(cipher) &&
		RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
  		goto err;

	EVP_CIPHER_CTX_init(&ctx);

	/* Dummy cipherinit to just setup the IV */
	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET,
					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
		EVP_CIPHER_CTX_cleanup(&ctx);
		goto err;
	}
	EVP_CIPHER_CTX_cleanup(&ctx);

	if(!(kdf = PBKDF2PARAM_new())) goto merr;
	if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;

	if (!saltlen) saltlen = PKCS5_SALT_LEN;
	if (!(osalt->data = OPENSSL_malloc (saltlen))) goto merr;
	osalt->length = saltlen;
	if (salt) memcpy (osalt->data, salt, saltlen);
	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;

	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
	if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;

	/* Now include salt in kdf structure */
	kdf->salt->value.octet_string = osalt;
	kdf->salt->type = V_ASN1_OCTET_STRING;
	osalt = NULL;

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc) {
		if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
		if(!ASN1_INTEGER_set (kdf->keylength,
				 EVP_CIPHER_key_length(cipher))) goto merr;
	}

	/* prf can stay NULL because we are using hmacWithSHA1 */

	/* Now setup the PBE2PARAM keyfunc structure */

	pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

	/* Encode PBKDF2PARAM into parameter of pbe2 */

	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;

	if(!ASN1_pack_string_of(PBKDF2PARAM, kdf, i2d_PBKDF2PARAM,
			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;

	PBKDF2PARAM_free(kdf);
	kdf = NULL;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_pack_string_of(PBE2PARAM, pbe2, i2d_PBE2PARAM,
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	ASN1err(ASN1_F_PKCS5_PBE2_SET,ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	M_ASN1_OCTET_STRING_free(osalt);
	PBKDF2PARAM_free(kdf);
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
Ejemplo n.º 5
0
int ASN1_item_sign_ctx(const ASN1_ITEM *it,
                       X509_ALGOR *algor1, X509_ALGOR *algor2,
                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
{
    const EVP_MD *type;
    EVP_PKEY *pkey;
    unsigned char *buf_in = NULL, *buf_out = NULL;
    size_t inl = 0, outl = 0, outll = 0;
    int signid, paramtype;
    int rv;

    type = EVP_MD_CTX_md(ctx);
    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));

    if (type == NULL || pkey == NULL) {
        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
        goto err;
    }

    if (pkey->ameth == NULL) {
        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
        goto err;
    }

    if (pkey->ameth->item_sign) {
        rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
        if (rv == 1)
            outl = signature->length;
        /*-
         * Return value meanings:
         * <=0: error.
         *   1: method does everything.
         *   2: carry on as normal.
         *   3: ASN1 method sets algorithm identifiers: just sign.
         */
        if (rv <= 0)
            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
        if (rv <= 1)
            goto err;
    } else
        rv = 2;

    if (rv == 2) {
        if (!OBJ_find_sigid_by_algs(&signid,
                                    EVP_MD_nid(type),
                                    pkey->ameth->pkey_id)) {
            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
                    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
            goto err;
        }

        if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
            paramtype = V_ASN1_NULL;
        else
            paramtype = V_ASN1_UNDEF;

        if (algor1)
            X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
        if (algor2)
            X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);

    }

    inl = ASN1_item_i2d(asn, &buf_in, it);
    outll = outl = EVP_PKEY_size(pkey);
    buf_out = OPENSSL_malloc((unsigned int)outl);
    if ((buf_in == NULL) || (buf_out == NULL)) {
        outl = 0;
        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
        outl = 0;
        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
        goto err;
    }
    OPENSSL_free(signature->data);
    signature->data = buf_out;
    buf_out = NULL;
    signature->length = outl;
    /*
     * In the interests of compatibility, I'll make sure that the bit string
     * has a 'not-used bits' value of 0
     */
    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
 err:
    EVP_MD_CTX_free(ctx);
    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
    OPENSSL_clear_free((char *)buf_out, outll);
    return (outl);
}
Ejemplo n.º 6
0
Archivo: f_enum.c Proyecto: 002301/node
int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
	{
	int ret=0;
	int i,j,k,m,n,again,bufsize;
	unsigned char *s=NULL,*sp;
	unsigned char *bufp;
	int num=0,slen=0,first=1;

	bs->type=V_ASN1_ENUMERATED;

	bufsize=BIO_gets(bp,buf,size);
	for (;;)
		{
		if (bufsize < 1) goto err_sl;
		i=bufsize;
		if (buf[i-1] == '\n') buf[--i]='\0';
		if (i == 0) goto err_sl;
		if (buf[i-1] == '\r') buf[--i]='\0';
		if (i == 0) goto err_sl;
		again=(buf[i-1] == '\\');

		for (j=0; j<i; j++)
			{
			if (!(	((buf[j] >= '0') && (buf[j] <= '9')) ||
				((buf[j] >= 'a') && (buf[j] <= 'f')) ||
				((buf[j] >= 'A') && (buf[j] <= 'F'))))
				{
				i=j;
				break;
				}
			}
		buf[i]='\0';
		/* We have now cleared all the crap off the end of the
		 * line */
		if (i < 2) goto err_sl;

		bufp=(unsigned char *)buf;
		if (first)
			{
			first=0;
			if ((bufp[0] == '0') && (buf[1] == '0'))
				{
				bufp+=2;
				i-=2;
				}
			}
		k=0;
		i-=again;
		if (i%2 != 0)
			{
			ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
			goto err;
			}
		i/=2;
		if (num+i > slen)
			{
			if (s == NULL)
				sp=(unsigned char *)OPENSSL_malloc(
					(unsigned int)num+i*2);
			else
				sp=(unsigned char *)OPENSSL_realloc(s,
					(unsigned int)num+i*2);
			if (sp == NULL)
				{
				ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
				if (s != NULL) OPENSSL_free(s);
				goto err;
				}
			s=sp;
			slen=num+i*2;
			}
		for (j=0; j<i; j++,k+=2)
			{
			for (n=0; n<2; n++)
				{
				m=bufp[k+n];
				if ((m >= '0') && (m <= '9'))
					m-='0';
				else if ((m >= 'a') && (m <= 'f'))
					m=m-'a'+10;
				else if ((m >= 'A') && (m <= 'F'))
					m=m-'A'+10;
				else
					{
					ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS);
					goto err;
					}
				s[num+j]<<=4;
				s[num+j]|=m;
				}
			}
		num+=i;
		if (again)
			bufsize=BIO_gets(bp,buf,size);
		else
			break;
		}
	bs->length=num;
	bs->data=s;
	ret=1;
err:
	if (0)
		{
err_sl:
		ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
		}
	return(ret);
	}
Ejemplo n.º 7
0
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
 * ASN1 integers: some broken software can encode a positive INTEGER
 * with its MSB set as negative (it doesn't add a padding zero).
 */
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 OPENSSL_malloc stuff, even for 0 bytes otherwise it
	 * signifies a missing NULL parameter. */
	s=(unsigned char *)OPENSSL_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--;
			}
		op_memcpy(s,p,(int)len);
		p+=len;
	}

	if (ret->data != NULL) OPENSSL_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 ((ret != NULL) && ((a == NULL) || (*a != ret)))
		M_ASN1_INTEGER_free(ret);
	return(NULL);
	}
Ejemplo n.º 8
0
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
				 unsigned char *salt, int saltlen,
				 unsigned char *aiv, int prf_nid)
{
	X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
	int alg_nid;
	EVP_CIPHER_CTX ctx;
	unsigned char iv[EVP_MAX_IV_LENGTH];
	PBKDF2PARAM *kdf = NULL;
	PBE2PARAM *pbe2 = NULL;
	ASN1_OCTET_STRING *osalt = NULL;
	ASN1_OBJECT *obj;

	alg_nid = EVP_CIPHER_type(cipher);
	if(alg_nid == NID_undef) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
				ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
		goto err;
	}
	obj = OBJ_nid2obj(alg_nid);

	if(!(pbe2 = PBE2PARAM_new())) goto merr;

	/* Setup the AlgorithmIdentifier for the encryption scheme */
	scheme = pbe2->encryption;

	scheme->algorithm = obj;
	if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;

	/* Create random IV */
	if (EVP_CIPHER_iv_length(cipher))
		{
		if (aiv)
			TINYCLR_SSL_MEMCPY(iv, aiv, EVP_CIPHER_iv_length(cipher));
		else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
  			goto err;
		}

	EVP_CIPHER_CTX_init(&ctx);

	/* Dummy cipherinit to just setup the IV, and PRF */
	EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0);
	if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
		ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
					ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
		EVP_CIPHER_CTX_cleanup(&ctx);
		goto err;
	}
	/* If prf NID unspecified see if cipher has a preference.
	 * An error is OK here: just means use default PRF.
	 */
	if ((prf_nid == -1) && 
	EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
		{
		ERR_clear_error();
		prf_nid = NID_hmacWithSHA1;
		}
	EVP_CIPHER_CTX_cleanup(&ctx);

	if(!(kdf = PBKDF2PARAM_new())) goto merr;
	if(!(osalt = M_ASN1_OCTET_STRING_new())) goto merr;

	if (!saltlen) saltlen = PKCS5_SALT_LEN;
	if (!(osalt->data = (unsigned char*)OPENSSL_malloc (saltlen))) goto merr; //MS: cast to unsigned char*
	osalt->length = saltlen;
	if (salt) TINYCLR_SSL_MEMCPY (osalt->data, salt, saltlen);
	else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0) goto merr;

	if(iter <= 0) iter = PKCS5_DEFAULT_ITER;
	if(!ASN1_INTEGER_set(kdf->iter, iter)) goto merr;

	/* Now include salt in kdf structure */
	kdf->salt->value.octet_string = osalt;
	kdf->salt->type = V_ASN1_OCTET_STRING;
	osalt = NULL;

	/* If its RC2 then we'd better setup the key length */

	if(alg_nid == NID_rc2_cbc) {
		if(!(kdf->keylength = M_ASN1_INTEGER_new())) goto merr;
		if(!ASN1_INTEGER_set (kdf->keylength,
				 EVP_CIPHER_key_length(cipher))) goto merr;
	}

	/* prf can stay NULL if we are using hmacWithSHA1 */
	if (prf_nid != NID_hmacWithSHA1)
		{
		kdf->prf = X509_ALGOR_new();
		if (!kdf->prf)
			goto merr;
		X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
					V_ASN1_NULL, NULL);
		}

	/* Now setup the PBE2PARAM keyfunc structure */

	pbe2->keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

	/* Encode PBKDF2PARAM into parameter of pbe2 */

	if(!(pbe2->keyfunc->parameter = ASN1_TYPE_new())) goto merr;

	if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
			 &pbe2->keyfunc->parameter->value.sequence)) goto merr;
	pbe2->keyfunc->parameter->type = V_ASN1_SEQUENCE;

	PBKDF2PARAM_free(kdf);
	kdf = NULL;

	/* Now set up top level AlgorithmIdentifier */

	if(!(ret = X509_ALGOR_new())) goto merr;
	if(!(ret->parameter = ASN1_TYPE_new())) goto merr;

	ret->algorithm = OBJ_nid2obj(NID_pbes2);

	/* Encode PBE2PARAM into parameter */

	if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
				 &ret->parameter->value.sequence)) goto merr;
	ret->parameter->type = V_ASN1_SEQUENCE;

	PBE2PARAM_free(pbe2);
	pbe2 = NULL;

	return ret;

	merr:
	ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);

	err:
	PBE2PARAM_free(pbe2);
	/* Note 'scheme' is freed as part of pbe2 */
	M_ASN1_OCTET_STRING_free(osalt);
	PBKDF2PARAM_free(kdf);
	X509_ALGOR_free(kalg);
	X509_ALGOR_free(ret);

	return NULL;

}
Ejemplo n.º 9
0
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
	{
	int i,first,len=0,c, use_bn;
	char ftmp[24], *tmp = ftmp;
	int tmpsize = sizeof ftmp;
	const char *p;
	unsigned long l;
	BIGNUM *bl = NULL;

	if (num == 0)
		return(0);
	else if (num == -1)
		num=strlen(buf);

	p=buf;
	c= *(p++);
	num--;
	if ((c >= '0') && (c <= '2'))
		{
		first= c-'0';
		}
	else
		{
		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
		goto err;
		}

	if (num <= 0)
		{
		ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
		goto err;
		}
	c= *(p++);
	num--;
	for (;;)
		{
		if (num <= 0) break;
		if ((c != '.') && (c != ' '))
			{
			ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
			goto err;
			}
		l=0;
		use_bn = 0;
		for (;;)
			{
			if (num <= 0) break;
			num--;
			c= *(p++);
			if ((c == ' ') || (c == '.'))
				break;
			if ((c < '0') || (c > '9'))
				{
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
				goto err;
				}
			if (!use_bn && l > (ULONG_MAX / 10L))
				{
				use_bn = 1;
				if (!bl)
					bl = BN_new();
				if (!bl || !BN_set_word(bl, l))
					goto err;
				}
			if (use_bn)
				{
				if (!BN_mul_word(bl, 10L)
					|| !BN_add_word(bl, c-'0'))
					goto err;
				}
			else
				l=l*10L+(long)(c-'0');
			}
		if (len == 0)
			{
			if ((first < 2) && (l >= 40))
				{
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
				goto err;
				}
			if (use_bn)
				{
				if (!BN_add_word(bl, first * 40))
					goto err;
				}
			else
				l+=(long)first*40;
			}
		i=0;
		if (use_bn)
			{
			int blsize;
			blsize = BN_num_bits(bl);
			blsize = (blsize + 6)/7;
			if (blsize > tmpsize)
				{
				if (tmp != ftmp)
					OPENSSL_free(tmp);
				tmpsize = blsize + 32;
				tmp = OPENSSL_malloc(tmpsize);
				if (!tmp)
					goto err;
				}
			while(blsize--)
				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
			}
		else
			{
					
			for (;;)
				{
				tmp[i++]=(unsigned char)l&0x7f;
				l>>=7L;
				if (l == 0L) break;
				}

			}
		if (out != NULL)
			{
			if (len+i > olen)
				{
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
				goto err;
				}
			while (--i > 0)
				out[len++]=tmp[i]|0x80;
			out[len++]=tmp[0];
			}
		else
			len+=i;
		}
	if (tmp != ftmp)
		OPENSSL_free(tmp);
	if (bl)
		BN_free(bl);
	return(len);
err:
	if (tmp != ftmp)
		OPENSSL_free(tmp);
	if (bl)
		BN_free(bl);
	return(0);
	}
Ejemplo n.º 10
0
/* int is_set:  if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)    */
int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag,
		 int ex_class, int is_set)
	{
	int ret=0,r;
	int i;
	unsigned char *p;
        unsigned char *pStart, *pTempMem;
        MYBLOB *rgSetBlob;
        int totSize;

	if (a == NULL) return(0);
	for (i=sk_num(a)-1; i>=0; i--)
		ret+=i2d(sk_value(a,i),NULL);
	r=ASN1_object_size(1,ret,ex_tag);
	if (pp == NULL) return(r);

	p= *pp;
	ASN1_put_object(&p,1,ret,ex_tag,ex_class);

/* Modified by [email protected] */
	/* And then again by Ben */
	/* And again by Steve */

	if(!is_set || (sk_num(a) < 2))
		{
		for (i=0; i<sk_num(a); i++)
                	i2d(sk_value(a,i),&p);

		*pp=p;
		return(r);
		}

        pStart  = p; /* Catch the beg of Setblobs*/
		/* In this array we will store the SET blobs */
		rgSetBlob = (MYBLOB *)OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB));
		if (rgSetBlob == NULL)
			{
			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
			return(0);
			}

        for (i=0; i<sk_num(a); i++)
	        {
                rgSetBlob[i].pbData = p;  /* catch each set encode blob */
                i2d(sk_value(a,i),&p);
                rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
SetBlob
*/
		}
        *pp=p;
        totSize = p - pStart; /* This is the total size of all set blobs */

 /* Now we have to sort the blobs. I am using a simple algo.
    *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
        qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
		if (!(pTempMem = OPENSSL_malloc(totSize)))
			{
			ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
			return(0);
			}

/* Copy to temp mem */
        p = pTempMem;
        for(i=0; i<sk_num(a); ++i)
		{
                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
                p += rgSetBlob[i].cbData;
		}

/* Copy back to user mem*/
        memcpy(pStart, pTempMem, totSize);
        OPENSSL_free(pTempMem);
        OPENSSL_free(rgSetBlob);

        return(r);
        }
Ejemplo n.º 11
0
ASN1_UTCTIME *ASN1_UTCTIME_adj (ASN1_UTCTIME * s, time_t t, int offset_day, long offset_sec)
{
    char *p;

    struct tm *ts;

    struct tm data;

    size_t len = 20;

    int free_s = 0;

    if (s == NULL)
    {
        free_s = 1;
        s = M_ASN1_UTCTIME_new ();
    }
    if (s == NULL)
        goto err;


    ts = OPENSSL_gmtime (&t, &data);
    if (ts == NULL)
        goto err;

    if (offset_day || offset_sec)
    {
        if (!OPENSSL_gmtime_adj (ts, offset_day, offset_sec))
            goto err;
    }

    if ((ts->tm_year < 50) || (ts->tm_year >= 150))
        goto err;

    p = (char *) s->data;
    if ((p == NULL) || ((size_t) s->length < len))
    {
        p = OPENSSL_malloc (len);
        if (p == NULL)
        {
            ASN1err (ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (s->data != NULL)
            OPENSSL_free (s->data);
        s->data = (unsigned char *) p;
    }

    BIO_snprintf (p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
                  ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec);
    s->length = strlen (p);
    s->type = V_ASN1_UTCTIME;
#ifdef CHARSET_EBCDIC_not
    ebcdic2ascii (s->data, s->data, s->length);
#endif
    return (s);
  err:
    if (free_s && s)
        M_ASN1_UTCTIME_free (s);
    return NULL;
}
Ejemplo n.º 12
0
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,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=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);
	}
Ejemplo n.º 13
0
int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
{
    const ASN1_TEMPLATE *tt = NULL;
    const ASN1_EXTERN_FUNCS *ef;
    const ASN1_AUX *aux = it->funcs;
    ASN1_aux_cb *asn1_cb;
    ASN1_VALUE **pseqval;
    int i;
    if (aux && aux->asn1_cb)
        asn1_cb = aux->asn1_cb;
    else
        asn1_cb = 0;

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
#endif

    switch (it->itype) {

    case ASN1_ITYPE_EXTERN:
        ef = it->funcs;
        if (ef && ef->asn1_ex_new) {
            if (!ef->asn1_ex_new(pval, it))
                goto memerr;
        }
        break;

    case ASN1_ITYPE_PRIMITIVE:
        if (it->templates) {
            if (!asn1_template_new(pval, it->templates))
                goto memerr;
        } else if (!asn1_primitive_new(pval, it, embed))
            goto memerr;
        break;

    case ASN1_ITYPE_MSTRING:
        if (!asn1_primitive_new(pval, it, embed))
            goto memerr;
        break;

    case ASN1_ITYPE_CHOICE:
        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
            if (!i)
                goto auxerr;
            if (i == 2) {
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
                OPENSSL_mem_debug_pop();
#endif
                return 1;
            }
        }
        if (embed) {
            memset(*pval, 0, it->size);
        } else {
            *pval = OPENSSL_zalloc(it->size);
            if (*pval == NULL)
                goto memerr;
        }
        asn1_set_choice_selector(pval, -1, it);
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr2;
        break;

    case ASN1_ITYPE_NDEF_SEQUENCE:
    case ASN1_ITYPE_SEQUENCE:
        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
            if (!i)
                goto auxerr;
            if (i == 2) {
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
                OPENSSL_mem_debug_pop();
#endif
                return 1;
            }
        }
        if (embed) {
            memset(*pval, 0, it->size);
        } else {
            *pval = OPENSSL_zalloc(it->size);
            if (*pval == NULL)
                goto memerr;
        }
        /* 0 : init. lock */
        if (asn1_do_lock(pval, 0, it) < 0) {
            if (!embed) {
                OPENSSL_free(*pval);
                *pval = NULL;
            }
            goto memerr;
        }
        asn1_enc_init(pval, it);
        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
            pseqval = asn1_get_field_ptr(pval, tt);
            if (!asn1_template_new(pseqval, tt))
                goto memerr2;
        }
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr2;
        break;
    }
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    OPENSSL_mem_debug_pop();
#endif
    return 1;

 memerr2:
    asn1_item_embed_free(pval, it, embed);
 memerr:
    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    OPENSSL_mem_debug_pop();
#endif
    return 0;

 auxerr2:
    asn1_item_embed_free(pval, it, embed);
 auxerr:
    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    OPENSSL_mem_debug_pop();
#endif
    return 0;

}
Ejemplo n.º 14
0
static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
                              int embed)
{
    ASN1_TYPE *typ;
    ASN1_STRING *str;
    int utype;

    if (!it)
        return 0;

    if (it->funcs) {
        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
        if (embed) {
            if (pf->prim_clear) {
                pf->prim_clear(pval, it);
                return 1;
            }
        } else if (pf->prim_new) {
            return pf->prim_new(pval, it);
        }
    }

    if (it->itype == ASN1_ITYPE_MSTRING)
        utype = -1;
    else
        utype = it->utype;
    switch (utype) {
    case V_ASN1_OBJECT:
        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
        return 1;

    case V_ASN1_BOOLEAN:
        *(ASN1_BOOLEAN *)pval = it->size;
        return 1;

    case V_ASN1_NULL:
        *pval = (ASN1_VALUE *)1;
        return 1;

    case V_ASN1_ANY:
        if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) {
            ASN1err(ASN1_F_ASN1_PRIMITIVE_NEW, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        typ->value.ptr = NULL;
        typ->type = -1;
        *pval = (ASN1_VALUE *)typ;
        break;

    default:
        if (embed) {
            str = *(ASN1_STRING **)pval;
            memset(str, 0, sizeof(*str));
            str->type = utype;
            str->flags = ASN1_STRING_FLAG_EMBED;
        } else {
            str = ASN1_STRING_type_new(utype);
            *pval = (ASN1_VALUE *)str;
        }
        if (it->itype == ASN1_ITYPE_MSTRING && str)
            str->flags |= ASN1_STRING_FLAG_MSTRING;
        break;
    }
    if (*pval)
        return 1;
    return 0;
}
Ejemplo n.º 15
0
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst,
		unsigned char **in, long len, int exptag, int expclass, char opt, ASN1_TLC *ctx)
{
	int i;
	int ptag, pclass;
	long plen;
	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, but 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, so 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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
0
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
    const ASN1_TEMPLATE *tt = NULL;
    const ASN1_EXTERN_FUNCS *ef;
    const ASN1_AUX *aux = it->funcs;
    ASN1_aux_cb *asn1_cb;
    ASN1_VALUE **pseqval;
    int i;
    if (aux && aux->asn1_cb)
        asn1_cb = aux->asn1_cb;
    else
        asn1_cb = 0;

    *pval = NULL;

#ifdef CRYPTO_MDEBUG
    if (it->sname)
        CRYPTO_push_info(it->sname);
#endif

    switch (it->itype) {

    case ASN1_ITYPE_EXTERN:
        ef = it->funcs;
        if (ef && ef->asn1_ex_new) {
            if (!ef->asn1_ex_new(pval, it))
                goto memerr;
        }
        break;

    case ASN1_ITYPE_PRIMITIVE:
        if (it->templates) {
            if (!asn1_template_new(pval, it->templates))
                goto memerr;
        } else if (!asn1_primitive_new(pval, it))
            goto memerr;
        break;

    case ASN1_ITYPE_MSTRING:
        if (!asn1_primitive_new(pval, it))
            goto memerr;
        break;

    case ASN1_ITYPE_CHOICE:
        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
            if (!i)
                goto auxerr;
            if (i == 2) {
#ifdef CRYPTO_MDEBUG
                if (it->sname)
                    CRYPTO_pop_info();
#endif
                return 1;
            }
        }
        *pval = OPENSSL_malloc(it->size);
        if (!*pval)
            goto memerr;
        memset(*pval, 0, it->size);
        asn1_set_choice_selector(pval, -1, it);
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr;
        break;

    case ASN1_ITYPE_NDEF_SEQUENCE:
    case ASN1_ITYPE_SEQUENCE:
        if (asn1_cb) {
            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
            if (!i)
                goto auxerr;
            if (i == 2) {
#ifdef CRYPTO_MDEBUG
                if (it->sname)
                    CRYPTO_pop_info();
#endif
                return 1;
            }
        }
        *pval = OPENSSL_malloc(it->size);
        if (!*pval)
            goto memerr;
        memset(*pval, 0, it->size);
        asn1_do_lock(pval, 0, it);
        asn1_enc_init(pval, it);
        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
            pseqval = asn1_get_field_ptr(pval, tt);
            if (!asn1_template_new(pseqval, tt))
                goto memerr;
        }
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr;
        break;
    }
#ifdef CRYPTO_MDEBUG
    if (it->sname)
        CRYPTO_pop_info();
#endif
    return 1;

 memerr:
    ASN1err(ASN1_F_ASN1_ITEM_EX_NEW, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
    if (it->sname)
        CRYPTO_pop_info();
#endif
    return 0;

 auxerr:
    ASN1err(ASN1_F_ASN1_ITEM_EX_NEW, ASN1_R_AUX_ERROR);
    ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
    if (it->sname)
        CRYPTO_pop_info();
#endif
    return 0;

}
Ejemplo n.º 18
0
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
	     long length)
	{
	EVP_PKEY *ret;

	if ((a == NULL) || (*a == NULL))
		{
		if ((ret=EVP_PKEY_new()) == NULL)
			{
			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
			return(NULL);
			}
		}
	else	ret= *a;

	if (!EVP_PKEY_set_type(ret, type))
		{
		ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
		goto err;
		}

	switch (EVP_PKEY_id(ret))
		{
#ifndef OPENSSL_NO_RSA
	case EVP_PKEY_RSA:
		if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL,
			(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
			{
			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
			goto err;
			}
		break;
#endif
#ifndef OPENSSL_NO_DSA
	case EVP_PKEY_DSA:
		if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
			(const unsigned char **)pp,length)) /* TMP UGLY CAST */
			{
			ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
			goto err;
			}
		break;
#endif
#ifndef OPENSSL_NO_EC
	case EVP_PKEY_EC:
		if (!o2i_ECPublicKey(&(ret->pkey.ec),
				     (const unsigned char **)pp, length))
			{
			ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
			goto err;
			}
	break;
#endif
	default:
		ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
		goto err;
		/* break; */
		}
	if (a != NULL) (*a)=ret;
	return(ret);
err:
	if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
	return(NULL);
	}
Ejemplo n.º 19
0
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
	     long len)
	{
	ASN1_INTEGER *ret=NULL;
	const unsigned char *p, *pend;
	unsigned char *to,*s;
	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;
	pend = p + len;

	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
	 * signifies a missing NULL parameter. */
	s=(unsigned char *)OPENSSL_malloc((int)len+1);
	if (s == NULL)
		{
		i=ERR_R_MALLOC_FAILURE;
		goto err;
		}
	to=s;
	if(!len) {
		/* Strictly speaking this is an illegal INTEGER but we
		 * tolerate it.
		 */
		ret->type=V_ASN1_INTEGER;
	} else if (*p & 0x80) /* a negative number */
		{
		ret->type=V_ASN1_NEG_INTEGER;
		if ((*p == 0xff) && (len != 1)) {
			p++;
			len--;
		}
		i = len;
		p += i - 1;
		to += i - 1;
		while((!*p) && i) {
			*(to--) = 0;
			i--;
			p--;
		}
		/* Special case: if all zeros then the number will be of
		 * the form FF followed by n zero bytes: this corresponds to
		 * 1 followed by n zero bytes. We've already written n zeros
		 * so we just append an extra one and set the first byte to
		 * a 1. This is treated separately because it is the only case
		 * where the number of bytes is larger than len.
		 */
		if(!i) {
			*s = 1;
			s[len] = 0;
			len++;
		} else {
			*(to--) = (*(p--) ^ 0xff) + 1;
			i--;
			for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
		}
	} else {
		ret->type=V_ASN1_INTEGER;
		if ((*p == 0) && (len != 1))
			{
			p++;
			len--;
			}
		op_memcpy(s,p,(int)len);
	}

	if (ret->data != NULL) OPENSSL_free(ret->data);
	ret->data=s;
	ret->length=(int)len;
	if (a != NULL) (*a)=ret;
	*pp=pend;
	return(ret);
err:
	ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
		M_ASN1_INTEGER_free(ret);
	return(NULL);
	}
Ejemplo n.º 20
0
int ASN1_item_ex_d2i(ASN1_VALUE **pval, unsigned char **in, long len, const ASN1_ITEM *it,
				int tag, int aclass, char opt, ASN1_TLC *ctx)
{
	const ASN1_TEMPLATE *tt, *errtt = NULL;
	const ASN1_COMPAT_FUNCS *cf;
	const ASN1_EXTERN_FUNCS *ef;
	const ASN1_AUX *aux = it->funcs;
	ASN1_aux_cb *asn1_cb;
	unsigned char *p, *q, imphack = 0, oclass;
	char seq_eoc, seq_nolen, cst, isopt;
	long tmplen;
	int i;
	int otag;
	int ret = 0;
	ASN1_VALUE *pchval, **pchptr, *ptmpval;
	if(!pval) return 0;
	if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb;
	else asn1_cb = 0;

	switch(it->itype) {

		case ASN1_ITYPE_PRIMITIVE:
		if(it->templates) {
			/* tagging or OPTIONAL is currently illegal on an item template
			 * because the flags can't get passed down. In practice this isn't
			 * a problem: we include the relevant flags from the item template
			 * in the template itself.
			 */
			if ((tag != -1) || opt) {
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
				goto err;
			}
			return asn1_template_ex_d2i(pval, in, len, it->templates, opt, ctx);
		}
		return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt, ctx);
		break;

		case ASN1_ITYPE_MSTRING:
		p = *in;
		/* Just read in tag and class */
		ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, &p, len, -1, 0, 1, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			goto err;
		} 
		/* Must be UNIVERSAL class */
		if(oclass != V_ASN1_UNIVERSAL) {
			/* If OPTIONAL, assume this is OK */
			if(opt) return -1;
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
			goto err;
		} 
		/* Check tag matches bit map */
		if(!(ASN1_tag2bit(otag) & it->utype)) {
			/* If OPTIONAL, assume this is OK */
			if(opt) return -1;
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG);
			goto err;
		} 
		return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);

		case ASN1_ITYPE_EXTERN:
		/* Use new style d2i */
		ef = it->funcs;
		return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);

		case ASN1_ITYPE_COMPAT:
		/* we must resort to old style evil hackery */
		cf = it->funcs;

		/* If OPTIONAL see if it is there */
		if(opt) {
			int exptag;
			p = *in;
			if(tag == -1) exptag = it->utype;
			else exptag = tag;
			/* Don't care about anything other than presence of expected tag */
			ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, &p, len, exptag, aclass, 1, ctx);
			if(!ret) {
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
				goto err;
			}
			if(ret == -1) return -1;
		}
		/* This is the old style evil hack IMPLICIT handling:
		 * since the underlying code is expecting a tag and
		 * class other than the one present we change the
		 * buffer temporarily then change it back afterwards.
		 * This doesn't and never did work for tags > 30.
		 *
		 * Yes this is *horrible* but it is only needed for
		 * old style d2i which will hopefully not be around
		 * for much longer.
		 * FIXME: should copy the buffer then modify it so
		 * the input buffer can be const: we should *always*
		 * copy because the old style d2i might modify the
		 * buffer.
		 */

		if(tag != -1) {
			p = *in;
			imphack = *p;
			*p = (unsigned char)((*p & V_ASN1_CONSTRUCTED) | it->utype);
		}

		ptmpval = cf->asn1_d2i(pval, in, len);

		if(tag != -1) *p = imphack;

		if(ptmpval) return 1;
		ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
		goto err;


		case ASN1_ITYPE_CHOICE:
		if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
				goto auxerr;

		/* Allocate structure */
		if(!*pval) {
			if(!ASN1_item_ex_new(pval, it)) {
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
				goto err;
			}
		}
		/* CHOICE type, try each possibility in turn */
		pchval = NULL;
		p = *in;
		for(i = 0, tt=it->templates; i < it->tcount; i++, tt++) {
			pchptr = asn1_get_field_ptr(pval, tt);
			/* We mark field as OPTIONAL so its absence
			 * can be recognised.
			 */
			ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
			/* If field not present, try the next one */
			if(ret == -1) continue;
			/* If positive return, read OK, break loop */
			if(ret > 0) break;
			/* Otherwise must be an ASN1 parsing error */
			errtt = tt;
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			goto err;
		}
		/* Did we fall off the end without reading anything? */
		if(i == it->tcount) {
			/* If OPTIONAL, this is OK */
			if(opt) {
				/* Free and zero it */
				ASN1_item_ex_free(pval, it);
				return -1;
			}
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
			goto err;
		}
		asn1_set_choice_selector(pval, i, it);
		*in = p;
		if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
				goto auxerr;
		return 1;

		case ASN1_ITYPE_SEQUENCE:
		p = *in;
		tmplen = len;

		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
		if(tag == -1) {
			tag = V_ASN1_SEQUENCE;
			aclass = V_ASN1_UNIVERSAL;
		}
		/* Get SEQUENCE length and update len, p */
		ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, &p, len, tag, aclass, opt, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			goto err;
		} else if(ret == -1) return -1;
		if(aux && (aux->flags & ASN1_AFLG_BROKEN)) {
			len = tmplen - (p - *in);
			seq_nolen = 1;
		} else seq_nolen = seq_eoc;	/* If indefinite we don't do a length check */
		if(!cst) {
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
			goto err;
		}

		if(!*pval) {
			if(!ASN1_item_ex_new(pval, it)) {
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
				goto err;
			}
		}
		if(asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it))
				goto auxerr;

		/* Get each field entry */
		for(i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
			const ASN1_TEMPLATE *seqtt;
			ASN1_VALUE **pseqval;
			seqtt = asn1_do_adb(pval, tt, 1);
			if(!seqtt) goto err;
			pseqval = asn1_get_field_ptr(pval, seqtt);
			/* Have we ran out of data? */
			if(!len) break;
			q = p;
			if(asn1_check_eoc(&p, len)) {
				if(!seq_eoc) {
					ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC);
					goto err;
				}
				len -= p - q;
				seq_eoc = 0;
				q = p;
				break;
			}
			/* This determines the OPTIONAL flag value. The field cannot
			 * be omitted if it is the last of a SEQUENCE and there is
			 * still data to be read. This isn't strictly necessary but
			 * it increases efficiency in some cases.
			 */
			if(i == (it->tcount - 1)) isopt = 0;
			else isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
			/* attempt to read in field, allowing each to be OPTIONAL */
			ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
			if(!ret) {
				errtt = seqtt;
				goto err;
			} else if(ret == -1) {
				/* OPTIONAL component absent. Free and zero the field
				 */
				ASN1_template_free(pseqval, seqtt);
				continue;
			}
			/* Update length */
			len -= p - q;
		}
		/* Check for EOC if expecting one */
		if(seq_eoc && !asn1_check_eoc(&p, len)) {
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC);
			goto err;
		}
		/* Check all data read */
		if(!seq_nolen && len) {
			ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
			goto err;
		}

		/* If we get here we've got no more data in the SEQUENCE,
		 * however we may not have read all fields so check all
		 * remaining are OPTIONAL and clear any that are.
		 */
		for(; i < it->tcount; tt++, i++) {
			const ASN1_TEMPLATE *seqtt;
			seqtt = asn1_do_adb(pval, tt, 1);
			if(!seqtt) goto err;
			if(seqtt->flags & ASN1_TFLG_OPTIONAL) {
				ASN1_VALUE **pseqval;
				pseqval = asn1_get_field_ptr(pval, seqtt);
				ASN1_template_free(pseqval, seqtt);
			} else {
				errtt = seqtt;
				ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING);
				goto err;
			}
		}
		/* Save encoding */
		if(!asn1_enc_save(pval, *in, p - *in, it)) goto auxerr;
		*in = p;
		if(asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it))
				goto auxerr;
		return 1;

		default:
		return 0;
	}
	auxerr:
	ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR);
	err:
	ASN1_item_ex_free(pval, it);
	if(errtt) ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname);
	else ERR_add_error_data(2, "Type=", it->sname);
	return 0;
}
Ejemplo n.º 21
0
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
	     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
	     const EVP_MD *type)
	{
	EVP_MD_CTX ctx;
	unsigned char *buf_in=NULL,*buf_out=NULL;
	int i,inl=0,outl=0,outll=0;
	X509_ALGOR *a;

	EVP_MD_CTX_init(&ctx);
	for (i=0; i<2; i++)
		{
		if (i == 0)
			a=algor1;
		else
			a=algor2;
		if (a == NULL) continue;
                if (type->pkey_type == NID_dsaWithSHA1 ||
			type->pkey_type == NID_ecdsa_with_SHA1)
			{
			/* special case: RFC 3279 tells us to omit 'parameters'
			 * with id-dsa-with-sha1 and ecdsa-with-SHA1 */
			ASN1_TYPE_free(a->parameter);
			a->parameter = NULL;
			}
		else if ((a->parameter == NULL) || 
			(a->parameter->type != V_ASN1_NULL))
			{
			ASN1_TYPE_free(a->parameter);
			if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
			a->parameter->type=V_ASN1_NULL;
			}
		ASN1_OBJECT_free(a->algorithm);
		a->algorithm=OBJ_nid2obj(type->pkey_type);
		if (a->algorithm == NULL)
			{
			ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
			goto err;
			}
		if (a->algorithm->length == 0)
			{
			ASN1err(ASN1_F_ASN1_ITEM_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
			goto err;
			}
		}
	inl=ASN1_item_i2d(asn,&buf_in, it);
	outll=outl=EVP_PKEY_size(pkey);
	buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
	if ((buf_in == NULL) || (buf_out == NULL))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!EVP_SignInit_ex(&ctx,type, NULL))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
		goto err;
		}
	EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
	if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
			(unsigned int *)&outl,pkey))
		{
		outl=0;
		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
		goto err;
		}
	if (signature->data != NULL) OPENSSL_free(signature->data);
	signature->data=buf_out;
	buf_out=NULL;
	signature->length=outl;
	/* In the interests of compatibility, I'll make sure that
	 * the bit string has a 'not-used bits' value of 0
	 */
	signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
	signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
err:
	EVP_MD_CTX_cleanup(&ctx);
	if (buf_in != NULL)
		{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
	if (buf_out != NULL)
		{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
	return(outl);
	}
Ejemplo n.º 22
0
static int asn1_template_ex_d2i(ASN1_VALUE **val, unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
{
	int flags, aclass;
	int ret;
	long len;
	unsigned char *p, *q;
	char exp_eoc;
	if(!val) return 0;
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;

	/* Check if EXPLICIT tag expected */
	if(flags & ASN1_TFLG_EXPTAG) {
		char cst;
		/* Need to work out amount of data available to the inner content and where it
		 * starts: so read in EXPLICIT header to get the info.
		 */
		ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, &p, inlen, tt->tag, aclass, opt, ctx);
		q = p;
		if(!ret) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			return 0;
		} else if(ret == -1) return -1;
		if(!cst) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
			return 0;
		}
		/* We've found the field so it can't be OPTIONAL now */
		ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			return 0;
		}
		/* We read the field in OK so update length */
		len -= p - q;
		if(exp_eoc) {
			/* If NDEF we must have an EOC here */
			if(!asn1_check_eoc(&p, len)) {
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
				goto err;
			}
		} else {
			/* Otherwise we must hit the EXPLICIT tag end or its an error */
			if(len) {
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
				goto err;
			}
		}
	} else 
		return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);

	*in = p;
	return 1;

	err:
	ASN1_template_free(val, tt);
	*val = NULL;
	return 0;
}
Ejemplo n.º 23
0
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
              const EVP_MD *type)
{
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    unsigned char *p, *buf_in = NULL, *buf_out = NULL;
    int i, inl = 0, outl = 0, outll = 0;
    X509_ALGOR *a;

    if (ctx == NULL) {
        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    for (i = 0; i < 2; i++) {
        if (i == 0)
            a = algor1;
        else
            a = algor2;
        if (a == NULL)
            continue;
        if (type->pkey_type == NID_dsaWithSHA1) {
            /*
             * special case: RFC 2459 tells us to omit 'parameters' with
             * id-dsa-with-sha1
             */
            ASN1_TYPE_free(a->parameter);
            a->parameter = NULL;
        } else if ((a->parameter == NULL) ||
                   (a->parameter->type != V_ASN1_NULL)) {
            ASN1_TYPE_free(a->parameter);
            if ((a->parameter = ASN1_TYPE_new()) == NULL)
                goto err;
            a->parameter->type = V_ASN1_NULL;
        }
        ASN1_OBJECT_free(a->algorithm);
        a->algorithm = OBJ_nid2obj(type->pkey_type);
        if (a->algorithm == NULL) {
            ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
            goto err;
        }
        if (a->algorithm->length == 0) {
            ASN1err(ASN1_F_ASN1_SIGN,
                    ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
            goto err;
        }
    }
    inl = i2d(data, NULL);
    buf_in = OPENSSL_malloc((unsigned int)inl);
    outll = outl = EVP_PKEY_size(pkey);
    buf_out = OPENSSL_malloc((unsigned int)outl);
    if ((buf_in == NULL) || (buf_out == NULL)) {
        outl = 0;
        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    p = buf_in;

    i2d(data, &p);
    if (!EVP_SignInit_ex(ctx, type, NULL)
        || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl)
        || !EVP_SignFinal(ctx, (unsigned char *)buf_out,
                          (unsigned int *)&outl, pkey)) {
        outl = 0;
        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
        goto err;
    }
    OPENSSL_free(signature->data);
    signature->data = buf_out;
    buf_out = NULL;
    signature->length = outl;
    /*
     * In the interests of compatibility, I'll make sure that the bit string
     * has a 'not-used bits' value of 0
     */
    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
 err:
    EVP_MD_CTX_free(ctx);
    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
    OPENSSL_clear_free((char *)buf_out, outll);
    return (outl);
}
Ejemplo n.º 24
0
static int asn1_template_noexp_d2i(ASN1_VALUE **val, unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx)
{
	int flags, aclass;
	int ret;
	unsigned char *p, *q;
	if(!val) return 0;
	flags = tt->flags;
	aclass = flags & ASN1_TFLG_TAG_CLASS;

	p = *in;
	q = p;

	if(flags & ASN1_TFLG_SK_MASK) {
		/* SET OF, SEQUENCE OF */
		int sktag, skaclass;
		char sk_eoc;
		/* First work out expected inner tag value */
		if(flags & ASN1_TFLG_IMPTAG) {
			sktag = tt->tag;
			skaclass = aclass;
		} else {
			skaclass = V_ASN1_UNIVERSAL;
			if(flags & ASN1_TFLG_SET_OF) sktag = V_ASN1_SET;
			else sktag = V_ASN1_SEQUENCE;
		}
		/* Get the tag */
		ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, &p, len, sktag, skaclass, opt, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
			return 0;
		} else if(ret == -1) return -1;
		if(!*val) *val = (ASN1_VALUE *)sk_new_null();
		else {
			/* We've got a valid STACK: free up any items present */
			STACK *sktmp = (STACK *)*val;
			ASN1_VALUE *vtmp;
			while(sk_num(sktmp) > 0) {
				vtmp = (ASN1_VALUE *)sk_pop(sktmp);
				ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
			}
		}
				
		if(!*val) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_MALLOC_FAILURE);
			goto err;
		}
		/* Read as many items as we can */
		while(len > 0) {
			ASN1_VALUE *skfield;
			q = p;
			/* See if EOC found */
			if(asn1_check_eoc(&p, len)) {
				if(!sk_eoc) {
					ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_UNEXPECTED_EOC);
					goto err;
				}
				len -= p - q;
				sk_eoc = 0;
				break;
			}
			skfield = NULL;
			if(!ASN1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
				goto err;
			}
			len -= p - q;
			if(!sk_push((STACK *)*val, (char *)skfield)) {
				ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_MALLOC_FAILURE);
				goto err;
			}
		}
		if(sk_eoc) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ASN1_R_MISSING_EOC);
			goto err;
		}
	} else if(flags & ASN1_TFLG_IMPTAG) {
		/* IMPLICIT tagging */
		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
			goto err;
		} else if(ret == -1) return -1;
	} else {
		/* Nothing special */
		ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), -1, 0, opt, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_TEMPLATE_D2I, ERR_R_NESTED_ASN1_ERROR);
			goto err;
		} else if(ret == -1) return -1;
	}

	*in = p;
	return 1;

	err:
	ASN1_template_free(val, tt);
	*val = NULL;
	return 0;
}
Ejemplo n.º 25
0
static int asn1_cb(const char *elem, int len, void *bitstr)
{
    tag_exp_arg *arg = bitstr;
    int i;
    int utype;
    int vlen = 0;
    const char *p, *vstart = NULL;

    int tmp_tag, tmp_class;

    if (elem == NULL)
        return -1;

    for (i = 0, p = elem; i < len; p++, i++) {
        /* Look for the ':' in name value pairs */
        if (*p == ':') {
            vstart = p + 1;
            vlen = len - (vstart - elem);
            len = p - elem;
            break;
        }
    }

    utype = asn1_str2tag(elem, len);

    if (utype == -1) {
        ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
        ERR_add_error_data(2, "tag=", elem);
        return -1;
    }

    /* If this is not a modifier mark end of string and exit */
    if (!(utype & ASN1_GEN_FLAG)) {
        arg->utype = utype;
        arg->str = vstart;
        /* If no value and not end of string, error */
        if (!vstart && elem[len]) {
            ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
            return -1;
        }
        return 0;
    }

    switch (utype) {

    case ASN1_GEN_FLAG_IMP:
        /* Check for illegal multiple IMPLICIT tagging */
        if (arg->imp_tag != -1) {
            ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
            return -1;
        }
        if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
            return -1;
        break;

    case ASN1_GEN_FLAG_EXP:

        if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
            return -1;
        if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
            return -1;
        break;

    case ASN1_GEN_FLAG_SEQWRAP:
        if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
            return -1;
        break;

    case ASN1_GEN_FLAG_SETWRAP:
        if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
            return -1;
        break;

    case ASN1_GEN_FLAG_BITWRAP:
        if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
            return -1;
        break;

    case ASN1_GEN_FLAG_OCTWRAP:
        if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
            return -1;
        break;

    case ASN1_GEN_FLAG_FORMAT:
        if (!vstart) {
            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
            return -1;
        }
        if (strncmp(vstart, "ASCII", 5) == 0)
            arg->format = ASN1_GEN_FORMAT_ASCII;
        else if (strncmp(vstart, "UTF8", 4) == 0)
            arg->format = ASN1_GEN_FORMAT_UTF8;
        else if (strncmp(vstart, "HEX", 3) == 0)
            arg->format = ASN1_GEN_FORMAT_HEX;
        else if (strncmp(vstart, "BITLIST", 7) == 0)
            arg->format = ASN1_GEN_FORMAT_BITLIST;
        else {
            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
            return -1;
        }
        break;

    }

    return 1;

}
Ejemplo n.º 26
0
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inlen, 
						const ASN1_ITEM *it,
						int tag, int aclass, char opt, ASN1_TLC *ctx)
{
	int ret = 0, utype;
	long plen;
	char cst, inf, free_cont = 0;
	unsigned char *p;
	BUF_MEM buf;
	unsigned char *cont = NULL;
	long len; 
	if(!pval) {
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
		return 0; /* Should never happen */
	}

	if(it->itype == ASN1_ITYPE_MSTRING) {
		utype = tag;
		tag = -1;
	} else utype = it->utype;

	if(utype == V_ASN1_ANY) {
		/* If type is ANY need to figure out type from tag */
		unsigned char oclass;
		if(tag >= 0) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
			return 0;
		}
		if(opt) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_OPTIONAL_ANY);
			return 0;
		}
		p = *in;
		ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, &p, inlen, -1, 0, 0, ctx);
		if(!ret) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
			return 0;
		}
		if(oclass != V_ASN1_UNIVERSAL) utype = V_ASN1_OTHER;
	}
	if(tag == -1) {
		tag = utype;
		aclass = V_ASN1_UNIVERSAL;
	}
	p = *in;
	/* Check header */
	ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, &p, inlen, tag, aclass, opt, ctx);
	if(!ret) {
		ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
		return 0;
	} else if(ret == -1) return -1;
	/* SEQUENCE, SET and "OTHER" are left in encoded form */
	if((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
		/* Clear context cache for type OTHER because the auto clear when
		 * we have a exact match wont work
		 */
		if(utype == V_ASN1_OTHER) {
			asn1_tlc_clear(ctx);
		/* SEQUENCE and SET must be constructed */
		} else if(!cst) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_CONSTRUCTED);
			return 0;
		}

		cont = *in;
		/* If indefinite length constructed find the real end */
		if(inf) {
			if(!asn1_find_end(&p, plen, inf)) goto err;
			len = p - cont;
		} else {
			len = p - cont + plen;
			p += plen;
			buf.data = NULL;
		}
	} else if(cst) {
		buf.length = 0;
		buf.max = 0;
		buf.data = NULL;
		/* Should really check the internal tags are correct but
		 * some things may get this wrong. The relevant specs
		 * say that constructed string types should be OCTET STRINGs
		 * internally irrespective of the type. So instead just check
		 * for UNIVERSAL class and ignore the tag.
		 */
		if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err;
		len = buf.length;
		/* Append a final null to string */
		if(!BUF_MEM_grow_clean(&buf, len + 1)) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
			return 0;
		}
		buf.data[len] = 0;
		cont = (unsigned char *)buf.data;
		free_cont = 1;
	} else {
		cont = p;
		len = plen;
		p += plen;
	}

	/* We now have content length and type: translate into a structure */
	if(!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) goto err;

	*in = p;
	ret = 1;
	err:
	if(free_cont && buf.data) OPENSSL_free(buf.data);
	return ret;
}
Ejemplo n.º 27
0
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
					int inform, unsigned long mask, 
					long minsize, long maxsize)
{
	int str_type;
	int ret;
	char free_out;
	int outform, outlen;
	ASN1_STRING *dest;
	unsigned char *p;
	int nchar;
	char strbuf[32];
	int (*cpyfunc)(unsigned long,void *) = NULL;
	if(len == -1) len = strlen((const char *)in);
	if(!mask) mask = DIRSTRING_TYPE;

	/* First do a string check and work out the number of characters */
	switch(inform) {

		case MBSTRING_BMP:
		if(len & 1) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
					 ASN1_R_INVALID_BMPSTRING_LENGTH);
			return -1;
		}
		nchar = len >> 1;
		break;

		case MBSTRING_UNIV:
		if(len & 3) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
					 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
			return -1;
		}
		nchar = len >> 2;
		break;

		case MBSTRING_UTF8:
		nchar = 0;
		/* This counts the characters and does utf8 syntax checking */
		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
		if(ret < 0) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
						 ASN1_R_INVALID_UTF8STRING);
			return -1;
		}
		break;

		case MBSTRING_ASC:
		nchar = len;
		break;

		default:
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_UNKNOWN_FORMAT);
		return -1;
	}

	if((minsize > 0) && (nchar < minsize)) {
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_SHORT);
		sprintf(strbuf, "%ld", minsize);
		ERR_add_error_data(2, "minsize=", strbuf);
		return -1;
	}

	if((maxsize > 0) && (nchar > maxsize)) {
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_STRING_TOO_LONG);
		sprintf(strbuf, "%ld", maxsize);
		ERR_add_error_data(2, "maxsize=", strbuf);
		return -1;
	}

	/* Now work out minimal type (if any) */
	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY, ASN1_R_ILLEGAL_CHARACTERS);
		return -1;
	}


	/* Now work out output format and string type */
	outform = MBSTRING_ASC;
	if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
	else if(mask & B_ASN1_BMPSTRING) {
		str_type = V_ASN1_BMPSTRING;
		outform = MBSTRING_BMP;
	} else if(mask & B_ASN1_UNIVERSALSTRING) {
		str_type = V_ASN1_UNIVERSALSTRING;
		outform = MBSTRING_UNIV;
	} else {
		str_type = V_ASN1_UTF8STRING;
		outform = MBSTRING_UTF8;
	}
	if(!out) return str_type;
	if(*out) {
		free_out = 0;
		dest = *out;
		if(dest->data) {
			dest->length = 0;
			OPENSSL_free(dest->data);
			dest->data = NULL;
		}
		dest->type = str_type;
	} else {
		free_out = 1;
		dest = ASN1_STRING_type_new(str_type);
		if(!dest) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,
							ERR_R_MALLOC_FAILURE);
			return -1;
		}
		*out = dest;
	}
	/* If both the same type just copy across */
	if(inform == outform) {
		if(!ASN1_STRING_set(dest, in, len)) {
			ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
			return -1;
		}
		return str_type;
	} 

	/* Work out how much space the destination will need */
	switch(outform) {
		case MBSTRING_ASC:
		outlen = nchar;
		cpyfunc = cpy_asc;
		break;

		case MBSTRING_BMP:
		outlen = nchar << 1;
		cpyfunc = cpy_bmp;
		break;

		case MBSTRING_UNIV:
		outlen = nchar << 2;
		cpyfunc = cpy_univ;
		break;

		case MBSTRING_UTF8:
		outlen = 0;
		traverse_string(in, len, inform, out_utf8, &outlen);
		cpyfunc = cpy_utf8;
		break;
	}
	if(!(p = OPENSSL_malloc(outlen + 1))) {
		if(free_out) ASN1_STRING_free(dest);
		ASN1err(ASN1_F_ASN1_MBSTRING_COPY,ERR_R_MALLOC_FAILURE);
		return -1;
	}
	dest->length = outlen;
	dest->data = p;
	p[outlen] = 0;
	traverse_string(in, len, inform, cpyfunc, &p);
	return str_type;	
}
Ejemplo n.º 28
0
int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it)
{
	ASN1_VALUE **opval = NULL;
	ASN1_STRING *stmp;
	ASN1_TYPE *typ = NULL;
	int ret = 0;
	const ASN1_PRIMITIVE_FUNCS *pf;
	ASN1_INTEGER **tint;
	pf = it->funcs;
	if(pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
	/* If ANY type clear type and set pointer to internal value */
	if(it->utype == V_ASN1_ANY) {
		if(!*pval) {
			typ = ASN1_TYPE_new();
			*pval = (ASN1_VALUE *)typ;
		} else typ = (ASN1_TYPE *)*pval;
		if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL);
		opval = pval;
		pval = (ASN1_VALUE **)&typ->value.ptr;
	}
	switch(utype) {
		case V_ASN1_OBJECT:
		if(!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err;
		break;

		case V_ASN1_NULL:
		if(len) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_NULL_IS_WRONG_LENGTH);
			goto err;
		}
		*pval = (ASN1_VALUE *)1;
		break;

		case V_ASN1_BOOLEAN:
		if(len != 1) {
			ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
			goto err;
		} else {
			ASN1_BOOLEAN *tbool;
			tbool = (ASN1_BOOLEAN *)pval;
			*tbool = *cont;
		}
		break;

		case V_ASN1_BIT_STRING:
		if(!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err;
		break;

		case V_ASN1_INTEGER:
		case V_ASN1_NEG_INTEGER:
		case V_ASN1_ENUMERATED:
		case V_ASN1_NEG_ENUMERATED:
		tint = (ASN1_INTEGER **)pval;
		if(!c2i_ASN1_INTEGER(tint, &cont, len)) goto err;
		/* Fixup type to match the expected form */
		(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
		break;

		case V_ASN1_OCTET_STRING:
		case V_ASN1_NUMERICSTRING:
		case V_ASN1_PRINTABLESTRING:
		case V_ASN1_T61STRING:
		case V_ASN1_VIDEOTEXSTRING:
		case V_ASN1_IA5STRING:
		case V_ASN1_UTCTIME:
		case V_ASN1_GENERALIZEDTIME:
		case V_ASN1_GRAPHICSTRING:
		case V_ASN1_VISIBLESTRING:
		case V_ASN1_GENERALSTRING:
		case V_ASN1_UNIVERSALSTRING:
		case V_ASN1_BMPSTRING:
		case V_ASN1_UTF8STRING:
		case V_ASN1_OTHER:
		case V_ASN1_SET:
		case V_ASN1_SEQUENCE:
		default:
		/* All based on ASN1_STRING and handled the same */
		if(!*pval) {
			stmp = ASN1_STRING_type_new(utype);
			if(!stmp) {
				ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
				goto err;
			}
			*pval = (ASN1_VALUE *)stmp;
		} else {
			stmp = (ASN1_STRING *)*pval;
			stmp->type = utype;
		}
		/* If we've already allocated a buffer use it */
		if(*free_cont) {
			if(stmp->data) OPENSSL_free(stmp->data);
			stmp->data = cont;
			stmp->length = len;
			*free_cont = 0;
		} else {
			if(!ASN1_STRING_set(stmp, cont, len)) {
				ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
				ASN1_STRING_free(stmp);	
				*pval = NULL;
				goto err;
			}
		}
		break;
	}
	/* If ASN1_ANY and NULL type fix up value */
	if(typ && utype==V_ASN1_NULL) typ->value.ptr = NULL;

	ret = 1;
	err:
	if(!ret)
		{
		ASN1_TYPE_free(typ);
		if (opval)
			*opval = NULL;
		}
	return ret;
}
Ejemplo n.º 29
0
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
                                     const unsigned char **pp, long len)
{
    ASN1_BIT_STRING *ret = NULL;
    const unsigned char *p;
    unsigned char *s;
    int i;

    if (len < 1) {
        i = ASN1_R_STRING_TOO_SHORT;
        goto err;
    }

    if (len > INT_MAX) {
        i = ASN1_R_STRING_TOO_LONG;
        goto err;
    }

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

    p = *pp;
    i = *(p++);
    if (i > 7) {
        i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
        goto err;
    }
    /*
     * We do this to preserve the settings.  If we modify the settings, via
     * the _set_bit function, we will recalculate on output
     */
    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */

    if (len-- > 1) {            /* using one because of the bits left byte */
        s = OPENSSL_malloc((int)len);
        if (s == NULL) {
            i = ERR_R_MALLOC_FAILURE;
            goto err;
        }
        memcpy(s, p, (int)len);
        s[len - 1] &= (0xff << i);
        p += len;
    } else
        s = NULL;

    ret->length = (int)len;
    OPENSSL_free(ret->data);
    ret->data = s;
    ret->type = V_ASN1_BIT_STRING;
    if (a != NULL)
        (*a) = ret;
    *pp = p;
    return ret;
 err:
    ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
    if ((a == NULL) || (*a != ret))
        ASN1_BIT_STRING_free(ret);
    return NULL;
}
Ejemplo n.º 30
0
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen)
{
    X509_ALGOR *keyfunc = NULL;
    PBKDF2PARAM *kdf = NULL;
    ASN1_OCTET_STRING *osalt = NULL;

    if (!(kdf = PBKDF2PARAM_new()))
        goto merr;
    if (!(osalt = M_ASN1_OCTET_STRING_new()))
        goto merr;

    kdf->salt->value.octet_string = osalt;
    kdf->salt->type = V_ASN1_OCTET_STRING;

    if (!saltlen)
        saltlen = PKCS5_SALT_LEN;
    if (!(osalt->data = OPENSSL_malloc(saltlen)))
        goto merr;

    osalt->length = saltlen;

    if (salt)
        sgx_memcpy(osalt->data, salt, saltlen);
    else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
        goto merr;

    if (iter <= 0)
        iter = PKCS5_DEFAULT_ITER;

    if (!ASN1_INTEGER_set(kdf->iter, iter))
        goto merr;

    /* If have a key len set it up */

    if (keylen > 0) {
        if (!(kdf->keylength = M_ASN1_INTEGER_new()))
            goto merr;
        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
            goto merr;
    }

    /* prf can stay NULL if we are using hmacWithSHA1 */
    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
        kdf->prf = X509_ALGOR_new();
        if (!kdf->prf)
            goto merr;
        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
    }

    /* Finally setup the keyfunc structure */

    keyfunc = X509_ALGOR_new();
    if (!keyfunc)
        goto merr;

    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

    /* Encode PBKDF2PARAM into parameter of pbe2 */

    if (!(keyfunc->parameter = ASN1_TYPE_new()))
        goto merr;

    if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
                        &keyfunc->parameter->value.sequence))
         goto merr;
    keyfunc->parameter->type = V_ASN1_SEQUENCE;

    PBKDF2PARAM_free(kdf);
    return keyfunc;

 merr:
    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
    PBKDF2PARAM_free(kdf);
    X509_ALGOR_free(keyfunc);
    return NULL;
}