Example #1
0
static isc_result_t
pkcs11ecdsa_tofile(const dst_key_t *key, const char *directory) {
	isc_result_t ret;
	pk11_object_t *ec;
	dst_private_t priv;
	unsigned char *buf = NULL;
	unsigned int i = 0;
	CK_ATTRIBUTE *attr;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	ec = key->keydata.pkey;
	attr = pk11_attribute_bytype(ec, CKA_VALUE);
	if (attr != NULL) {
		buf = isc_mem_get(key->mctx, attr->ulValueLen);
		if (buf == NULL)
			return (ISC_R_NOMEMORY);
		priv.elements[i].tag = TAG_ECDSA_PRIVATEKEY;
		priv.elements[i].length = (unsigned short) attr->ulValueLen;
		memmove(buf, attr->pValue, attr->ulValueLen);
		priv.elements[i].data = buf;
		i++;
	}

	if (key->engine != NULL) {
		priv.elements[i].tag = TAG_ECDSA_ENGINE;
		priv.elements[i].length = strlen(key->engine) + 1;
		priv.elements[i].data = (unsigned char *)key->engine;
		i++;
	}

	if (key->label != NULL) {
		priv.elements[i].tag = TAG_ECDSA_LABEL;
		priv.elements[i].length = strlen(key->label) + 1;
		priv.elements[i].data = (unsigned char *)key->label;
		i++;
	}

	priv.nelements = i;
	ret = dst__privstruct_writefile(key, &priv, directory);

	if (buf != NULL) {
		memset(buf, 0, attr->ulValueLen);
		isc_mem_put(key->mctx, buf, attr->ulValueLen);
	}
	return (ret);
}
Example #2
0
static isc_result_t
openssldsa_tofile(const dst_key_t *key, const char *directory) {
	int cnt = 0;
	DSA *dsa;
	dst_private_t priv;
	unsigned char bufs[5][128];

	if (key->keydata.dsa == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	dsa = key->keydata.dsa;

	priv.elements[cnt].tag = TAG_DSA_PRIME;
	priv.elements[cnt].length = BN_num_bytes(dsa->p);
	BN_bn2bin(dsa->p, bufs[cnt]);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
	priv.elements[cnt].length = BN_num_bytes(dsa->q);
	BN_bn2bin(dsa->q, bufs[cnt]);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_BASE;
	priv.elements[cnt].length = BN_num_bytes(dsa->g);
	BN_bn2bin(dsa->g, bufs[cnt]);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PRIVATE;
	priv.elements[cnt].length = BN_num_bytes(dsa->priv_key);
	BN_bn2bin(dsa->priv_key, bufs[cnt]);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PUBLIC;
	priv.elements[cnt].length = BN_num_bytes(dsa->pub_key);
	BN_bn2bin(dsa->pub_key, bufs[cnt]);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.nelements = cnt;
	return (dst__privstruct_writefile(key, &priv, directory));
}
Example #3
0
static isc_result_t
pkcs11gost_tofile(const dst_key_t *key, const char *directory) {
	isc_result_t ret;
	pk11_object_t *gost;
	dst_private_t priv;
	unsigned char *buf = NULL;
	unsigned int i = 0;
	CK_ATTRIBUTE *attr;
	int adj;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	gost = key->keydata.pkey;
	attr = pk11_attribute_bytype(gost, CKA_VALUE2);
	if (attr != NULL) {
		buf = isc_mem_get(key->mctx, attr->ulValueLen + 39);
		if (buf == NULL)
			return (ISC_R_NOMEMORY);
		priv.elements[i].tag = TAG_GOST_PRIVASN1;
		priv.elements[i].length =
			(unsigned short) attr->ulValueLen + 39;
		memmove(buf, gost_private_der, 39);
		memmove(buf + 39, attr->pValue, attr->ulValueLen);
		adj = (int) attr->ulValueLen - 32;
		if (adj != 0) {
			buf[1] += adj;
			buf[36] += adj;
			buf[38] += adj;
		}
		priv.elements[i].data = buf;
		i++;
	} else
		return (DST_R_CRYPTOFAILURE);

	priv.nelements = i;
	ret = dst__privstruct_writefile(key, &priv, directory);

	if (buf != NULL) {
		memset(buf, 0, attr->ulValueLen);
		isc_mem_put(key->mctx, buf, attr->ulValueLen);
	}
	return (ret);
}
Example #4
0
static isc_result_t
opensslgost_tofile(const dst_key_t *key, const char *directory) {
	EVP_PKEY *pkey;
	dst_private_t priv;
	isc_result_t result;
	unsigned char *der, *p;
	int len;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	pkey = key->keydata.pkey;

	len = i2d_PrivateKey(pkey, NULL);
	der = isc_mem_get(key->mctx, (size_t) len);
	if (der == NULL)
		return (ISC_R_NOMEMORY);

	p = der;
	if (i2d_PrivateKey(pkey, &p) != len) {
		result = dst__openssl_toresult(DST_R_OPENSSLFAILURE);
		goto fail;
	}

	priv.elements[0].tag = TAG_GOST_PRIVASN1;
	priv.elements[0].length = len;
	priv.elements[0].data = der;
	priv.nelements = GOST_NTAGS;

	result = dst__privstruct_writefile(key, &priv, directory);
 fail:
	if (der != NULL)
		isc_mem_put(key->mctx, der, (size_t) len);
	return (result);
}
static isc_result_t
opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
	isc_result_t ret;
	EVP_PKEY *pkey;
	EC_KEY *eckey = NULL;
	const BIGNUM *privkey;
	dst_private_t priv;
	unsigned char *buf = NULL;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	pkey = key->keydata.pkey;
	eckey = EVP_PKEY_get1_EC_KEY(pkey);
	if (eckey == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
	privkey = EC_KEY_get0_private_key(eckey);
	if (privkey == NULL)
		DST_RET (ISC_R_FAILURE);

	buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
	if (buf == NULL)
		DST_RET (ISC_R_NOMEMORY);

	priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
	priv.elements[0].length = BN_num_bytes(privkey);
	BN_bn2bin(privkey, buf);
	priv.elements[0].data = buf;
	priv.nelements = 1;
	ret = dst__privstruct_writefile(key, &priv, directory);

 err:
	if (eckey != NULL)
		EC_KEY_free(eckey);
	if (buf != NULL)
		isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
	return (ret);
}
static isc_result_t
hmacmd5_tofile(const dst_key_t *key, const char *directory) {
	int cnt = 0;
	HMAC_Key *hkey;
	dst_private_t priv;
	int bytes = (key->key_size + 7) / 8;

	if (key->opaque == NULL)
		return (DST_R_NULLKEY);

	hkey = (HMAC_Key *) key->opaque;

	priv.elements[cnt].tag = TAG_HMACMD5_KEY;
	priv.elements[cnt].length = bytes;
	priv.elements[cnt++].data = hkey->key;

	priv.nelements = cnt;
	return (dst__privstruct_writefile(key, &priv, directory));
}
Example #7
0
static isc_result_t
pkcs11rsa_tofile(const dst_key_t *key, const char *directory) {
	int i;
	pk11_object_t *rsa;
	CK_ATTRIBUTE *attr;
	CK_ATTRIBUTE *modulus = NULL, *exponent = NULL;
	CK_ATTRIBUTE  *d = NULL, *p = NULL, *q = NULL;
	CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
	dst_private_t priv;
	unsigned char *bufs[10];
	isc_result_t result;

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	rsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(rsa);
	     attr != NULL;
	     attr = pk11_attribute_next(rsa, attr))
		switch (attr->type) {
		case CKA_MODULUS:
			modulus = attr;
			break;
		case CKA_PUBLIC_EXPONENT:
			exponent = attr;
			break;
		case CKA_PRIVATE_EXPONENT:
			d = attr;
			break;
		case CKA_PRIME_1:
			p = attr;
			break;
		case CKA_PRIME_2:
			q = attr;
			break;
		case CKA_EXPONENT_1:
			dmp1 = attr;
			break;
		case CKA_EXPONENT_2:
			dmq1 = attr;
			break;
		case CKA_COEFFICIENT:
			iqmp = attr;
			break;
		}
	if ((modulus == NULL) || (exponent == NULL))
		return (DST_R_NULLKEY);

	memset(bufs, 0, sizeof(bufs));

	for (i = 0; i < 10; i++) {
		bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen);
		if (bufs[i] == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		memset(bufs[i], 0, modulus->ulValueLen);
	}

	i = 0;

	priv.elements[i].tag = TAG_RSA_MODULUS;
	priv.elements[i].length = (unsigned short) modulus->ulValueLen;
	memmove(bufs[i], modulus->pValue, modulus->ulValueLen);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
	priv.elements[i].length = (unsigned short) exponent->ulValueLen;
	memmove(bufs[i], exponent->pValue, exponent->ulValueLen);
	priv.elements[i].data = bufs[i];
	i++;

	if (d != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
		priv.elements[i].length = (unsigned short) d->ulValueLen;
		memmove(bufs[i], d->pValue, d->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (p != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME1;
		priv.elements[i].length = (unsigned short) p->ulValueLen;
		memmove(bufs[i], p->pValue, p->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (q != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME2;
		priv.elements[i].length = (unsigned short) q->ulValueLen;
		memmove(bufs[i], q->pValue, q->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmp1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT1;
		priv.elements[i].length = (unsigned short) dmp1->ulValueLen;
		memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmq1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT2;
		priv.elements[i].length = (unsigned short) dmq1->ulValueLen;
		memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (iqmp != NULL) {
		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
		priv.elements[i].length = (unsigned short) iqmp->ulValueLen;
		memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (key->engine != NULL) {
		priv.elements[i].tag = TAG_RSA_ENGINE;
		priv.elements[i].length = strlen(key->engine) + 1;
		priv.elements[i].data = (unsigned char *)key->engine;
		i++;
	}

	if (key->label != NULL) {
		priv.elements[i].tag = TAG_RSA_LABEL;
		priv.elements[i].length = strlen(key->label) + 1;
		priv.elements[i].data = (unsigned char *)key->label;
		i++;
	}

	priv.nelements = i;
	result = dst__privstruct_writefile(key, &priv, directory);
 fail:
	for (i = 0; i < 10; i++) {
		if (bufs[i] == NULL)
			break;
		memset(bufs[i], 0, modulus->ulValueLen);
		isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen);
	}
	return (result);
}
Example #8
0
static isc_result_t
opensslrsa_tofile(const dst_key_t *key, const char *directory) {
	int i;
	RSA *rsa;
	dst_private_t priv;
	unsigned char *bufs[8];
	isc_result_t result;

#if USE_EVP
	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);
	rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
	if (rsa == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#else
	if (key->keydata.rsa == NULL)
		return (DST_R_NULLKEY);
	rsa = key->keydata.rsa;
#endif

	memset(bufs, 0, sizeof(bufs));
	for (i = 0; i < 8; i++) {
		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
		if (bufs[i] == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
	}

	i = 0;

	priv.elements[i].tag = TAG_RSA_MODULUS;
	priv.elements[i].length = BN_num_bytes(rsa->n);
	BN_bn2bin(rsa->n, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
	priv.elements[i].length = BN_num_bytes(rsa->e);
	BN_bn2bin(rsa->e, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	if (rsa->d != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
		priv.elements[i].length = BN_num_bytes(rsa->d);
		BN_bn2bin(rsa->d, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (rsa->p != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME1;
		priv.elements[i].length = BN_num_bytes(rsa->p);
		BN_bn2bin(rsa->p, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (rsa->q != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME2;
		priv.elements[i].length = BN_num_bytes(rsa->q);
		BN_bn2bin(rsa->q, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (rsa->dmp1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT1;
		priv.elements[i].length = BN_num_bytes(rsa->dmp1);
		BN_bn2bin(rsa->dmp1, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (rsa->dmq1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT2;
		priv.elements[i].length = BN_num_bytes(rsa->dmq1);
		BN_bn2bin(rsa->dmq1, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (rsa->iqmp != NULL) {
		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
		priv.elements[i].length = BN_num_bytes(rsa->iqmp);
		BN_bn2bin(rsa->iqmp, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (key->engine != NULL) {
		priv.elements[i].tag = TAG_RSA_ENGINE;
		priv.elements[i].length = strlen(key->engine) + 1;
		priv.elements[i].data = (unsigned char *)key->engine;
		i++;
	}

	if (key->label != NULL) {
		priv.elements[i].tag = TAG_RSA_LABEL;
		priv.elements[i].length = strlen(key->label) + 1;
		priv.elements[i].data = (unsigned char *)key->label;
		i++;
	}


	priv.nelements = i;
	result = dst__privstruct_writefile(key, &priv, directory);
 fail:
#if USE_EVP
	RSA_free(rsa);
#endif
	for (i = 0; i < 8; i++) {
		if (bufs[i] == NULL)
			break;
		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
	}
	return (result);
}
static isc_result_t
opensslrsa_tofile(const dst_key_t *key, const char *directory) {
	int i;
	RSA *rsa;
	dst_private_t priv;
	unsigned char *bufs[8];
	isc_result_t result;

	if (key->opaque == NULL)
		return (DST_R_NULLKEY);

	rsa = (RSA *) key->opaque;

	for (i = 0; i < 8; i++) {
		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
		if (bufs[i] == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
	}

	i = 0;

	priv.elements[i].tag = TAG_RSA_MODULUS;
	priv.elements[i].length = BN_num_bytes(rsa->n);
	BN_bn2bin(rsa->n, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
	priv.elements[i].length = BN_num_bytes(rsa->e);
	BN_bn2bin(rsa->e, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
	priv.elements[i].length = BN_num_bytes(rsa->d);
	BN_bn2bin(rsa->d, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PRIME1;
	priv.elements[i].length = BN_num_bytes(rsa->p);
	BN_bn2bin(rsa->p, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PRIME2;
	priv.elements[i].length = BN_num_bytes(rsa->q);
	BN_bn2bin(rsa->q, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_EXPONENT1;
	priv.elements[i].length = BN_num_bytes(rsa->dmp1);
	BN_bn2bin(rsa->dmp1, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_EXPONENT2;
	priv.elements[i].length = BN_num_bytes(rsa->dmq1);
	BN_bn2bin(rsa->dmq1, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_COEFFICIENT;
	priv.elements[i].length = BN_num_bytes(rsa->iqmp);
	BN_bn2bin(rsa->iqmp, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.nelements = i;
	result =  dst__privstruct_writefile(key, &priv, directory);
 fail:
	for (i = 0; i < 8; i++) {
		if (bufs[i] == NULL)
			break;
		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
	}
	return (result);
}
Example #10
0
static isc_result_t
opensslrsa_tofile(const dst_key_t *key, const char *directory) {
	int i;
	RSA *rsa;
	dst_private_t priv;
	unsigned char *bufs[8];
	isc_result_t result;
	const BIGNUM *n = NULL, *e = NULL, *d = NULL;
	const BIGNUM *p = NULL, *q = NULL;
	const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;

#if USE_EVP
	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);
	rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
	if (rsa == NULL)
		return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
#else
	if (key->keydata.rsa == NULL)
		return (DST_R_NULLKEY);
	rsa = key->keydata.rsa;
#endif
	memset(bufs, 0, sizeof(bufs));

	RSA_get0_key(rsa, &n, &e, &d);
	RSA_get0_factors(rsa, &p, &q);
	RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);

	if (key->external) {
		priv.nelements = 0;
		result = dst__privstruct_writefile(key, &priv, directory);
		goto fail;
	}

	for (i = 0; i < 8; i++) {
		bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(n));
		if (bufs[i] == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
	}

	i = 0;

	priv.elements[i].tag = TAG_RSA_MODULUS;
	priv.elements[i].length = BN_num_bytes(n);
	BN_bn2bin(n, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
	priv.elements[i].length = BN_num_bytes(e);
	BN_bn2bin(e, bufs[i]);
	priv.elements[i].data = bufs[i];
	i++;

	if (d != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
		priv.elements[i].length = BN_num_bytes(d);
		BN_bn2bin(d, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (p != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME1;
		priv.elements[i].length = BN_num_bytes(p);
		BN_bn2bin(p, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (q != NULL) {
		priv.elements[i].tag = TAG_RSA_PRIME2;
		priv.elements[i].length = BN_num_bytes(q);
		BN_bn2bin(q, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmp1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT1;
		priv.elements[i].length = BN_num_bytes(dmp1);
		BN_bn2bin(dmp1, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (dmq1 != NULL) {
		priv.elements[i].tag = TAG_RSA_EXPONENT2;
		priv.elements[i].length = BN_num_bytes(dmq1);
		BN_bn2bin(dmq1, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (iqmp != NULL) {
		priv.elements[i].tag = TAG_RSA_COEFFICIENT;
		priv.elements[i].length = BN_num_bytes(iqmp);
		BN_bn2bin(iqmp, bufs[i]);
		priv.elements[i].data = bufs[i];
		i++;
	}

	if (key->engine != NULL) {
		priv.elements[i].tag = TAG_RSA_ENGINE;
		priv.elements[i].length =
			(unsigned short)strlen(key->engine) + 1;
		priv.elements[i].data = (unsigned char *)key->engine;
		i++;
	}

	if (key->label != NULL) {
		priv.elements[i].tag = TAG_RSA_LABEL;
		priv.elements[i].length =
			(unsigned short)strlen(key->label) + 1;
		priv.elements[i].data = (unsigned char *)key->label;
		i++;
	}


	priv.nelements = i;
	result = dst__privstruct_writefile(key, &priv, directory);
 fail:
#if USE_EVP
	RSA_free(rsa);
#endif
	for (i = 0; i < 8; i++) {
		if (bufs[i] == NULL)
			break;
		isc_mem_put(key->mctx, bufs[i], BN_num_bytes(n));
	}
	return (result);
}
static isc_result_t
pkcs11dsa_tofile(const dst_key_t *key, const char *directory) {
	int cnt = 0;
	pk11_object_t *dsa;
	CK_ATTRIBUTE *attr;
	CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL;
	CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL;
	dst_private_t priv;
	unsigned char bufs[5][128];

	if (key->keydata.pkey == NULL)
		return (DST_R_NULLKEY);

	if (key->external) {
		priv.nelements = 0;
		return (dst__privstruct_writefile(key, &priv, directory));
	}

	dsa = key->keydata.pkey;

	for (attr = pk11_attribute_first(dsa);
	     attr != NULL;
	     attr = pk11_attribute_next(dsa, attr))
		switch (attr->type) {
		case CKA_PRIME:
			prime = attr;
			break;
		case CKA_SUBPRIME:
			subprime = attr;
			break;
		case CKA_BASE:
			base = attr;
			break;
		case CKA_VALUE:
			pub_key = attr;
			break;
		case CKA_VALUE2:
			priv_key = attr;
			break;
		}
	if ((prime == NULL) || (subprime == NULL) || (base == NULL) ||
	    (pub_key == NULL) || (priv_key ==NULL))
		return (DST_R_NULLKEY);

	priv.elements[cnt].tag = TAG_DSA_PRIME;
	priv.elements[cnt].length = (unsigned short) prime->ulValueLen;
	memmove(bufs[cnt], prime->pValue, prime->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
	priv.elements[cnt].length = (unsigned short) subprime->ulValueLen;
	memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_BASE;
	priv.elements[cnt].length = (unsigned short) base->ulValueLen;
	memmove(bufs[cnt], base->pValue, base->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PRIVATE;
	priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen;
	memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.elements[cnt].tag = TAG_DSA_PUBLIC;
	priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen;
	memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen);
	priv.elements[cnt].data = bufs[cnt];
	cnt++;

	priv.nelements = cnt;
	return (dst__privstruct_writefile(key, &priv, directory));
}