Exemplo n.º 1
0
X509_PKEY *
X509_PKEY_new(void)
{
	X509_PKEY *ret = NULL;

	if ((ret = malloc(sizeof(X509_PKEY))) == NULL) {
		ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE,
		    __LINE__);
		return NULL;
	}
	ret->version = 0;
	if ((ret->enc_algor = X509_ALGOR_new()) == NULL) {
		free(ret);
		return NULL;
	}
	if ((ret->enc_pkey = M_ASN1_OCTET_STRING_new()) == NULL) {
		X509_ALGOR_free(ret->enc_algor);
		free(ret);
		return NULL;
	}
	ret->dec_pkey = NULL;
	ret->key_length = 0;
	ret->key_data = NULL;
	ret->key_free = 0;
	ret->cipher.cipher = NULL;
	memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
	ret->references = 1;
	return (ret);
}
Exemplo n.º 2
0
ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
        const ASN1_ITEM *it,
        const char *pass, int passlen,
        void *obj, int zbuf)
{
    ASN1_OCTET_STRING *oct;
    unsigned char *in = NULL;
    int inlen;
    if (!(oct = M_ASN1_OCTET_STRING_new())) {
        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    inlen = ASN1_item_i2d(obj, &in, it);
    if (!in) {
        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR);
        return NULL;
    }
    if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
                          &oct->length, 1)) {
        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
        OPENSSL_free(in);
        return NULL;
    }
    if (zbuf)
        OPENSSL_cleanse(in, inlen);
    OPENSSL_free(in);
    return oct;
}
Exemplo n.º 3
0
static X509_EXTENSION *do_ext_i2d(X509V3_EXT_METHOD *method, int ext_nid,
						 int crit, void *ext_struc)
{
	unsigned char *ext_der, *p;
	int ext_len;
	ASN1_OCTET_STRING *ext_oct;
	X509_EXTENSION *ext;
	/* Convert internal representation to DER */
	ext_len = method->i2d(ext_struc, NULL);
	if(!(ext_der = OPENSSL_malloc(ext_len))) goto merr;
	p = ext_der;
	method->i2d(ext_struc, &p);
	if(!(ext_oct = M_ASN1_OCTET_STRING_new())) goto merr;
	ext_oct->data = ext_der;
	ext_oct->length = ext_len;
	
	ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
	if(!ext) goto merr;
	M_ASN1_OCTET_STRING_free(ext_oct);

	return ext;

	merr:
	X509V3err(X509V3_F_DO_EXT_I2D,ERR_R_MALLOC_FAILURE);
	return NULL;

}
Exemplo n.º 4
0
PKCS12 *PKCS12_init(int mode)
{
	PKCS12 *pkcs12;
	if (!(pkcs12 = PKCS12_new())) {
		PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	ASN1_INTEGER_set(pkcs12->version, 3);
	pkcs12->authsafes->type = OBJ_nid2obj(mode);
	switch (mode) {
		case NID_pkcs7_data:
			if (!(pkcs12->authsafes->d.data =
				 M_ASN1_OCTET_STRING_new())) {
			PKCS12err(PKCS12_F_PKCS12_INIT,ERR_R_MALLOC_FAILURE);
			goto err;
		}
		break;
		default:
			PKCS12err(PKCS12_F_PKCS12_INIT,
				PKCS12_R_UNSUPPORTED_PKCS12_MODE);
			goto err;
	}
		
	return pkcs12;
err:
	if (pkcs12 != NULL) PKCS12_free(pkcs12);
	return NULL;
}
Exemplo n.º 5
0
static ASN1_OCTET_STRING *pkcs12_item_i2d_encrypt(X509_ALGOR *algor,
                                                  const ASN1_ITEM *it,
                                                  const uint8_t *pass_raw,
                                                  size_t pass_raw_len, void *obj) {
  ASN1_OCTET_STRING *oct;
  uint8_t *in = NULL;
  int in_len;
  size_t crypt_len;

  oct = M_ASN1_OCTET_STRING_new();
  if (oct == NULL) {
    OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  in_len = ASN1_item_i2d(obj, &in, it);
  if (!in) {
    OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCODE_ERROR);
    return NULL;
  }
  if (!pbe_crypt(algor, pass_raw, pass_raw_len, in, in_len, &oct->data, &crypt_len,
                 1 /* encrypt */)) {
    OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCRYPT_ERROR);
    OPENSSL_free(in);
    return NULL;
  }
  oct->length = crypt_len;
  OPENSSL_cleanse(in, in_len);
  OPENSSL_free(in);
  return oct;
}
Exemplo n.º 6
0
int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
	{
	ASN1_OCTET_STRING *os = NULL;

	switch (OBJ_obj2nid(p7->type))
		{
		case NID_pkcs7_data:
		os = p7->d.data;
		break;

		case NID_pkcs7_signedAndEnveloped:
		os = p7->d.signed_and_enveloped->enc_data->enc_data;
		if (os == NULL)
			{
			os=M_ASN1_OCTET_STRING_new();
			p7->d.signed_and_enveloped->enc_data->enc_data=os;
			}
		break;

		case NID_pkcs7_enveloped:
		os = p7->d.enveloped->enc_data->enc_data;
		if (os == NULL)
			{
			os=M_ASN1_OCTET_STRING_new();
			p7->d.enveloped->enc_data->enc_data=os;
			}
		break;

		case NID_pkcs7_signed:
		os=p7->d.sign->contents->d.data;
		break;

		default:
		os = NULL;
		break;
		}
	
	if (os == NULL)
		return 0;

	os->flags |= ASN1_STRING_FLAG_NDEF;
	*boundary = &os->data;

	return 1;
	}
