static isc_result_t hmacmd5_fromdns(dst_key_t *key, isc_buffer_t *data) { HMAC_Key *hkey; int keylen; isc_region_t r; isc_md5_t md5ctx; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); hkey = (HMAC_Key *) isc_mem_get(key->mctx, sizeof(HMAC_Key)); if (hkey == NULL) return (ISC_R_NOMEMORY); memset(hkey->key, 0, sizeof(hkey->key)); if (r.length > HMAC_LEN) { isc_md5_init(&md5ctx); isc_md5_update(&md5ctx, r.base, r.length); isc_md5_final(&md5ctx, hkey->key); keylen = ISC_MD5_DIGESTLENGTH; } else { memcpy(hkey->key, r.base, r.length); keylen = r.length; } key->key_size = keylen * 8; key->opaque = hkey; return (ISC_R_SUCCESS); }
static isc_result_t opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_region_t r; EVP_PKEY *pkey = NULL; unsigned char der[37 + 64]; const unsigned char *p; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != 64) return (DST_R_INVALIDPUBLICKEY); memcpy(der, gost_prefix, 37); memcpy(der + 37, r.base, 64); isc_buffer_forward(data, 64); p = der; if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) return (dst__openssl_toresult2("d2i_PUBKEY", DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; return (ISC_R_SUCCESS); }
static isc_result_t opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_result_t ret; EVP_PKEY *pkey; EC_KEY *eckey = NULL; isc_region_t r; int group_nid; unsigned int len; const unsigned char *cp; unsigned char buf[DNS_KEY_ECDSA384SIZE + 1]; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) { len = DNS_KEY_ECDSA256SIZE; group_nid = NID_X9_62_prime256v1; } else { len = DNS_KEY_ECDSA384SIZE; group_nid = NID_secp384r1; } isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length < len) return (DST_R_INVALIDPUBLICKEY); eckey = EC_KEY_new_by_curve_name(group_nid); if (eckey == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); buf[0] = POINT_CONVERSION_UNCOMPRESSED; memmove(buf + 1, r.base, len); cp = buf; if (o2i_ECPublicKey(&eckey, (const unsigned char **) &cp, (long) len + 1) == NULL) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); if (EC_KEY_check_key(eckey) != 1) DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY)); pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET (ISC_R_NOMEMORY); if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) { EVP_PKEY_free(pkey); DST_RET (dst__openssl_toresult(ISC_R_FAILURE)); } isc_buffer_forward(data, len); key->keydata.pkey = pkey; key->key_size = len * 4; ret = ISC_R_SUCCESS; err: if (eckey != NULL) EC_KEY_free(eckey); return (ret); }
static isc_result_t pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *gost; isc_region_t r; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != ISC_GOST_PUBKEYLENGTH) return (DST_R_INVALIDPUBLICKEY); gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); if (gost == NULL) return (ISC_R_NOMEMORY); memset(gost, 0, sizeof(*gost)); gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr)); if (gost->repr == NULL) goto nomemory; gost->attrcnt = 1; attr = gost->repr; attr->type = CKA_VALUE; attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH); if (attr->pValue == NULL) goto nomemory; memmove((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH); attr->ulValueLen = ISC_GOST_PUBKEYLENGTH; isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH); key->keydata.pkey = gost; key->key_size = ISC_GOST_KEYSIZE; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(gost); attr != NULL; attr = pk11_attribute_next(gost, attr)) switch (attr->type) { case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (gost->repr != NULL) { memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, gost->repr, gost->attrcnt * sizeof(*attr)); } memset(gost, 0, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); return (ISC_R_NOMEMORY); }
static void use(dst_key_t *key, isc_mem_t *mctx) { isc_result_t ret; const char *data = "This is some data"; unsigned char sig[512]; isc_buffer_t databuf, sigbuf; isc_region_t datareg, sigreg; dst_context_t *ctx = NULL; isc_buffer_init(&sigbuf, sig, sizeof(sig)); /* * Advance 1 byte for fun. */ isc_buffer_add(&sigbuf, 1); isc_buffer_init(&databuf, data, strlen(data)); isc_buffer_add(&databuf, strlen(data)); isc_buffer_usedregion(&databuf, &datareg); ret = dst_context_create(key, mctx, &ctx); if (ret != ISC_R_SUCCESS) { printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); return; } ret = dst_context_adddata(ctx, &datareg); if (ret != ISC_R_SUCCESS) { printf("adddata(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); dst_context_destroy(&ctx); return; } ret = dst_context_sign(ctx, &sigbuf); printf("sign(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); dst_context_destroy(&ctx); isc_buffer_forward(&sigbuf, 1); isc_buffer_remainingregion(&sigbuf, &sigreg); ret = dst_context_create(key, mctx, &ctx); if (ret != ISC_R_SUCCESS) { printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); return; } ret = dst_context_adddata(ctx, &datareg); if (ret != ISC_R_SUCCESS) { printf("adddata(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); dst_context_destroy(&ctx); return; } ret = dst_context_verify(ctx, &sigreg); printf("verify(%d) returned: %s\n", dst_key_alg(key), isc_result_totext(ret)); dst_context_destroy(&ctx); }
static isc_result_t openssldsa_fromdns(dst_key_t *key, isc_buffer_t *data) { DSA *dsa; isc_region_t r; unsigned int t, p_bytes; isc_mem_t *mctx = key->mctx; UNUSED(mctx); isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dsa = DSA_new(); if (dsa == NULL) return (ISC_R_NOMEMORY); dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { DSA_free(dsa); return (DST_R_INVALIDPUBLICKEY); } dsa->q = BN_bin2bn(r.base, ISC_SHA1_DIGESTLENGTH, NULL); isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); dsa->p = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); dsa->g = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); dsa->pub_key = BN_bin2bn(r.base, p_bytes, NULL); isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); key->keydata.dsa = dsa; return (ISC_R_SUCCESS); }
static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); rsa = RSA_new(); if (rsa == NULL) return (ISC_R_NOMEMORY); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base++; r.length--; if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = ((*r.base++) << 8); e_bytes += *r.base++; r.length -= 2; } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } rsa->e = BN_bin2bn(r.base, e_bytes, NULL); r.base += e_bytes; r.length -= e_bytes; rsa->n = BN_bin2bn(r.base, r.length, NULL); key->key_size = BN_num_bits(rsa->n); isc_buffer_forward(data, r.length); key->opaque = (void *) rsa; return (ISC_R_SUCCESS); }
isc_result_t dst_key_fromdns(dns_name_t *name, dns_rdataclass_t rdclass, isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) { isc_uint8_t alg, proto; isc_uint32_t flags, extflags; dst_key_t *key = NULL; dns_keytag_t id, rid; isc_region_t r; isc_result_t result; REQUIRE(dst_initialized); isc_buffer_remainingregion(source, &r); if (isc_buffer_remaininglength(source) < 4) return (DST_R_INVALIDPUBLICKEY); flags = isc_buffer_getuint16(source); proto = isc_buffer_getuint8(source); alg = isc_buffer_getuint8(source); id = dst_region_computeid(&r, alg); rid = dst_region_computerid(&r, alg); if (flags & DNS_KEYFLAG_EXTENDED) { if (isc_buffer_remaininglength(source) < 2) return (DST_R_INVALIDPUBLICKEY); extflags = isc_buffer_getuint16(source); flags |= (extflags << 16); } result = frombuffer(name, alg, flags, proto, rdclass, source, mctx, &key); if (result != ISC_R_SUCCESS) return (result); key->key_id = id; key->key_rid = rid; *keyp = key; return (ISC_R_SUCCESS); }
static isc_result_t gssapi_restore(dst_key_t *key, const char *keystr) { OM_uint32 major, minor; unsigned int len; isc_buffer_t *b = NULL; isc_region_t r; gss_buffer_desc gssbuffer; isc_result_t result; len = strlen(keystr); if ((len % 4) != 0U) return (ISC_R_BADBASE64); len = (len / 4) * 3; result = isc_buffer_allocate(key->mctx, &b, len); if (result != ISC_R_SUCCESS) return (result); result = isc_base64_decodestring(keystr, b); if (result != ISC_R_SUCCESS) { isc_buffer_free(&b); return (result); } isc_buffer_remainingregion(b, &r); REGION_TO_GBUFFER(r, gssbuffer); major = gss_import_sec_context(&minor, &gssbuffer, &key->keydata.gssctx); if (major != GSS_S_COMPLETE) { isc_buffer_free(&b); return (ISC_R_FAILURE); } isc_buffer_free(&b); return (ISC_R_SUCCESS); }
static isc_result_t addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, isc_boolean_t optout, isc_boolean_t secure, dns_rdataset_t *addedrdataset) { isc_result_t result; isc_buffer_t buffer; isc_region_t r; dns_rdataset_t *rdataset; dns_rdatatype_t type; dns_name_t *name; dns_ttl_t ttl; dns_trust_t trust; dns_rdata_t rdata[DNS_NCACHE_RDATA]; dns_rdataset_t ncrdataset; dns_rdatalist_t ncrdatalist; unsigned char data[4096]; unsigned int next = 0; /* * Convert the authority data from 'message' into a negative cache * rdataset, and store it in 'cache' at 'node'. */ REQUIRE(message != NULL); /* * We assume that all data in the authority section has been * validated by the caller. */ /* * Initialize the list. */ dns_rdatalist_init(&ncrdatalist); ncrdatalist.rdclass = dns_db_class(cache); ncrdatalist.covers = covers; ncrdatalist.ttl = maxttl; /* * Build an ncache rdatas into buffer. */ ttl = maxttl; trust = 0xffff; isc_buffer_init(&buffer, data, sizeof(data)); if (message->counts[DNS_SECTION_AUTHORITY]) result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); else result = ISC_R_NOMORE; while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if ((rdataset->attributes & DNS_RDATASETATTR_NCACHE) == 0) continue; type = rdataset->type; if (type == dns_rdatatype_rrsig) type = rdataset->covers; if (type == dns_rdatatype_soa || type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3) { if (ttl > rdataset->ttl) ttl = rdataset->ttl; if (trust > rdataset->trust) trust = rdataset->trust; /* * Copy the owner name to the buffer. */ dns_name_toregion(name, &r); result = isc_buffer_copyregion(&buffer, &r); if (result != ISC_R_SUCCESS) return (result); /* * Copy the type to the buffer. */ isc_buffer_availableregion(&buffer, &r); if (r.length < 3) return (ISC_R_NOSPACE); isc_buffer_putuint16(&buffer, rdataset->type); isc_buffer_putuint8(&buffer, (unsigned char)rdataset->trust); /* * Copy the rdataset into the buffer. */ result = copy_rdataset(rdataset, &buffer); if (result != ISC_R_SUCCESS) return (result); if (next >= DNS_NCACHE_RDATA) return (ISC_R_NOSPACE); dns_rdata_init(&rdata[next]); isc_buffer_remainingregion(&buffer, &r); rdata[next].data = r.base; rdata[next].length = r.length; rdata[next].rdclass = ncrdatalist.rdclass; rdata[next].type = 0; rdata[next].flags = 0; ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link); isc_buffer_forward(&buffer, r.length); next++; } } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } if (result != ISC_R_NOMORE) return (result); if (trust == 0xffff) { if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 && message->counts[DNS_SECTION_ANSWER] == 0) { /* * The response has aa set and we haven't followed * any CNAME or DNAME chains. */ trust = dns_trust_authauthority; } else trust = dns_trust_additional; ttl = 0; } INSIST(trust != 0xffff); ncrdatalist.ttl = ttl; dns_rdataset_init(&ncrdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset) == ISC_R_SUCCESS); if (!secure && trust > dns_trust_answer) trust = dns_trust_answer; ncrdataset.trust = trust; ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE; if (message->rcode == dns_rcode_nxdomain) ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN; if (optout) ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT; return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset, 0, addedrdataset)); }
isc_result_t dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl, dns_ttl_t maxttl, isc_boolean_t optout, dns_rdataset_t *addedrdataset) { isc_result_t result; isc_buffer_t buffer; isc_region_t r; dns_rdataset_t *rdataset; dns_rdatatype_t type; dns_name_t *name; dns_ttl_t ttl; dns_trust_t trust; dns_rdata_t rdata[DNS_NCACHE_RDATA]; dns_rdataset_t ncrdataset; dns_rdatalist_t ncrdatalist; unsigned char data[4096]; unsigned int next = 0; /* * Convert the authority data from 'message' into a negative cache * rdataset, and store it in 'cache' at 'node'. */ REQUIRE(message != NULL); /* * We assume that all data in the authority section has been * validated by the caller. */ /* * Initialize the list. */ ncrdatalist.rdclass = dns_db_class(cache); ncrdatalist.type = 0; ncrdatalist.covers = covers; ncrdatalist.ttl = maxttl; ISC_LIST_INIT(ncrdatalist.rdata); ISC_LINK_INIT(&ncrdatalist, link); /* * Build an ncache rdatas into buffer. */ ttl = maxttl; trust = 0xffff; isc_buffer_init(&buffer, data, sizeof(data)); if (message->counts[DNS_SECTION_AUTHORITY]) result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); else result = ISC_R_NOMORE; while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name); if ((name->attributes & DNS_NAMEATTR_NCACHE) != 0) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if ((rdataset->attributes & DNS_RDATASETATTR_NCACHE) == 0) continue; type = rdataset->type; if (type == dns_rdatatype_rrsig) type = rdataset->covers; if (type == dns_rdatatype_soa || type == dns_rdatatype_nsec || type == dns_rdatatype_nsec3) { if (ttl > rdataset->ttl) ttl = rdataset->ttl; if (ttl < minttl) ttl = minttl; if (trust > rdataset->trust) trust = rdataset->trust; /* * Copy the owner name to the buffer. */ dns_name_toregion(name, &r); result = isc_buffer_copyregion(&buffer, &r); if (result != ISC_R_SUCCESS) return (result); /* * Copy the type to the buffer. */ isc_buffer_availableregion(&buffer, &r); if (r.length < 2) return (ISC_R_NOSPACE); isc_buffer_putuint16(&buffer, rdataset->type); isc_buffer_putuint8(&buffer, (unsigned char)rdataset->trust); /* * Copy the rdataset into the buffer. */ result = copy_rdataset(rdataset, &buffer); if (result != ISC_R_SUCCESS) return (result); if (next >= DNS_NCACHE_RDATA) return (ISC_R_NOSPACE); dns_rdata_init(&rdata[next]); isc_buffer_remainingregion(&buffer, &r); rdata[next].data = r.base; rdata[next].length = r.length; rdata[next].rdclass = ncrdatalist.rdclass; rdata[next].type = 0; rdata[next].flags = 0; ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link); isc_buffer_forward(&buffer, r.length); next++; } } } result = dns_message_nextname(message, DNS_SECTION_AUTHORITY); } if (result != ISC_R_NOMORE) return (result); if (trust == 0xffff) { /* * We didn't find any authority data from which to create a * negative cache rdataset. In particular, we have no SOA. * * We trust that the caller wants negative caching, so this * means we have a "type 3 nxdomain" or "type 3 nodata" * response (see RFC2308 for details). * * We will now build a suitable negative cache rdataset that * will cause zero bytes to be emitted when converted to * wire format. */ /* * The ownername must exist, but it doesn't matter what value * it has. We use the root name. */ dns_name_toregion(dns_rootname, &r); result = isc_buffer_copyregion(&buffer, &r); if (result != ISC_R_SUCCESS) return (result); /* * Copy the type and a zero rdata count to the buffer. */ isc_buffer_availableregion(&buffer, &r); if (r.length < 5) return (ISC_R_NOSPACE); isc_buffer_putuint16(&buffer, 0); /* type */ /* * RFC2308, section 5, says that negative answers without * SOAs should not be cached. */ ttl = 0; /* * Set trust. */ if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 && message->counts[DNS_SECTION_ANSWER] == 0) { /* * The response has aa set and we haven't followed * any CNAME or DNAME chains. */ trust = dns_trust_authauthority; } else trust = dns_trust_additional; isc_buffer_putuint8(&buffer, (unsigned char)trust); /* trust */ isc_buffer_putuint16(&buffer, 0); /* count */ /* * Now add it to the cache. */ if (next >= DNS_NCACHE_RDATA) return (ISC_R_NOSPACE); dns_rdata_init(&rdata[next]); isc_buffer_remainingregion(&buffer, &r); rdata[next].data = r.base; rdata[next].length = r.length; rdata[next].rdclass = ncrdatalist.rdclass; rdata[next].type = 0; rdata[next].flags = 0; ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link); } INSIST(trust != 0xffff); ncrdatalist.ttl = ttl; dns_rdataset_init(&ncrdataset); RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset) == ISC_R_SUCCESS); ncrdataset.trust = trust; if (message->rcode == dns_rcode_nxdomain) ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN; if (optout) ncrdataset.attributes |= DNS_RDATASETATTR_OPTOUT; return (dns_db_addrdataset(cache, node, NULL, now, &ncrdataset, 0, addedrdataset)); }
static isc_result_t pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *rsa; isc_region_t r; unsigned int e_bytes, mod_bytes; CK_BYTE *exponent = NULL, *modulus = NULL; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); if (rsa == NULL) return (ISC_R_NOMEMORY); memset(rsa, 0, sizeof(*rsa)); if (r.length < 1) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base++; r.length--; if (e_bytes == 0) { if (r.length < 2) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } e_bytes = ((*r.base++) << 8); e_bytes += *r.base++; r.length -= 2; } if (r.length < e_bytes) { memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } exponent = r.base; r.base += e_bytes; r.length -= e_bytes; modulus = r.base; mod_bytes = r.length; key->key_size = pk11_numbits(modulus, mod_bytes); isc_buffer_forward(data, r.length); rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (rsa->repr == NULL) goto nomemory; memset(rsa->repr, 0, sizeof(*attr) * 2); rsa->attrcnt = 2; attr = rsa->repr; attr[0].type = CKA_MODULUS; attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, modulus, mod_bytes); attr[0].ulValueLen = (CK_ULONG) mod_bytes; attr[1].type = CKA_PUBLIC_EXPONENT; attr[1].pValue = isc_mem_get(key->mctx, e_bytes); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, exponent, e_bytes); attr[1].ulValueLen = (CK_ULONG) e_bytes; key->keydata.pkey = rsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (rsa->repr != NULL) { memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } memset(rsa, 0, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (ISC_R_NOMEMORY); }
static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; #if USE_EVP EVP_PKEY *pkey; #endif isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); rsa = RSA_new(); if (rsa == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base++; r.length--; if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = ((*r.base++) << 8); e_bytes += *r.base++; r.length -= 2; } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } rsa->e = BN_bin2bn(r.base, e_bytes, NULL); r.base += e_bytes; r.length -= e_bytes; rsa->n = BN_bin2bn(r.base, r.length, NULL); key->key_size = BN_num_bits(rsa->n); isc_buffer_forward(data, r.length); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) { RSA_free(rsa); return (ISC_R_NOMEMORY); } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); }
static isc_result_t opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) { RSA *rsa; isc_region_t r; unsigned int e_bytes; unsigned int length; #if USE_EVP EVP_PKEY *pkey; #endif BIGNUM *e = NULL, *n = NULL; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); length = r.length; rsa = RSA_new(); if (rsa == NULL) return (dst__openssl_toresult(ISC_R_NOMEMORY)); SET_FLAGS(rsa); if (r.length < 1) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = *r.base; isc_region_consume(&r, 1); if (e_bytes == 0) { if (r.length < 2) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); e_bytes += *r.base; isc_region_consume(&r, 1); } if (r.length < e_bytes) { RSA_free(rsa); return (DST_R_INVALIDPUBLICKEY); } e = BN_bin2bn(r.base, e_bytes, NULL); isc_region_consume(&r, e_bytes); n = BN_bin2bn(r.base, r.length, NULL); if (RSA_set0_key(rsa, n, e, NULL) == 0) { if (n != NULL) BN_free(n); if (e != NULL) BN_free(e); RSA_free(rsa); return (ISC_R_NOMEMORY); } key->key_size = BN_num_bits(n); isc_buffer_forward(data, length); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) { RSA_free(rsa); return (ISC_R_NOMEMORY); } if (!EVP_PKEY_set1_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); RSA_free(rsa); return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; #endif return (ISC_R_SUCCESS); }
isc_result_t dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t covers, dns_rdataset_t *rdataset) { dns_name_t tname; dns_rdata_rrsig_t rrsig; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t clone; dns_rdatatype_t type; dns_trust_t trust = dns_trust_none; isc_buffer_t source; isc_region_t remaining, sigregion; isc_result_t result; unsigned char *raw; unsigned int count; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); isc_region_consume(&remaining, tname.length); INSIST(remaining.length >= 2); type = isc_buffer_getuint16(&source); isc_region_consume(&remaining, 2); if (type != dns_rdatatype_rrsig || !dns_name_equal(&tname, name)) { result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); continue; } INSIST(remaining.length >= 1); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_region_consume(&remaining, 1); raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, dns_rdatatype_rrsig, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); if (rrsig.covered == covers) { isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = dns_rdatatype_rrsig; rdataset->covers = covers; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); }
isc_result_t dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx, isc_buffer_t *target, unsigned int options, unsigned int *countp) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; isc_region_t remaining, tavailable; isc_buffer_t source, savedbuffer, rdlen; dns_name_t name; dns_rdatatype_t type; unsigned int i, rcount, count; /* * Convert the negative caching rdataset 'rdataset' to wire format, * compressing names as specified in 'cctx', and storing the result in * 'target'. */ REQUIRE(rdataset != NULL); REQUIRE(rdataset->type == 0); REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); savedbuffer = *target; count = 0; result = dns_rdataset_first(rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&name, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&name, &remaining); INSIST(remaining.length >= name.length); isc_buffer_forward(&source, name.length); remaining.length -= name.length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); isc_buffer_forward(&source, 1); rcount = isc_buffer_getuint16(&source); for (i = 0; i < rcount; i++) { /* * Get the length of this rdata and set up an * rdata structure for it. */ isc_buffer_remainingregion(&source, &remaining); INSIST(remaining.length >= 2); dns_rdata_reset(&rdata); rdata.length = isc_buffer_getuint16(&source); isc_buffer_remainingregion(&source, &remaining); rdata.data = remaining.base; rdata.type = type; rdata.rdclass = rdataset->rdclass; INSIST(remaining.length >= rdata.length); isc_buffer_forward(&source, rdata.length); if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 && dns_rdatatype_isdnssec(type)) continue; /* * Write the name. */ dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14); result = dns_name_towire(&name, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * See if we have space for type, class, ttl, and * rdata length. Write the type, class, and ttl. */ isc_buffer_availableregion(target, &tavailable); if (tavailable.length < 10) { result = ISC_R_NOSPACE; goto rollback; } isc_buffer_putuint16(target, type); isc_buffer_putuint16(target, rdataset->rdclass); isc_buffer_putuint32(target, rdataset->ttl); /* * Save space for rdata length. */ rdlen = *target; isc_buffer_add(target, 2); /* * Write the rdata. */ result = dns_rdata_towire(&rdata, cctx, target); if (result != ISC_R_SUCCESS) goto rollback; /* * Set the rdata length field to the compressed * length. */ INSIST((target->used >= rdlen.used + 2) && (target->used - rdlen.used - 2 < 65536)); isc_buffer_putuint16(&rdlen, (isc_uint16_t)(target->used - rdlen.used - 2)); count++; } INSIST(isc_buffer_remaininglength(&source) == 0); result = dns_rdataset_next(rdataset); dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto rollback; *countp = count; return (ISC_R_SUCCESS); rollback: INSIST(savedbuffer.used < 65536); dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used); *countp = 0; *target = savedbuffer; return (result); }
isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t remaining; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t ttype; unsigned int i, rcount; isc_uint16_t length; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); REQUIRE(type != dns_rdatatype_rrsig); result = dns_rdataset_first(ncacherdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(ncacherdataset, &rdata); INSIST(dns_rdataset_next(ncacherdataset) == ISC_R_NOMORE); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); do { dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); remaining.length -= tname.length; INSIST(remaining.length >= 4); ttype = isc_buffer_getuint16(&source); if (ttype == type && dns_name_equal(&tname, name)) { isc_buffer_remainingregion(&source, &remaining); break; } rcount = isc_buffer_getuint16(&source); for (i = 0; i < rcount; i++) { isc_buffer_remainingregion(&source, &remaining); INSIST(remaining.length >= 2); length = isc_buffer_getuint16(&source); isc_buffer_remainingregion(&source, &remaining); INSIST(remaining.length >= length); isc_buffer_forward(&source, length); } isc_buffer_remainingregion(&source, &remaining); } while (remaining.length > 0); if (remaining.length == 0) return (ISC_R_NOTFOUND); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = ncacherdataset->trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; return (ISC_R_SUCCESS); }
isc_result_t dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset) { isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t remaining; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t ttype; dns_trust_t trust = dns_trust_none; dns_rdataset_t clone; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(name != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); REQUIRE(type != dns_rdatatype_rrsig); dns_rdataset_init(&clone); dns_rdataset_clone(ncacherdataset, &clone); result = dns_rdataset_first(&clone); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&clone, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(&tname, &remaining); INSIST(remaining.length >= tname.length); isc_buffer_forward(&source, tname.length); remaining.length -= tname.length; INSIST(remaining.length >= 3); ttype = isc_buffer_getuint16(&source); if (ttype == type && dns_name_equal(&tname, name)) { trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); break; } result = dns_rdataset_next(&clone); dns_rdata_reset(&rdata); } dns_rdataset_disassociate(&clone); if (result == ISC_R_NOMORE) return (ISC_R_NOTFOUND); if (result != ISC_R_SUCCESS) return (result); INSIST(remaining.length != 0); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; return (ISC_R_SUCCESS); }
static isc_result_t pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *ec; isc_region_t r; unsigned int len; CK_ATTRIBUTE *attr; REQUIRE(key->key_alg == DST_ALG_ECDSA256 || key->key_alg == DST_ALG_ECDSA384); if (key->key_alg == DST_ALG_ECDSA256) len = DNS_KEY_ECDSA256SIZE; else len = DNS_KEY_ECDSA384SIZE; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != len) return (DST_R_INVALIDPUBLICKEY); ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); if (ec == NULL) return (ISC_R_NOMEMORY); memset(ec, 0, sizeof(*ec)); ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); if (ec->repr == NULL) goto nomemory; ec->attrcnt = 2; attr = ec->repr; attr->type = CKA_EC_PARAMS; if (key->key_alg == DST_ALG_ECDSA256) { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); attr->ulValueLen = sizeof(pk11_ecc_prime256v1); } else { attr->pValue = isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1)); if (attr->pValue == NULL) goto nomemory; memmove(attr->pValue, pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); attr->ulValueLen = sizeof(pk11_ecc_secp384r1); } attr++; attr->type = CKA_EC_POINT; attr->pValue = isc_mem_get(key->mctx, len + 3); if (attr->pValue == NULL) goto nomemory; ((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING; ((CK_BYTE_PTR) attr->pValue)[1] = len + 1; ((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED; memmove((CK_BYTE_PTR) attr->pValue + 3, r.base, len); attr->ulValueLen = len + 3; isc_buffer_forward(data, len); key->keydata.pkey = ec; key->key_size = len * 4; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(ec); attr != NULL; attr = pk11_attribute_next(ec, attr)) switch (attr->type) { case CKA_EC_PARAMS: case CKA_EC_POINT: FREECURVE(); break; } if (ec->repr != NULL) { memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, ec->repr, ec->attrcnt * sizeof(*attr)); } memset(ec, 0, sizeof(*ec)); isc_mem_put(key->mctx, ec, sizeof(*ec)); return (ISC_R_NOMEMORY); }
void dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found, dns_rdataset_t *rdataset) { dns_rdata_t rdata = DNS_RDATA_INIT; dns_trust_t trust; isc_region_t remaining, sigregion; isc_buffer_t source; dns_name_t tname; dns_rdatatype_t type; unsigned int count; dns_rdata_rrsig_t rrsig; unsigned char *raw; REQUIRE(ncacherdataset != NULL); REQUIRE(ncacherdataset->type == 0); REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0); REQUIRE(found != NULL); REQUIRE(!dns_rdataset_isassociated(rdataset)); dns_rdataset_current(ncacherdataset, &rdata); isc_buffer_init(&source, rdata.data, rdata.length); isc_buffer_add(&source, rdata.length); dns_name_init(&tname, NULL); isc_buffer_remainingregion(&source, &remaining); dns_name_fromregion(found, &remaining); INSIST(remaining.length >= found->length); isc_buffer_forward(&source, found->length); remaining.length -= found->length; INSIST(remaining.length >= 5); type = isc_buffer_getuint16(&source); trust = isc_buffer_getuint8(&source); INSIST(trust <= dns_trust_ultimate); isc_buffer_remainingregion(&source, &remaining); rdataset->methods = &rdataset_methods; rdataset->rdclass = ncacherdataset->rdclass; rdataset->type = type; if (type == dns_rdatatype_rrsig) { /* * Extract covers from RRSIG. */ raw = remaining.base; count = raw[0] * 256 + raw[1]; INSIST(count > 0); raw += 2; sigregion.length = raw[0] * 256 + raw[1]; raw += 2; sigregion.base = raw; dns_rdata_reset(&rdata); dns_rdata_fromregion(&rdata, rdataset->rdclass, rdataset->type, &sigregion); (void)dns_rdata_tostruct(&rdata, &rrsig, NULL); rdataset->covers = rrsig.covered; } else rdataset->covers = 0; rdataset->ttl = ncacherdataset->ttl; rdataset->trust = trust; rdataset->private1 = NULL; rdataset->private2 = NULL; rdataset->private3 = remaining.base; /* * Reset iterator state. */ rdataset->privateuint4 = 0; rdataset->private5 = NULL; rdataset->private6 = NULL; }
static isc_result_t pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { pk11_object_t *dsa; isc_region_t r; unsigned int t, p_bytes; CK_BYTE *prime, *subprime, *base, *pub_key; CK_ATTRIBUTE *attr; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); if (dsa == NULL) return (ISC_R_NOMEMORY); memset(dsa, 0, sizeof(*dsa)); t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } subprime = r.base; isc_region_consume(&r, ISC_SHA1_DIGESTLENGTH); prime = r.base; isc_region_consume(&r, p_bytes); base = r.base; isc_region_consume(&r, p_bytes); pub_key = r.base; isc_region_consume(&r, p_bytes); key->key_size = p_bytes * 8; isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); if (dsa->repr == NULL) goto nomemory; memset(dsa->repr, 0, sizeof(*attr) * 4); dsa->attrcnt = 4; attr = dsa->repr; attr[0].type = CKA_PRIME; attr[0].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[0].pValue == NULL) goto nomemory; memmove(attr[0].pValue, prime, p_bytes); attr[0].ulValueLen = p_bytes; attr[1].type = CKA_SUBPRIME; attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH); if (attr[1].pValue == NULL) goto nomemory; memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH); attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH; attr[2].type = CKA_BASE; attr[2].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[2].pValue == NULL) goto nomemory; memmove(attr[2].pValue, base, p_bytes); attr[2].ulValueLen = p_bytes; attr[3].type = CKA_VALUE; attr[3].pValue = isc_mem_get(key->mctx, p_bytes); if (attr[3].pValue == NULL) goto nomemory; memmove(attr[3].pValue, pub_key, p_bytes); attr[3].ulValueLen = p_bytes; key->keydata.pkey = dsa; return (ISC_R_SUCCESS); nomemory: for (attr = pk11_attribute_first(dsa); attr != NULL; attr = pk11_attribute_next(dsa, attr)) switch (attr->type) { case CKA_PRIME: case CKA_SUBPRIME: case CKA_BASE: case CKA_VALUE: if (attr->pValue != NULL) { memset(attr->pValue, 0, attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); } break; } if (dsa->repr != NULL) { memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } memset(dsa, 0, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (ISC_R_NOMEMORY); }