Exemplo n.º 1
0
int
gost2814789_get_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params)
{
	int ret = -1;
	int len;
	GOST_CIPHER_PARAMS *gcp = NULL;
	EVP_GOST2814789_CTX *c = ctx->cipher_data;
	unsigned char *p;

	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
		return ret;

	p = params->value.sequence->data;

	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
	    params->value.sequence->length);

	len = gcp->iv->length;
	if (len != ctx->cipher->iv_len) {
		GOST_CIPHER_PARAMS_free(gcp);
		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
		    GOST_R_INVALID_IV_LENGTH);
		return -1;
	}

	if (!Gost2814789_set_sbox(&c->ks, OBJ_obj2nid(gcp->enc_param_set))) {
		GOST_CIPHER_PARAMS_free(gcp);
		return -1;
	}
	c->param_nid = OBJ_obj2nid(gcp->enc_param_set);

	memcpy(ctx->oiv, gcp->iv->data, len);
	memcpy(ctx->iv, gcp->iv->data, len);

	GOST_CIPHER_PARAMS_free(gcp);

	return 1;
}
Exemplo n.º 2
0
int
EAC_CTX_init_ef_cardsecurity(const unsigned char *ef_cardsecurity,
            size_t ef_cardsecurity_len, EAC_CTX *ctx)
{
	PKCS7 *p7 = NULL, *signed_data;
    ASN1_OCTET_STRING *os;
    int r = 0;

    check(ef_cardsecurity, "Invalid arguments");

    if (!d2i_PKCS7(&p7, &ef_cardsecurity, ef_cardsecurity_len)
            || !PKCS7_type_is_signed(p7))
        goto err;

    if (ctx && ctx->ca_ctx &&
            !(ctx->ca_ctx->flags & CA_FLAG_DISABLE_PASSIVE_AUTH))
        check((CA_passive_authentication(ctx, p7) == 1),
                "Failed to perform passive authentication");

    signed_data = p7->d.sign->contents;
    if (OBJ_obj2nid(signed_data->type) != NID_id_SecurityObject
            || ASN1_TYPE_get(signed_data->d.other) != V_ASN1_OCTET_STRING)
        goto err;
    os = signed_data->d.other->value.octet_string;

    if (!EAC_CTX_init_ef_cardaccess(os->data, os->length, ctx)
            || !ctx || !ctx->ca_ctx || !ctx->ca_ctx->ka_ctx)
        goto err;

    r = 1;

err:
    if (p7)
        PKCS7_free(p7);

    return r;
}
Exemplo n.º 3
0
/* Store parameters into ASN1 structure */
int  gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
	{
	int ret = -1;
	int len; 
	GOST_CIPHER_PARAMS *gcp = NULL;
	unsigned char *p;
	struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
	if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
		{
		return ret;
		}

	p = params->value.sequence->data;

	gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
		params->value.sequence->length);

	len = gcp->iv->length;
	if (len != ctx->cipher->iv_len)
		{
		GOST_CIPHER_PARAMS_free(gcp);
		GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
			GOST_R_INVALID_IV_LENGTH);
		return -1;
		}
	if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
		{
		GOST_CIPHER_PARAMS_free(gcp);
		return -1;
		}
	memcpy(ctx->oiv, gcp->iv->data, len);

	GOST_CIPHER_PARAMS_free(gcp);

	return 1;
	}