Exemplo n.º 7
0
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
{
    ASN1_STRING *os;

    if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
    if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
    ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
    return(1);
}
Exemplo n.º 8
0
PKCS12_MAC_DATA *PKCS12_MAC_DATA_new(void)
{
	PKCS12_MAC_DATA *ret=NULL;
	ASN1_CTX c;
	M_ASN1_New_Malloc(ret, PKCS12_MAC_DATA);
	ret->dinfo = X509_SIG_new();
	ret->salt = M_ASN1_OCTET_STRING_new();
	ret->iter = NULL;
	return(ret);
	M_ASN1_New_Error(ASN1_F_PKCS12_MAC_DATA_NEW);
}
Exemplo n.º 9
0
static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
                                      X509V3_CTX *ctx, char *str)
{
    ASN1_OCTET_STRING *oct;
    ASN1_BIT_STRING *pk;
    unsigned char pkey_dig[EVP_MAX_MD_SIZE];
    unsigned int diglen;

    if (strcmp(str, "hash"))
        return s2i_ASN1_OCTET_STRING(method, ctx, str);

    if (!(oct = M_ASN1_OCTET_STRING_new())) {
        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (ctx && (ctx->flags == CTX_TEST))
        return oct;

    if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
        goto err;
    }

    if (ctx->subject_req)
        pk = ctx->subject_req->req_info->pubkey->public_key;
    else
        pk = ctx->subject_cert->cert_info->key->public_key;

    if (!pk) {
        OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
        goto err;
    }

    if (!EVP_Digest
        (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL))
        goto err;

    if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
        OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    return oct;

 err:
    M_ASN1_OCTET_STRING_free(oct);
    return NULL;
}
int PKCS7_set_type(PKCS7 *p7, int type)
	{
	ASN1_OBJECT *obj;

	PKCS7_content_free(p7);
	obj=OBJ_nid2obj(type); /* will not fail */

	switch (type)
		{
	case NID_pkcs7_signed:
		p7->type=obj;
		if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL)
			goto err;
		ASN1_INTEGER_set(p7->d.sign->version,1);
		break;
	case NID_pkcs7_data:
		p7->type=obj;
		if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL)
			goto err;
		break;
	case NID_pkcs7_signedAndEnveloped:
		p7->type=obj;
		if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new())
			== NULL) goto err;
		ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1);
		break;
	case NID_pkcs7_enveloped:
		p7->type=obj;
		if ((p7->d.enveloped=PKCS7_ENVELOPE_new())
			== NULL) goto err;
		ASN1_INTEGER_set(p7->d.enveloped->version,0);
		break;
	case NID_pkcs7_encrypted:
		p7->type=obj;
		if ((p7->d.encrypted=PKCS7_ENCRYPT_new())
			== NULL) goto err;
		ASN1_INTEGER_set(p7->d.encrypted->version,0);
		break;

	case NID_pkcs7_digest:
	default:
		PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
		goto err;
		}
	return(1);
