ssl/dnssec.c: compilation errors.
[oweals/openssl.git] / ssl / dnssec.c
1 #include <openssl/opensslconf.h>
2
3 #include <string.h>
4 #include <netdb.h>
5 #include <openssl/bio.h>
6 #include <openssl/dso.h>
7
8 #ifndef OPENSSL_NO_LIBUNBOUND
9 #include <unbound.h>
10
11 static struct ub_ctx *ctx = NULL;
12 static DSO *unbound_dso = NULL;
13
14 static union {
15         void *p; struct ub_ctx *(*f)(); }
16         p_ub_ctx_create = {NULL};
17
18 static union {
19         void *p; int (*f)(struct ub_ctx *,const char *); }
20         p_ub_ctx_resolvconf = {NULL};
21
22 static union {
23         void *p; int (*f)(struct ub_ctx *,const char *); }
24         p_ub_ctx_add_ta_file = {NULL};
25
26 static union {
27         void *p; void (*f)(struct ub_ctx *); }
28         p_ub_ctx_delete = {NULL};
29
30 static union {
31         void *p; int (*f)(struct ub_ctx *,const char *,int,int,struct ub_result**); }
32         p_ub_resolve = {NULL};
33
34 static union {
35         void *p; void (*f)(struct ub_result*); }
36         p_ub_resolve_free = {NULL};
37
38 #if defined(__GNUC__) && __GNUC__>=2
39  static void unbound_init(void) __attribute__((constructor));
40  static void unbound_fini(void) __attribute__((destructor));
41 #endif 
42
43 static void unbound_init(void)
44 {
45         DSO *dso;
46
47         if ((dso = DSO_load(NULL, "unbound", NULL, 0)) == NULL) return;
48
49         if ((p_ub_ctx_create.p = DSO_bind_func(dso,"ub_ctx_create")) == NULL ||
50             (p_ub_ctx_resolvconf.p = DSO_bind_func(dso,"ub_ctx_resolvconf")) == NULL ||
51             (p_ub_ctx_add_ta_file.p = DSO_bind_func(dso,"ub_ctx_add_ta_file")) == NULL ||
52             (p_ub_ctx_delete.p = DSO_bind_func(dso,"ub_ctx_delete")) == NULL ||
53             (p_ub_resolve.p = DSO_bind_func(dso,"ub_resolve")) == NULL ||
54             (p_ub_resolve_free.p = DSO_bind_func(dso,"ub_resolve_free")) == NULL ||
55             (ctx = p_ub_ctx_create.f()) == NULL) {
56                 DSO_free(dso);
57                 return;
58         }
59
60         unbound_dso = dso;
61
62         /* FIXME: parameterize these through CONF */
63         p_ub_ctx_resolvconf.f(ctx,"/etc/resolv.conf");
64         p_ub_ctx_add_ta_file.f(ctx,"/var/lib/unbound/root.key");
65 }
66
67 static void unbound_fini(void)
68 {
69         if (ctx != NULL) p_ub_ctx_delete.f(ctx);
70         if (unbound_dso != NULL) DSO_free(unbound_dso);
71 }
72 #endif
73
74 /*
75  * Output is array packed as [len][data][len][data][0]
76  */
77 unsigned char *SSL_get_tlsa_record_byname (const char *name,int port,int type)
78 {
79         unsigned char *ret=NULL;
80         char *query=NULL;
81         size_t qlen;
82
83 #ifndef OPENSSL_NO_LIBUNBOUND
84         if (ctx == NULL) return NULL;
85 #elif defined(RRSET_VALIDATED)
86         static union {
87                 void *p; int (*f)(const char*,unsigned int,unsigned int,unsigned int,struct rrsetinfo **); }
88                 p_getrrsetbyname = {NULL};
89         static union {
90                 void *p; void (*f)(struct rrsetinfo *); }
91                 p_freerrset = {NULL};
92
93         if (p_getrrsetbyname.p==NULL) {
94                 if ((p_getrrsetbyname.p = DSO_global_lookup("getrrsetbyname")) == NULL ||
95                     (p_freerrset.p = DSO_global_lookup("freerrset")) == NULL)
96                         p_getrrsetbyname.p = (void*)-1;
97         }
98
99         if (p_getrrsetbyname.p == (void *)-1) return NULL;
100 #endif
101
102         qlen = 7+5+strlen(name)+1;
103         if ((query = OPENSSL_malloc(qlen)) == NULL)
104                 return NULL;
105
106         BIO_snprintf(query,qlen,"_%u._%s.%s",port&0xffff,type==SOCK_STREAM?"tcp":"udp",name);
107
108 #ifndef OPENSSL_NO_LIBUNBOUND
109         {
110         struct ub_result *tlsa=NULL;
111
112         if (p_ub_resolve.f(ctx,query,52,1,&tlsa)==0 &&
113             tlsa->havedata && tlsa->data[0]!=NULL) {
114                 ret=(void*)-1;  /* -1 means insecure */
115                 if (tlsa->secure) do {
116                         unsigned char *data;
117                         unsigned int dlen, i;
118
119                         for (dlen=0, i=0; tlsa->data[i]; i++)
120                                 dlen += sizeof(int)+(unsigned int)tlsa->len[i];
121                         dlen +=sizeof(int);
122
123                         if ((ret = OPENSSL_malloc(dlen)) == NULL) break;
124                         
125                         for (data=ret, i=0; tlsa->data[i]; i++) {
126                                 *(unsigned int *)data = dlen = (unsigned int)tlsa->len[i];
127                                 data += sizeof(unsigned int);
128                                 memcpy(data,tlsa->data[i],dlen);
129                                 data += dlen;
130                         }
131                         *(unsigned int *)data = 0;      /* trailing zero */
132                 } while (0);    
133                 p_ub_resolve_free.f(tlsa);
134         }
135         }
136 #elif defined(RRSET_VALIDATED)
137         {
138         struct rrsetinfo *rrset=NULL;
139
140         if (p_getrrsetbyname.f(query,1,52,RRSET_VALIDATED,&rrset) == 0 && rrset->rri_nrdatas) {
141                 ret=(void*)-1;  /* -1 means insecure */
142                 if ((rrset->rri_flags&RRSET_VALIDATED)) do {
143                         unsigned char *data;
144                         unsigned int dlen, i;
145
146                         for (dlen=0, i=0; i<rrset->rri_nrdatas; i++)
147                                 dlen += sizeof(int)+rrset->rri_rdatas[i].rdi_length;
148                         dlen +=sizeof(int);
149
150                         if ((ret = OPENSSL_malloc(sizeof(int)+dlen)) == NULL) break;
151
152                         for (data=ret, i=0; i<rrset->rri_rdatas[i].rdi_length; i++) {
153                                 *(unsigned int *)data = dlen = rrset->rri_rdatas[i].rdi_length;
154                                 data += sizeof(unsigned int);
155                                 memcpy(data,rrset->rri_rdatas[i].rdi_data,dlen);
156                                 data += dlen;
157                         }
158                         *(unsigned int *)data = 0;      /* trailing zero */
159                 } while (0);    
160                 p_freerrset.f(rrset);
161         }
162         }
163 #elif defined(_WIN32_NOT_YET)
164         {
165         PDNS_RECORD rrset;
166
167         DnsQuery_A(query,52,DNS_QUERY_STANDARD,NULL,&rrset,NULL);
168         DnsRecordListFree(rrset,DnsFreeRecordList);
169         }
170 #endif
171         CRYPTO_free(query);
172
173         return ret;
174 }