Exemplo n.º 4
0
static int dh_cms_encrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    EVP_PKEY *pkey;
    EVP_CIPHER_CTX *ctx;
    int keylen;
    X509_ALGOR *talg, *wrap_alg = NULL;
    ASN1_OBJECT *aoid;
    ASN1_BIT_STRING *pubkey;
    ASN1_STRING *wrap_str;
    ASN1_OCTET_STRING *ukm;
    unsigned char *penc = NULL, *dukm = NULL;
    int penclen;
    size_t dukmlen = 0;
    int rv = 0;
    int kdf_type, wrap_nid;
    const EVP_MD *kdf_md;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* Get ephemeral key */
    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
                                             NULL, NULL, NULL))
        goto err;
    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
    /* Is everything uninitialised? */
    if (aoid == OBJ_nid2obj(NID_undef)) {
        ASN1_INTEGER *pubk;
        pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
        if (!pubk)
            goto err;
        /* Set the key */

        penclen = i2d_ASN1_INTEGER(pubk, &penc);
        ASN1_INTEGER_free(pubk);
        if (penclen <= 0)
            goto err;
        ASN1_STRING_set0(pubkey, penc, penclen);
        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;

        penc = NULL;
        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
                        V_ASN1_UNDEF, NULL);
    }

    /* See if custom paraneters set */
    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
    if (kdf_type <= 0)
        goto err;
    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
        goto err;

    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
        kdf_type = EVP_PKEY_DH_KDF_X9_42;
        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
            goto err;
    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
        /* Unknown KDF */
        goto err;
    if (kdf_md == NULL) {
        /* Only SHA1 supported */
        kdf_md = EVP_sha1();
        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
            goto err;
    } else if (EVP_MD_type(kdf_md) != NID_sha1)
        /* Unsupported digest */
        goto err;

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
        goto err;

    /* Get wrap NID */
    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    wrap_nid = EVP_CIPHER_CTX_type(ctx);
    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
        goto err;
    keylen = EVP_CIPHER_CTX_key_length(ctx);

    /* Package wrap algorithm in an AlgorithmIdentifier */

    wrap_alg = X509_ALGOR_new();
    if (!wrap_alg)
        goto err;
    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
    wrap_alg->parameter = ASN1_TYPE_new();
    if (!wrap_alg->parameter)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
        goto err;
    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
        ASN1_TYPE_free(wrap_alg->parameter);
        wrap_alg->parameter = NULL;
    }

    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
        goto err;

    if (ukm) {
        dukmlen = ASN1_STRING_length(ukm);
        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
        if (!dukm)
            goto err;
    }

    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
        goto err;
    dukm = NULL;

    /*
     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     * of another AlgorithmIdentifier.
     */
    penc = NULL;
    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
    if (!penc || !penclen)
        goto err;
    wrap_str = ASN1_STRING_new();
    if (!wrap_str)
        goto err;
    ASN1_STRING_set0(wrap_str, penc, penclen);
    penc = NULL;
    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
                    V_ASN1_SEQUENCE, wrap_str);

    rv = 1;

 err:
    if (penc)
        OPENSSL_free(penc);
    if (wrap_alg)
        X509_ALGOR_free(wrap_alg);
    return rv;
}
Exemplo n.º 5
0
int MAIN(int argc, char **argv)
{
    int i, badops = 0, offset = 0, ret = 1, j;
    unsigned int length = 0;
    long num, tmplen;
    BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
    int informat, indent = 0, noout = 0, dump = 0, strictpem = 0;
    char *infile = NULL, *str = NULL, *prog, *oidfile = NULL, *derfile =
        NULL, *name = NULL, *header = NULL;
    char *genstr = NULL, *genconf = NULL;
    unsigned char *tmpbuf;
    const unsigned char *ctmpbuf;
    BUF_MEM *buf = NULL;
    STACK_OF(OPENSSL_STRING) *osk = NULL;
    ASN1_TYPE *at = NULL;

    informat = FORMAT_PEM;

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

    prog = argv[0];
    argc--;
    argv++;
    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
        BIO_printf(bio_err, "Memory allocation failure\n");
        goto end;
    }
    while (argc >= 1) {
        if (strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            derfile = *(++argv);
        } else if (strcmp(*argv, "-i") == 0) {
            indent = 1;
        } else if (strcmp(*argv, "-noout") == 0)
            noout = 1;
        else if (strcmp(*argv, "-oid") == 0) {
            if (--argc < 1)
                goto bad;
            oidfile = *(++argv);
        } else if (strcmp(*argv, "-offset") == 0) {
            if (--argc < 1)
                goto bad;
            offset = atoi(*(++argv));
        } else if (strcmp(*argv, "-length") == 0) {
            if (--argc < 1)
                goto bad;
            length = atoi(*(++argv));
            if (length == 0)
                goto bad;
        } else if (strcmp(*argv, "-dump") == 0) {
            dump = -1;
        } else if (strcmp(*argv, "-dlimit") == 0) {
            if (--argc < 1)
                goto bad;
            dump = atoi(*(++argv));
            if (dump <= 0)
                goto bad;
        } else if (strcmp(*argv, "-strparse") == 0) {
            if (--argc < 1)
                goto bad;
            sk_OPENSSL_STRING_push(osk, *(++argv));
        } else if (strcmp(*argv, "-genstr") == 0) {
            if (--argc < 1)
                goto bad;
            genstr = *(++argv);
        } else if (strcmp(*argv, "-genconf") == 0) {
            if (--argc < 1)
                goto bad;
            genconf = *(++argv);
        } else if (strcmp(*argv, "-strictpem") == 0) {
            strictpem = 1;
            informat = FORMAT_PEM;
        } else {
            BIO_printf(bio_err, "unknown option %s\n", *argv);
            badops = 1;
            break;
        }
        argc--;
        argv++;
    }

    if (badops) {
 bad:
        BIO_printf(bio_err, "%s [options] <infile\n", prog);
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
        BIO_printf(bio_err, " -in arg       input file\n");
        BIO_printf(bio_err,
                   " -out arg      output file (output format is always DER\n");
        BIO_printf(bio_err, " -noout arg    don't produce any output\n");
        BIO_printf(bio_err, " -offset arg   offset into file\n");
        BIO_printf(bio_err, " -length arg   length of section in file\n");
        BIO_printf(bio_err, " -i            indent entries\n");
        BIO_printf(bio_err, " -dump         dump unknown data in hex form\n");
        BIO_printf(bio_err,
                   " -dlimit arg   dump the first arg bytes of unknown data in hex form\n");
        BIO_printf(bio_err, " -oid file     file of extra oid definitions\n");
        BIO_printf(bio_err, " -strparse offset\n");
        BIO_printf(bio_err,
                   "               a series of these can be used to 'dig' into multiple\n");
        BIO_printf(bio_err, "               ASN1 blob wrappings\n");
        BIO_printf(bio_err,
                   " -genstr str   string to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -genconf file file to generate ASN1 structure from\n");
        BIO_printf(bio_err,
                   " -strictpem    do not attempt base64 decode outside PEM markers (-inform \n");
        BIO_printf(bio_err, "               will be ignored)\n");
        goto end;
    }

    ERR_load_crypto_strings();

    in = BIO_new(BIO_s_file());
    out = BIO_new(BIO_s_file());
    if ((in == NULL) || (out == NULL)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
#ifdef OPENSSL_SYS_VMS
    {
        BIO *tmpbio = BIO_new(BIO_f_linebuffer());
        out = BIO_push(tmpbio, out);
    }
#endif

    if (oidfile != NULL) {
        if (BIO_read_filename(in, oidfile) <= 0) {
            BIO_printf(bio_err, "problems opening %s\n", oidfile);
            ERR_print_errors(bio_err);
            goto end;
        }
        OBJ_create_objects(in);
    }

    if (infile == NULL)
        BIO_set_fp(in, stdin, BIO_NOCLOSE);
    else {
        if (BIO_read_filename(in, infile) <= 0) {
            perror(infile);
            goto end;
        }
    }

    if (derfile) {
        if (!(derout = BIO_new_file(derfile, "wb"))) {
            BIO_printf(bio_err, "problems opening %s\n", derfile);
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (strictpem) {
        if (PEM_read_bio(in, &name, &header, (unsigned char **)&str, &num) !=
            1) {
            BIO_printf(bio_err, "Error reading PEM file\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    } else {

        if ((buf = BUF_MEM_new()) == NULL)
            goto end;
        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
            goto end;           /* Pre-allocate :-) */

        if (genstr || genconf) {
            num = do_generate(bio_err, genstr, genconf, buf);
            if (num < 0) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        else {

            if (informat == FORMAT_PEM) {
                BIO *tmp;

                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
                    goto end;
                BIO_push(b64, in);
                tmp = in;
                in = b64;
                b64 = tmp;
            }

            num = 0;
            for (;;) {
                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
                    goto end;
                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
                if (i <= 0)
                    break;
                num += i;
            }
        }
        str = buf->data;

    }

    /* If any structs to parse go through in sequence */

    if (sk_OPENSSL_STRING_num(osk)) {
        tmpbuf = (unsigned char *)str;
        tmplen = num;
        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
            ASN1_TYPE *atmp;
            int typ;
            j = atoi(sk_OPENSSL_STRING_value(osk, i));
            if (j == 0) {
                BIO_printf(bio_err, "'%s' is an invalid number\n",
                           sk_OPENSSL_STRING_value(osk, i));
                continue;
            }
            tmpbuf += j;
            tmplen -= j;
            atmp = at;
            ctmpbuf = tmpbuf;
            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
            ASN1_TYPE_free(atmp);
            if (!at) {
                BIO_printf(bio_err, "Error parsing structure\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            typ = ASN1_TYPE_get(at);
            if ((typ == V_ASN1_OBJECT)
                || (typ == V_ASN1_NULL)) {
                BIO_printf(bio_err, "Can't parse %s type\n",
                           typ == V_ASN1_NULL ? "NULL" : "OBJECT");
                ERR_print_errors(bio_err);
                goto end;
            }
            /* hmm... this is a little evil but it works */
            tmpbuf = at->value.asn1_string->data;
            tmplen = at->value.asn1_string->length;
        }
        str = (char *)tmpbuf;
        num = tmplen;
    }

    if (offset >= num) {
        BIO_printf(bio_err, "Error: offset too large\n");
        goto end;
    }

    num -= offset;

    if ((length == 0) || ((long)length > num))
        length = (unsigned int)num;
    if (derout) {
        if (BIO_write(derout, str + offset, length) != (int)length) {
            BIO_printf(bio_err, "Error writing output\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    if (!noout &&
        !ASN1_parse_dump(out, (unsigned char *)&(str[offset]), length,
                         indent, dump)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(derout);
    BIO_free(in);
    BIO_free_all(out);
    BIO_free(b64);
    if (ret != 0)
        ERR_print_errors(bio_err);
    if (buf != NULL)
        BUF_MEM_free(buf);
    if (name != NULL)
        OPENSSL_free(name);
    if (header != NULL)
        OPENSSL_free(header);
    if (strictpem && str != NULL)
        OPENSSL_free(str);
    if (at != NULL)
        ASN1_TYPE_free(at);
    if (osk != NULL)
        sk_OPENSSL_STRING_free(osk);
    OBJ_cleanup();
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemplo n.º 6
0
/*
 * read an attribute of type string
 */
char	*sigattr_string(scep_t *scep, char *attrname) {
	STACK_OF(X509_ATTRIBUTE)	*sig_attribs;
	ASN1_OBJECT			*asn1_obj;
	ASN1_TYPE			*asn1_type;
	X509_ATTRIBUTE			*attr;
	int				len, i;
	char				*data = NULL;
	scepmsg_t			*msg;
	
	if (debug)
		BIO_printf(bio_err, "%s:%d: looking for attribute '%s'\n",
			__FILE__, __LINE__, attrname);

	/* decide which message to study: client reads attrs from reply	*/
	if (scep->client)
		msg = &scep->reply;
	else
		msg = &scep->request;

	/* find the object we by name					*/
	asn1_obj = OBJ_nid2obj(OBJ_sn2nid(attrname));
	asn1_type = NULL;

	/* retrieve the stack of signed attributes			*/
	if (NULL == (sig_attribs = PKCS7_get_signed_attributes(msg->si))) {
		BIO_printf(bio_err, "%s:%d: no signed attributes\n",
			__FILE__, __LINE__);
		return NULL;
	}

	/* scan all attributes for the one we are looking for		*/
	for (i = 0; i < sk_X509_ATTRIBUTE_num(sig_attribs); i++) {
		attr = sk_X509_ATTRIBUTE_value(sig_attribs, i);
		if (OBJ_cmp(attr->object, asn1_obj) == 0) {
			if (debug)
				BIO_printf(bio_err, "%s:%d: found attribute\n",
					__FILE__, __LINE__);
			asn1_type = sk_ASN1_TYPE_value(attr->value.set, 0);
			break;
		}
	}

	/* if we cannot find the required argument, we just return NULL	*/
	if (asn1_type == NULL) {
		BIO_printf(bio_err, "%s:%d: cannot find attribute\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (ASN1_TYPE_get(asn1_type) != V_ASN1_PRINTABLESTRING) {
		BIO_printf(bio_err, "%s:%d: attribute has wrong type\n",
			__FILE__, __LINE__);
		goto err;
	}

	if (debug)
		BIO_printf(bio_err, "%s:%d: found attribute '%s'\n", 
			__FILE__, __LINE__, attrname);
	/* unpack the ASN1_STRING into a C-String (0-terminated)	*/
	len = ASN1_STRING_length(asn1_type->value.asn1_string);
	data = (char *)malloc(1 + len);
	memcpy(data, ASN1_STRING_data(asn1_type->value.asn1_string), len);
	data[len] = '\0';
	if (debug)
		BIO_printf(bio_err, "%s:%d: value of %d bytes retrieved\n",
			__FILE__, __LINE__, len);

	/* return the data						*/
	return data;
err:
	ERR_print_errors(bio_err);
	return NULL;
}
Exemplo n.º 7
0
ASN1_OCTET_STRING	*sigattr_asn1_octet(scep_t *scep, char *attrname) {
	STACK_OF(X509_ATTRIBUTE)	*sig_attribs;
	ASN1_OBJECT			*asn1_obj;
	ASN1_TYPE			*asn1_type;
	X509_ATTRIBUTE			*attr;
	int				i;
	scepmsg_t			*msg;
	int single;
	
	if (debug)
		BIO_printf(bio_err, "%s:%d: looking for attribute '%s'\n",
			__FILE__, __LINE__, attrname);

	/* decide which message to study: client reads attrs from reply	*/
	if (scep->client)
		msg = &scep->reply;
	else
		msg = &scep->request;

	/* find the object we by name					*/
	asn1_obj = OBJ_nid2obj(OBJ_sn2nid(attrname));
	asn1_type = NULL;

	/* retrieve the stack of signed attributes			*/
	if (NULL == (sig_attribs = PKCS7_get_signed_attributes(msg->si))) {
		BIO_printf(bio_err, "%s:%d: signed attributes not found\n",
			__FILE__, __LINE__);
		return NULL;
	}

	/* scan all attributes for the one we are looking for		*/
	for (i = 0; i < sk_X509_ATTRIBUTE_num(sig_attribs); i++) {
		attr = sk_X509_ATTRIBUTE_value(sig_attribs, i);
		if (OBJ_cmp(attr->object, asn1_obj) == 0) {
#if OPENSSL_VERSION_NUMBER < 0x00907000L
			/* attr->set was replaced with attr->single (with opposite
			   meaning) somewhere between 0.9.6m-engine and 0.9.7d */
			single = !attr->set;
#else
			single = attr->single;
#endif
			if (single || (sk_ASN1_TYPE_num(attr->value.set) == 0)) {
 				BIO_printf(bio_err, "%s:%d: attr has no val\n",__FILE__, __LINE__);
				goto err;
 				 					 				
				BIO_printf(bio_err, "%s:%d: attr has no val\n",
					__FILE__, __LINE__);
				goto err;
			}
			if (debug)
				BIO_printf(bio_err, "%s:%d: found matching "
					"attribute with %d values\n", __FILE__,
					__LINE__,
					sk_ASN1_TYPE_num(attr->value.set));
			asn1_type = sk_ASN1_TYPE_value(attr->value.set, 0);
			if (debug)
				BIO_printf(bio_err, "%s:%d: type found: %p\n",
					__FILE__, __LINE__, asn1_type);
			break;
		}
	}

	/* if we cannot find the required argument, we just return NULL	*/
	if (debug)
		BIO_printf(bio_err, "%s:%d: checking for attribute\n",
			__FILE__, __LINE__);
	if (asn1_type == NULL) {
		BIO_printf(bio_err, "%s:%d: attribute has no type\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (ASN1_TYPE_get(asn1_type) != V_ASN1_OCTET_STRING) {
		BIO_printf(bio_err, "%s:%d: attribute has wrong type\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: found attribute '%s'\n", 
			__FILE__, __LINE__, attrname);

	/* this is an ASN1_OCTET_STRING, so we can retrieve the 	*/
	/* appropriate element of the union				*/
	return asn1_type->value.octet_string;

	/* error return, or attribute not found				*/
err:
	if (debug)
		BIO_printf(bio_err, "%s:%d: attribute not found or error\n",
			__FILE__, __LINE__);
	ERR_print_errors(bio_err);
	return NULL;
}
Exemplo n.º 8
0
int int_rsa_verify(int dtype, const unsigned char *m,
                   unsigned int m_len,
                   unsigned char *rm, size_t *prm_len,
                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
{
    int i, ret = 0, sigtype;
    unsigned char *s;
    X509_SIG *sig = NULL;

    if (siglen != (unsigned int)RSA_size(rsa)) {
        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
        return (0);
    }

    if ((dtype == NID_md5_sha1) && rm) {
        i = RSA_public_decrypt((int)siglen,
                               sigbuf, rm, rsa, RSA_PKCS1_PADDING);
        if (i <= 0)
            return 0;
        *prm_len = i;
        return 1;
    }

    s = OPENSSL_malloc((unsigned int)siglen);
    if (s == NULL) {
        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) {
        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
        goto err;
    }
    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);

    if (i <= 0)
        goto err;
    /*
     * Oddball MDC2 case: signature can be OCTET STRING. check for correct
     * tag and length octets.
     */
    if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) {
        if (rm) {
            memcpy(rm, s + 2, 16);
            *prm_len = 16;
            ret = 1;
        } else if (memcmp(m, s + 2, 16))
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        else
            ret = 1;
    }

    /* Special case: SSL signature */
    if (dtype == NID_md5_sha1) {
        if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        else
            ret = 1;
    } else {
        const unsigned char *p = s;
        sig = d2i_X509_SIG(NULL, &p, (long)i);

        if (sig == NULL)
            goto err;

        /* Excess data can be used to create forgeries */
        if (p != s + i || !rsa_check_digestinfo(sig, s, i)) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }

        /*
         * Parameters to the signature algorithm can also be used to create
         * forgeries
         */
        if (sig->algor->parameter
            && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
            goto err;
        }

        sigtype = OBJ_obj2nid(sig->algor->algorithm);

#ifdef RSA_DEBUG
        /* put a backward compatibility flag in EAY */
        fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype),
                OBJ_nid2ln(dtype));
#endif
        if (sigtype != dtype) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
            goto err;
        }
        if (rm) {
            const EVP_MD *md;
            md = EVP_get_digestbynid(dtype);
            if (md && (EVP_MD_size(md) != sig->digest->length))
                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
            else {
                memcpy(rm, sig->digest->data, sig->digest->length);
                *prm_len = sig->digest->length;
                ret = 1;
            }
        } else if (((unsigned int)sig->digest->length != m_len) ||
                   (memcmp(m, sig->digest->data, m_len) != 0)) {
            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
        } else
            ret = 1;
    }
 err:
    X509_SIG_free(sig);
    OPENSSL_clear_free(s, (unsigned int)siglen);
    return (ret);
}
Exemplo n.º 9
0
int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
	     unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
	{
	int i,ret=0,sigtype;
	unsigned char *p,*s;
	X509_SIG *sig=NULL;

	if (siglen != (unsigned int)RSA_size(rsa))
		{
		RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
		return(0);
		}

	if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
		{
		return rsa->meth->rsa_verify(dtype, m, m_len,
			sigbuf, siglen, rsa);
		}

	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
	if (s == NULL)
		{
		RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
			RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
			goto err;
	}
	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);

	if (i <= 0) goto err;

	/* Special case: SSL signature */
	if(dtype == NID_md5_sha1) {
		if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))
				RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
		else ret = 1;
	} else {
		p=s;
		sig=d2i_X509_SIG(NULL,&p,(long)i);

		if (sig == NULL) goto err;

		/* Excess data can be used to create forgeries */
		if(p != s+i)
			{
			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			goto err;
			}

		/* Parameters to the signature algorithm can also be used to
		   create forgeries */
		if(sig->algor->parameter
		   && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
			{
			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			goto err;
			}

		sigtype=OBJ_obj2nid(sig->algor->algorithm);


	#ifdef RSA_DEBUG
		/* put a backward compatibility flag in EAY */
		fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype),
			OBJ_nid2ln(dtype));
	#endif
		if (sigtype != dtype)
			{
			if (((dtype == NID_md5) &&
				(sigtype == NID_md5WithRSAEncryption)) ||
				((dtype == NID_md2) &&
				(sigtype == NID_md2WithRSAEncryption)))
				{
				/* ok, we will let it through */
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
				fprintf(stderr,"signature has problems, re-make with post SSLeay045\n");
#endif
				}
			else
				{
				RSAerr(RSA_F_RSA_VERIFY,
						RSA_R_ALGORITHM_MISMATCH);
				goto err;
				}
			}
		if (	((unsigned int)sig->digest->length != m_len) ||
			(memcmp(m,sig->digest->data,m_len) != 0))
			{
			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			}
		else
			ret=1;
	}
err:
	if (sig != NULL) X509_SIG_free(sig);
	if (s != NULL)
		{
		OPENSSL_cleanse(s,(unsigned int)siglen);
		OPENSSL_free(s);
		}
	return(ret);
	}
Exemplo n.º 10
0
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    EVP_PKEY *pkey;
    EVP_CIPHER_CTX *ctx;
    int keylen;
    X509_ALGOR *talg, *wrap_alg = NULL;
    ASN1_OBJECT *aoid;
    ASN1_BIT_STRING *pubkey;
    ASN1_STRING *wrap_str;
    ASN1_OCTET_STRING *ukm;
    unsigned char *penc = NULL;
    int penclen;
    int rv = 0;
    int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
    const EVP_MD *kdf_md;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* Get ephemeral key */
    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
                                             NULL, NULL, NULL))
        goto err;
    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
    /* Is everything uninitialised? */
    if (aoid == OBJ_nid2obj(NID_undef)) {

        EC_KEY *eckey = pkey->pkey.ec;
        /* Set the key */
        unsigned char *p;

        penclen = i2o_ECPublicKey(eckey, NULL);
        if (penclen <= 0)
            goto err;
        penc = OPENSSL_malloc(penclen);
        if (!penc)
            goto err;
        p = penc;
        penclen = i2o_ECPublicKey(eckey, &p);
        if (penclen <= 0)
            goto err;
        ASN1_STRING_set0(pubkey, penc, penclen);
        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;

        penc = NULL;
        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
                        V_ASN1_UNDEF, NULL);
    }

    /* See if custom paraneters set */
    kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
    if (kdf_type <= 0)
        goto err;
    if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
        goto err;
    ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
    if (ecdh_nid < 0)
        goto err;
    else if (ecdh_nid == 0)
        ecdh_nid = NID_dh_std_kdf;
    else if (ecdh_nid == 1)
        ecdh_nid = NID_dh_cofactor_kdf;

    if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
        kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
        if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
            goto err;
    } else
        /* Uknown KDF */
        goto err;
    if (kdf_md == NULL) {
        /* Fixme later for better MD */
        kdf_md = EVP_sha1();
        if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
            goto err;
    }

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
        goto err;

    /* Lookup NID for KDF+cofactor+digest */

    if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
        goto err;
    /* Get wrap NID */
    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    wrap_nid = EVP_CIPHER_CTX_type(ctx);
    keylen = EVP_CIPHER_CTX_key_length(ctx);

    /* Package wrap algorithm in an AlgorithmIdentifier */

    wrap_alg = X509_ALGOR_new();
    if (!wrap_alg)
        goto err;
    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
    wrap_alg->parameter = ASN1_TYPE_new();
    if (!wrap_alg->parameter)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
        goto err;
    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
        ASN1_TYPE_free(wrap_alg->parameter);
        wrap_alg->parameter = NULL;
    }

    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
        goto err;

    penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);

    if (!penclen)
        goto err;

    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
        goto err;
    penc = NULL;

    /*
     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     * of another AlgorithmIdentifier.
     */
    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
    if (!penc || !penclen)
        goto err;
    wrap_str = ASN1_STRING_new();
    if (!wrap_str)
        goto err;
    ASN1_STRING_set0(wrap_str, penc, penclen);
    penc = NULL;
    X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);

    rv = 1;

 err:
    OPENSSL_free(penc);
    X509_ALGOR_free(wrap_alg);
    return rv;
}
Exemplo n.º 11
0
int asn1parse_main(int argc, char **argv)
{
    ASN1_TYPE *at = NULL;
    BIO *in = NULL, *b64 = NULL, *derout = NULL;
    BUF_MEM *buf = NULL;
    STACK_OF(OPENSSL_STRING) *osk = NULL;
    char *genstr = NULL, *genconf = NULL;
    char *infile = NULL, *oidfile = NULL, *derfile = NULL;
    unsigned char *str = NULL;
    char *name = NULL, *header = NULL, *prog;
    const unsigned char *ctmpbuf;
    int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM;
    int offset = 0, ret = 1, i, j;
    long num, tmplen;
    unsigned char *tmpbuf;
    unsigned int length = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, asn1parse_options);

    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
        BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
        goto end;
    }

    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(asn1parse_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            derfile = opt_arg();
            break;
        case OPT_INDENT:
            indent = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_OID:
            oidfile = opt_arg();
            break;
        case OPT_OFFSET:
            offset = strtol(opt_arg(), NULL, 0);
            break;
        case OPT_LENGTH:
            length = atoi(opt_arg());
            break;
        case OPT_DUMP:
            dump = -1;
            break;
        case OPT_DLIMIT:
            dump = atoi(opt_arg());
            break;
        case OPT_STRPARSE:
            sk_OPENSSL_STRING_push(osk, opt_arg());
            break;
        case OPT_GENSTR:
            genstr = opt_arg();
            break;
        case OPT_GENCONF:
            genconf = opt_arg();
            break;
        case OPT_STRICTPEM:
            strictpem = 1;
            informat = FORMAT_PEM;
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (oidfile != NULL) {
        in = bio_open_default(oidfile, 'r', FORMAT_TEXT);
        if (in == NULL)
            goto end;
        OBJ_create_objects(in);
        BIO_free(in);
    }

    if ((in = bio_open_default(infile, 'r', informat)) == NULL)
        goto end;

    if (derfile && (derout = bio_open_default(derfile, 'w', FORMAT_ASN1)) == NULL)
        goto end;

    if (strictpem) {
        if (PEM_read_bio(in, &name, &header, &str, &num) !=
            1) {
            BIO_printf(bio_err, "Error reading PEM file\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    } else {

        if ((buf = BUF_MEM_new()) == NULL)
            goto end;
        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
            goto end;           /* Pre-allocate :-) */

        if (genstr || genconf) {
            num = do_generate(genstr, genconf, buf);
            if (num < 0) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        else {

            if (informat == FORMAT_PEM) {
                BIO *tmp;

                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
                    goto end;
                BIO_push(b64, in);
                tmp = in;
                in = b64;
                b64 = tmp;
            }

            num = 0;
            for (;;) {
                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
                    goto end;
                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
                if (i <= 0)
                    break;
                num += i;
            }
        }
        str = (unsigned char *)buf->data;

    }

    /* If any structs to parse go through in sequence */

    if (sk_OPENSSL_STRING_num(osk)) {
        tmpbuf = str;
        tmplen = num;
        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
            ASN1_TYPE *atmp;
            int typ;
            j = atoi(sk_OPENSSL_STRING_value(osk, i));
            if (j == 0) {
                BIO_printf(bio_err, "'%s' is an invalid number\n",
                           sk_OPENSSL_STRING_value(osk, i));
                continue;
            }
            tmpbuf += j;
            tmplen -= j;
            atmp = at;
            ctmpbuf = tmpbuf;
            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
            ASN1_TYPE_free(atmp);
            if (!at) {
                BIO_printf(bio_err, "Error parsing structure\n");
                ERR_print_errors(bio_err);
                goto end;
            }
            typ = ASN1_TYPE_get(at);
            if ((typ == V_ASN1_OBJECT)
                || (typ == V_ASN1_BOOLEAN)
                || (typ == V_ASN1_NULL)) {
                BIO_printf(bio_err, "Can't parse %s type\n", ASN1_tag2str(typ));
                ERR_print_errors(bio_err);
                goto end;
            }
            /* hmm... this is a little evil but it works */
            tmpbuf = at->value.asn1_string->data;
            tmplen = at->value.asn1_string->length;
        }
        str = tmpbuf;
        num = tmplen;
    }

    if (offset >= num) {
        BIO_printf(bio_err, "Error: offset too large\n");
        goto end;
    }

    num -= offset;

    if ((length == 0) || ((long)length > num))
        length = (unsigned int)num;
    if (derout) {
        if (BIO_write(derout, str + offset, length) != (int)length) {
            BIO_printf(bio_err, "Error writing output\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    if (!noout &&
        !ASN1_parse_dump(bio_out, &(str[offset]), length,
                         indent, dump)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    ret = 0;
 end:
    BIO_free(derout);
    BIO_free(in);
    BIO_free(b64);
    if (ret != 0)
        ERR_print_errors(bio_err);
    BUF_MEM_free(buf);
    OPENSSL_free(name);
    OPENSSL_free(header);
    if (strictpem)
        OPENSSL_free(str);
    ASN1_TYPE_free(at);
    sk_OPENSSL_STRING_free(osk);
    return (ret);
}
int int_rsa_verify(int dtype, const unsigned char *m,
			  unsigned int m_len,
			  unsigned char *rm, size_t *prm_len,
			  const unsigned char *sigbuf, size_t siglen,
			  RSA *rsa)
	{
	int i,ret=0,sigtype;
	unsigned char *s;
	X509_SIG *sig=NULL;

	if (siglen != (unsigned int)RSA_size(rsa))
		{
		RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
		return(0);
		}

	if((dtype == NID_md5_sha1) && rm)
		{
		i = RSA_public_decrypt((int)siglen,
					sigbuf,rm,rsa,RSA_PKCS1_PADDING);
		if (i <= 0)
			return 0;
		*prm_len = i;
		return 1;
		}

	s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen);
	if (s == NULL)
		{
		RSAerr(RSA_F_INT_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
			goto err;
	}
	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);

	if (i <= 0) goto err;

	/* Special case: SSL signature */
	if(dtype == NID_md5_sha1) {
		if((i != SSL_SIG_LENGTH) || TINYCLR_SSL_MEMCMP(s, m, SSL_SIG_LENGTH))
				RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
		else ret = 1;
	} else {
		const unsigned char *p=s;
		sig=d2i_X509_SIG(NULL,&p,(long)i);

		if (sig == NULL) goto err;

		/* Excess data can be used to create forgeries */
		if(p != s+i)
			{
			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			goto err;
			}

		/* Parameters to the signature algorithm can also be used to
		   create forgeries */
		if(sig->algor->parameter
		   && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL)
			{
			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			goto err;
			}

		sigtype=OBJ_obj2nid(sig->algor->algorithm);


	#ifdef RSA_DEBUG
		/* put a backward compatibility flag in EAY */
		TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype),
			OBJ_nid2ln(dtype));
	#endif
		if (sigtype != dtype)
			{
			if (((dtype == NID_md5) &&
				(sigtype == NID_md5WithRSAEncryption)) ||
				((dtype == NID_md2) &&
				(sigtype == NID_md2WithRSAEncryption)))
				{
				/* ok, we will let it through */
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
				TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR,"signature has problems, re-make with post SSLeay045\n");
#endif
				}
			else
				{
				RSAerr(RSA_F_INT_RSA_VERIFY,
						RSA_R_ALGORITHM_MISMATCH);
				goto err;
				}
			}
		if (rm)
			{
			const EVP_MD *md;
			md = EVP_get_digestbynid(dtype);
			if (md && (EVP_MD_size(md) != sig->digest->length))
				RSAerr(RSA_F_INT_RSA_VERIFY,
						RSA_R_INVALID_DIGEST_LENGTH);
			else
				{
				TINYCLR_SSL_MEMCPY(rm, sig->digest->data,
							sig->digest->length);
				*prm_len = sig->digest->length;
				ret = 1;
				}
			}
		else if (((unsigned int)sig->digest->length != m_len) ||
			(TINYCLR_SSL_MEMCMP(m,sig->digest->data,m_len) != 0))
			{
			RSAerr(RSA_F_INT_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
			}
		else
			ret=1;
	}
err:
	if (sig != NULL) X509_SIG_free(sig);
	if (s != NULL)
		{
		OPENSSL_cleanse(s,(unsigned int)siglen);
		OPENSSL_free(s);
		}
	return(ret);
	}
Exemplo n.º 13
0
int
int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
    unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf,
    size_t siglen, RSA *rsa)
{
	int i, ret = 0, sigtype;
	unsigned char *s;
	X509_SIG *sig = NULL;

	if (siglen != (unsigned int)RSA_size(rsa)) {
		RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
		return 0;
	}

	if ((dtype == NID_md5_sha1) && rm) {
		i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa,
		    RSA_PKCS1_PADDING);
		if (i <= 0)
			return 0;
		*prm_len = i;
		return 1;
	}

	s = malloc(siglen);
	if (s == NULL) {
		RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (dtype == NID_md5_sha1 && m_len != SSL_SIG_LENGTH) {
		RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
		goto err;
	}
	i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);

	if (i <= 0)
		goto err;

	/* Special case: SSL signature */
	if (dtype == NID_md5_sha1) {
		if (i != SSL_SIG_LENGTH || memcmp(s, m, SSL_SIG_LENGTH))
			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
		else
			ret = 1;
	} else {
		const unsigned char *p = s;

		sig = d2i_X509_SIG(NULL, &p, (long)i);

		if (sig == NULL)
			goto err;

		/* Excess data can be used to create forgeries */
		if (p != s + i) {
			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
			goto err;
		}

		/* Parameters to the signature algorithm can also be used to
		   create forgeries */
		if (sig->algor->parameter &&
		    ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) {
			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
			goto err;
		}

		sigtype = OBJ_obj2nid(sig->algor->algorithm);

		if (sigtype != dtype) {
			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);
			goto err;
		}
		if (rm) {
			const EVP_MD *md;

			md = EVP_get_digestbynid(dtype);
			if (md && (EVP_MD_size(md) != sig->digest->length))
				RSAerr(RSA_F_INT_RSA_VERIFY,
				    RSA_R_INVALID_DIGEST_LENGTH);
			else {
				memcpy(rm, sig->digest->data,
				    sig->digest->length);
				*prm_len = sig->digest->length;
				ret = 1;
			}
		} else if ((unsigned int)sig->digest->length != m_len ||
		    memcmp(m, sig->digest->data, m_len) != 0) {
			RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
		} else
			ret = 1;
	}