err:
	return(0);
	}
Exemplo n.º 11
0
/* Create a generic extension: for now just handle DER type */
static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
					    int crit, int gen_type,
					    X509V3_CTX *ctx)
	{
	unsigned char *ext_der=NULL;
	long ext_len;
	ASN1_OBJECT *obj=NULL;
	ASN1_OCTET_STRING *oct=NULL;
	X509_EXTENSION *extension=NULL;
	if (!(obj = OBJ_txt2obj(ext, 0)))
		{
		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR);
		ERR_add_error_data(2, "name=", ext);
		goto err;
		}

	if (gen_type == 1)
		ext_der = string_to_hex(value, &ext_len);
	else if (gen_type == 2)
		ext_der = generic_asn1(value, ctx, &ext_len);

	if (ext_der == NULL)
		{
		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR);
		ERR_add_error_data(2, "value=", value);
		goto err;
		}

	if (!(oct = M_ASN1_OCTET_STRING_new()))
		{
		X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	oct->data = ext_der;
	oct->length = ext_len;
	ext_der = NULL;

	extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);

	err:
	ASN1_OBJECT_free(obj);
	M_ASN1_OCTET_STRING_free(oct);
	if(ext_der) OPENSSL_free(ext_der);
	return extension;

	}
Exemplo n.º 12
0
ASN1_OCTET_STRING *
s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str)
{
	ASN1_OCTET_STRING *oct;
	long length;

	if (!(oct = M_ASN1_OCTET_STRING_new())) {
		X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	if (!(oct->data = string_to_hex(str, &length))) {
		M_ASN1_OCTET_STRING_free(oct);
		return NULL;
	}

	oct->length = length;

	return oct;
}
Exemplo n.º 13
0
static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
                                  int ext_nid, int crit, void *ext_struc)
{
    unsigned char *ext_der;
    int ext_len;
    ASN1_OCTET_STRING *ext_oct;
    X509_EXTENSION *ext;
    /* Convert internal representation to DER */
    if (method->it) {
        ext_der = NULL;
        ext_len =
            ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
        if (ext_len < 0)
            goto merr;
    } else {
        unsigned char *p;
        ext_len = method->i2d(ext_struc, NULL);
        if (!(ext_der = OPENSSL_malloc(ext_len)))
            goto merr;
        p = ext_der;
        method->i2d(ext_struc, &p);
    }
    if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
        goto merr;
    ext_oct->data = ext_der;
    ext_oct->length = ext_len;

    ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
    if (!ext)
        goto merr;
    M_ASN1_OCTET_STRING_free(ext_oct);

    return ext;

 merr:
    OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    return NULL;

}
Exemplo n.º 14
0
X509_PKEY *X509_PKEY_new(void)
{
    X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
    if (ret == NULL) {
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    memset(ret, 0, sizeof(X509_PKEY));

    ret->enc_algor = X509_ALGOR_new();
    if (ret->enc_algor == NULL)
        goto err;
    ret->enc_pkey = M_ASN1_OCTET_STRING_new();
    if (ret->enc_pkey == NULL)
        goto err;
    return ret;

 err:
    if (ret != NULL)
        X509_PKEY_free(ret);
    return NULL;
}
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 (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
		goto err;

	/* Dummy cipherinit to just setup the IV */
	EVP_CipherInit(&ctx, cipher, 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);
		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(kdf, (i2d_func_t)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(pbe2, (i2d_func_t)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;

}
Exemplo n.º 16
0
bool InteropResolver::checkMatch(DSIGKeyInfoList * lst, X509 * x) {

	// Check if the parameters in x match the required certificate


	int sz = (int) lst->getSize();
	DSIGKeyInfo* k;
	
	for (int i = 0; i < sz; ++i) {

		k = lst->item(i);

		if (k->getKeyInfoType() == DSIGKeyInfo::KEYINFO_X509) {

			DSIGKeyInfoX509 * kx = static_cast<DSIGKeyInfoX509 *>(k);
			
			const XMLCh * serial = kx->getX509IssuerSerialNumber();

			if (serial != NULL) {

				char * cserial = XMLString::transcode(serial);
				char * xserial;

				BIGNUM * bnserial = ASN1_INTEGER_to_BN(x->cert_info->serialNumber, NULL);
				xserial = BN_bn2dec(bnserial);
				BN_free(bnserial);

				if (strcmp(xserial, cserial) == 0) {
					
					OPENSSL_free(xserial);
					XSEC_RELEASE_XMLCH(cserial);
					return true;

				}
				//delete[] xserial;
				XSEC_RELEASE_XMLCH(cserial);
				OPENSSL_free(xserial);

			}

			/* 
			 * Either it's not a serial number, or we didn't pass, so lets
			 * look at the next option.
			 */
			
			const XMLCh * ski = kx->getX509SKI();
			
			if (ski != NULL) {

				char * cski = XMLString::transcode(ski);
				int clen = (int) strlen(cski);
				unsigned char * xski = new unsigned char[clen];
				ArrayJanitor <unsigned char> j_xski(xski);

				// Decode

				OpenSSLCryptoBase64 b64;
				b64.decodeInit();
				int xlen = b64.decode((unsigned char *) cski, clen, xski, clen);
				xlen += b64.decodeFinish(&xski[xlen], clen - xlen);
                XSEC_RELEASE_XMLCH(cski);

				if (xlen != 0) {

					// Have a buffer with a number in it
					STACK_OF(X509_EXTENSION) *exts;
					exts = x->cert_info->extensions;

					if (exts != NULL) {

						// Find the Subject Key Identifier OID
						X509_EXTENSION * ext;
						ASN1_OBJECT * objski = OBJ_nid2obj(NID_subject_key_identifier);
						int extn = X509v3_get_ext_by_OBJ(exts, objski, -1);
						if (extn != -1) {
							// Dummy up an OCTET_STRING from the xski
							unsigned char * octxski = new unsigned char[xlen + 2];
							ArrayJanitor<unsigned char> j_octxski(octxski);

							octxski[0] = 4;
							octxski[1] = xlen;
							memcpy(&octxski[2], xski, xlen);
							
							ext = sk_X509_EXTENSION_value(exts,extn);
							ASN1_OCTET_STRING *skid = ext->value;
							ASN1_OCTET_STRING * xskid = M_ASN1_OCTET_STRING_new();
							ASN1_STRING_set(xskid, octxski, xlen+2);
							
							if (ASN1_OCTET_STRING_cmp(xskid, skid) == 0) {
								ASN1_OCTET_STRING_free(xskid);
								return true;
							}
						}

					}

				}

			}

			/* Not a subject key identifier */
			const XMLCh *sn = kx->getX509SubjectName();

			if (sn != NULL) {

				char * csn = XMLString::transcode(sn);

				X509_NAME * x509name = X509_get_subject_name(x);
				X509_NAME * snname = X509_NAME_create_from_txt(csn);
				XSEC_RELEASE_XMLCH(csn);

				if (snname != NULL) {

					if (!X509_NAME_cmp(x509name, snname)) {
						X509_NAME_free(snname);
						return true;
					}
				
					X509_NAME_free(snname);
				}
			}
		}
	}

	return false;

}
Exemplo n.º 17
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	unsigned char *p,*pp=NULL;
	int x;
	ASN1_OCTET_STRING *os=NULL;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		os=M_ASN1_OCTET_STRING_new();
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		os=M_ASN1_OCTET_STRING_new();
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=p7->d.sign->contents->d.data;
		/* If detached data then the content is excluded */
		if(p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;
		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;
			for (;;)
				{
				if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) 
					== NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
					goto err;
					}
				BIO_get_md_ctx(btmp,&mdc);
				if (mdc == NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
					goto err;
					}
				if (EVP_MD_CTX_type(mdc) == j)
					break;
				else
					btmp=BIO_next(btmp);
				}
			
			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp));
			if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE];
				unsigned int md_len;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time */
				sign_time=X509_gmtime_adj(NULL,0);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_signingTime,
					V_ASN1_UTCTIME,sign_time);

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
				digest=M_ASN1_OCTET_STRING_new();
				M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the mess */
				EVP_SignInit(&ctx_tmp,md_tmp);
				x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,
					   i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				pp=(unsigned char *)OPENSSL_malloc(x);
				p=pp;
				i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,
				           i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				EVP_SignUpdate(&ctx_tmp,pp,x);
				OPENSSL_free(pp);
				pp=NULL;
				}

