]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/dns/tsec.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / dns / tsec.c
1 /*
2  * Copyright (C) 2009, 2010  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id: tsec.c,v 1.7 2010/12/09 00:54:34 marka Exp $ */
18
19 #include <config.h>
20
21 #include <isc/mem.h>
22
23 #include <dns/tsec.h>
24 #include <dns/tsig.h>
25 #include <dns/result.h>
26
27 #include <dst/dst.h>
28
29 #define DNS_TSEC_MAGIC                  ISC_MAGIC('T', 's', 'e', 'c')
30 #define DNS_TSEC_VALID(t)               ISC_MAGIC_VALID(t, DNS_TSEC_MAGIC)
31
32 /*%
33  * DNS Transaction Security object.  We assume this is not shared by
34  * multiple threads, and so the structure does not contain a lock.
35  */
36 struct dns_tsec {
37         unsigned int            magic;
38         dns_tsectype_t          type;
39         isc_mem_t               *mctx;
40         union {
41                 dns_tsigkey_t   *tsigkey;
42                 dst_key_t       *key;
43         } ukey;
44 };
45
46 isc_result_t
47 dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key,
48                 dns_tsec_t **tsecp)
49 {
50         isc_result_t result;
51         dns_tsec_t *tsec;
52         dns_tsigkey_t *tsigkey = NULL;
53         dns_name_t *algname;
54
55         REQUIRE(mctx != NULL);
56         REQUIRE(tsecp != NULL && *tsecp == NULL);
57
58         tsec = isc_mem_get(mctx, sizeof(*tsec));
59         if (tsec == NULL)
60                 return (ISC_R_NOMEMORY);
61
62         tsec->type = type;
63         tsec->mctx = mctx;
64
65         switch (type) {
66         case dns_tsectype_tsig:
67                 switch (dst_key_alg(key)) {
68                 case DST_ALG_HMACMD5:
69                         algname = dns_tsig_hmacmd5_name;
70                         break;
71                 case DST_ALG_HMACSHA1:
72                         algname = dns_tsig_hmacsha1_name;
73                         break;
74                 case DST_ALG_HMACSHA224:
75                         algname = dns_tsig_hmacsha224_name;
76                         break;
77                 case DST_ALG_HMACSHA256:
78                         algname = dns_tsig_hmacsha256_name;
79                         break;
80                 case DST_ALG_HMACSHA384:
81                         algname = dns_tsig_hmacsha384_name;
82                         break;
83                 case DST_ALG_HMACSHA512:
84                         algname = dns_tsig_hmacsha512_name;
85                         break;
86                 default:
87                         isc_mem_put(mctx, tsec, sizeof(*tsec));
88                         return (DNS_R_BADALG);
89                 }
90                 result = dns_tsigkey_createfromkey(dst_key_name(key),
91                                                    algname, key, ISC_FALSE,
92                                                    NULL, 0, 0, mctx, NULL,
93                                                    &tsigkey);
94                 if (result != ISC_R_SUCCESS) {
95                         isc_mem_put(mctx, tsec, sizeof(*tsec));
96                         return (result);
97                 }
98                 tsec->ukey.tsigkey = tsigkey;
99                 break;
100         case dns_tsectype_sig0:
101                 tsec->ukey.key = key;
102                 break;
103         default:
104                 INSIST(0);
105         }
106
107         tsec->magic = DNS_TSEC_MAGIC;
108
109         *tsecp = tsec;
110         return (ISC_R_SUCCESS);
111 }
112
113 void
114 dns_tsec_destroy(dns_tsec_t **tsecp) {
115         dns_tsec_t *tsec;
116
117         REQUIRE(tsecp != NULL && *tsecp != NULL);
118         tsec = *tsecp;
119         REQUIRE(DNS_TSEC_VALID(tsec));
120
121         switch (tsec->type) {
122         case dns_tsectype_tsig:
123                 dns_tsigkey_detach(&tsec->ukey.tsigkey);
124                 break;
125         case dns_tsectype_sig0:
126                 dst_key_free(&tsec->ukey.key);
127                 break;
128         default:
129                 INSIST(0);
130         }
131
132         tsec->magic = 0;
133         isc_mem_put(tsec->mctx, tsec, sizeof(*tsec));
134
135         *tsecp = NULL;
136 }
137
138 dns_tsectype_t
139 dns_tsec_gettype(dns_tsec_t *tsec) {
140         REQUIRE(DNS_TSEC_VALID(tsec));
141
142         return (tsec->type);
143 }
144
145 void
146 dns_tsec_getkey(dns_tsec_t *tsec, void *keyp) {
147         REQUIRE(DNS_TSEC_VALID(tsec));
148         REQUIRE(keyp != NULL);
149
150         switch (tsec->type) {
151         case dns_tsectype_tsig:
152                 dns_tsigkey_attach(tsec->ukey.tsigkey, (dns_tsigkey_t **)keyp);
153                 break;
154         case dns_tsectype_sig0:
155                 *(dst_key_t **)keyp = tsec->ukey.key;
156                 break;
157         default:
158                 INSIST(0);
159         }
160 }