1825eb42bSJan Lentfer #include <ldns/config.h> 2825eb42bSJan Lentfer 3825eb42bSJan Lentfer #include <ldns/ldns.h> 4825eb42bSJan Lentfer 5825eb42bSJan Lentfer #include <ldns/dnssec.h> 6825eb42bSJan Lentfer #include <ldns/dnssec_sign.h> 7825eb42bSJan Lentfer 8825eb42bSJan Lentfer #include <strings.h> 9825eb42bSJan Lentfer #include <time.h> 10825eb42bSJan Lentfer 11825eb42bSJan Lentfer #ifdef HAVE_SSL 12825eb42bSJan Lentfer /* this entire file is rather useless when you don't have 13825eb42bSJan Lentfer * crypto... 14825eb42bSJan Lentfer */ 15825eb42bSJan Lentfer #include <openssl/ssl.h> 16825eb42bSJan Lentfer #include <openssl/evp.h> 17825eb42bSJan Lentfer #include <openssl/rand.h> 18825eb42bSJan Lentfer #include <openssl/err.h> 19825eb42bSJan Lentfer #include <openssl/md5.h> 20825eb42bSJan Lentfer #endif /* HAVE_SSL */ 21825eb42bSJan Lentfer 22825eb42bSJan Lentfer ldns_rr * 23825eb42bSJan Lentfer ldns_create_empty_rrsig(ldns_rr_list *rrset, 24825eb42bSJan Lentfer ldns_key *current_key) 25825eb42bSJan Lentfer { 26825eb42bSJan Lentfer uint32_t orig_ttl; 27825eb42bSJan Lentfer ldns_rr_class orig_class; 28825eb42bSJan Lentfer time_t now; 29825eb42bSJan Lentfer ldns_rr *current_sig; 30825eb42bSJan Lentfer uint8_t label_count; 31*d1b2b5caSJohn Marino ldns_rdf *signame; 32825eb42bSJan Lentfer 33825eb42bSJan Lentfer label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset, 34825eb42bSJan Lentfer 0))); 35ac996e71SJan Lentfer /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */ 36ac996e71SJan Lentfer if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)))) 37ac996e71SJan Lentfer label_count --; 38825eb42bSJan Lentfer 39825eb42bSJan Lentfer current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG); 40825eb42bSJan Lentfer 41825eb42bSJan Lentfer /* set the type on the new signature */ 42825eb42bSJan Lentfer orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)); 43825eb42bSJan Lentfer orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0)); 44825eb42bSJan Lentfer 45825eb42bSJan Lentfer ldns_rr_set_ttl(current_sig, orig_ttl); 46825eb42bSJan Lentfer ldns_rr_set_class(current_sig, orig_class); 47825eb42bSJan Lentfer ldns_rr_set_owner(current_sig, 48825eb42bSJan Lentfer ldns_rdf_clone( 49825eb42bSJan Lentfer ldns_rr_owner( 50825eb42bSJan Lentfer ldns_rr_list_rr(rrset, 51825eb42bSJan Lentfer 0)))); 52825eb42bSJan Lentfer 53825eb42bSJan Lentfer /* fill in what we know of the signature */ 54825eb42bSJan Lentfer 55825eb42bSJan Lentfer /* set the orig_ttl */ 56825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_origttl( 57825eb42bSJan Lentfer current_sig, 58825eb42bSJan Lentfer ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 59825eb42bSJan Lentfer orig_ttl)); 60825eb42bSJan Lentfer /* the signers name */ 61*d1b2b5caSJohn Marino signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key)); 62*d1b2b5caSJohn Marino ldns_dname2canonical(signame); 63825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_signame( 64825eb42bSJan Lentfer current_sig, 65*d1b2b5caSJohn Marino signame); 66825eb42bSJan Lentfer /* label count - get it from the first rr in the rr_list */ 67825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_labels( 68825eb42bSJan Lentfer current_sig, 69825eb42bSJan Lentfer ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 70825eb42bSJan Lentfer label_count)); 71825eb42bSJan Lentfer /* inception, expiration */ 72825eb42bSJan Lentfer now = time(NULL); 73825eb42bSJan Lentfer if (ldns_key_inception(current_key) != 0) { 74825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_inception( 75825eb42bSJan Lentfer current_sig, 76825eb42bSJan Lentfer ldns_native2rdf_int32( 77825eb42bSJan Lentfer LDNS_RDF_TYPE_TIME, 78825eb42bSJan Lentfer ldns_key_inception(current_key))); 79825eb42bSJan Lentfer } else { 80825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_inception( 81825eb42bSJan Lentfer current_sig, 82825eb42bSJan Lentfer ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now)); 83825eb42bSJan Lentfer } 84825eb42bSJan Lentfer if (ldns_key_expiration(current_key) != 0) { 85825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_expiration( 86825eb42bSJan Lentfer current_sig, 87825eb42bSJan Lentfer ldns_native2rdf_int32( 88825eb42bSJan Lentfer LDNS_RDF_TYPE_TIME, 89825eb42bSJan Lentfer ldns_key_expiration(current_key))); 90825eb42bSJan Lentfer } else { 91825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_expiration( 92825eb42bSJan Lentfer current_sig, 93825eb42bSJan Lentfer ldns_native2rdf_int32( 94825eb42bSJan Lentfer LDNS_RDF_TYPE_TIME, 95825eb42bSJan Lentfer now + LDNS_DEFAULT_EXP_TIME)); 96825eb42bSJan Lentfer } 97825eb42bSJan Lentfer 98825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_keytag( 99825eb42bSJan Lentfer current_sig, 100825eb42bSJan Lentfer ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 101825eb42bSJan Lentfer ldns_key_keytag(current_key))); 102825eb42bSJan Lentfer 103825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_algorithm( 104825eb42bSJan Lentfer current_sig, 105825eb42bSJan Lentfer ldns_native2rdf_int8( 106825eb42bSJan Lentfer LDNS_RDF_TYPE_ALG, 107825eb42bSJan Lentfer ldns_key_algorithm(current_key))); 108825eb42bSJan Lentfer 109825eb42bSJan Lentfer (void)ldns_rr_rrsig_set_typecovered( 110825eb42bSJan Lentfer current_sig, 111825eb42bSJan Lentfer ldns_native2rdf_int16( 112825eb42bSJan Lentfer LDNS_RDF_TYPE_TYPE, 113825eb42bSJan Lentfer ldns_rr_get_type(ldns_rr_list_rr(rrset, 114825eb42bSJan Lentfer 0)))); 115825eb42bSJan Lentfer return current_sig; 116825eb42bSJan Lentfer } 117825eb42bSJan Lentfer 118825eb42bSJan Lentfer #ifdef HAVE_SSL 119825eb42bSJan Lentfer ldns_rdf * 120825eb42bSJan Lentfer ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key) 121825eb42bSJan Lentfer { 122825eb42bSJan Lentfer ldns_rdf *b64rdf = NULL; 123825eb42bSJan Lentfer 124825eb42bSJan Lentfer switch(ldns_key_algorithm(current_key)) { 125825eb42bSJan Lentfer case LDNS_SIGN_DSA: 126fd185f4dSJan Lentfer case LDNS_SIGN_DSA_NSEC3: 127825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 128825eb42bSJan Lentfer sign_buf, 129825eb42bSJan Lentfer ldns_key_evp_key(current_key), 130825eb42bSJan Lentfer EVP_dss1()); 131825eb42bSJan Lentfer break; 132825eb42bSJan Lentfer case LDNS_SIGN_RSASHA1: 133825eb42bSJan Lentfer case LDNS_SIGN_RSASHA1_NSEC3: 134825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 135825eb42bSJan Lentfer sign_buf, 136825eb42bSJan Lentfer ldns_key_evp_key(current_key), 137825eb42bSJan Lentfer EVP_sha1()); 138825eb42bSJan Lentfer break; 139825eb42bSJan Lentfer #ifdef USE_SHA2 140825eb42bSJan Lentfer case LDNS_SIGN_RSASHA256: 141825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 142825eb42bSJan Lentfer sign_buf, 143825eb42bSJan Lentfer ldns_key_evp_key(current_key), 144825eb42bSJan Lentfer EVP_sha256()); 145825eb42bSJan Lentfer break; 146825eb42bSJan Lentfer case LDNS_SIGN_RSASHA512: 147825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 148825eb42bSJan Lentfer sign_buf, 149825eb42bSJan Lentfer ldns_key_evp_key(current_key), 150825eb42bSJan Lentfer EVP_sha512()); 151825eb42bSJan Lentfer break; 152825eb42bSJan Lentfer #endif /* USE_SHA2 */ 153825eb42bSJan Lentfer #ifdef USE_GOST 154ac996e71SJan Lentfer case LDNS_SIGN_ECC_GOST: 155825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 156825eb42bSJan Lentfer sign_buf, 157825eb42bSJan Lentfer ldns_key_evp_key(current_key), 158825eb42bSJan Lentfer EVP_get_digestbyname("md_gost94")); 159825eb42bSJan Lentfer break; 160825eb42bSJan Lentfer #endif /* USE_GOST */ 161ac996e71SJan Lentfer #ifdef USE_ECDSA 162ac996e71SJan Lentfer case LDNS_SIGN_ECDSAP256SHA256: 163ac996e71SJan Lentfer b64rdf = ldns_sign_public_evp( 164ac996e71SJan Lentfer sign_buf, 165ac996e71SJan Lentfer ldns_key_evp_key(current_key), 166ac996e71SJan Lentfer EVP_sha256()); 167ac996e71SJan Lentfer break; 168ac996e71SJan Lentfer case LDNS_SIGN_ECDSAP384SHA384: 169ac996e71SJan Lentfer b64rdf = ldns_sign_public_evp( 170ac996e71SJan Lentfer sign_buf, 171ac996e71SJan Lentfer ldns_key_evp_key(current_key), 172ac996e71SJan Lentfer EVP_sha384()); 173ac996e71SJan Lentfer break; 174ac996e71SJan Lentfer #endif 175825eb42bSJan Lentfer case LDNS_SIGN_RSAMD5: 176825eb42bSJan Lentfer b64rdf = ldns_sign_public_evp( 177825eb42bSJan Lentfer sign_buf, 178825eb42bSJan Lentfer ldns_key_evp_key(current_key), 179825eb42bSJan Lentfer EVP_md5()); 180825eb42bSJan Lentfer break; 181825eb42bSJan Lentfer default: 182825eb42bSJan Lentfer /* do _you_ know this alg? */ 183825eb42bSJan Lentfer printf("unknown algorithm, "); 184825eb42bSJan Lentfer printf("is the one used available on this system?\n"); 185825eb42bSJan Lentfer break; 186825eb42bSJan Lentfer } 187825eb42bSJan Lentfer 188825eb42bSJan Lentfer return b64rdf; 189825eb42bSJan Lentfer } 190825eb42bSJan Lentfer 191825eb42bSJan Lentfer /** 192825eb42bSJan Lentfer * use this function to sign with a public/private key alg 193825eb42bSJan Lentfer * return the created signatures 194825eb42bSJan Lentfer */ 195825eb42bSJan Lentfer ldns_rr_list * 196825eb42bSJan Lentfer ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys) 197825eb42bSJan Lentfer { 198825eb42bSJan Lentfer ldns_rr_list *signatures; 199825eb42bSJan Lentfer ldns_rr_list *rrset_clone; 200825eb42bSJan Lentfer ldns_rr *current_sig; 201825eb42bSJan Lentfer ldns_rdf *b64rdf; 202825eb42bSJan Lentfer ldns_key *current_key; 203825eb42bSJan Lentfer size_t key_count; 204825eb42bSJan Lentfer uint16_t i; 205825eb42bSJan Lentfer ldns_buffer *sign_buf; 206825eb42bSJan Lentfer ldns_rdf *new_owner; 207825eb42bSJan Lentfer 208825eb42bSJan Lentfer if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) { 209825eb42bSJan Lentfer return NULL; 210825eb42bSJan Lentfer } 211825eb42bSJan Lentfer 212825eb42bSJan Lentfer new_owner = NULL; 213825eb42bSJan Lentfer 214825eb42bSJan Lentfer signatures = ldns_rr_list_new(); 215825eb42bSJan Lentfer 216825eb42bSJan Lentfer /* prepare a signature and add all the know data 217825eb42bSJan Lentfer * prepare the rrset. Sign this together. */ 218825eb42bSJan Lentfer rrset_clone = ldns_rr_list_clone(rrset); 219825eb42bSJan Lentfer if (!rrset_clone) { 220825eb42bSJan Lentfer return NULL; 221825eb42bSJan Lentfer } 222825eb42bSJan Lentfer 223825eb42bSJan Lentfer /* make it canonical */ 224825eb42bSJan Lentfer for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) { 225825eb42bSJan Lentfer ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), 226825eb42bSJan Lentfer ldns_rr_ttl(ldns_rr_list_rr(rrset, 0))); 227825eb42bSJan Lentfer ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i)); 228825eb42bSJan Lentfer } 229825eb42bSJan Lentfer /* sort */ 230825eb42bSJan Lentfer ldns_rr_list_sort(rrset_clone); 231825eb42bSJan Lentfer 232825eb42bSJan Lentfer for (key_count = 0; 233825eb42bSJan Lentfer key_count < ldns_key_list_key_count(keys); 234825eb42bSJan Lentfer key_count++) { 235825eb42bSJan Lentfer if (!ldns_key_use(ldns_key_list_key(keys, key_count))) { 236825eb42bSJan Lentfer continue; 237825eb42bSJan Lentfer } 238825eb42bSJan Lentfer sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN); 239825eb42bSJan Lentfer if (!sign_buf) { 240825eb42bSJan Lentfer ldns_rr_list_free(rrset_clone); 241825eb42bSJan Lentfer ldns_rr_list_free(signatures); 242825eb42bSJan Lentfer ldns_rdf_free(new_owner); 243825eb42bSJan Lentfer return NULL; 244825eb42bSJan Lentfer } 245825eb42bSJan Lentfer b64rdf = NULL; 246825eb42bSJan Lentfer 247825eb42bSJan Lentfer current_key = ldns_key_list_key(keys, key_count); 248825eb42bSJan Lentfer /* sign all RRs with keys that have ZSKbit, !SEPbit. 249825eb42bSJan Lentfer sign DNSKEY RRs with keys that have ZSKbit&SEPbit */ 250ac996e71SJan Lentfer if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) { 251825eb42bSJan Lentfer current_sig = ldns_create_empty_rrsig(rrset_clone, 252825eb42bSJan Lentfer current_key); 253825eb42bSJan Lentfer 254825eb42bSJan Lentfer /* right now, we have: a key, a semi-sig and an rrset. For 255825eb42bSJan Lentfer * which we can create the sig and base64 encode that and 256825eb42bSJan Lentfer * add that to the signature */ 257825eb42bSJan Lentfer 258825eb42bSJan Lentfer if (ldns_rrsig2buffer_wire(sign_buf, current_sig) 259825eb42bSJan Lentfer != LDNS_STATUS_OK) { 260825eb42bSJan Lentfer ldns_buffer_free(sign_buf); 261825eb42bSJan Lentfer /* ERROR */ 262825eb42bSJan Lentfer ldns_rr_list_deep_free(rrset_clone); 263*d1b2b5caSJohn Marino ldns_rr_free(current_sig); 264*d1b2b5caSJohn Marino ldns_rr_list_deep_free(signatures); 265825eb42bSJan Lentfer return NULL; 266825eb42bSJan Lentfer } 267825eb42bSJan Lentfer 268825eb42bSJan Lentfer /* add the rrset in sign_buf */ 269825eb42bSJan Lentfer if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone) 270825eb42bSJan Lentfer != LDNS_STATUS_OK) { 271825eb42bSJan Lentfer ldns_buffer_free(sign_buf); 272825eb42bSJan Lentfer ldns_rr_list_deep_free(rrset_clone); 273*d1b2b5caSJohn Marino ldns_rr_free(current_sig); 274*d1b2b5caSJohn Marino ldns_rr_list_deep_free(signatures); 275825eb42bSJan Lentfer return NULL; 276825eb42bSJan Lentfer } 277825eb42bSJan Lentfer 278825eb42bSJan Lentfer b64rdf = ldns_sign_public_buffer(sign_buf, current_key); 279825eb42bSJan Lentfer 280825eb42bSJan Lentfer if (!b64rdf) { 281825eb42bSJan Lentfer /* signing went wrong */ 282825eb42bSJan Lentfer ldns_rr_list_deep_free(rrset_clone); 283*d1b2b5caSJohn Marino ldns_rr_free(current_sig); 284*d1b2b5caSJohn Marino ldns_rr_list_deep_free(signatures); 285825eb42bSJan Lentfer return NULL; 286825eb42bSJan Lentfer } 287825eb42bSJan Lentfer 288825eb42bSJan Lentfer ldns_rr_rrsig_set_sig(current_sig, b64rdf); 289825eb42bSJan Lentfer 290825eb42bSJan Lentfer /* push the signature to the signatures list */ 291825eb42bSJan Lentfer ldns_rr_list_push_rr(signatures, current_sig); 292825eb42bSJan Lentfer } 293825eb42bSJan Lentfer ldns_buffer_free(sign_buf); /* restart for the next key */ 294825eb42bSJan Lentfer } 295825eb42bSJan Lentfer ldns_rr_list_deep_free(rrset_clone); 296825eb42bSJan Lentfer 297825eb42bSJan Lentfer return signatures; 298825eb42bSJan Lentfer } 299825eb42bSJan Lentfer 300825eb42bSJan Lentfer /** 301825eb42bSJan Lentfer * Sign data with DSA 302825eb42bSJan Lentfer * 303825eb42bSJan Lentfer * \param[in] to_sign The ldns_buffer containing raw data that is 304825eb42bSJan Lentfer * to be signed 305825eb42bSJan Lentfer * \param[in] key The DSA key structure to sign with 306825eb42bSJan Lentfer * \return ldns_rdf for the RRSIG ldns_rr 307825eb42bSJan Lentfer */ 308825eb42bSJan Lentfer ldns_rdf * 309825eb42bSJan Lentfer ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key) 310825eb42bSJan Lentfer { 311825eb42bSJan Lentfer unsigned char *sha1_hash; 312825eb42bSJan Lentfer ldns_rdf *sigdata_rdf; 313825eb42bSJan Lentfer ldns_buffer *b64sig; 314825eb42bSJan Lentfer 315825eb42bSJan Lentfer DSA_SIG *sig; 316825eb42bSJan Lentfer uint8_t *data; 317825eb42bSJan Lentfer size_t pad; 318825eb42bSJan Lentfer 319825eb42bSJan Lentfer b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 320825eb42bSJan Lentfer if (!b64sig) { 321825eb42bSJan Lentfer return NULL; 322825eb42bSJan Lentfer } 323825eb42bSJan Lentfer 324825eb42bSJan Lentfer sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), 325825eb42bSJan Lentfer ldns_buffer_position(to_sign), NULL); 326825eb42bSJan Lentfer if (!sha1_hash) { 327825eb42bSJan Lentfer ldns_buffer_free(b64sig); 328825eb42bSJan Lentfer return NULL; 329825eb42bSJan Lentfer } 330825eb42bSJan Lentfer 331825eb42bSJan Lentfer sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key); 332fd185f4dSJan Lentfer if(!sig) { 333fd185f4dSJan Lentfer ldns_buffer_free(b64sig); 334fd185f4dSJan Lentfer return NULL; 335fd185f4dSJan Lentfer } 336825eb42bSJan Lentfer 337825eb42bSJan Lentfer data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH); 338fd185f4dSJan Lentfer if(!data) { 339fd185f4dSJan Lentfer ldns_buffer_free(b64sig); 340fd185f4dSJan Lentfer DSA_SIG_free(sig); 341fd185f4dSJan Lentfer return NULL; 342fd185f4dSJan Lentfer } 343825eb42bSJan Lentfer 344825eb42bSJan Lentfer data[0] = 1; 345825eb42bSJan Lentfer pad = 20 - (size_t) BN_num_bytes(sig->r); 346825eb42bSJan Lentfer if (pad > 0) { 347825eb42bSJan Lentfer memset(data + 1, 0, pad); 348825eb42bSJan Lentfer } 349825eb42bSJan Lentfer BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad); 350825eb42bSJan Lentfer 351825eb42bSJan Lentfer pad = 20 - (size_t) BN_num_bytes(sig->s); 352825eb42bSJan Lentfer if (pad > 0) { 353825eb42bSJan Lentfer memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad); 354825eb42bSJan Lentfer } 355825eb42bSJan Lentfer BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad)); 356825eb42bSJan Lentfer 357825eb42bSJan Lentfer sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, 358825eb42bSJan Lentfer 1 + 2 * SHA_DIGEST_LENGTH, 359825eb42bSJan Lentfer data); 360825eb42bSJan Lentfer 361825eb42bSJan Lentfer ldns_buffer_free(b64sig); 362825eb42bSJan Lentfer LDNS_FREE(data); 363fd185f4dSJan Lentfer DSA_SIG_free(sig); 364825eb42bSJan Lentfer 365825eb42bSJan Lentfer return sigdata_rdf; 366825eb42bSJan Lentfer } 367825eb42bSJan Lentfer 368ac996e71SJan Lentfer #ifdef USE_ECDSA 369fd185f4dSJan Lentfer #ifndef S_SPLINT_S 370ac996e71SJan Lentfer static int 371ac996e71SJan Lentfer ldns_pkey_is_ecdsa(EVP_PKEY* pkey) 372ac996e71SJan Lentfer { 373ac996e71SJan Lentfer EC_KEY* ec; 374ac996e71SJan Lentfer const EC_GROUP* g; 375ac996e71SJan Lentfer if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) 376ac996e71SJan Lentfer return 0; 377ac996e71SJan Lentfer ec = EVP_PKEY_get1_EC_KEY(pkey); 378ac996e71SJan Lentfer g = EC_KEY_get0_group(ec); 379ac996e71SJan Lentfer if(!g) { 380ac996e71SJan Lentfer EC_KEY_free(ec); 381ac996e71SJan Lentfer return 0; 382ac996e71SJan Lentfer } 383ac996e71SJan Lentfer if(EC_GROUP_get_curve_name(g) == NID_secp224r1 || 384ac996e71SJan Lentfer EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 || 385ac996e71SJan Lentfer EC_GROUP_get_curve_name(g) == NID_secp384r1) { 386ac996e71SJan Lentfer EC_KEY_free(ec); 387ac996e71SJan Lentfer return 1; 388ac996e71SJan Lentfer } 389ac996e71SJan Lentfer /* downref the eckey, the original is still inside the pkey */ 390ac996e71SJan Lentfer EC_KEY_free(ec); 391ac996e71SJan Lentfer return 0; 392ac996e71SJan Lentfer } 393fd185f4dSJan Lentfer #endif /* splint */ 394ac996e71SJan Lentfer #endif /* USE_ECDSA */ 395ac996e71SJan Lentfer 396825eb42bSJan Lentfer ldns_rdf * 397825eb42bSJan Lentfer ldns_sign_public_evp(ldns_buffer *to_sign, 398825eb42bSJan Lentfer EVP_PKEY *key, 399825eb42bSJan Lentfer const EVP_MD *digest_type) 400825eb42bSJan Lentfer { 401825eb42bSJan Lentfer unsigned int siglen; 402825eb42bSJan Lentfer ldns_rdf *sigdata_rdf; 403825eb42bSJan Lentfer ldns_buffer *b64sig; 404825eb42bSJan Lentfer EVP_MD_CTX ctx; 405825eb42bSJan Lentfer const EVP_MD *md_type; 406825eb42bSJan Lentfer int r; 407825eb42bSJan Lentfer 408825eb42bSJan Lentfer siglen = 0; 409825eb42bSJan Lentfer b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 410825eb42bSJan Lentfer if (!b64sig) { 411825eb42bSJan Lentfer return NULL; 412825eb42bSJan Lentfer } 413825eb42bSJan Lentfer 414825eb42bSJan Lentfer /* initializes a signing context */ 415825eb42bSJan Lentfer md_type = digest_type; 416825eb42bSJan Lentfer if(!md_type) { 417825eb42bSJan Lentfer /* unknown message difest */ 418825eb42bSJan Lentfer ldns_buffer_free(b64sig); 419825eb42bSJan Lentfer return NULL; 420825eb42bSJan Lentfer } 421825eb42bSJan Lentfer 422825eb42bSJan Lentfer EVP_MD_CTX_init(&ctx); 423825eb42bSJan Lentfer r = EVP_SignInit(&ctx, md_type); 424825eb42bSJan Lentfer if(r == 1) { 425825eb42bSJan Lentfer r = EVP_SignUpdate(&ctx, (unsigned char*) 426825eb42bSJan Lentfer ldns_buffer_begin(to_sign), 427825eb42bSJan Lentfer ldns_buffer_position(to_sign)); 428825eb42bSJan Lentfer } else { 429825eb42bSJan Lentfer ldns_buffer_free(b64sig); 430825eb42bSJan Lentfer return NULL; 431825eb42bSJan Lentfer } 432825eb42bSJan Lentfer if(r == 1) { 433825eb42bSJan Lentfer r = EVP_SignFinal(&ctx, (unsigned char*) 434825eb42bSJan Lentfer ldns_buffer_begin(b64sig), &siglen, key); 435825eb42bSJan Lentfer } else { 436825eb42bSJan Lentfer ldns_buffer_free(b64sig); 437825eb42bSJan Lentfer return NULL; 438825eb42bSJan Lentfer } 439825eb42bSJan Lentfer if(r != 1) { 440825eb42bSJan Lentfer ldns_buffer_free(b64sig); 441825eb42bSJan Lentfer return NULL; 442825eb42bSJan Lentfer } 443825eb42bSJan Lentfer 444825eb42bSJan Lentfer /* unfortunately, OpenSSL output is differenct from DNS DSA format */ 445fd185f4dSJan Lentfer #ifndef S_SPLINT_S 446825eb42bSJan Lentfer if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) { 447825eb42bSJan Lentfer sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen); 448ac996e71SJan Lentfer #ifdef USE_ECDSA 449ac996e71SJan Lentfer } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC && 450ac996e71SJan Lentfer ldns_pkey_is_ecdsa(key)) { 451ac996e71SJan Lentfer sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen); 452ac996e71SJan Lentfer #endif 453825eb42bSJan Lentfer } else { 454825eb42bSJan Lentfer /* ok output for other types is the same */ 455825eb42bSJan Lentfer sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 456825eb42bSJan Lentfer ldns_buffer_begin(b64sig)); 457825eb42bSJan Lentfer } 458fd185f4dSJan Lentfer #endif /* splint */ 459825eb42bSJan Lentfer ldns_buffer_free(b64sig); 460825eb42bSJan Lentfer EVP_MD_CTX_cleanup(&ctx); 461825eb42bSJan Lentfer return sigdata_rdf; 462825eb42bSJan Lentfer } 463825eb42bSJan Lentfer 464825eb42bSJan Lentfer ldns_rdf * 465825eb42bSJan Lentfer ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key) 466825eb42bSJan Lentfer { 467825eb42bSJan Lentfer unsigned char *sha1_hash; 468825eb42bSJan Lentfer unsigned int siglen; 469825eb42bSJan Lentfer ldns_rdf *sigdata_rdf; 470825eb42bSJan Lentfer ldns_buffer *b64sig; 471825eb42bSJan Lentfer int result; 472825eb42bSJan Lentfer 473825eb42bSJan Lentfer siglen = 0; 474825eb42bSJan Lentfer b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 475825eb42bSJan Lentfer if (!b64sig) { 476825eb42bSJan Lentfer return NULL; 477825eb42bSJan Lentfer } 478825eb42bSJan Lentfer 479825eb42bSJan Lentfer sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign), 480825eb42bSJan Lentfer ldns_buffer_position(to_sign), NULL); 481825eb42bSJan Lentfer if (!sha1_hash) { 482825eb42bSJan Lentfer ldns_buffer_free(b64sig); 483825eb42bSJan Lentfer return NULL; 484825eb42bSJan Lentfer } 485825eb42bSJan Lentfer 486825eb42bSJan Lentfer result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH, 487825eb42bSJan Lentfer (unsigned char*)ldns_buffer_begin(b64sig), 488825eb42bSJan Lentfer &siglen, key); 489825eb42bSJan Lentfer if (result != 1) { 490*d1b2b5caSJohn Marino ldns_buffer_free(b64sig); 491825eb42bSJan Lentfer return NULL; 492825eb42bSJan Lentfer } 493825eb42bSJan Lentfer 494825eb42bSJan Lentfer sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 495825eb42bSJan Lentfer ldns_buffer_begin(b64sig)); 496825eb42bSJan Lentfer ldns_buffer_free(b64sig); /* can't free this buffer ?? */ 497825eb42bSJan Lentfer return sigdata_rdf; 498825eb42bSJan Lentfer } 499825eb42bSJan Lentfer 500825eb42bSJan Lentfer ldns_rdf * 501825eb42bSJan Lentfer ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key) 502825eb42bSJan Lentfer { 503825eb42bSJan Lentfer unsigned char *md5_hash; 504825eb42bSJan Lentfer unsigned int siglen; 505825eb42bSJan Lentfer ldns_rdf *sigdata_rdf; 506825eb42bSJan Lentfer ldns_buffer *b64sig; 507825eb42bSJan Lentfer 508825eb42bSJan Lentfer b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN); 509825eb42bSJan Lentfer if (!b64sig) { 510825eb42bSJan Lentfer return NULL; 511825eb42bSJan Lentfer } 512825eb42bSJan Lentfer 513825eb42bSJan Lentfer md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign), 514825eb42bSJan Lentfer ldns_buffer_position(to_sign), NULL); 515825eb42bSJan Lentfer if (!md5_hash) { 516825eb42bSJan Lentfer ldns_buffer_free(b64sig); 517825eb42bSJan Lentfer return NULL; 518825eb42bSJan Lentfer } 519825eb42bSJan Lentfer 520825eb42bSJan Lentfer RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH, 521825eb42bSJan Lentfer (unsigned char*)ldns_buffer_begin(b64sig), 522825eb42bSJan Lentfer &siglen, key); 523825eb42bSJan Lentfer 524825eb42bSJan Lentfer sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 525825eb42bSJan Lentfer ldns_buffer_begin(b64sig)); 526825eb42bSJan Lentfer ldns_buffer_free(b64sig); 527825eb42bSJan Lentfer return sigdata_rdf; 528825eb42bSJan Lentfer } 529825eb42bSJan Lentfer #endif /* HAVE_SSL */ 530825eb42bSJan Lentfer 531b5dedccaSJan Lentfer /** 532b5dedccaSJan Lentfer * Pushes all rrs from the rrsets of type A and AAAA on gluelist. 533b5dedccaSJan Lentfer */ 534b5dedccaSJan Lentfer static ldns_status 535b5dedccaSJan Lentfer ldns_dnssec_addresses_on_glue_list( 536b5dedccaSJan Lentfer ldns_dnssec_rrsets *cur_rrset, 537b5dedccaSJan Lentfer ldns_rr_list *glue_list) 538825eb42bSJan Lentfer { 539b5dedccaSJan Lentfer ldns_dnssec_rrs *cur_rrs; 540825eb42bSJan Lentfer while (cur_rrset) { 541b5dedccaSJan Lentfer if (cur_rrset->type == LDNS_RR_TYPE_A 542b5dedccaSJan Lentfer || cur_rrset->type == LDNS_RR_TYPE_AAAA) { 543b5dedccaSJan Lentfer for (cur_rrs = cur_rrset->rrs; 544b5dedccaSJan Lentfer cur_rrs; 545b5dedccaSJan Lentfer cur_rrs = cur_rrs->next) { 546b5dedccaSJan Lentfer if (cur_rrs->rr) { 547b5dedccaSJan Lentfer if (!ldns_rr_list_push_rr(glue_list, 548b5dedccaSJan Lentfer cur_rrs->rr)) { 549b5dedccaSJan Lentfer return LDNS_STATUS_MEM_ERR; 550b5dedccaSJan Lentfer /* ldns_rr_list_push_rr() 551b5dedccaSJan Lentfer * returns false when unable 552b5dedccaSJan Lentfer * to increase the capacity 553b5dedccaSJan Lentfer * of the ldsn_rr_list 554b5dedccaSJan Lentfer */ 555b5dedccaSJan Lentfer } 556b5dedccaSJan Lentfer } 557b5dedccaSJan Lentfer } 558b5dedccaSJan Lentfer } 559825eb42bSJan Lentfer cur_rrset = cur_rrset->next; 560825eb42bSJan Lentfer } 561b5dedccaSJan Lentfer return LDNS_STATUS_OK; 562825eb42bSJan Lentfer } 563825eb42bSJan Lentfer 564b5dedccaSJan Lentfer /** 565b5dedccaSJan Lentfer * Marks the names in the zone that are occluded. Those names will be skipped 566b5dedccaSJan Lentfer * when walking the tree with the ldns_dnssec_name_node_next_nonglue() 567b5dedccaSJan Lentfer * function. But watch out! Names that are partially occluded (like glue with 568b5dedccaSJan Lentfer * the same name as the delegation) will not be marked and should specifically 569b5dedccaSJan Lentfer * be taken into account seperately. 570b5dedccaSJan Lentfer * 571b5dedccaSJan Lentfer * When glue_list is given (not NULL), in the process of marking the names, all 572b5dedccaSJan Lentfer * glue resource records will be pushed to that list, even glue at delegation names. 573b5dedccaSJan Lentfer * 574b5dedccaSJan Lentfer * \param[in] zone the zone in which to mark the names 575b5dedccaSJan Lentfer * \param[in] glue_list the list to which to push the glue rrs 576b5dedccaSJan Lentfer * \return LDNS_STATUS_OK on success, an error code otherwise 577825eb42bSJan Lentfer */ 578b5dedccaSJan Lentfer ldns_status 579b5dedccaSJan Lentfer ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 580b5dedccaSJan Lentfer ldns_rr_list *glue_list) 581b5dedccaSJan Lentfer { 582b5dedccaSJan Lentfer ldns_rbnode_t *node; 583b5dedccaSJan Lentfer ldns_dnssec_name *name; 584b5dedccaSJan Lentfer ldns_rdf *owner; 585b5dedccaSJan Lentfer ldns_rdf *cut = NULL; /* keeps track of zone cuts */ 586b5dedccaSJan Lentfer /* When the cut is caused by a delegation, below_delegation will be 1. 587b5dedccaSJan Lentfer * When caused by a DNAME, below_delegation will be 0. 588b5dedccaSJan Lentfer */ 589b5dedccaSJan Lentfer int below_delegation = -1; /* init suppresses comiler warning */ 590b5dedccaSJan Lentfer ldns_status s; 591b5dedccaSJan Lentfer 592b5dedccaSJan Lentfer if (!zone || !zone->names) { 593b5dedccaSJan Lentfer return LDNS_STATUS_NULL; 594825eb42bSJan Lentfer } 595b5dedccaSJan Lentfer for (node = ldns_rbtree_first(zone->names); 596b5dedccaSJan Lentfer node != LDNS_RBTREE_NULL; 597b5dedccaSJan Lentfer node = ldns_rbtree_next(node)) { 598b5dedccaSJan Lentfer name = (ldns_dnssec_name *) node->data; 599b5dedccaSJan Lentfer owner = ldns_dnssec_name_name(name); 600b5dedccaSJan Lentfer 601b5dedccaSJan Lentfer if (cut) { 602b5dedccaSJan Lentfer /* The previous node was a zone cut, or a subdomain 603b5dedccaSJan Lentfer * below a zone cut. Is this node (still) a subdomain 604b5dedccaSJan Lentfer * below the cut? Then the name is occluded. Unless 605b5dedccaSJan Lentfer * the name contains a SOA, after which we are 606b5dedccaSJan Lentfer * authoritative again. 607b5dedccaSJan Lentfer * 608b5dedccaSJan Lentfer * FIXME! If there are labels in between the SOA and 609b5dedccaSJan Lentfer * the cut, going from the authoritative space (below 610b5dedccaSJan Lentfer * the SOA) up into occluded space again, will not be 611b5dedccaSJan Lentfer * detected with the contruct below! 612b5dedccaSJan Lentfer */ 613b5dedccaSJan Lentfer if (ldns_dname_is_subdomain(owner, cut) && 614b5dedccaSJan Lentfer !ldns_dnssec_rrsets_contains_type( 615b5dedccaSJan Lentfer name->rrsets, LDNS_RR_TYPE_SOA)) { 616b5dedccaSJan Lentfer 617b5dedccaSJan Lentfer if (below_delegation && glue_list) { 618b5dedccaSJan Lentfer s = ldns_dnssec_addresses_on_glue_list( 619b5dedccaSJan Lentfer name->rrsets, glue_list); 620b5dedccaSJan Lentfer if (s != LDNS_STATUS_OK) { 621b5dedccaSJan Lentfer return s; 622825eb42bSJan Lentfer } 623b5dedccaSJan Lentfer } 624b5dedccaSJan Lentfer name->is_glue = true; /* Mark occluded name! */ 625b5dedccaSJan Lentfer continue; 626b5dedccaSJan Lentfer } else { 627b5dedccaSJan Lentfer cut = NULL; 628b5dedccaSJan Lentfer } 629b5dedccaSJan Lentfer } 630b5dedccaSJan Lentfer 631b5dedccaSJan Lentfer /* The node is not below a zone cut. Is it a zone cut itself? 632b5dedccaSJan Lentfer * Everything below a SOA is authoritative of course; Except 633b5dedccaSJan Lentfer * when the name also contains a DNAME :). 634b5dedccaSJan Lentfer */ 635b5dedccaSJan Lentfer if (ldns_dnssec_rrsets_contains_type( 636b5dedccaSJan Lentfer name->rrsets, LDNS_RR_TYPE_NS) 637b5dedccaSJan Lentfer && !ldns_dnssec_rrsets_contains_type( 638b5dedccaSJan Lentfer name->rrsets, LDNS_RR_TYPE_SOA)) { 639b5dedccaSJan Lentfer cut = owner; 640b5dedccaSJan Lentfer below_delegation = 1; 641b5dedccaSJan Lentfer if (glue_list) { /* record glue on the zone cut */ 642b5dedccaSJan Lentfer s = ldns_dnssec_addresses_on_glue_list( 643b5dedccaSJan Lentfer name->rrsets, glue_list); 644b5dedccaSJan Lentfer if (s != LDNS_STATUS_OK) { 645b5dedccaSJan Lentfer return s; 646b5dedccaSJan Lentfer } 647b5dedccaSJan Lentfer } 648b5dedccaSJan Lentfer } else if (ldns_dnssec_rrsets_contains_type( 649b5dedccaSJan Lentfer name->rrsets, LDNS_RR_TYPE_DNAME)) { 650b5dedccaSJan Lentfer cut = owner; 651b5dedccaSJan Lentfer below_delegation = 0; 652825eb42bSJan Lentfer } 653825eb42bSJan Lentfer } 654825eb42bSJan Lentfer return LDNS_STATUS_OK; 655825eb42bSJan Lentfer } 656825eb42bSJan Lentfer 657b5dedccaSJan Lentfer /** 658b5dedccaSJan Lentfer * Marks the names in the zone that are occluded. Those names will be skipped 659b5dedccaSJan Lentfer * when walking the tree with the ldns_dnssec_name_node_next_nonglue() 660b5dedccaSJan Lentfer * function. But watch out! Names that are partially occluded (like glue with 661b5dedccaSJan Lentfer * the same name as the delegation) will not be marked and should specifically 662b5dedccaSJan Lentfer * be taken into account seperately. 663b5dedccaSJan Lentfer * 664b5dedccaSJan Lentfer * \param[in] zone the zone in which to mark the names 665b5dedccaSJan Lentfer * \return LDNS_STATUS_OK on success, an error code otherwise 666b5dedccaSJan Lentfer */ 667b5dedccaSJan Lentfer ldns_status 668b5dedccaSJan Lentfer ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone) 669b5dedccaSJan Lentfer { 670b5dedccaSJan Lentfer return ldns_dnssec_zone_mark_and_get_glue(zone, NULL); 671b5dedccaSJan Lentfer } 672b5dedccaSJan Lentfer 673825eb42bSJan Lentfer ldns_rbnode_t * 674825eb42bSJan Lentfer ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node) 675825eb42bSJan Lentfer { 676825eb42bSJan Lentfer ldns_rbnode_t *next_node = NULL; 677825eb42bSJan Lentfer ldns_dnssec_name *next_name = NULL; 678825eb42bSJan Lentfer bool done = false; 679825eb42bSJan Lentfer 680825eb42bSJan Lentfer if (node == LDNS_RBTREE_NULL) { 681825eb42bSJan Lentfer return NULL; 682825eb42bSJan Lentfer } 683825eb42bSJan Lentfer next_node = node; 684825eb42bSJan Lentfer while (!done) { 685825eb42bSJan Lentfer if (next_node == LDNS_RBTREE_NULL) { 686825eb42bSJan Lentfer return NULL; 687825eb42bSJan Lentfer } else { 688825eb42bSJan Lentfer next_name = (ldns_dnssec_name *)next_node->data; 689825eb42bSJan Lentfer if (!next_name->is_glue) { 690825eb42bSJan Lentfer done = true; 691825eb42bSJan Lentfer } else { 692825eb42bSJan Lentfer next_node = ldns_rbtree_next(next_node); 693825eb42bSJan Lentfer } 694825eb42bSJan Lentfer } 695825eb42bSJan Lentfer } 696825eb42bSJan Lentfer return next_node; 697825eb42bSJan Lentfer } 698825eb42bSJan Lentfer 699825eb42bSJan Lentfer ldns_status 700825eb42bSJan Lentfer ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone, 701825eb42bSJan Lentfer ldns_rr_list *new_rrs) 702825eb42bSJan Lentfer { 703825eb42bSJan Lentfer 704825eb42bSJan Lentfer ldns_rbnode_t *first_node, *cur_node, *next_node; 705825eb42bSJan Lentfer ldns_dnssec_name *cur_name, *next_name; 706825eb42bSJan Lentfer ldns_rr *nsec_rr; 707825eb42bSJan Lentfer uint32_t nsec_ttl; 708825eb42bSJan Lentfer ldns_dnssec_rrsets *soa; 709825eb42bSJan Lentfer 710825eb42bSJan Lentfer /* the TTL of NSEC rrs should be set to the minimum TTL of 711825eb42bSJan Lentfer * the zone SOA (RFC4035 Section 2.3) 712825eb42bSJan Lentfer */ 713825eb42bSJan Lentfer soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); 714825eb42bSJan Lentfer 715825eb42bSJan Lentfer /* did the caller actually set it? if not, 716825eb42bSJan Lentfer * fall back to default ttl 717825eb42bSJan Lentfer */ 718b5dedccaSJan Lentfer if (soa && soa->rrs && soa->rrs->rr 719b5dedccaSJan Lentfer && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) { 720b5dedccaSJan Lentfer nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6)); 721825eb42bSJan Lentfer } else { 722825eb42bSJan Lentfer nsec_ttl = LDNS_DEFAULT_TTL; 723825eb42bSJan Lentfer } 724825eb42bSJan Lentfer 725825eb42bSJan Lentfer first_node = ldns_dnssec_name_node_next_nonglue( 726825eb42bSJan Lentfer ldns_rbtree_first(zone->names)); 727825eb42bSJan Lentfer cur_node = first_node; 728825eb42bSJan Lentfer if (cur_node) { 729825eb42bSJan Lentfer next_node = ldns_dnssec_name_node_next_nonglue( 730825eb42bSJan Lentfer ldns_rbtree_next(cur_node)); 731825eb42bSJan Lentfer } else { 732825eb42bSJan Lentfer next_node = NULL; 733825eb42bSJan Lentfer } 734825eb42bSJan Lentfer 735825eb42bSJan Lentfer while (cur_node && next_node) { 736825eb42bSJan Lentfer cur_name = (ldns_dnssec_name *)cur_node->data; 737825eb42bSJan Lentfer next_name = (ldns_dnssec_name *)next_node->data; 738825eb42bSJan Lentfer nsec_rr = ldns_dnssec_create_nsec(cur_name, 739825eb42bSJan Lentfer next_name, 740825eb42bSJan Lentfer LDNS_RR_TYPE_NSEC); 741825eb42bSJan Lentfer ldns_rr_set_ttl(nsec_rr, nsec_ttl); 742fd185f4dSJan Lentfer if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){ 743fd185f4dSJan Lentfer ldns_rr_free(nsec_rr); 744fd185f4dSJan Lentfer return LDNS_STATUS_ERR; 745fd185f4dSJan Lentfer } 746825eb42bSJan Lentfer ldns_rr_list_push_rr(new_rrs, nsec_rr); 747825eb42bSJan Lentfer cur_node = next_node; 748825eb42bSJan Lentfer if (cur_node) { 749825eb42bSJan Lentfer next_node = ldns_dnssec_name_node_next_nonglue( 750825eb42bSJan Lentfer ldns_rbtree_next(cur_node)); 751825eb42bSJan Lentfer } 752825eb42bSJan Lentfer } 753825eb42bSJan Lentfer 754825eb42bSJan Lentfer if (cur_node && !next_node) { 755825eb42bSJan Lentfer cur_name = (ldns_dnssec_name *)cur_node->data; 756825eb42bSJan Lentfer next_name = (ldns_dnssec_name *)first_node->data; 757825eb42bSJan Lentfer nsec_rr = ldns_dnssec_create_nsec(cur_name, 758825eb42bSJan Lentfer next_name, 759825eb42bSJan Lentfer LDNS_RR_TYPE_NSEC); 760825eb42bSJan Lentfer ldns_rr_set_ttl(nsec_rr, nsec_ttl); 761fd185f4dSJan Lentfer if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){ 762fd185f4dSJan Lentfer ldns_rr_free(nsec_rr); 763fd185f4dSJan Lentfer return LDNS_STATUS_ERR; 764fd185f4dSJan Lentfer } 765825eb42bSJan Lentfer ldns_rr_list_push_rr(new_rrs, nsec_rr); 766825eb42bSJan Lentfer } else { 767825eb42bSJan Lentfer printf("error\n"); 768825eb42bSJan Lentfer } 769825eb42bSJan Lentfer 770825eb42bSJan Lentfer return LDNS_STATUS_OK; 771825eb42bSJan Lentfer } 772825eb42bSJan Lentfer 773825eb42bSJan Lentfer #ifdef HAVE_SSL 774b5dedccaSJan Lentfer /* in dnssec_zone.c */ 775b5dedccaSJan Lentfer extern int ldns_dname_compare_v(const void *a, const void *b); 776b5dedccaSJan Lentfer 777825eb42bSJan Lentfer ldns_status 778b5dedccaSJan Lentfer ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone, 779825eb42bSJan Lentfer ldns_rr_list *new_rrs, 780825eb42bSJan Lentfer uint8_t algorithm, 781825eb42bSJan Lentfer uint8_t flags, 782825eb42bSJan Lentfer uint16_t iterations, 783825eb42bSJan Lentfer uint8_t salt_length, 784b5dedccaSJan Lentfer uint8_t *salt, 785b5dedccaSJan Lentfer ldns_rbtree_t **map) 786825eb42bSJan Lentfer { 787825eb42bSJan Lentfer ldns_rbnode_t *first_name_node; 788825eb42bSJan Lentfer ldns_rbnode_t *current_name_node; 789825eb42bSJan Lentfer ldns_dnssec_name *current_name; 790825eb42bSJan Lentfer ldns_status result = LDNS_STATUS_OK; 791825eb42bSJan Lentfer ldns_rr *nsec_rr; 792825eb42bSJan Lentfer ldns_rr_list *nsec3_list; 793825eb42bSJan Lentfer uint32_t nsec_ttl; 794825eb42bSJan Lentfer ldns_dnssec_rrsets *soa; 795b5dedccaSJan Lentfer ldns_rbnode_t *hashmap_node; 796825eb42bSJan Lentfer 797825eb42bSJan Lentfer if (!zone || !new_rrs || !zone->names) { 798825eb42bSJan Lentfer return LDNS_STATUS_ERR; 799825eb42bSJan Lentfer } 800825eb42bSJan Lentfer 801825eb42bSJan Lentfer /* the TTL of NSEC rrs should be set to the minimum TTL of 802825eb42bSJan Lentfer * the zone SOA (RFC4035 Section 2.3) 803825eb42bSJan Lentfer */ 804825eb42bSJan Lentfer soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA); 805825eb42bSJan Lentfer 806825eb42bSJan Lentfer /* did the caller actually set it? if not, 807825eb42bSJan Lentfer * fall back to default ttl 808825eb42bSJan Lentfer */ 809b5dedccaSJan Lentfer if (soa && soa->rrs && soa->rrs->rr 810b5dedccaSJan Lentfer && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) { 811b5dedccaSJan Lentfer nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6)); 812825eb42bSJan Lentfer } else { 813825eb42bSJan Lentfer nsec_ttl = LDNS_DEFAULT_TTL; 814825eb42bSJan Lentfer } 815825eb42bSJan Lentfer 816b5dedccaSJan Lentfer if (map) { 817b5dedccaSJan Lentfer if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 818b5dedccaSJan Lentfer == NULL) { 819b5dedccaSJan Lentfer map = NULL; 820b5dedccaSJan Lentfer }; 821b5dedccaSJan Lentfer } 822825eb42bSJan Lentfer nsec3_list = ldns_rr_list_new(); 823825eb42bSJan Lentfer 824825eb42bSJan Lentfer first_name_node = ldns_dnssec_name_node_next_nonglue( 825825eb42bSJan Lentfer ldns_rbtree_first(zone->names)); 826825eb42bSJan Lentfer 827825eb42bSJan Lentfer current_name_node = first_name_node; 828825eb42bSJan Lentfer 829825eb42bSJan Lentfer while (current_name_node && 830825eb42bSJan Lentfer current_name_node != LDNS_RBTREE_NULL) { 831825eb42bSJan Lentfer current_name = (ldns_dnssec_name *) current_name_node->data; 832825eb42bSJan Lentfer nsec_rr = ldns_dnssec_create_nsec3(current_name, 833825eb42bSJan Lentfer NULL, 834825eb42bSJan Lentfer zone->soa->name, 835825eb42bSJan Lentfer algorithm, 836825eb42bSJan Lentfer flags, 837825eb42bSJan Lentfer iterations, 838825eb42bSJan Lentfer salt_length, 839825eb42bSJan Lentfer salt); 840825eb42bSJan Lentfer /* by default, our nsec based generator adds rrsigs 841825eb42bSJan Lentfer * remove the bitmap for empty nonterminals */ 842825eb42bSJan Lentfer if (!current_name->rrsets) { 843825eb42bSJan Lentfer ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr)); 844825eb42bSJan Lentfer } 845825eb42bSJan Lentfer ldns_rr_set_ttl(nsec_rr, nsec_ttl); 846fd185f4dSJan Lentfer result = ldns_dnssec_name_add_rr(current_name, nsec_rr); 847825eb42bSJan Lentfer ldns_rr_list_push_rr(new_rrs, nsec_rr); 848825eb42bSJan Lentfer ldns_rr_list_push_rr(nsec3_list, nsec_rr); 849b5dedccaSJan Lentfer if (map) { 850b5dedccaSJan Lentfer hashmap_node = LDNS_MALLOC(ldns_rbnode_t); 851b5dedccaSJan Lentfer if (hashmap_node && ldns_rr_owner(nsec_rr)) { 852b5dedccaSJan Lentfer hashmap_node->key = ldns_dname_label( 853b5dedccaSJan Lentfer ldns_rr_owner(nsec_rr), 0); 854b5dedccaSJan Lentfer if (hashmap_node->key) { 855b5dedccaSJan Lentfer hashmap_node->data = current_name->name; 856b5dedccaSJan Lentfer (void) ldns_rbtree_insert( 857b5dedccaSJan Lentfer *map, hashmap_node); 858b5dedccaSJan Lentfer } 859b5dedccaSJan Lentfer } 860b5dedccaSJan Lentfer } 861825eb42bSJan Lentfer current_name_node = ldns_dnssec_name_node_next_nonglue( 862825eb42bSJan Lentfer ldns_rbtree_next(current_name_node)); 863825eb42bSJan Lentfer } 864fd185f4dSJan Lentfer if (result != LDNS_STATUS_OK) { 865*d1b2b5caSJohn Marino ldns_rr_list_free(nsec3_list); 866fd185f4dSJan Lentfer return result; 867fd185f4dSJan Lentfer } 868825eb42bSJan Lentfer 869825eb42bSJan Lentfer ldns_rr_list_sort_nsec3(nsec3_list); 870fd185f4dSJan Lentfer result = ldns_dnssec_chain_nsec3_list(nsec3_list); 871825eb42bSJan Lentfer ldns_rr_list_free(nsec3_list); 872*d1b2b5caSJohn Marino 873825eb42bSJan Lentfer return result; 874825eb42bSJan Lentfer } 875b5dedccaSJan Lentfer 876b5dedccaSJan Lentfer ldns_status 877b5dedccaSJan Lentfer ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone, 878b5dedccaSJan Lentfer ldns_rr_list *new_rrs, 879b5dedccaSJan Lentfer uint8_t algorithm, 880b5dedccaSJan Lentfer uint8_t flags, 881b5dedccaSJan Lentfer uint16_t iterations, 882b5dedccaSJan Lentfer uint8_t salt_length, 883b5dedccaSJan Lentfer uint8_t *salt) 884b5dedccaSJan Lentfer { 885b5dedccaSJan Lentfer return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm, 886b5dedccaSJan Lentfer flags, iterations, salt_length, salt, NULL); 887b5dedccaSJan Lentfer 888b5dedccaSJan Lentfer } 889825eb42bSJan Lentfer #endif /* HAVE_SSL */ 890825eb42bSJan Lentfer 891825eb42bSJan Lentfer ldns_dnssec_rrs * 892*d1b2b5caSJohn Marino ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures 893*d1b2b5caSJohn Marino , ATTR_UNUSED(ldns_key_list *key_list) 894*d1b2b5caSJohn Marino , int (*func)(ldns_rr *, void *) 895*d1b2b5caSJohn Marino , void *arg 896*d1b2b5caSJohn Marino ) 897825eb42bSJan Lentfer { 898825eb42bSJan Lentfer ldns_dnssec_rrs *base_rrs = signatures; 899825eb42bSJan Lentfer ldns_dnssec_rrs *cur_rr = base_rrs; 900825eb42bSJan Lentfer ldns_dnssec_rrs *prev_rr = NULL; 901825eb42bSJan Lentfer ldns_dnssec_rrs *next_rr; 902825eb42bSJan Lentfer 903825eb42bSJan Lentfer uint16_t keytag; 904825eb42bSJan Lentfer size_t i; 905825eb42bSJan Lentfer 906825eb42bSJan Lentfer if (!cur_rr) { 907825eb42bSJan Lentfer switch(func(NULL, arg)) { 908825eb42bSJan Lentfer case LDNS_SIGNATURE_LEAVE_ADD_NEW: 909825eb42bSJan Lentfer case LDNS_SIGNATURE_REMOVE_ADD_NEW: 910825eb42bSJan Lentfer break; 911825eb42bSJan Lentfer case LDNS_SIGNATURE_LEAVE_NO_ADD: 912825eb42bSJan Lentfer case LDNS_SIGNATURE_REMOVE_NO_ADD: 913825eb42bSJan Lentfer ldns_key_list_set_use(key_list, false); 914825eb42bSJan Lentfer break; 915825eb42bSJan Lentfer default: 916825eb42bSJan Lentfer fprintf(stderr, "[XX] unknown return value from callback\n"); 917825eb42bSJan Lentfer break; 918825eb42bSJan Lentfer } 919825eb42bSJan Lentfer return NULL; 920825eb42bSJan Lentfer } 921ac996e71SJan Lentfer (void)func(cur_rr->rr, arg); 922825eb42bSJan Lentfer 923825eb42bSJan Lentfer while (cur_rr) { 924825eb42bSJan Lentfer next_rr = cur_rr->next; 925825eb42bSJan Lentfer 926825eb42bSJan Lentfer switch (func(cur_rr->rr, arg)) { 927825eb42bSJan Lentfer case LDNS_SIGNATURE_LEAVE_ADD_NEW: 928825eb42bSJan Lentfer prev_rr = cur_rr; 929825eb42bSJan Lentfer break; 930825eb42bSJan Lentfer case LDNS_SIGNATURE_LEAVE_NO_ADD: 931825eb42bSJan Lentfer keytag = ldns_rdf2native_int16( 932825eb42bSJan Lentfer ldns_rr_rrsig_keytag(cur_rr->rr)); 933825eb42bSJan Lentfer for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 934825eb42bSJan Lentfer if (ldns_key_keytag(ldns_key_list_key(key_list, i)) == 935825eb42bSJan Lentfer keytag) { 936825eb42bSJan Lentfer ldns_key_set_use(ldns_key_list_key(key_list, i), 937825eb42bSJan Lentfer false); 938825eb42bSJan Lentfer } 939825eb42bSJan Lentfer } 940825eb42bSJan Lentfer prev_rr = cur_rr; 941825eb42bSJan Lentfer break; 942825eb42bSJan Lentfer case LDNS_SIGNATURE_REMOVE_NO_ADD: 943825eb42bSJan Lentfer keytag = ldns_rdf2native_int16( 944825eb42bSJan Lentfer ldns_rr_rrsig_keytag(cur_rr->rr)); 945825eb42bSJan Lentfer for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 946825eb42bSJan Lentfer if (ldns_key_keytag(ldns_key_list_key(key_list, i)) 947825eb42bSJan Lentfer == keytag) { 948825eb42bSJan Lentfer ldns_key_set_use(ldns_key_list_key(key_list, i), 949825eb42bSJan Lentfer false); 950825eb42bSJan Lentfer } 951825eb42bSJan Lentfer } 952825eb42bSJan Lentfer if (prev_rr) { 953825eb42bSJan Lentfer prev_rr->next = next_rr; 954825eb42bSJan Lentfer } else { 955825eb42bSJan Lentfer base_rrs = next_rr; 956825eb42bSJan Lentfer } 957825eb42bSJan Lentfer LDNS_FREE(cur_rr); 958825eb42bSJan Lentfer break; 959825eb42bSJan Lentfer case LDNS_SIGNATURE_REMOVE_ADD_NEW: 960825eb42bSJan Lentfer if (prev_rr) { 961825eb42bSJan Lentfer prev_rr->next = next_rr; 962825eb42bSJan Lentfer } else { 963825eb42bSJan Lentfer base_rrs = next_rr; 964825eb42bSJan Lentfer } 965825eb42bSJan Lentfer LDNS_FREE(cur_rr); 966825eb42bSJan Lentfer break; 967825eb42bSJan Lentfer default: 968825eb42bSJan Lentfer fprintf(stderr, "[XX] unknown return value from callback\n"); 969825eb42bSJan Lentfer break; 970825eb42bSJan Lentfer } 971825eb42bSJan Lentfer cur_rr = next_rr; 972825eb42bSJan Lentfer } 973825eb42bSJan Lentfer 974825eb42bSJan Lentfer return base_rrs; 975825eb42bSJan Lentfer } 976825eb42bSJan Lentfer 977825eb42bSJan Lentfer #ifdef HAVE_SSL 978825eb42bSJan Lentfer ldns_status 979825eb42bSJan Lentfer ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone, 980825eb42bSJan Lentfer ldns_rr_list *new_rrs, 981825eb42bSJan Lentfer ldns_key_list *key_list, 982825eb42bSJan Lentfer int (*func)(ldns_rr *, void*), 983825eb42bSJan Lentfer void *arg) 984825eb42bSJan Lentfer { 985825eb42bSJan Lentfer return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list, 986825eb42bSJan Lentfer func, arg, 0); 987825eb42bSJan Lentfer } 988825eb42bSJan Lentfer 989825eb42bSJan Lentfer /** If there are KSKs use only them and mark ZSKs unused */ 990825eb42bSJan Lentfer static void 991825eb42bSJan Lentfer ldns_key_list_filter_for_dnskey(ldns_key_list *key_list) 992825eb42bSJan Lentfer { 993825eb42bSJan Lentfer int saw_ksk = 0; 994825eb42bSJan Lentfer size_t i; 995825eb42bSJan Lentfer for(i=0; i<ldns_key_list_key_count(key_list); i++) 996825eb42bSJan Lentfer if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) { 997825eb42bSJan Lentfer saw_ksk = 1; 998825eb42bSJan Lentfer break; 999825eb42bSJan Lentfer } 1000825eb42bSJan Lentfer if(!saw_ksk) 1001825eb42bSJan Lentfer return; 1002825eb42bSJan Lentfer for(i=0; i<ldns_key_list_key_count(key_list); i++) 1003825eb42bSJan Lentfer if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) 1004825eb42bSJan Lentfer ldns_key_set_use(ldns_key_list_key(key_list, i), 0); 1005825eb42bSJan Lentfer } 1006825eb42bSJan Lentfer 1007ac996e71SJan Lentfer /** If there are no ZSKs use KSK as ZSK */ 1008ac996e71SJan Lentfer static void 1009ac996e71SJan Lentfer ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list) 1010ac996e71SJan Lentfer { 1011ac996e71SJan Lentfer int saw_zsk = 0; 1012ac996e71SJan Lentfer size_t i; 1013ac996e71SJan Lentfer for(i=0; i<ldns_key_list_key_count(key_list); i++) 1014ac996e71SJan Lentfer if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) { 1015ac996e71SJan Lentfer saw_zsk = 1; 1016ac996e71SJan Lentfer break; 1017ac996e71SJan Lentfer } 1018ac996e71SJan Lentfer if(!saw_zsk) 1019ac996e71SJan Lentfer return; 1020ac996e71SJan Lentfer /* else filter all KSKs */ 1021ac996e71SJan Lentfer for(i=0; i<ldns_key_list_key_count(key_list); i++) 1022ac996e71SJan Lentfer if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) 1023ac996e71SJan Lentfer ldns_key_set_use(ldns_key_list_key(key_list, i), 0); 1024ac996e71SJan Lentfer } 1025ac996e71SJan Lentfer 1026825eb42bSJan Lentfer ldns_status 1027*d1b2b5caSJohn Marino ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone 1028*d1b2b5caSJohn Marino , ldns_rr_list *new_rrs 1029*d1b2b5caSJohn Marino , ldns_key_list *key_list 1030*d1b2b5caSJohn Marino , int (*func)(ldns_rr *, void*) 1031*d1b2b5caSJohn Marino , void *arg 1032*d1b2b5caSJohn Marino , int flags 1033*d1b2b5caSJohn Marino ) 1034825eb42bSJan Lentfer { 1035825eb42bSJan Lentfer ldns_status result = LDNS_STATUS_OK; 1036825eb42bSJan Lentfer 1037825eb42bSJan Lentfer ldns_rbnode_t *cur_node; 1038825eb42bSJan Lentfer ldns_rr_list *rr_list; 1039825eb42bSJan Lentfer 1040825eb42bSJan Lentfer ldns_dnssec_name *cur_name; 1041825eb42bSJan Lentfer ldns_dnssec_rrsets *cur_rrset; 1042825eb42bSJan Lentfer ldns_dnssec_rrs *cur_rr; 1043825eb42bSJan Lentfer 1044825eb42bSJan Lentfer ldns_rr_list *siglist; 1045825eb42bSJan Lentfer 1046825eb42bSJan Lentfer size_t i; 1047825eb42bSJan Lentfer 1048b5dedccaSJan Lentfer int on_delegation_point = 0; /* handle partially occluded names */ 1049b5dedccaSJan Lentfer 1050825eb42bSJan Lentfer ldns_rr_list *pubkey_list = ldns_rr_list_new(); 1051825eb42bSJan Lentfer for (i = 0; i<ldns_key_list_key_count(key_list); i++) { 1052*d1b2b5caSJohn Marino ldns_rr_list_push_rr( pubkey_list 1053*d1b2b5caSJohn Marino , ldns_key2rr(ldns_key_list_key( 1054*d1b2b5caSJohn Marino key_list, i)) 1055*d1b2b5caSJohn Marino ); 1056825eb42bSJan Lentfer } 1057825eb42bSJan Lentfer /* TODO: callback to see is list should be signed */ 1058825eb42bSJan Lentfer /* TODO: remove 'old' signatures from signature list */ 1059825eb42bSJan Lentfer cur_node = ldns_rbtree_first(zone->names); 1060825eb42bSJan Lentfer while (cur_node != LDNS_RBTREE_NULL) { 1061825eb42bSJan Lentfer cur_name = (ldns_dnssec_name *) cur_node->data; 1062825eb42bSJan Lentfer 1063825eb42bSJan Lentfer if (!cur_name->is_glue) { 1064b5dedccaSJan Lentfer on_delegation_point = ldns_dnssec_rrsets_contains_type( 1065b5dedccaSJan Lentfer cur_name->rrsets, LDNS_RR_TYPE_NS) 1066b5dedccaSJan Lentfer && !ldns_dnssec_rrsets_contains_type( 1067b5dedccaSJan Lentfer cur_name->rrsets, LDNS_RR_TYPE_SOA); 1068825eb42bSJan Lentfer cur_rrset = cur_name->rrsets; 1069825eb42bSJan Lentfer while (cur_rrset) { 1070825eb42bSJan Lentfer /* reset keys to use */ 1071825eb42bSJan Lentfer ldns_key_list_set_use(key_list, true); 1072825eb42bSJan Lentfer 1073825eb42bSJan Lentfer /* walk through old sigs, remove the old, 1074825eb42bSJan Lentfer and mark which keys (not) to use) */ 1075825eb42bSJan Lentfer cur_rrset->signatures = 1076825eb42bSJan Lentfer ldns_dnssec_remove_signatures(cur_rrset->signatures, 1077825eb42bSJan Lentfer key_list, 1078825eb42bSJan Lentfer func, 1079825eb42bSJan Lentfer arg); 1080825eb42bSJan Lentfer if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) && 1081825eb42bSJan Lentfer cur_rrset->type == LDNS_RR_TYPE_DNSKEY) 1082825eb42bSJan Lentfer ldns_key_list_filter_for_dnskey(key_list); 1083825eb42bSJan Lentfer 1084ac996e71SJan Lentfer if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY) 1085ac996e71SJan Lentfer ldns_key_list_filter_for_non_dnskey(key_list); 1086ac996e71SJan Lentfer 1087825eb42bSJan Lentfer /* TODO: just set count to zero? */ 1088825eb42bSJan Lentfer rr_list = ldns_rr_list_new(); 1089825eb42bSJan Lentfer 1090825eb42bSJan Lentfer cur_rr = cur_rrset->rrs; 1091825eb42bSJan Lentfer while (cur_rr) { 1092825eb42bSJan Lentfer ldns_rr_list_push_rr(rr_list, cur_rr->rr); 1093825eb42bSJan Lentfer cur_rr = cur_rr->next; 1094825eb42bSJan Lentfer } 1095825eb42bSJan Lentfer 1096825eb42bSJan Lentfer /* only sign non-delegation RRsets */ 1097b5dedccaSJan Lentfer /* (glue should have been marked earlier, 1098b5dedccaSJan Lentfer * except on the delegation points itself) */ 1099b5dedccaSJan Lentfer if (!on_delegation_point || 1100b5dedccaSJan Lentfer ldns_rr_list_type(rr_list) 1101b5dedccaSJan Lentfer == LDNS_RR_TYPE_DS || 1102b5dedccaSJan Lentfer ldns_rr_list_type(rr_list) 1103b5dedccaSJan Lentfer == LDNS_RR_TYPE_NSEC || 1104b5dedccaSJan Lentfer ldns_rr_list_type(rr_list) 1105b5dedccaSJan Lentfer == LDNS_RR_TYPE_NSEC3) { 1106825eb42bSJan Lentfer siglist = ldns_sign_public(rr_list, key_list); 1107825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) { 1108825eb42bSJan Lentfer if (cur_rrset->signatures) { 1109fd185f4dSJan Lentfer result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures, 1110825eb42bSJan Lentfer ldns_rr_list_rr(siglist, 1111825eb42bSJan Lentfer i)); 1112825eb42bSJan Lentfer } else { 1113825eb42bSJan Lentfer cur_rrset->signatures = ldns_dnssec_rrs_new(); 1114825eb42bSJan Lentfer cur_rrset->signatures->rr = 1115825eb42bSJan Lentfer ldns_rr_list_rr(siglist, i); 1116*d1b2b5caSJohn Marino } 1117*d1b2b5caSJohn Marino if (new_rrs) { 1118825eb42bSJan Lentfer ldns_rr_list_push_rr(new_rrs, 1119825eb42bSJan Lentfer ldns_rr_list_rr(siglist, 1120825eb42bSJan Lentfer i)); 1121825eb42bSJan Lentfer } 1122825eb42bSJan Lentfer } 1123825eb42bSJan Lentfer ldns_rr_list_free(siglist); 1124825eb42bSJan Lentfer } 1125825eb42bSJan Lentfer 1126825eb42bSJan Lentfer ldns_rr_list_free(rr_list); 1127825eb42bSJan Lentfer 1128825eb42bSJan Lentfer cur_rrset = cur_rrset->next; 1129825eb42bSJan Lentfer } 1130825eb42bSJan Lentfer 1131825eb42bSJan Lentfer /* sign the nsec */ 1132ac996e71SJan Lentfer ldns_key_list_set_use(key_list, true); 1133825eb42bSJan Lentfer cur_name->nsec_signatures = 1134825eb42bSJan Lentfer ldns_dnssec_remove_signatures(cur_name->nsec_signatures, 1135825eb42bSJan Lentfer key_list, 1136825eb42bSJan Lentfer func, 1137825eb42bSJan Lentfer arg); 1138ac996e71SJan Lentfer ldns_key_list_filter_for_non_dnskey(key_list); 1139825eb42bSJan Lentfer 1140825eb42bSJan Lentfer rr_list = ldns_rr_list_new(); 1141825eb42bSJan Lentfer ldns_rr_list_push_rr(rr_list, cur_name->nsec); 1142825eb42bSJan Lentfer siglist = ldns_sign_public(rr_list, key_list); 1143825eb42bSJan Lentfer 1144825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) { 1145825eb42bSJan Lentfer if (cur_name->nsec_signatures) { 1146fd185f4dSJan Lentfer result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures, 1147825eb42bSJan Lentfer ldns_rr_list_rr(siglist, i)); 1148825eb42bSJan Lentfer } else { 1149825eb42bSJan Lentfer cur_name->nsec_signatures = ldns_dnssec_rrs_new(); 1150825eb42bSJan Lentfer cur_name->nsec_signatures->rr = 1151825eb42bSJan Lentfer ldns_rr_list_rr(siglist, i); 1152*d1b2b5caSJohn Marino } 1153*d1b2b5caSJohn Marino if (new_rrs) { 1154825eb42bSJan Lentfer ldns_rr_list_push_rr(new_rrs, 1155825eb42bSJan Lentfer ldns_rr_list_rr(siglist, i)); 1156825eb42bSJan Lentfer } 1157825eb42bSJan Lentfer } 1158825eb42bSJan Lentfer 1159825eb42bSJan Lentfer ldns_rr_list_free(siglist); 1160825eb42bSJan Lentfer ldns_rr_list_free(rr_list); 1161825eb42bSJan Lentfer } 1162825eb42bSJan Lentfer cur_node = ldns_rbtree_next(cur_node); 1163825eb42bSJan Lentfer } 1164825eb42bSJan Lentfer 1165825eb42bSJan Lentfer ldns_rr_list_deep_free(pubkey_list); 1166825eb42bSJan Lentfer return result; 1167825eb42bSJan Lentfer } 1168825eb42bSJan Lentfer 1169825eb42bSJan Lentfer ldns_status 1170825eb42bSJan Lentfer ldns_dnssec_zone_sign(ldns_dnssec_zone *zone, 1171825eb42bSJan Lentfer ldns_rr_list *new_rrs, 1172825eb42bSJan Lentfer ldns_key_list *key_list, 1173825eb42bSJan Lentfer int (*func)(ldns_rr *, void *), 1174825eb42bSJan Lentfer void *arg) 1175825eb42bSJan Lentfer { 1176825eb42bSJan Lentfer return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0); 1177825eb42bSJan Lentfer } 1178825eb42bSJan Lentfer 1179825eb42bSJan Lentfer ldns_status 1180825eb42bSJan Lentfer ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, 1181825eb42bSJan Lentfer ldns_rr_list *new_rrs, 1182825eb42bSJan Lentfer ldns_key_list *key_list, 1183825eb42bSJan Lentfer int (*func)(ldns_rr *, void *), 1184825eb42bSJan Lentfer void *arg, 1185825eb42bSJan Lentfer int flags) 1186825eb42bSJan Lentfer { 1187825eb42bSJan Lentfer ldns_status result = LDNS_STATUS_OK; 1188825eb42bSJan Lentfer 1189825eb42bSJan Lentfer if (!zone || !new_rrs || !key_list) { 1190825eb42bSJan Lentfer return LDNS_STATUS_ERR; 1191825eb42bSJan Lentfer } 1192825eb42bSJan Lentfer 1193825eb42bSJan Lentfer /* zone is already sorted */ 1194fd185f4dSJan Lentfer result = ldns_dnssec_zone_mark_glue(zone); 1195fd185f4dSJan Lentfer if (result != LDNS_STATUS_OK) { 1196fd185f4dSJan Lentfer return result; 1197fd185f4dSJan Lentfer } 1198825eb42bSJan Lentfer 1199825eb42bSJan Lentfer /* check whether we need to add nsecs */ 1200825eb42bSJan Lentfer if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) { 1201825eb42bSJan Lentfer result = ldns_dnssec_zone_create_nsecs(zone, new_rrs); 1202825eb42bSJan Lentfer if (result != LDNS_STATUS_OK) { 1203825eb42bSJan Lentfer return result; 1204825eb42bSJan Lentfer } 1205825eb42bSJan Lentfer } 1206825eb42bSJan Lentfer 1207825eb42bSJan Lentfer result = ldns_dnssec_zone_create_rrsigs_flg(zone, 1208825eb42bSJan Lentfer new_rrs, 1209825eb42bSJan Lentfer key_list, 1210825eb42bSJan Lentfer func, 1211825eb42bSJan Lentfer arg, 1212825eb42bSJan Lentfer flags); 1213825eb42bSJan Lentfer 1214825eb42bSJan Lentfer return result; 1215825eb42bSJan Lentfer } 1216825eb42bSJan Lentfer 1217825eb42bSJan Lentfer ldns_status 1218825eb42bSJan Lentfer ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone, 1219825eb42bSJan Lentfer ldns_rr_list *new_rrs, 1220825eb42bSJan Lentfer ldns_key_list *key_list, 1221825eb42bSJan Lentfer int (*func)(ldns_rr *, void *), 1222825eb42bSJan Lentfer void *arg, 1223825eb42bSJan Lentfer uint8_t algorithm, 1224825eb42bSJan Lentfer uint8_t flags, 1225825eb42bSJan Lentfer uint16_t iterations, 1226825eb42bSJan Lentfer uint8_t salt_length, 1227825eb42bSJan Lentfer uint8_t *salt) 1228825eb42bSJan Lentfer { 1229b5dedccaSJan Lentfer return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list, 1230b5dedccaSJan Lentfer func, arg, algorithm, flags, iterations, salt_length, salt, 0, 1231b5dedccaSJan Lentfer NULL); 1232825eb42bSJan Lentfer } 1233825eb42bSJan Lentfer 1234825eb42bSJan Lentfer ldns_status 1235b5dedccaSJan Lentfer ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, 1236825eb42bSJan Lentfer ldns_rr_list *new_rrs, 1237825eb42bSJan Lentfer ldns_key_list *key_list, 1238825eb42bSJan Lentfer int (*func)(ldns_rr *, void *), 1239825eb42bSJan Lentfer void *arg, 1240825eb42bSJan Lentfer uint8_t algorithm, 1241825eb42bSJan Lentfer uint8_t flags, 1242825eb42bSJan Lentfer uint16_t iterations, 1243825eb42bSJan Lentfer uint8_t salt_length, 1244825eb42bSJan Lentfer uint8_t *salt, 1245b5dedccaSJan Lentfer int signflags, 1246b5dedccaSJan Lentfer ldns_rbtree_t **map) 1247825eb42bSJan Lentfer { 1248b5dedccaSJan Lentfer ldns_rr *nsec3, *nsec3param; 1249825eb42bSJan Lentfer ldns_status result = LDNS_STATUS_OK; 1250825eb42bSJan Lentfer 1251825eb42bSJan Lentfer /* zone is already sorted */ 1252fd185f4dSJan Lentfer result = ldns_dnssec_zone_mark_glue(zone); 1253fd185f4dSJan Lentfer if (result != LDNS_STATUS_OK) { 1254fd185f4dSJan Lentfer return result; 1255fd185f4dSJan Lentfer } 1256825eb42bSJan Lentfer 1257825eb42bSJan Lentfer /* TODO if there are already nsec3s presents and their 1258825eb42bSJan Lentfer * parameters are the same as these, we don't have to recreate 1259825eb42bSJan Lentfer */ 1260825eb42bSJan Lentfer if (zone->names) { 1261825eb42bSJan Lentfer /* add empty nonterminals */ 1262fd185f4dSJan Lentfer result = ldns_dnssec_zone_add_empty_nonterminals(zone); 1263fd185f4dSJan Lentfer if (result != LDNS_STATUS_OK) { 1264fd185f4dSJan Lentfer return result; 1265fd185f4dSJan Lentfer } 1266825eb42bSJan Lentfer 1267825eb42bSJan Lentfer nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec; 1268825eb42bSJan Lentfer if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) { 1269825eb42bSJan Lentfer /* no need to recreate */ 1270825eb42bSJan Lentfer } else { 1271825eb42bSJan Lentfer if (!ldns_dnssec_zone_find_rrset(zone, 1272825eb42bSJan Lentfer zone->soa->name, 1273b5dedccaSJan Lentfer LDNS_RR_TYPE_NSEC3PARAM)) { 1274b5dedccaSJan Lentfer /* create and add the nsec3param rr */ 1275b5dedccaSJan Lentfer nsec3param = 1276b5dedccaSJan Lentfer ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM); 1277b5dedccaSJan Lentfer ldns_rr_set_owner(nsec3param, 1278825eb42bSJan Lentfer ldns_rdf_clone(zone->soa->name)); 1279b5dedccaSJan Lentfer ldns_nsec3_add_param_rdfs(nsec3param, 1280825eb42bSJan Lentfer algorithm, 1281825eb42bSJan Lentfer flags, 1282825eb42bSJan Lentfer iterations, 1283825eb42bSJan Lentfer salt_length, 1284825eb42bSJan Lentfer salt); 1285825eb42bSJan Lentfer /* always set bit 7 of the flags to zero, according to 1286*d1b2b5caSJohn Marino * rfc5155 section 11. The bits are counted from right to left, 1287*d1b2b5caSJohn Marino * so bit 7 in rfc5155 is bit 0 in ldns */ 1288*d1b2b5caSJohn Marino ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0); 1289b5dedccaSJan Lentfer result = ldns_dnssec_zone_add_rr(zone, nsec3param); 1290fd185f4dSJan Lentfer if (result != LDNS_STATUS_OK) { 1291fd185f4dSJan Lentfer return result; 1292fd185f4dSJan Lentfer } 1293b5dedccaSJan Lentfer ldns_rr_list_push_rr(new_rrs, nsec3param); 1294825eb42bSJan Lentfer } 1295b5dedccaSJan Lentfer result = ldns_dnssec_zone_create_nsec3s_mkmap(zone, 1296825eb42bSJan Lentfer new_rrs, 1297825eb42bSJan Lentfer algorithm, 1298825eb42bSJan Lentfer flags, 1299825eb42bSJan Lentfer iterations, 1300825eb42bSJan Lentfer salt_length, 1301b5dedccaSJan Lentfer salt, 1302b5dedccaSJan Lentfer map); 1303825eb42bSJan Lentfer if (result != LDNS_STATUS_OK) { 1304825eb42bSJan Lentfer return result; 1305825eb42bSJan Lentfer } 1306825eb42bSJan Lentfer } 1307825eb42bSJan Lentfer 1308825eb42bSJan Lentfer result = ldns_dnssec_zone_create_rrsigs_flg(zone, 1309825eb42bSJan Lentfer new_rrs, 1310825eb42bSJan Lentfer key_list, 1311825eb42bSJan Lentfer func, 1312825eb42bSJan Lentfer arg, 1313825eb42bSJan Lentfer signflags); 1314825eb42bSJan Lentfer } 1315825eb42bSJan Lentfer 1316825eb42bSJan Lentfer return result; 1317825eb42bSJan Lentfer } 1318825eb42bSJan Lentfer 1319b5dedccaSJan Lentfer ldns_status 1320b5dedccaSJan Lentfer ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone, 1321b5dedccaSJan Lentfer ldns_rr_list *new_rrs, 1322b5dedccaSJan Lentfer ldns_key_list *key_list, 1323b5dedccaSJan Lentfer int (*func)(ldns_rr *, void *), 1324b5dedccaSJan Lentfer void *arg, 1325b5dedccaSJan Lentfer uint8_t algorithm, 1326b5dedccaSJan Lentfer uint8_t flags, 1327b5dedccaSJan Lentfer uint16_t iterations, 1328b5dedccaSJan Lentfer uint8_t salt_length, 1329b5dedccaSJan Lentfer uint8_t *salt, 1330b5dedccaSJan Lentfer int signflags) 1331b5dedccaSJan Lentfer { 1332b5dedccaSJan Lentfer return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list, 1333b5dedccaSJan Lentfer func, arg, algorithm, flags, iterations, salt_length, salt, 1334b5dedccaSJan Lentfer signflags, NULL); 1335b5dedccaSJan Lentfer } 1336825eb42bSJan Lentfer 1337825eb42bSJan Lentfer ldns_zone * 1338825eb42bSJan Lentfer ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list) 1339825eb42bSJan Lentfer { 1340825eb42bSJan Lentfer ldns_dnssec_zone *dnssec_zone; 1341825eb42bSJan Lentfer ldns_zone *signed_zone; 1342825eb42bSJan Lentfer ldns_rr_list *new_rrs; 1343825eb42bSJan Lentfer size_t i; 1344825eb42bSJan Lentfer 1345825eb42bSJan Lentfer signed_zone = ldns_zone_new(); 1346825eb42bSJan Lentfer dnssec_zone = ldns_dnssec_zone_new(); 1347825eb42bSJan Lentfer 1348825eb42bSJan Lentfer (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone)); 1349ac996e71SJan Lentfer ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone))); 1350825eb42bSJan Lentfer 1351825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 1352825eb42bSJan Lentfer (void) ldns_dnssec_zone_add_rr(dnssec_zone, 1353825eb42bSJan Lentfer ldns_rr_list_rr(ldns_zone_rrs(zone), 1354825eb42bSJan Lentfer i)); 1355825eb42bSJan Lentfer ldns_zone_push_rr(signed_zone, 1356825eb42bSJan Lentfer ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone), 1357825eb42bSJan Lentfer i))); 1358825eb42bSJan Lentfer } 1359825eb42bSJan Lentfer 1360825eb42bSJan Lentfer new_rrs = ldns_rr_list_new(); 1361825eb42bSJan Lentfer (void) ldns_dnssec_zone_sign(dnssec_zone, 1362825eb42bSJan Lentfer new_rrs, 1363825eb42bSJan Lentfer key_list, 1364825eb42bSJan Lentfer ldns_dnssec_default_replace_signatures, 1365825eb42bSJan Lentfer NULL); 1366825eb42bSJan Lentfer 1367825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) { 1368825eb42bSJan Lentfer ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone), 1369825eb42bSJan Lentfer ldns_rr_clone(ldns_rr_list_rr(new_rrs, i))); 1370825eb42bSJan Lentfer } 1371825eb42bSJan Lentfer 1372825eb42bSJan Lentfer ldns_rr_list_deep_free(new_rrs); 1373825eb42bSJan Lentfer ldns_dnssec_zone_free(dnssec_zone); 1374825eb42bSJan Lentfer 1375825eb42bSJan Lentfer return signed_zone; 1376825eb42bSJan Lentfer } 1377825eb42bSJan Lentfer 1378825eb42bSJan Lentfer ldns_zone * 1379825eb42bSJan Lentfer ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt) 1380825eb42bSJan Lentfer { 1381825eb42bSJan Lentfer ldns_dnssec_zone *dnssec_zone; 1382825eb42bSJan Lentfer ldns_zone *signed_zone; 1383825eb42bSJan Lentfer ldns_rr_list *new_rrs; 1384825eb42bSJan Lentfer size_t i; 1385825eb42bSJan Lentfer 1386825eb42bSJan Lentfer signed_zone = ldns_zone_new(); 1387825eb42bSJan Lentfer dnssec_zone = ldns_dnssec_zone_new(); 1388825eb42bSJan Lentfer 1389825eb42bSJan Lentfer (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone)); 1390ac996e71SJan Lentfer ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone))); 1391825eb42bSJan Lentfer 1392825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 1393825eb42bSJan Lentfer (void) ldns_dnssec_zone_add_rr(dnssec_zone, 1394825eb42bSJan Lentfer ldns_rr_list_rr(ldns_zone_rrs(zone), 1395825eb42bSJan Lentfer i)); 1396825eb42bSJan Lentfer ldns_zone_push_rr(signed_zone, 1397825eb42bSJan Lentfer ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone), 1398825eb42bSJan Lentfer i))); 1399825eb42bSJan Lentfer } 1400825eb42bSJan Lentfer 1401825eb42bSJan Lentfer new_rrs = ldns_rr_list_new(); 1402825eb42bSJan Lentfer (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone, 1403825eb42bSJan Lentfer new_rrs, 1404825eb42bSJan Lentfer key_list, 1405825eb42bSJan Lentfer ldns_dnssec_default_replace_signatures, 1406825eb42bSJan Lentfer NULL, 1407825eb42bSJan Lentfer algorithm, 1408825eb42bSJan Lentfer flags, 1409825eb42bSJan Lentfer iterations, 1410825eb42bSJan Lentfer salt_length, 1411825eb42bSJan Lentfer salt); 1412825eb42bSJan Lentfer 1413825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) { 1414825eb42bSJan Lentfer ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone), 1415825eb42bSJan Lentfer ldns_rr_clone(ldns_rr_list_rr(new_rrs, i))); 1416825eb42bSJan Lentfer } 1417825eb42bSJan Lentfer 1418825eb42bSJan Lentfer ldns_rr_list_deep_free(new_rrs); 1419825eb42bSJan Lentfer ldns_dnssec_zone_free(dnssec_zone); 1420825eb42bSJan Lentfer 1421825eb42bSJan Lentfer return signed_zone; 1422825eb42bSJan Lentfer } 1423825eb42bSJan Lentfer #endif /* HAVE_SSL */ 1424825eb42bSJan Lentfer 1425b5dedccaSJan Lentfer 1426