#ifndef NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}

	if (!p7->detached)
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	if (pp != NULL) OPENSSL_free(pp);
	pp=NULL;

	ret=1;
err:
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
Exemplo n.º 18
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)
		memcpy (osalt->data, salt, saltlen);
	else if (!RAND_bytes(osalt->data, saltlen))
		goto merr;

	if(iter <= 0)
		iter = PKCS5_DEFAULT_ITERATIONS;

	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 = (ASN1_OBJECT*) 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:
	OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
	PBKDF2PARAM_free(kdf);
	X509_ALGOR_free(keyfunc);
	return NULL;
	}
Exemplo n.º 19
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;

}
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	ASN1_OCTET_STRING *os=NULL;

	EVP_MD_CTX_init(&ctx_tmp);
	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=PKCS7_get_octet_string(p7->d.sign->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;

	case NID_pkcs7_digest:
		os=PKCS7_get_octet_string(p7->d.digest->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
			{
			M_ASN1_OCTET_STRING_free(os);
			p7->d.digest->contents->d.data = NULL;
			}
		break;

		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
			if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
				unsigned int md_len, alen;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time if not already present */
				if (!PKCS7_get_signed_attribute(si,
							NID_pkcs9_signingTime))
					{
					if (!(sign_time=X509_gmtime_adj(NULL,0)))
						{
						PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
							ERR_R_MALLOC_FAILURE);
						goto err;
						}
					PKCS7_add_signed_attribute(si,
						NID_pkcs9_signingTime,
						V_ASN1_UTCTIME,sign_time);
					}

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
				if (!(digest=M_ASN1_OCTET_STRING_new()))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				if (!M_ASN1_OCTET_STRING_set(digest,md_data,
								md_len))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the attributes */
				EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
				alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
							ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
				if(!abuf) goto err;
				EVP_SignUpdate(&ctx_tmp,abuf,alen);
				OPENSSL_free(abuf);
				}

