ldns  1.7.0
dnssec_sign.c
Go to the documentation of this file.
1 #include <ldns/config.h>
2 
3 #include <ldns/ldns.h>
4 
5 #include <ldns/dnssec.h>
6 #include <ldns/dnssec_sign.h>
7 
8 #include <strings.h>
9 #include <time.h>
10 
11 #ifdef HAVE_SSL
12 /* this entire file is rather useless when you don't have
13  * crypto...
14  */
15 #include <openssl/ssl.h>
16 #include <openssl/evp.h>
17 #include <openssl/rand.h>
18 #include <openssl/err.h>
19 #include <openssl/md5.h>
20 #endif /* HAVE_SSL */
21 
22 ldns_rr *
24  const ldns_key *current_key)
25 {
26  uint32_t orig_ttl;
27  ldns_rr_class orig_class;
28  time_t now;
29  ldns_rr *current_sig;
30  uint8_t label_count;
31  ldns_rdf *signame;
32 
34  0)));
35  /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
37  label_count --;
38 
40 
41  /* set the type on the new signature */
42  orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
43  orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
44 
45  ldns_rr_set_ttl(current_sig, orig_ttl);
46  ldns_rr_set_class(current_sig, orig_class);
47  ldns_rr_set_owner(current_sig,
50  ldns_rr_list_rr(rrset,
51  0))));
52 
53  /* fill in what we know of the signature */
54 
55  /* set the orig_ttl */
57  current_sig,
59  orig_ttl));
60  /* the signers name */
61  signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
62  ldns_dname2canonical(signame);
64  current_sig,
65  signame);
66  /* label count - get it from the first rr in the rr_list */
68  current_sig,
70  label_count));
71  /* inception, expiration */
72  now = time(NULL);
73  if (ldns_key_inception(current_key) != 0) {
75  current_sig,
78  ldns_key_inception(current_key)));
79  } else {
81  current_sig,
83  }
84  if (ldns_key_expiration(current_key) != 0) {
86  current_sig,
89  ldns_key_expiration(current_key)));
90  } else {
92  current_sig,
95  now + LDNS_DEFAULT_EXP_TIME));
96  }
97 
99  current_sig,
101  ldns_key_keytag(current_key)));
102 
104  current_sig,
107  ldns_key_algorithm(current_key)));
108 
110  current_sig,
114  0))));
115  return current_sig;
116 }
117 
118 #ifdef HAVE_SSL
119 ldns_rdf *
121 {
122  ldns_rdf *b64rdf = NULL;
123 
124  switch(ldns_key_algorithm(current_key)) {
125 #ifdef USE_DSA
126  case LDNS_SIGN_DSA:
127  case LDNS_SIGN_DSA_NSEC3:
128  b64rdf = ldns_sign_public_evp(
129  sign_buf,
130  ldns_key_evp_key(current_key),
131 # ifdef HAVE_EVP_DSS1
132  EVP_dss1()
133 # else
134  EVP_sha1()
135 # endif
136  );
137  break;
138 #endif /* USE_DSA */
139  case LDNS_SIGN_RSASHA1:
141  b64rdf = ldns_sign_public_evp(
142  sign_buf,
143  ldns_key_evp_key(current_key),
144  EVP_sha1());
145  break;
146 #ifdef USE_SHA2
147  case LDNS_SIGN_RSASHA256:
148  b64rdf = ldns_sign_public_evp(
149  sign_buf,
150  ldns_key_evp_key(current_key),
151  EVP_sha256());
152  break;
153  case LDNS_SIGN_RSASHA512:
154  b64rdf = ldns_sign_public_evp(
155  sign_buf,
156  ldns_key_evp_key(current_key),
157  EVP_sha512());
158  break;
159 #endif /* USE_SHA2 */
160 #ifdef USE_GOST
161  case LDNS_SIGN_ECC_GOST:
162  b64rdf = ldns_sign_public_evp(
163  sign_buf,
164  ldns_key_evp_key(current_key),
165  EVP_get_digestbyname("md_gost94"));
166  break;
167 #endif /* USE_GOST */
168 #ifdef USE_ECDSA
170  b64rdf = ldns_sign_public_evp(
171  sign_buf,
172  ldns_key_evp_key(current_key),
173  EVP_sha256());
174  break;
176  b64rdf = ldns_sign_public_evp(
177  sign_buf,
178  ldns_key_evp_key(current_key),
179  EVP_sha384());
180  break;
181 #endif
182 #ifdef USE_ED25519
183  case LDNS_SIGN_ED25519:
184  b64rdf = ldns_sign_public_evp(
185  sign_buf,
186  ldns_key_evp_key(current_key),
187  EVP_sha512());
188  break;
189 #endif
190 #ifdef USE_ED448
191  case LDNS_SIGN_ED448:
192  b64rdf = ldns_sign_public_evp(
193  sign_buf,
194  ldns_key_evp_key(current_key),
195  EVP_sha512());
196  break;
197 #endif
198  case LDNS_SIGN_RSAMD5:
199  b64rdf = ldns_sign_public_evp(
200  sign_buf,
201  ldns_key_evp_key(current_key),
202  EVP_md5());
203  break;
204  default:
205  /* do _you_ know this alg? */
206  printf("unknown algorithm, ");
207  printf("is the one used available on this system?\n");
208  break;
209  }
210 
211  return b64rdf;
212 }
213 
218 ldns_rr_list *
220 {
221  ldns_rr_list *signatures;
222  ldns_rr_list *rrset_clone;
223  ldns_rr *current_sig;
224  ldns_rdf *b64rdf;
225  ldns_key *current_key;
226  size_t key_count;
227  uint16_t i;
228  ldns_buffer *sign_buf;
229  ldns_rdf *new_owner;
230 
231  if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
232  return NULL;
233  }
234 
235  new_owner = NULL;
236 
237  signatures = ldns_rr_list_new();
238 
239  /* prepare a signature and add all the know data
240  * prepare the rrset. Sign this together. */
241  rrset_clone = ldns_rr_list_clone(rrset);
242  if (!rrset_clone) {
243  return NULL;
244  }
245 
246  /* make it canonical */
247  for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
248  ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
249  ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
250  ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
251  }
252  /* sort */
253  ldns_rr_list_sort(rrset_clone);
254 
255  for (key_count = 0;
256  key_count < ldns_key_list_key_count(keys);
257  key_count++) {
258  if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
259  continue;
260  }
262  if (!sign_buf) {
263  ldns_rr_list_free(rrset_clone);
264  ldns_rr_list_free(signatures);
265  ldns_rdf_free(new_owner);
266  return NULL;
267  }
268  b64rdf = NULL;
269 
270  current_key = ldns_key_list_key(keys, key_count);
271  /* sign all RRs with keys that have ZSKbit, !SEPbit.
272  sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
273  if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
274  current_sig = ldns_create_empty_rrsig(rrset_clone,
275  current_key);
276 
277  /* right now, we have: a key, a semi-sig and an rrset. For
278  * which we can create the sig and base64 encode that and
279  * add that to the signature */
280 
281  if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
282  != LDNS_STATUS_OK) {
283  ldns_buffer_free(sign_buf);
284  /* ERROR */
285  ldns_rr_list_deep_free(rrset_clone);
286  ldns_rr_free(current_sig);
287  ldns_rr_list_deep_free(signatures);
288  return NULL;
289  }
290 
291  /* add the rrset in sign_buf */
292  if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
293  != LDNS_STATUS_OK) {
294  ldns_buffer_free(sign_buf);
295  ldns_rr_list_deep_free(rrset_clone);
296  ldns_rr_free(current_sig);
297  ldns_rr_list_deep_free(signatures);
298  return NULL;
299  }
300 
301  b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
302 
303  if (!b64rdf) {
304  /* signing went wrong */
305  ldns_rr_list_deep_free(rrset_clone);
306  ldns_rr_free(current_sig);
307  ldns_rr_list_deep_free(signatures);
308  return NULL;
309  }
310 
311  ldns_rr_rrsig_set_sig(current_sig, b64rdf);
312 
313  /* push the signature to the signatures list */
314  ldns_rr_list_push_rr(signatures, current_sig);
315  }
316  ldns_buffer_free(sign_buf); /* restart for the next key */
317  }
318  ldns_rr_list_deep_free(rrset_clone);
319 
320  return signatures;
321 }
322 
331 ldns_rdf *
333 {
334 #ifdef USE_DSA
335  unsigned char *sha1_hash;
336  ldns_rdf *sigdata_rdf;
337  ldns_buffer *b64sig;
338 
339  DSA_SIG *sig;
340  const BIGNUM *R, *S;
341  uint8_t *data;
342  size_t pad;
343 
345  if (!b64sig) {
346  return NULL;
347  }
348 
349  sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
350  ldns_buffer_position(to_sign), NULL);
351  if (!sha1_hash) {
352  ldns_buffer_free(b64sig);
353  return NULL;
354  }
355 
356  sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
357  if(!sig) {
358  ldns_buffer_free(b64sig);
359  return NULL;
360  }
361 
362  data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
363  if(!data) {
364  ldns_buffer_free(b64sig);
365  DSA_SIG_free(sig);
366  return NULL;
367  }
368 
369  data[0] = 1;
370 # ifdef HAVE_DSA_SIG_GET0
371  DSA_SIG_get0(sig, &R, &S);
372 # else
373  R = sig->r;
374  S = sig->s;
375 # endif
376  pad = 20 - (size_t) BN_num_bytes(R);
377  if (pad > 0) {
378  memset(data + 1, 0, pad);
379  }
380  BN_bn2bin(R, (unsigned char *) (data + 1) + pad);
381 
382  pad = 20 - (size_t) BN_num_bytes(S);
383  if (pad > 0) {
384  memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
385  }
386  BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
387 
389  1 + 2 * SHA_DIGEST_LENGTH,
390  data);
391 
392  ldns_buffer_free(b64sig);
393  LDNS_FREE(data);
394  DSA_SIG_free(sig);
395 
396  return sigdata_rdf;
397 #else
398  (void)to_sign; (void)key;
399  return NULL;
400 #endif
401 }
402 
403 #ifdef USE_ECDSA
404 #ifndef S_SPLINT_S
405 
406 static int
407 ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
408 {
409  EC_KEY* ec;
410  const EC_GROUP* g;
411 #ifdef HAVE_EVP_PKEY_BASE_ID
412  if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
413  return 0;
414 #else
415  if(EVP_PKEY_type(key->type) != EVP_PKEY_EC)
416  return 0;
417 #endif
418  ec = EVP_PKEY_get1_EC_KEY(pkey);
419  g = EC_KEY_get0_group(ec);
420  if(!g) {
421  EC_KEY_free(ec);
422  return 0;
423  }
424  if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) {
425  EC_KEY_free(ec);
426  return 32; /* 256/8 */
427  }
428  if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
429  EC_KEY_free(ec);
430  return 48; /* 384/8 */
431  }
432  /* downref the eckey, the original is still inside the pkey */
433  EC_KEY_free(ec);
434  return 0;
435 }
436 #endif /* splint */
437 #endif /* USE_ECDSA */
438 
439 ldns_rdf *
441  EVP_PKEY *key,
442  const EVP_MD *digest_type)
443 {
444  unsigned int siglen;
445  ldns_rdf *sigdata_rdf = NULL;
446  ldns_buffer *b64sig;
447  EVP_MD_CTX *ctx;
448  const EVP_MD *md_type;
449  int r;
450 
451  siglen = 0;
453  if (!b64sig) {
454  return NULL;
455  }
456 
457  /* initializes a signing context */
458  md_type = digest_type;
459  if(!md_type) {
460  /* unknown message difest */
461  ldns_buffer_free(b64sig);
462  return NULL;
463  }
464 
465 #ifdef HAVE_EVP_MD_CTX_NEW
466  ctx = EVP_MD_CTX_new();
467 #else
468  ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
469  if(ctx) EVP_MD_CTX_init(ctx);
470 #endif
471  if(!ctx) {
472  ldns_buffer_free(b64sig);
473  return NULL;
474  }
475 
476  r = EVP_SignInit(ctx, md_type);
477  if(r == 1) {
478  r = EVP_SignUpdate(ctx, (unsigned char*)
479  ldns_buffer_begin(to_sign),
480  ldns_buffer_position(to_sign));
481  } else {
482  ldns_buffer_free(b64sig);
483  EVP_MD_CTX_destroy(ctx);
484  return NULL;
485  }
486  if(r == 1) {
487  r = EVP_SignFinal(ctx, (unsigned char*)
488  ldns_buffer_begin(b64sig), &siglen, key);
489  } else {
490  ldns_buffer_free(b64sig);
491  EVP_MD_CTX_destroy(ctx);
492  return NULL;
493  }
494  if(r != 1) {
495  ldns_buffer_free(b64sig);
496  EVP_MD_CTX_des