err:
	if (sig != NULL)
		X509_SIG_free(sig);
	if (s != NULL) {
		explicit_bzero(s, (unsigned int)siglen);
		free(s);
	}
	return ret;
}
Exemplo n.º 14
0
char	*get_challenge(scep_t *scep) {
	int		loc, type, n;
	X509_ATTRIBUTE	*attr;
	X509_REQ	*req;
	ASN1_TYPE	*asn1;
	ASN1_IA5STRING	*asn1_string;
	char		*challenge;

	/* get our hands on the request					*/
	req = scep->clientreq;
	if (debug)
		BIO_printf(bio_err, "%s:%d: getting challenge password from "
			"X.509 request %p\n", __FILE__, __LINE__, req);

	/* if the client req is not set, we have no chance of finding	*/
	/* password							*/
	if (NULL == req) {
		BIO_printf(bio_err, "%s:%d: no X.509 request available\n",
			__FILE__, __LINE__);
		goto err;
	}

	/* get the challengePassword attribute from the request		*/
	n = X509_REQ_get_attr_count(req);
	if (debug)
		BIO_printf(bio_err, "%s%d: %d attributes found\n", __FILE__,
			__LINE__, n);
	loc = X509_REQ_get_attr_by_NID(req, NID_pkcs9_challengePassword, -1);
	if (loc < 0) {
		if (debug)
			BIO_printf(bio_err, "%s:%d: challengePassword not "
				"found\n", __FILE__, __LINE__);
		return NULL;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: challengePassword at offset %d\n",
			__FILE__, __LINE__, loc);
	attr = X509_REQ_get_attr(req, loc);

	/* retrieve the value of the challengePassword attribute	*/
	if (NULL == (asn1 = X509_ATTRIBUTE_get0_type(attr, 0))) {
		BIO_printf(bio_err, "%s:%d: cannot retrieve value\n",
			__FILE__, __LINE__);
		goto err;
	}
	
	type = ASN1_TYPE_get(asn1);
	if (debug)
		BIO_printf(bio_err, "%s:%d: type of challengePassword is %d\n",
			__FILE__, __LINE__, type);
	if ((type != V_ASN1_IA5STRING) && (type != V_ASN1_PRINTABLESTRING)) {
		BIO_printf(bio_err, "%s:%d: challengePassword has wrong type\n",
			__FILE__, __LINE__, type);
		goto err;
	}

	asn1_string = (ASN1_STRING *)asn1->value.ptr;
	challenge = (char *)malloc(asn1_string->length + 1);
	memcpy(challenge, asn1_string->data, asn1_string->length);
	challenge[asn1_string->length] = '\0';
	if (debug)
		BIO_printf(bio_err, "%s:%d: challenge Password '%s'\n",
			__FILE__, __LINE__, challenge);

	/* return the challenge password we have found			*/
	return challenge;

	/* error return							*/
err:
	ERR_print_errors(bio_err);
	return NULL;
}