#ifndef OPENSSL_NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
 			if (si->pkey->type == EVP_PKEY_EC)
 				ctx_tmp.digest=EVP_ecdsa();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}
	else if (i == NID_pkcs7_digest)
		{
		unsigned char md_data[EVP_MAX_MD_SIZE];
		unsigned int md_len;
		if (!PKCS7_find_digest(&mdc, bio,
				OBJ_obj2nid(p7->d.digest->md->algorithm)))
			goto err;
		EVP_DigestFinal_ex(mdc,md_data,&md_len);
		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
		}

	if (!PKCS7_is_detached(p7))
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	ret=1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
Exemplo n.º 21
0
static LUA_FUNCTION(openssl_pkcs7_sign_digest)
{
  PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7");
  size_t l;
  const char* data = luaL_checklstring(L, 2, &l);
  long flags = luaL_optint(L, 3, 0);
  int hash = lua_isnoneornil(L, 4) ? 0 : lua_toboolean(L, 4);

  int ret = 0;
  int i, j;

  const EVP_MD* md;
  PKCS7_SIGNER_INFO *si;
  EVP_MD_CTX mdc;
  STACK_OF(X509_ATTRIBUTE) *sk;
  STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
  ASN1_OCTET_STRING *os = NULL;

  if (p7->d.ptr == NULL)
  {
    luaL_error(L, "pkcs7 without content");
    return 0;
  }

  flags |= PKCS7_DETACHED;
  PKCS7_set_detached(p7, 1);

  EVP_MD_CTX_init(&mdc);
  i = OBJ_obj2nid(p7->type);
  p7->state = PKCS7_S_HEADER;

  switch (i)
  {
  case NID_pkcs7_data:
    os = p7->d.data;
    break;
  case NID_pkcs7_signedAndEnveloped:
    /* XXXXXXXXXXXXXXXX */
    si_sk = p7->d.signed_and_enveloped->signer_info;
    os = p7->d.signed_and_enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.signed_and_enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_enveloped:
    /* XXXXXXXXXXXXXXXX */
    os = p7->d.enveloped->enc_data->enc_data;
    if (!os)
    {
      os = M_ASN1_OCTET_STRING_new();
      if (!os)
      {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      p7->d.enveloped->enc_data->enc_data = os;
    }
    break;
  case NID_pkcs7_signed:
    si_sk = p7->d.sign->signer_info;
    os = PKCS7_get_octet_string(p7->d.sign->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.sign->contents->d.data = NULL;
    }
    break;

  case NID_pkcs7_digest:
    os = PKCS7_get_octet_string(p7->d.digest->contents);
    /* If detached data then the content is excluded */
    if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
    {
      M_ASN1_OCTET_STRING_free(os);
      os = NULL;
      p7->d.digest->contents->d.data = NULL;
    }
    break;

  default:
    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
    goto err;
  }

  if (si_sk != NULL)
  {
    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
    {
      si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
      if (si->pkey == NULL)
        continue;
      j = OBJ_obj2nid(si->digest_alg->algorithm);
      md = EVP_get_digestbynid(j);
      EVP_DigestInit_ex(&mdc, md, NULL);

      if (hash)
      {
        if (l == (size_t) mdc.digest->ctx_size)
        {
          memcpy(mdc.md_data, data, l);
        }
        else
        {
          EVP_MD_CTX_cleanup(&mdc);
          luaL_argerror(L, 2, "data with wrong length");
        }
      }
      else
        EVP_DigestUpdate(&mdc, data, l);

      sk = si->auth_attr;

      /*
      * If there are attributes, we add the digest attribute and only
      * sign the attributes
      */
      if (sk_X509_ATTRIBUTE_num(sk) > 0)
      {
        if (!do_pkcs7_signed_attrib(si, &mdc))
          goto err;
      }
      else
      {
        unsigned char *abuf = NULL;
        unsigned int abuflen;
        abuflen = EVP_PKEY_size(si->pkey);
        abuf = OPENSSL_malloc(abuflen);
        if (!abuf)
          goto err;

        if (!EVP_SignFinal(&mdc, abuf, &abuflen, si->pkey))
        {
          PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
          goto err;
        }
        ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
      }
    }
  }
  else if (i == NID_pkcs7_digest)
  {
    unsigned char md_data[EVP_MAX_MD_SIZE];
    unsigned int md_len;
    md = EVP_get_digestbynid(OBJ_obj2nid(p7->d.digest->md->algorithm));
    EVP_DigestInit_ex(&mdc, md, NULL);
    if (l == (size_t) mdc.digest->ctx_size)
    {
      memcpy(mdc.md_data, data, l);
    }
    else
    {
      EVP_MD_CTX_cleanup(&mdc);
      luaL_error(L, "data with wrong data");
    }
    if (!EVP_DigestFinal_ex(&mdc, md_data, &md_len))
      goto err;
    M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
  }

  if (!PKCS7_is_detached(p7))
  {
    /*
    * NOTE(emilia): I think we only reach os == NULL here because detached
    * digested data support is broken.
    */
    if (os == NULL)
      goto err;
    if (!(os->flags & ASN1_STRING_FLAG_NDEF))
    {
      char *cont = memdup(data, l);
      long contlen = l;
      ASN1_STRING_set0(os, (unsigned char *) cont, contlen);
    }
  }

  ret = 1;
err:
  EVP_MD_CTX_cleanup(&mdc);
  return openssl_pushresult(L, ret);
}
Exemplo n.º 22
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
{
    int ret = 0;
    int i, j;
    BIO *btmp;
    PKCS7_SIGNER_INFO *si;
    EVP_MD_CTX *mdc, ctx_tmp;
    STACK_OF(X509_ATTRIBUTE) *sk;
    STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
    ASN1_OCTET_STRING *os = NULL;

    if (p7 == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
        return 0;
    }

    if (p7->d.ptr == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
        return 0;
    }

    EVP_MD_CTX_init(&ctx_tmp);
    i = OBJ_obj2nid(p7->type);
    p7->state = PKCS7_S_HEADER;

    switch (i) {
    case NID_pkcs7_data:
        os = p7->d.data;
        break;
    case NID_pkcs7_signedAndEnveloped:
        /* XXXXXXXXXXXXXXXX */
        si_sk = p7->d.signed_and_enveloped->signer_info;
        os = p7->d.signed_and_enveloped->enc_data->enc_data;
        if (!os) {
            os = M_ASN1_OCTET_STRING_new();
            if (!os) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            p7->d.signed_and_enveloped->enc_data->enc_data = os;
        }
        break;
    case NID_pkcs7_enveloped:
        /* XXXXXXXXXXXXXXXX */
        os = p7->d.enveloped->enc_data->enc_data;
        if (!os) {
            os = M_ASN1_OCTET_STRING_new();
            if (!os) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            p7->d.enveloped->enc_data->enc_data = os;
        }
        break;
    case NID_pkcs7_signed:
        si_sk = p7->d.sign->signer_info;
        os = PKCS7_get_octet_string(p7->d.sign->contents);
        /* If detached data then the content is excluded */
        if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
            M_ASN1_OCTET_STRING_free(os);
            os = NULL;
            p7->d.sign->contents->d.data = NULL;
        }
        break;

    case NID_pkcs7_digest:
        os = PKCS7_get_octet_string(p7->d.digest->contents);
        /* If detached data then the content is excluded */
        if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
            M_ASN1_OCTET_STRING_free(os);
            os = NULL;
            p7->d.digest->contents->d.data = NULL;
        }
        break;

    default:
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        goto err;
    }

    if (si_sk != NULL) {
        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
            si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
            if (si->pkey == NULL)
                continue;

            j = OBJ_obj2nid(si->digest_alg->algorithm);

            btmp = bio;

            btmp = PKCS7_find_digest(&mdc, btmp, j);

            if (btmp == NULL)
                goto err;

            /*
             * We now have the EVP_MD_CTX, lets do the signing.
             */
            if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
                goto err;

            sk = si->auth_attr;

            /*
             * If there are attributes, we add the digest attribute and only
             * sign the attributes
             */
            if (sk_X509_ATTRIBUTE_num(sk) > 0) {
                if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
                    goto err;
            } else {
                unsigned char *abuf = NULL;
                unsigned int abuflen;
                abuflen = EVP_PKEY_size(si->pkey);
                abuf = OPENSSL_malloc(abuflen);
                if (!abuf)
                    goto err;

                if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) {
                    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
                    goto err;
                }
                ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
            }
        }
    } else if (i == NID_pkcs7_digest) {
        unsigned char md_data[EVP_MAX_MD_SIZE];
        unsigned int md_len;
        if (!PKCS7_find_digest(&mdc, bio,
                               OBJ_obj2nid(p7->d.digest->md->algorithm)))
            goto err;
        if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
            goto err;
        M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
    }

    if (!PKCS7_is_detached(p7)) {
        /*
         * NOTE(emilia): I think we only reach os == NULL here because detached
         * digested data support is broken.
         */
        if (os == NULL)
            goto err;
        if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
            char *cont;
            long contlen;
            btmp = BIO_find_type(bio, BIO_TYPE_MEM);
            if (btmp == NULL) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
                goto err;
            }
            contlen = BIO_get_mem_data(btmp, &cont);
            /*
             * Mark the BIO read only then we can use its copy of the data
             * instead of making an extra copy.
             */
            BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
            BIO_set_mem_eof_return(btmp, 0);
            ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
        }
    }
    ret = 1;
 err:
    EVP_MD_CTX_cleanup(&ctx_tmp);
    return (ret);
}
Exemplo n.º 23
0
ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void)
{ return M_ASN1_OCTET_STRING_new(); }