| @@ -1,4186 +1,4191 @@ | | | @@ -1,4186 +1,4191 @@ |
1 | /* $NetBSD: ntp_crypto.c,v 1.10.4.1 2007/08/21 08:40:01 ghen Exp $ */ | | 1 | /* $NetBSD: ntp_crypto.c,v 1.10.4.2 2009/05/26 05:17:29 snj Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * ntp_crypto.c - NTP version 4 public key routines | | 4 | * ntp_crypto.c - NTP version 4 public key routines |
5 | */ | | 5 | */ |
6 | #ifdef HAVE_CONFIG_H | | 6 | #ifdef HAVE_CONFIG_H |
7 | #include <config.h> | | 7 | #include <config.h> |
8 | #endif | | 8 | #endif |
9 | | | 9 | |
10 | #ifdef OPENSSL | | 10 | #ifdef OPENSSL |
11 | #include <stdio.h> | | 11 | #include <stdio.h> |
12 | #include <sys/types.h> | | 12 | #include <sys/types.h> |
13 | #include <sys/param.h> | | 13 | #include <sys/param.h> |
14 | #include <unistd.h> | | 14 | #include <unistd.h> |
15 | #include <fcntl.h> | | 15 | #include <fcntl.h> |
16 | | | 16 | |
17 | #include "ntpd.h" | | 17 | #include "ntpd.h" |
18 | #include "ntp_stdlib.h" | | 18 | #include "ntp_stdlib.h" |
19 | #include "ntp_unixtime.h" | | 19 | #include "ntp_unixtime.h" |
20 | #include "ntp_string.h" | | 20 | #include "ntp_string.h" |
21 | #include <ntp_random.h> | | 21 | #include <ntp_random.h> |
22 | | | 22 | |
23 | #include "openssl/asn1_mac.h" | | 23 | #include "openssl/asn1_mac.h" |
24 | #include "openssl/bn.h" | | 24 | #include "openssl/bn.h" |
25 | #include "openssl/err.h" | | 25 | #include "openssl/err.h" |
26 | #include "openssl/evp.h" | | 26 | #include "openssl/evp.h" |
27 | #include "openssl/pem.h" | | 27 | #include "openssl/pem.h" |
28 | #include "openssl/rand.h" | | 28 | #include "openssl/rand.h" |
29 | #include "openssl/x509v3.h" | | 29 | #include "openssl/x509v3.h" |
30 | | | 30 | |
31 | #ifdef KERNEL_PLL | | 31 | #ifdef KERNEL_PLL |
32 | #include "ntp_syscall.h" | | 32 | #include "ntp_syscall.h" |
33 | #endif /* KERNEL_PLL */ | | 33 | #endif /* KERNEL_PLL */ |
34 | | | 34 | |
35 | /* | | 35 | /* |
36 | * Extension field message format | | 36 | * Extension field message format |
37 | * | | 37 | * |
38 | * These are always signed and saved before sending in network byte | | 38 | * These are always signed and saved before sending in network byte |
39 | * order. They must be converted to and from host byte order for | | 39 | * order. They must be converted to and from host byte order for |
40 | * processing. | | 40 | * processing. |
41 | * | | 41 | * |
42 | * +-------+-------+ | | 42 | * +-------+-------+ |
43 | * | op | len | <- extension pointer | | 43 | * | op | len | <- extension pointer |
44 | * +-------+-------+ | | 44 | * +-------+-------+ |
45 | * | assocID | | | 45 | * | assocID | |
46 | * +---------------+ | | 46 | * +---------------+ |
47 | * | timestamp | <- value pointer | | 47 | * | timestamp | <- value pointer |
48 | * +---------------+ | | 48 | * +---------------+ |
49 | * | filestamp | | | 49 | * | filestamp | |
50 | * +---------------+ | | 50 | * +---------------+ |
51 | * | value len | | | 51 | * | value len | |
52 | * +---------------+ | | 52 | * +---------------+ |
53 | * | | | | 53 | * | | |
54 | * = value = | | 54 | * = value = |
55 | * | | | | 55 | * | | |
56 | * +---------------+ | | 56 | * +---------------+ |
57 | * | signature len | | | 57 | * | signature len | |
58 | * +---------------+ | | 58 | * +---------------+ |
59 | * | | | | 59 | * | | |
60 | * = signature = | | 60 | * = signature = |
61 | * | | | | 61 | * | | |
62 | * +---------------+ | | 62 | * +---------------+ |
63 | * | | 63 | * |
64 | * The CRYPTO_RESP bit is set to 0 for requests, 1 for responses. | | 64 | * The CRYPTO_RESP bit is set to 0 for requests, 1 for responses. |
65 | * Requests carry the association ID of the receiver; responses carry | | 65 | * Requests carry the association ID of the receiver; responses carry |
66 | * the association ID of the sender. Some messages include only the | | 66 | * the association ID of the sender. Some messages include only the |
67 | * operation/length and association ID words and so have length 8 | | 67 | * operation/length and association ID words and so have length 8 |
68 | * octets. Ohers include the value structure and associated value and | | 68 | * octets. Ohers include the value structure and associated value and |
69 | * signature fields. These messages include the timestamp, filestamp, | | 69 | * signature fields. These messages include the timestamp, filestamp, |
70 | * value and signature words and so have length at least 24 octets. The | | 70 | * value and signature words and so have length at least 24 octets. The |
71 | * signature and/or value fields can be empty, in which case the | | 71 | * signature and/or value fields can be empty, in which case the |
72 | * respective length words are zero. An empty value with nonempty | | 72 | * respective length words are zero. An empty value with nonempty |
73 | * signature is syntactically valid, but semantically questionable. | | 73 | * signature is syntactically valid, but semantically questionable. |
74 | * | | 74 | * |
75 | * The filestamp represents the time when a cryptographic data file such | | 75 | * The filestamp represents the time when a cryptographic data file such |
76 | * as a public/private key pair is created. It follows every reference | | 76 | * as a public/private key pair is created. It follows every reference |
77 | * depending on that file and serves as a means to obsolete earlier data | | 77 | * depending on that file and serves as a means to obsolete earlier data |
78 | * of the same type. The timestamp represents the time when the | | 78 | * of the same type. The timestamp represents the time when the |
79 | * cryptographic data of the message were last signed. Creation of a | | 79 | * cryptographic data of the message were last signed. Creation of a |
80 | * cryptographic data file or signing a message can occur only when the | | 80 | * cryptographic data file or signing a message can occur only when the |
81 | * creator or signor is synchronized to an authoritative source and | | 81 | * creator or signor is synchronized to an authoritative source and |
82 | * proventicated to a trusted authority. | | 82 | * proventicated to a trusted authority. |
83 | * | | 83 | * |
84 | * Note there are four conditions required for server trust. First, the | | 84 | * Note there are four conditions required for server trust. First, the |
85 | * public key on the certificate must be verified, which involves a | | 85 | * public key on the certificate must be verified, which involves a |
86 | * number of format, content and consistency checks. Next, the server | | 86 | * number of format, content and consistency checks. Next, the server |
87 | * identity must be confirmed by one of four schemes: private | | 87 | * identity must be confirmed by one of four schemes: private |
88 | * certificate, IFF scheme, GQ scheme or certificate trail hike to a | | 88 | * certificate, IFF scheme, GQ scheme or certificate trail hike to a |
89 | * self signed trusted certificate. Finally, the server signature must | | 89 | * self signed trusted certificate. Finally, the server signature must |
90 | * be verified. | | 90 | * be verified. |
91 | */ | | 91 | */ |
92 | /* | | 92 | /* |
93 | * Cryptodefines | | 93 | * Cryptodefines |
94 | */ | | 94 | */ |
95 | #define TAI_1972 10 /* initial TAI offset (s) */ | | 95 | #define TAI_1972 10 /* initial TAI offset (s) */ |
96 | #define MAX_LEAP 100 /* max UTC leapseconds (s) */ | | 96 | #define MAX_LEAP 100 /* max UTC leapseconds (s) */ |
97 | #define VALUE_LEN (6 * 4) /* min response field length */ | | 97 | #define VALUE_LEN (6 * 4) /* min response field length */ |
98 | #define YEAR (60 * 60 * 24 * 365) /* seconds in year */ | | 98 | #define YEAR (60 * 60 * 24 * 365) /* seconds in year */ |
99 | | | 99 | |
100 | /* | | 100 | /* |
101 | * Global cryptodata in host byte order | | 101 | * Global cryptodata in host byte order |
102 | */ | | 102 | */ |
103 | u_int32 crypto_flags = 0x0; /* status word */ | | 103 | u_int32 crypto_flags = 0x0; /* status word */ |
104 | | | 104 | |
105 | /* | | 105 | /* |
106 | * Global cryptodata in network byte order | | 106 | * Global cryptodata in network byte order |
107 | */ | | 107 | */ |
108 | struct cert_info *cinfo = NULL; /* certificate info/value */ | | 108 | struct cert_info *cinfo = NULL; /* certificate info/value */ |
109 | struct value hostval; /* host value */ | | 109 | struct value hostval; /* host value */ |
110 | struct value pubkey; /* public key */ | | 110 | struct value pubkey; /* public key */ |
111 | struct value tai_leap; /* leapseconds table */ | | 111 | struct value tai_leap; /* leapseconds table */ |
112 | EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */ | | 112 | EVP_PKEY *iffpar_pkey = NULL; /* IFF parameters */ |
113 | EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */ | | 113 | EVP_PKEY *gqpar_pkey = NULL; /* GQ parameters */ |
114 | EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */ | | 114 | EVP_PKEY *mvpar_pkey = NULL; /* MV parameters */ |
115 | char *iffpar_file = NULL; /* IFF parameters file */ | | 115 | char *iffpar_file = NULL; /* IFF parameters file */ |
116 | char *gqpar_file = NULL; /* GQ parameters file */ | | 116 | char *gqpar_file = NULL; /* GQ parameters file */ |
117 | char *mvpar_file = NULL; /* MV parameters file */ | | 117 | char *mvpar_file = NULL; /* MV parameters file */ |
118 | | | 118 | |
119 | /* | | 119 | /* |
120 | * Private cryptodata in host byte order | | 120 | * Private cryptodata in host byte order |
121 | */ | | 121 | */ |
122 | static char *passwd = NULL; /* private key password */ | | 122 | static char *passwd = NULL; /* private key password */ |
123 | static EVP_PKEY *host_pkey = NULL; /* host key */ | | 123 | static EVP_PKEY *host_pkey = NULL; /* host key */ |
124 | static EVP_PKEY *sign_pkey = NULL; /* sign key */ | | 124 | static EVP_PKEY *sign_pkey = NULL; /* sign key */ |
125 | static const EVP_MD *sign_digest = NULL; /* sign digest */ | | 125 | static const EVP_MD *sign_digest = NULL; /* sign digest */ |
126 | static u_int sign_siglen; /* sign key length */ | | 126 | static u_int sign_siglen; /* sign key length */ |
127 | static char *rand_file = NULL; /* random seed file */ | | 127 | static char *rand_file = NULL; /* random seed file */ |
128 | static char *host_file = NULL; /* host key file */ | | 128 | static char *host_file = NULL; /* host key file */ |
129 | static char *sign_file = NULL; /* sign key file */ | | 129 | static char *sign_file = NULL; /* sign key file */ |
130 | static char *cert_file = NULL; /* certificate file */ | | 130 | static char *cert_file = NULL; /* certificate file */ |
131 | static char *leap_file = NULL; /* leapseconds file */ | | 131 | static char *leap_file = NULL; /* leapseconds file */ |
132 | static tstamp_t if_fstamp = 0; /* IFF filestamp */ | | 132 | static tstamp_t if_fstamp = 0; /* IFF filestamp */ |
133 | static tstamp_t gq_fstamp = 0; /* GQ file stamp */ | | 133 | static tstamp_t gq_fstamp = 0; /* GQ file stamp */ |
134 | static tstamp_t mv_fstamp = 0; /* MV filestamp */ | | 134 | static tstamp_t mv_fstamp = 0; /* MV filestamp */ |
135 | static u_int ident_scheme = 0; /* server identity scheme */ | | 135 | static u_int ident_scheme = 0; /* server identity scheme */ |
136 | | | 136 | |
137 | /* | | 137 | /* |
138 | * Cryptotypes | | 138 | * Cryptotypes |
139 | */ | | 139 | */ |
140 | static int crypto_verify P((struct exten *, struct value *, | | 140 | static int crypto_verify P((struct exten *, struct value *, |
141 | struct peer *)); | | 141 | struct peer *)); |
142 | static int crypto_encrypt P((struct exten *, struct value *, | | 142 | static int crypto_encrypt P((struct exten *, struct value *, |
143 | keyid_t *)); | | 143 | keyid_t *)); |
144 | static int crypto_alice P((struct peer *, struct value *)); | | 144 | static int crypto_alice P((struct peer *, struct value *)); |
145 | static int crypto_alice2 P((struct peer *, struct value *)); | | 145 | static int crypto_alice2 P((struct peer *, struct value *)); |
146 | static int crypto_alice3 P((struct peer *, struct value *)); | | 146 | static int crypto_alice3 P((struct peer *, struct value *)); |
147 | static int crypto_bob P((struct exten *, struct value *)); | | 147 | static int crypto_bob P((struct exten *, struct value *)); |
148 | static int crypto_bob2 P((struct exten *, struct value *)); | | 148 | static int crypto_bob2 P((struct exten *, struct value *)); |
149 | static int crypto_bob3 P((struct exten *, struct value *)); | | 149 | static int crypto_bob3 P((struct exten *, struct value *)); |
150 | static int crypto_iff P((struct exten *, struct peer *)); | | 150 | static int crypto_iff P((struct exten *, struct peer *)); |
151 | static int crypto_gq P((struct exten *, struct peer *)); | | 151 | static int crypto_gq P((struct exten *, struct peer *)); |
152 | static int crypto_mv P((struct exten *, struct peer *)); | | 152 | static int crypto_mv P((struct exten *, struct peer *)); |
153 | static u_int crypto_send P((struct exten *, struct value *)); | | 153 | static u_int crypto_send P((struct exten *, struct value *)); |
154 | static tstamp_t crypto_time P((void)); | | 154 | static tstamp_t crypto_time P((void)); |
155 | static u_long asn2ntp P((ASN1_TIME *)); | | 155 | static u_long asn2ntp P((ASN1_TIME *)); |
156 | static struct cert_info *cert_parse P((u_char *, u_int, tstamp_t)); | | 156 | static struct cert_info *cert_parse P((u_char *, u_int, tstamp_t)); |
157 | static int cert_sign P((struct exten *, struct value *)); | | 157 | static int cert_sign P((struct exten *, struct value *)); |
158 | static int cert_valid P((struct cert_info *, EVP_PKEY *)); | | 158 | static int cert_valid P((struct cert_info *, EVP_PKEY *)); |
159 | static int cert_install P((struct exten *, struct peer *)); | | 159 | static int cert_install P((struct exten *, struct peer *)); |
160 | static void cert_free P((struct cert_info *)); | | 160 | static void cert_free P((struct cert_info *)); |
161 | static EVP_PKEY *crypto_key P((char *, tstamp_t *)); | | 161 | static EVP_PKEY *crypto_key P((char *, tstamp_t *)); |
162 | static int bighash P((BIGNUM *, BIGNUM *)); | | 162 | static int bighash P((BIGNUM *, BIGNUM *)); |
163 | static struct cert_info *crypto_cert P((char *)); | | 163 | static struct cert_info *crypto_cert P((char *)); |
164 | static void crypto_tai P((char *)); | | 164 | static void crypto_tai P((char *)); |
165 | | | 165 | |
166 | #ifdef SYS_WINNT | | 166 | #ifdef SYS_WINNT |
167 | int | | 167 | int |
168 | readlink(char * link, char * file, int len) { | | 168 | readlink(char * link, char * file, int len) { |
169 | return (-1); | | 169 | return (-1); |
170 | } | | 170 | } |
171 | #endif | | 171 | #endif |
172 | | | 172 | |
173 | /* | | 173 | /* |
174 | * session_key - generate session key | | 174 | * session_key - generate session key |
175 | * | | 175 | * |
176 | * This routine generates a session key from the source address, | | 176 | * This routine generates a session key from the source address, |
177 | * destination address, key ID and private value. The value of the | | 177 | * destination address, key ID and private value. The value of the |
178 | * session key is the MD5 hash of these values, while the next key ID is | | 178 | * session key is the MD5 hash of these values, while the next key ID is |
179 | * the first four octets of the hash. | | 179 | * the first four octets of the hash. |
180 | * | | 180 | * |
181 | * Returns the next key ID | | 181 | * Returns the next key ID |
182 | */ | | 182 | */ |
183 | keyid_t | | 183 | keyid_t |
184 | session_key( | | 184 | session_key( |
185 | struct sockaddr_storage *srcadr, /* source address */ | | 185 | struct sockaddr_storage *srcadr, /* source address */ |
186 | struct sockaddr_storage *dstadr, /* destination address */ | | 186 | struct sockaddr_storage *dstadr, /* destination address */ |
187 | keyid_t keyno, /* key ID */ | | 187 | keyid_t keyno, /* key ID */ |
188 | keyid_t private, /* private value */ | | 188 | keyid_t private, /* private value */ |
189 | u_long lifetime /* key lifetime */ | | 189 | u_long lifetime /* key lifetime */ |
190 | ) | | 190 | ) |
191 | { | | 191 | { |
192 | EVP_MD_CTX ctx; /* message digest context */ | | 192 | EVP_MD_CTX ctx; /* message digest context */ |
193 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ | | 193 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ |
194 | keyid_t keyid; /* key identifer */ | | 194 | keyid_t keyid; /* key identifer */ |
195 | u_int32 header[10]; /* data in network byte order */ | | 195 | u_int32 header[10]; /* data in network byte order */ |
196 | u_int hdlen, len; | | 196 | u_int hdlen, len; |
197 | | | 197 | |
198 | if (!dstadr) | | 198 | if (!dstadr) |
199 | return 0; | | 199 | return 0; |
200 | | | 200 | |
201 | /* | | 201 | /* |
202 | * Generate the session key and key ID. If the lifetime is | | 202 | * Generate the session key and key ID. If the lifetime is |
203 | * greater than zero, install the key and call it trusted. | | 203 | * greater than zero, install the key and call it trusted. |
204 | */ | | 204 | */ |
205 | hdlen = 0; | | 205 | hdlen = 0; |
206 | switch(srcadr->ss_family) { | | 206 | switch(srcadr->ss_family) { |
207 | case AF_INET: | | 207 | case AF_INET: |
208 | header[0] = ((struct sockaddr_in *)srcadr)->sin_addr.s_addr; | | 208 | header[0] = ((struct sockaddr_in *)srcadr)->sin_addr.s_addr; |
209 | header[1] = ((struct sockaddr_in *)dstadr)->sin_addr.s_addr; | | 209 | header[1] = ((struct sockaddr_in *)dstadr)->sin_addr.s_addr; |
210 | header[2] = htonl(keyno); | | 210 | header[2] = htonl(keyno); |
211 | header[3] = htonl(private); | | 211 | header[3] = htonl(private); |
212 | hdlen = 4 * sizeof(u_int32); | | 212 | hdlen = 4 * sizeof(u_int32); |
213 | break; | | 213 | break; |
214 | | | 214 | |
215 | case AF_INET6: | | 215 | case AF_INET6: |
216 | memcpy(&header[0], &GET_INADDR6(*srcadr), | | 216 | memcpy(&header[0], &GET_INADDR6(*srcadr), |
217 | sizeof(struct in6_addr)); | | 217 | sizeof(struct in6_addr)); |
218 | memcpy(&header[4], &GET_INADDR6(*dstadr), | | 218 | memcpy(&header[4], &GET_INADDR6(*dstadr), |
219 | sizeof(struct in6_addr)); | | 219 | sizeof(struct in6_addr)); |
220 | header[8] = htonl(keyno); | | 220 | header[8] = htonl(keyno); |
221 | header[9] = htonl(private); | | 221 | header[9] = htonl(private); |
222 | hdlen = 10 * sizeof(u_int32); | | 222 | hdlen = 10 * sizeof(u_int32); |
223 | break; | | 223 | break; |
224 | } | | 224 | } |
225 | EVP_DigestInit(&ctx, EVP_md5()); | | 225 | EVP_DigestInit(&ctx, EVP_md5()); |
226 | EVP_DigestUpdate(&ctx, (u_char *)header, hdlen); | | 226 | EVP_DigestUpdate(&ctx, (u_char *)header, hdlen); |
227 | EVP_DigestFinal(&ctx, dgst, &len); | | 227 | EVP_DigestFinal(&ctx, dgst, &len); |
228 | memcpy(&keyid, dgst, 4); | | 228 | memcpy(&keyid, dgst, 4); |
229 | keyid = ntohl(keyid); | | 229 | keyid = ntohl(keyid); |
230 | if (lifetime != 0) { | | 230 | if (lifetime != 0) { |
231 | MD5auth_setkey(keyno, dgst, len); | | 231 | MD5auth_setkey(keyno, dgst, len); |
232 | authtrust(keyno, lifetime); | | 232 | authtrust(keyno, lifetime); |
233 | } | | 233 | } |
234 | #ifdef DEBUG | | 234 | #ifdef DEBUG |
235 | if (debug > 1) | | 235 | if (debug > 1) |
236 | printf( | | 236 | printf( |
237 | "session_key: %s > %s %08x %08x hash %08x life %lu\n", | | 237 | "session_key: %s > %s %08x %08x hash %08x life %lu\n", |
238 | stoa(srcadr), stoa(dstadr), keyno, | | 238 | stoa(srcadr), stoa(dstadr), keyno, |
239 | private, keyid, lifetime); | | 239 | private, keyid, lifetime); |
240 | #endif | | 240 | #endif |
241 | return (keyid); | | 241 | return (keyid); |
242 | } | | 242 | } |
243 | | | 243 | |
244 | | | 244 | |
245 | /* | | 245 | /* |
246 | * make_keylist - generate key list | | 246 | * make_keylist - generate key list |
247 | * | | 247 | * |
248 | * Returns | | 248 | * Returns |
249 | * XEVNT_OK success | | 249 | * XEVNT_OK success |
250 | * XEVNT_PER host certificate expired | | 250 | * XEVNT_PER host certificate expired |
251 | * | | 251 | * |
252 | * This routine constructs a pseudo-random sequence by repeatedly | | 252 | * This routine constructs a pseudo-random sequence by repeatedly |
253 | * hashing the session key starting from a given source address, | | 253 | * hashing the session key starting from a given source address, |
254 | * destination address, private value and the next key ID of the | | 254 | * destination address, private value and the next key ID of the |
255 | * preceeding session key. The last entry on the list is saved along | | 255 | * preceeding session key. The last entry on the list is saved along |
256 | * with its sequence number and public signature. | | 256 | * with its sequence number and public signature. |
257 | */ | | 257 | */ |
258 | int | | 258 | int |
259 | make_keylist( | | 259 | make_keylist( |
260 | struct peer *peer, /* peer structure pointer */ | | 260 | struct peer *peer, /* peer structure pointer */ |
261 | struct interface *dstadr /* interface */ | | 261 | struct interface *dstadr /* interface */ |
262 | ) | | 262 | ) |
263 | { | | 263 | { |
264 | EVP_MD_CTX ctx; /* signature context */ | | 264 | EVP_MD_CTX ctx; /* signature context */ |
265 | tstamp_t tstamp; /* NTP timestamp */ | | 265 | tstamp_t tstamp; /* NTP timestamp */ |
266 | struct autokey *ap; /* autokey pointer */ | | 266 | struct autokey *ap; /* autokey pointer */ |
267 | struct value *vp; /* value pointer */ | | 267 | struct value *vp; /* value pointer */ |
268 | keyid_t keyid = 0; /* next key ID */ | | 268 | keyid_t keyid = 0; /* next key ID */ |
269 | keyid_t cookie; /* private value */ | | 269 | keyid_t cookie; /* private value */ |
270 | u_long lifetime; | | 270 | u_long lifetime; |
271 | u_int len, mpoll; | | 271 | u_int len, mpoll; |
272 | int i; | | 272 | int i; |
273 | | | 273 | |
274 | if (!dstadr) | | 274 | if (!dstadr) |
275 | return XEVNT_OK; | | 275 | return XEVNT_OK; |
276 | | | 276 | |
277 | /* | | 277 | /* |
278 | * Allocate the key list if necessary. | | 278 | * Allocate the key list if necessary. |
279 | */ | | 279 | */ |
280 | tstamp = crypto_time(); | | 280 | tstamp = crypto_time(); |
281 | if (peer->keylist == NULL) | | 281 | if (peer->keylist == NULL) |
282 | peer->keylist = emalloc(sizeof(keyid_t) * | | 282 | peer->keylist = emalloc(sizeof(keyid_t) * |
283 | NTP_MAXSESSION); | | 283 | NTP_MAXSESSION); |
284 | | | 284 | |
285 | /* | | 285 | /* |
286 | * Generate an initial key ID which is unique and greater than | | 286 | * Generate an initial key ID which is unique and greater than |
287 | * NTP_MAXKEY. | | 287 | * NTP_MAXKEY. |
288 | */ | | 288 | */ |
289 | while (1) { | | 289 | while (1) { |
290 | keyid = (ntp_random() + NTP_MAXKEY + 1) & ((1 << | | 290 | keyid = (ntp_random() + NTP_MAXKEY + 1) & ((1 << |
291 | sizeof(keyid_t)) - 1); | | 291 | sizeof(keyid_t)) - 1); |
292 | if (authhavekey(keyid)) | | 292 | if (authhavekey(keyid)) |
293 | continue; | | 293 | continue; |
294 | break; | | 294 | break; |
295 | } | | 295 | } |
296 | | | 296 | |
297 | /* | | 297 | /* |
298 | * Generate up to NTP_MAXSESSION session keys. Stop if the | | 298 | * Generate up to NTP_MAXSESSION session keys. Stop if the |
299 | * next one would not be unique or not a session key ID or if | | 299 | * next one would not be unique or not a session key ID or if |
300 | * it would expire before the next poll. The private value | | 300 | * it would expire before the next poll. The private value |
301 | * included in the hash is zero if broadcast mode, the peer | | 301 | * included in the hash is zero if broadcast mode, the peer |
302 | * cookie if client mode or the host cookie if symmetric modes. | | 302 | * cookie if client mode or the host cookie if symmetric modes. |
303 | */ | | 303 | */ |
304 | mpoll = 1 << min(peer->ppoll, peer->hpoll); | | 304 | mpoll = 1 << min(peer->ppoll, peer->hpoll); |
305 | lifetime = min(sys_automax, NTP_MAXSESSION * mpoll); | | 305 | lifetime = min(sys_automax, NTP_MAXSESSION * mpoll); |
306 | if (peer->hmode == MODE_BROADCAST) | | 306 | if (peer->hmode == MODE_BROADCAST) |
307 | cookie = 0; | | 307 | cookie = 0; |
308 | else | | 308 | else |
309 | cookie = peer->pcookie; | | 309 | cookie = peer->pcookie; |
310 | for (i = 0; i < NTP_MAXSESSION; i++) { | | 310 | for (i = 0; i < NTP_MAXSESSION; i++) { |
311 | peer->keylist[i] = keyid; | | 311 | peer->keylist[i] = keyid; |
312 | peer->keynumber = i; | | 312 | peer->keynumber = i; |
313 | keyid = session_key(&dstadr->sin, &peer->srcadr, keyid, | | 313 | keyid = session_key(&dstadr->sin, &peer->srcadr, keyid, |
314 | cookie, lifetime); | | 314 | cookie, lifetime); |
315 | lifetime -= mpoll; | | 315 | lifetime -= mpoll; |
316 | if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || | | 316 | if (auth_havekey(keyid) || keyid <= NTP_MAXKEY || |
317 | lifetime <= mpoll) | | 317 | lifetime <= mpoll) |
318 | break; | | 318 | break; |
319 | } | | 319 | } |
320 | | | 320 | |
321 | /* | | 321 | /* |
322 | * Save the last session key ID, sequence number and timestamp, | | 322 | * Save the last session key ID, sequence number and timestamp, |
323 | * then sign these values for later retrieval by the clients. Be | | 323 | * then sign these values for later retrieval by the clients. Be |
324 | * careful not to use invalid key media. Use the public values | | 324 | * careful not to use invalid key media. Use the public values |
325 | * timestamp as filestamp. | | 325 | * timestamp as filestamp. |
326 | */ | | 326 | */ |
327 | vp = &peer->sndval; | | 327 | vp = &peer->sndval; |
328 | if (vp->ptr == NULL) | | 328 | if (vp->ptr == NULL) |
329 | vp->ptr = emalloc(sizeof(struct autokey)); | | 329 | vp->ptr = emalloc(sizeof(struct autokey)); |
330 | ap = (struct autokey *)vp->ptr; | | 330 | ap = (struct autokey *)vp->ptr; |
331 | ap->seq = htonl(peer->keynumber); | | 331 | ap->seq = htonl(peer->keynumber); |
332 | ap->key = htonl(keyid); | | 332 | ap->key = htonl(keyid); |
333 | vp->tstamp = htonl(tstamp); | | 333 | vp->tstamp = htonl(tstamp); |
334 | vp->fstamp = hostval.tstamp; | | 334 | vp->fstamp = hostval.tstamp; |
335 | vp->vallen = htonl(sizeof(struct autokey)); | | 335 | vp->vallen = htonl(sizeof(struct autokey)); |
336 | vp->siglen = 0; | | 336 | vp->siglen = 0; |
337 | if (tstamp != 0) { | | 337 | if (tstamp != 0) { |
338 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 338 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
339 | return (XEVNT_PER); | | 339 | return (XEVNT_PER); |
340 | | | 340 | |
341 | if (vp->sig == NULL) | | 341 | if (vp->sig == NULL) |
342 | vp->sig = emalloc(sign_siglen); | | 342 | vp->sig = emalloc(sign_siglen); |
343 | EVP_SignInit(&ctx, sign_digest); | | 343 | EVP_SignInit(&ctx, sign_digest); |
344 | EVP_SignUpdate(&ctx, (u_char *)vp, 12); | | 344 | EVP_SignUpdate(&ctx, (u_char *)vp, 12); |
345 | EVP_SignUpdate(&ctx, vp->ptr, sizeof(struct autokey)); | | 345 | EVP_SignUpdate(&ctx, vp->ptr, sizeof(struct autokey)); |
346 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 346 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
347 | vp->siglen = htonl(len); | | 347 | vp->siglen = htonl(len); |
348 | else | | 348 | else |
349 | msyslog(LOG_ERR, "make_keys %s\n", | | 349 | msyslog(LOG_ERR, "make_keys %s\n", |
350 | ERR_error_string(ERR_get_error(), NULL)); | | 350 | ERR_error_string(ERR_get_error(), NULL)); |
351 | peer->flags |= FLAG_ASSOC; | | 351 | peer->flags |= FLAG_ASSOC; |
352 | } | | 352 | } |
353 | #ifdef DEBUG | | 353 | #ifdef DEBUG |
354 | if (debug) | | 354 | if (debug) |
355 | printf("make_keys: %d %08x %08x ts %u fs %u poll %d\n", | | 355 | printf("make_keys: %d %08x %08x ts %u fs %u poll %d\n", |
356 | ntohl(ap->seq), ntohl(ap->key), cookie, | | 356 | ntohl(ap->seq), ntohl(ap->key), cookie, |
357 | ntohl(vp->tstamp), ntohl(vp->fstamp), peer->hpoll); | | 357 | ntohl(vp->tstamp), ntohl(vp->fstamp), peer->hpoll); |
358 | #endif | | 358 | #endif |
359 | return (XEVNT_OK); | | 359 | return (XEVNT_OK); |
360 | } | | 360 | } |
361 | | | 361 | |
362 | | | 362 | |
363 | /* | | 363 | /* |
364 | * crypto_recv - parse extension fields | | 364 | * crypto_recv - parse extension fields |
365 | * | | 365 | * |
366 | * This routine is called when the packet has been matched to an | | 366 | * This routine is called when the packet has been matched to an |
367 | * association and passed sanity, format and MAC checks. We believe the | | 367 | * association and passed sanity, format and MAC checks. We believe the |
368 | * extension field values only if the field has proper format and | | 368 | * extension field values only if the field has proper format and |
369 | * length, the timestamp and filestamp are valid and the signature has | | 369 | * length, the timestamp and filestamp are valid and the signature has |
370 | * valid length and is verified. There are a few cases where some values | | 370 | * valid length and is verified. There are a few cases where some values |
371 | * are believed even if the signature fails, but only if the proventic | | 371 | * are believed even if the signature fails, but only if the proventic |
372 | * bit is not set. | | 372 | * bit is not set. |
373 | */ | | 373 | */ |
374 | int | | 374 | int |
375 | crypto_recv( | | 375 | crypto_recv( |
376 | struct peer *peer, /* peer structure pointer */ | | 376 | struct peer *peer, /* peer structure pointer */ |
377 | struct recvbuf *rbufp /* packet buffer pointer */ | | 377 | struct recvbuf *rbufp /* packet buffer pointer */ |
378 | ) | | 378 | ) |
379 | { | | 379 | { |
380 | const EVP_MD *dp; /* message digest algorithm */ | | 380 | const EVP_MD *dp; /* message digest algorithm */ |
381 | u_int32 *pkt; /* receive packet pointer */ | | 381 | u_int32 *pkt; /* receive packet pointer */ |
382 | struct autokey *ap, *bp; /* autokey pointer */ | | 382 | struct autokey *ap, *bp; /* autokey pointer */ |
383 | struct exten *ep, *fp; /* extension pointers */ | | 383 | struct exten *ep, *fp; /* extension pointers */ |
384 | int has_mac; /* length of MAC field */ | | 384 | int has_mac; /* length of MAC field */ |
385 | int authlen; /* offset of MAC field */ | | 385 | int authlen; /* offset of MAC field */ |
386 | associd_t associd; /* association ID */ | | 386 | associd_t associd; /* association ID */ |
387 | tstamp_t tstamp = 0; /* timestamp */ | | 387 | tstamp_t tstamp = 0; /* timestamp */ |
388 | tstamp_t fstamp = 0; /* filestamp */ | | 388 | tstamp_t fstamp = 0; /* filestamp */ |
389 | u_int len; /* extension field length */ | | 389 | u_int len; /* extension field length */ |
390 | u_int code; /* extension field opcode */ | | 390 | u_int code; /* extension field opcode */ |
391 | u_int vallen = 0; /* value length */ | | 391 | u_int vallen = 0; /* value length */ |
392 | X509 *cert; /* X509 certificate */ | | 392 | X509 *cert; /* X509 certificate */ |
393 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 393 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
394 | keyid_t cookie; /* crumbles */ | | 394 | keyid_t cookie; /* crumbles */ |
395 | int hismode; /* packet mode */ | | 395 | int hismode; /* packet mode */ |
396 | int rval = XEVNT_OK; | | 396 | int rval = XEVNT_OK; |
397 | const u_char *ptr; | | 397 | const u_char *ptr; |
398 | u_int32 temp32; | | 398 | u_int32 temp32; |
399 | | | 399 | |
400 | /* | | 400 | /* |
401 | * Initialize. Note that the packet has already been checked for | | 401 | * Initialize. Note that the packet has already been checked for |
402 | * valid format and extension field lengths. First extract the | | 402 | * valid format and extension field lengths. First extract the |
403 | * field length, command code and association ID in host byte | | 403 | * field length, command code and association ID in host byte |
404 | * order. These are used with all commands and modes. Then check | | 404 | * order. These are used with all commands and modes. Then check |
405 | * the version number, which must be 2, and length, which must | | 405 | * the version number, which must be 2, and length, which must |
406 | * be at least 8 for requests and VALUE_LEN (24) for responses. | | 406 | * be at least 8 for requests and VALUE_LEN (24) for responses. |
407 | * Packets that fail either test sink without a trace. The | | 407 | * Packets that fail either test sink without a trace. The |
408 | * association ID is saved only if nonzero. | | 408 | * association ID is saved only if nonzero. |
409 | */ | | 409 | */ |
410 | authlen = LEN_PKT_NOMAC; | | 410 | authlen = LEN_PKT_NOMAC; |
411 | hismode = (int)PKT_MODE((&rbufp->recv_pkt)->li_vn_mode); | | 411 | hismode = (int)PKT_MODE((&rbufp->recv_pkt)->li_vn_mode); |
412 | while ((has_mac = rbufp->recv_length - authlen) > MAX_MAC_LEN) { | | 412 | while ((has_mac = rbufp->recv_length - authlen) > MAX_MAC_LEN) { |
413 | pkt = (u_int32 *)&rbufp->recv_pkt + authlen / 4; | | 413 | pkt = (u_int32 *)&rbufp->recv_pkt + authlen / 4; |
414 | ep = (struct exten *)pkt; | | 414 | ep = (struct exten *)pkt; |
415 | code = ntohl(ep->opcode) & 0xffff0000; | | 415 | code = ntohl(ep->opcode) & 0xffff0000; |
416 | len = ntohl(ep->opcode) & 0x0000ffff; | | 416 | len = ntohl(ep->opcode) & 0x0000ffff; |
417 | associd = (associd_t) ntohl(pkt[1]); | | 417 | associd = (associd_t) ntohl(pkt[1]); |
418 | rval = XEVNT_OK; | | 418 | rval = XEVNT_OK; |
419 | #ifdef DEBUG | | 419 | #ifdef DEBUG |
420 | if (debug) | | 420 | if (debug) |
421 | printf( | | 421 | printf( |
422 | "crypto_recv: flags 0x%x ext offset %d len %u code 0x%x assocID %d\n", | | 422 | "crypto_recv: flags 0x%x ext offset %d len %u code 0x%x assocID %d\n", |
423 | peer->crypto, authlen, len, code >> 16, | | 423 | peer->crypto, authlen, len, code >> 16, |
424 | associd); | | 424 | associd); |
425 | #endif | | 425 | #endif |
426 | | | 426 | |
427 | /* | | 427 | /* |
428 | * Check version number and field length. If bad, | | 428 | * Check version number and field length. If bad, |
429 | * quietly ignore the packet. | | 429 | * quietly ignore the packet. |
430 | */ | | 430 | */ |
431 | if (((code >> 24) & 0x3f) != CRYPTO_VN || len < 8) { | | 431 | if (((code >> 24) & 0x3f) != CRYPTO_VN || len < 8) { |
432 | sys_unknownversion++; | | 432 | sys_unknownversion++; |
433 | code |= CRYPTO_ERROR; | | 433 | code |= CRYPTO_ERROR; |
434 | } | | 434 | } |
435 | | | 435 | |
436 | /* | | 436 | /* |
437 | * Little vulnerability bandage here. If a perp tosses a | | 437 | * Little vulnerability bandage here. If a perp tosses a |
438 | * fake association ID over the fence, we better toss it | | 438 | * fake association ID over the fence, we better toss it |
439 | * out. Only the first one counts. | | 439 | * out. Only the first one counts. |
440 | */ | | 440 | */ |
441 | if (code & CRYPTO_RESP) { | | 441 | if (code & CRYPTO_RESP) { |
442 | if (peer->assoc == 0) | | 442 | if (peer->assoc == 0) |
443 | peer->assoc = associd; | | 443 | peer->assoc = associd; |
444 | else if (peer->assoc != associd) | | 444 | else if (peer->assoc != associd) |
445 | code |= CRYPTO_ERROR; | | 445 | code |= CRYPTO_ERROR; |
446 | } | | 446 | } |
447 | if (len >= VALUE_LEN) { | | 447 | if (len >= VALUE_LEN) { |
448 | tstamp = ntohl(ep->tstamp); | | 448 | tstamp = ntohl(ep->tstamp); |
449 | fstamp = ntohl(ep->fstamp); | | 449 | fstamp = ntohl(ep->fstamp); |
450 | vallen = ntohl(ep->vallen); | | 450 | vallen = ntohl(ep->vallen); |
451 | } | | 451 | } |
452 | switch (code) { | | 452 | switch (code) { |
453 | | | 453 | |
454 | /* | | 454 | /* |
455 | * Install status word, host name, signature scheme and | | 455 | * Install status word, host name, signature scheme and |
456 | * association ID. In OpenSSL the signature algorithm is | | 456 | * association ID. In OpenSSL the signature algorithm is |
457 | * bound to the digest algorithm, so the NID completely | | 457 | * bound to the digest algorithm, so the NID completely |
458 | * defines the signature scheme. Note the request and | | 458 | * defines the signature scheme. Note the request and |
459 | * response are identical, but neither is validated by | | 459 | * response are identical, but neither is validated by |
460 | * signature. The request is processed here only in | | 460 | * signature. The request is processed here only in |
461 | * symmetric modes. The server name field might be | | 461 | * symmetric modes. The server name field might be |
462 | * useful to implement access controls in future. | | 462 | * useful to implement access controls in future. |
463 | */ | | 463 | */ |
464 | case CRYPTO_ASSOC: | | 464 | case CRYPTO_ASSOC: |
465 | | | 465 | |
466 | /* | | 466 | /* |
467 | * If the machine is running when this message | | 467 | * If the machine is running when this message |
468 | * arrives, the other fellow has reset and so | | 468 | * arrives, the other fellow has reset and so |
469 | * must we. Otherwise, pass the extension field | | 469 | * must we. Otherwise, pass the extension field |
470 | * to the transmit side. | | 470 | * to the transmit side. |
471 | */ | | 471 | */ |
472 | if (peer->crypto) { | | 472 | if (peer->crypto) { |
473 | rval = XEVNT_ERR; | | 473 | rval = XEVNT_ERR; |
474 | break; | | 474 | break; |
475 | } | | 475 | } |
476 | fp = emalloc(len); | | 476 | fp = emalloc(len); |
477 | memcpy(fp, ep, len); | | 477 | memcpy(fp, ep, len); |
478 | temp32 = CRYPTO_RESP; | | 478 | temp32 = CRYPTO_RESP; |
479 | fp->opcode |= htonl(temp32); | | 479 | fp->opcode |= htonl(temp32); |
480 | peer->cmmd = fp; | | 480 | peer->cmmd = fp; |
481 | /* fall through */ | | 481 | /* fall through */ |
482 | | | 482 | |
483 | case CRYPTO_ASSOC | CRYPTO_RESP: | | 483 | case CRYPTO_ASSOC | CRYPTO_RESP: |
484 | | | 484 | |
485 | /* | | 485 | /* |
486 | * Discard the message if it has already been | | 486 | * Discard the message if it has already been |
487 | * stored or the message has been amputated. | | 487 | * stored or the message has been amputated. |
488 | */ | | 488 | */ |
489 | if (peer->crypto) | | 489 | if (peer->crypto) |
490 | break; | | 490 | break; |
491 | | | 491 | |
492 | if (vallen == 0 || vallen > MAXHOSTNAME || | | 492 | if (vallen == 0 || vallen > MAXHOSTNAME || |
493 | len < VALUE_LEN + vallen) { | | 493 | len < VALUE_LEN + vallen) { |
494 | rval = XEVNT_LEN; | | 494 | rval = XEVNT_LEN; |
495 | break; | | 495 | break; |
496 | } | | 496 | } |
497 | | | 497 | |
498 | /* | | 498 | /* |
499 | * Check the identity schemes are compatible. If | | 499 | * Check the identity schemes are compatible. If |
500 | * the client has PC, the server must have PC, | | 500 | * the client has PC, the server must have PC, |
501 | * in which case the server public key and | | 501 | * in which case the server public key and |
502 | * identity are presumed valid, so we skip the | | 502 | * identity are presumed valid, so we skip the |
503 | * certificate and identity exchanges and move | | 503 | * certificate and identity exchanges and move |
504 | * immediately to the cookie exchange which | | 504 | * immediately to the cookie exchange which |
505 | * confirms the server signature. | | 505 | * confirms the server signature. |
506 | */ | | 506 | */ |
507 | #ifdef DEBUG | | 507 | #ifdef DEBUG |
508 | if (debug) | | 508 | if (debug) |
509 | printf( | | 509 | printf( |
510 | "crypto_recv: ident host 0x%x server 0x%x\n", | | 510 | "crypto_recv: ident host 0x%x server 0x%x\n", |
511 | crypto_flags, fstamp); | | 511 | crypto_flags, fstamp); |
512 | #endif | | 512 | #endif |
513 | temp32 = (crypto_flags | ident_scheme) & | | 513 | temp32 = (crypto_flags | ident_scheme) & |
514 | fstamp & CRYPTO_FLAG_MASK; | | 514 | fstamp & CRYPTO_FLAG_MASK; |
515 | if (crypto_flags & CRYPTO_FLAG_PRIV) { | | 515 | if (crypto_flags & CRYPTO_FLAG_PRIV) { |
516 | if (!(fstamp & CRYPTO_FLAG_PRIV)) { | | 516 | if (!(fstamp & CRYPTO_FLAG_PRIV)) { |
517 | rval = XEVNT_KEY; | | 517 | rval = XEVNT_KEY; |
518 | break; | | 518 | break; |
519 | | | 519 | |
520 | } else { | | 520 | } else { |
521 | fstamp |= CRYPTO_FLAG_VALID | | | 521 | fstamp |= CRYPTO_FLAG_VALID | |
522 | CRYPTO_FLAG_VRFY | | | 522 | CRYPTO_FLAG_VRFY | |
523 | CRYPTO_FLAG_SIGN; | | 523 | CRYPTO_FLAG_SIGN; |
524 | } | | 524 | } |
525 | /* | | 525 | /* |
526 | * In symmetric modes it is an error if either | | 526 | * In symmetric modes it is an error if either |
527 | * peer requests identity and the other peer | | 527 | * peer requests identity and the other peer |
528 | * does not support it. | | 528 | * does not support it. |
529 | */ | | 529 | */ |
530 | } else if ((hismode == MODE_ACTIVE || hismode == | | 530 | } else if ((hismode == MODE_ACTIVE || hismode == |
531 | MODE_PASSIVE) && ((crypto_flags | fstamp) & | | 531 | MODE_PASSIVE) && ((crypto_flags | fstamp) & |
532 | CRYPTO_FLAG_MASK) && !temp32) { | | 532 | CRYPTO_FLAG_MASK) && !temp32) { |
533 | rval = XEVNT_KEY; | | 533 | rval = XEVNT_KEY; |
534 | break; | | 534 | break; |
535 | /* | | 535 | /* |
536 | * It is an error if the client requests | | 536 | * It is an error if the client requests |
537 | * identity and the server does not support it. | | 537 | * identity and the server does not support it. |
538 | */ | | 538 | */ |
539 | } else if (hismode == MODE_CLIENT && (fstamp & | | 539 | } else if (hismode == MODE_CLIENT && (fstamp & |
540 | CRYPTO_FLAG_MASK) && !temp32) { | | 540 | CRYPTO_FLAG_MASK) && !temp32) { |
541 | rval = XEVNT_KEY; | | 541 | rval = XEVNT_KEY; |
542 | break; | | 542 | break; |
543 | } | | 543 | } |
544 | | | 544 | |
545 | /* | | 545 | /* |
546 | * Otherwise, the identity scheme(s) are those | | 546 | * Otherwise, the identity scheme(s) are those |
547 | * that both client and server support. | | 547 | * that both client and server support. |
548 | */ | | 548 | */ |
549 | fstamp = temp32 | (fstamp & ~CRYPTO_FLAG_MASK); | | 549 | fstamp = temp32 | (fstamp & ~CRYPTO_FLAG_MASK); |
550 | | | 550 | |
551 | /* | | 551 | /* |
552 | * Discard the message if the signature digest | | 552 | * Discard the message if the signature digest |
553 | * NID is not supported. | | 553 | * NID is not supported. |
554 | */ | | 554 | */ |
555 | temp32 = (fstamp >> 16) & 0xffff; | | 555 | temp32 = (fstamp >> 16) & 0xffff; |
556 | dp = | | 556 | dp = |
557 | (const EVP_MD *)EVP_get_digestbynid(temp32); | | 557 | (const EVP_MD *)EVP_get_digestbynid(temp32); |
558 | if (dp == NULL) { | | 558 | if (dp == NULL) { |
559 | rval = XEVNT_MD; | | 559 | rval = XEVNT_MD; |
560 | break; | | 560 | break; |
561 | } | | 561 | } |
562 | | | 562 | |
563 | /* | | 563 | /* |
564 | * Save status word, host name and message | | 564 | * Save status word, host name and message |
565 | * digest/signature type. | | 565 | * digest/signature type. |
566 | */ | | 566 | */ |
567 | peer->crypto = fstamp; | | 567 | peer->crypto = fstamp; |
568 | peer->digest = dp; | | 568 | peer->digest = dp; |
569 | peer->subject = emalloc(vallen + 1); | | 569 | peer->subject = emalloc(vallen + 1); |
570 | memcpy(peer->subject, ep->pkt, vallen); | | 570 | memcpy(peer->subject, ep->pkt, vallen); |
571 | peer->subject[vallen] = '\0'; | | 571 | peer->subject[vallen] = '\0'; |
572 | peer->issuer = emalloc(vallen + 1); | | 572 | peer->issuer = emalloc(vallen + 1); |
573 | strcpy(peer->issuer, peer->subject); | | 573 | strcpy(peer->issuer, peer->subject); |
574 | temp32 = (fstamp >> 16) & 0xffff; | | 574 | temp32 = (fstamp >> 16) & 0xffff; |
575 | sprintf(statstr, | | 575 | snprintf(statstr, NTP_MAXSTRLEN, |
576 | "flags 0x%x host %s signature %s", fstamp, | | 576 | "flags 0x%x host %s signature %s", fstamp, |
577 | peer->subject, OBJ_nid2ln(temp32)); | | 577 | peer->subject, OBJ_nid2ln(temp32)); |
578 | record_crypto_stats(&peer->srcadr, statstr); | | 578 | record_crypto_stats(&peer->srcadr, statstr); |
579 | #ifdef DEBUG | | 579 | #ifdef DEBUG |
580 | if (debug) | | 580 | if (debug) |
581 | printf("crypto_recv: %s\n", statstr); | | 581 | printf("crypto_recv: %s\n", statstr); |
582 | #endif | | 582 | #endif |
583 | break; | | 583 | break; |
584 | | | 584 | |
585 | /* | | 585 | /* |
586 | * Decode X509 certificate in ASN.1 format and extract | | 586 | * Decode X509 certificate in ASN.1 format and extract |
587 | * the data containing, among other things, subject | | 587 | * the data containing, among other things, subject |
588 | * name and public key. In the default identification | | 588 | * name and public key. In the default identification |
589 | * scheme, the certificate trail is followed to a self | | 589 | * scheme, the certificate trail is followed to a self |
590 | * signed trusted certificate. | | 590 | * signed trusted certificate. |
591 | */ | | 591 | */ |
592 | case CRYPTO_CERT | CRYPTO_RESP: | | 592 | case CRYPTO_CERT | CRYPTO_RESP: |
593 | | | 593 | |
594 | /* | | 594 | /* |
595 | * Discard the message if invalid. | | 595 | * Discard the message if invalid. |
596 | */ | | 596 | */ |
597 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 597 | if ((rval = crypto_verify(ep, NULL, peer)) != |
598 | XEVNT_OK) | | 598 | XEVNT_OK) |
599 | break; | | 599 | break; |
600 | | | 600 | |
601 | /* | | 601 | /* |
602 | * Scan the certificate list to delete old | | 602 | * Scan the certificate list to delete old |
603 | * versions and link the newest version first on | | 603 | * versions and link the newest version first on |
604 | * the list. | | 604 | * the list. |
605 | */ | | 605 | */ |
606 | if ((rval = cert_install(ep, peer)) != XEVNT_OK) | | 606 | if ((rval = cert_install(ep, peer)) != XEVNT_OK) |
607 | break; | | 607 | break; |
608 | | | 608 | |
609 | /* | | 609 | /* |
610 | * If we snatch the certificate before the | | 610 | * If we snatch the certificate before the |
611 | * server certificate has been signed by its | | 611 | * server certificate has been signed by its |
612 | * server, it will be self signed. When it is, | | 612 | * server, it will be self signed. When it is, |
613 | * we chase the certificate issuer, which the | | 613 | * we chase the certificate issuer, which the |
614 | * server has, and keep going until a self | | 614 | * server has, and keep going until a self |
615 | * signed trusted certificate is found. Be sure | | 615 | * signed trusted certificate is found. Be sure |
616 | * to update the issuer field, since it may | | 616 | * to update the issuer field, since it may |
617 | * change. | | 617 | * change. |
618 | */ | | 618 | */ |
619 | if (peer->issuer != NULL) | | 619 | if (peer->issuer != NULL) |
620 | free(peer->issuer); | | 620 | free(peer->issuer); |
621 | peer->issuer = emalloc(strlen(cinfo->issuer) + | | 621 | peer->issuer = emalloc(strlen(cinfo->issuer) + |
622 | 1); | | 622 | 1); |
623 | strcpy(peer->issuer, cinfo->issuer); | | 623 | strcpy(peer->issuer, cinfo->issuer); |
624 | | | 624 | |
625 | /* | | 625 | /* |
626 | * We plug in the public key and lifetime from | | 626 | * We plug in the public key and lifetime from |
627 | * the first certificate received. However, note | | 627 | * the first certificate received. However, note |
628 | * that this certificate might not be signed by | | 628 | * that this certificate might not be signed by |
629 | * the server, so we can't check the | | 629 | * the server, so we can't check the |
630 | * signature/digest NID. | | 630 | * signature/digest NID. |
631 | */ | | 631 | */ |
632 | if (peer->pkey == NULL) { | | 632 | if (peer->pkey == NULL) { |
633 | ptr = (u_char *)cinfo->cert.ptr; | | 633 | ptr = (u_char *)cinfo->cert.ptr; |
634 | cert = d2i_X509(NULL, &ptr, | | 634 | cert = d2i_X509(NULL, &ptr, |
635 | ntohl(cinfo->cert.vallen)); | | 635 | ntohl(cinfo->cert.vallen)); |
636 | peer->pkey = X509_get_pubkey(cert); | | 636 | peer->pkey = X509_get_pubkey(cert); |
637 | X509_free(cert); | | 637 | X509_free(cert); |
638 | } | | 638 | } |
639 | peer->flash &= ~TEST8; | | 639 | peer->flash &= ~TEST8; |
640 | temp32 = cinfo->nid; | | 640 | temp32 = cinfo->nid; |
641 | sprintf(statstr, "cert %s 0x%x %s (%u) fs %u", | | 641 | snprintf(statstr, NTP_MAXSTRLEN, |
| | | 642 | "cert %s 0x%x %s (%u) fs %u", |
642 | cinfo->subject, cinfo->flags, | | 643 | cinfo->subject, cinfo->flags, |
643 | OBJ_nid2ln(temp32), temp32, | | 644 | OBJ_nid2ln(temp32), temp32, |
644 | ntohl(ep->fstamp)); | | 645 | ntohl(ep->fstamp)); |
645 | record_crypto_stats(&peer->srcadr, statstr); | | 646 | record_crypto_stats(&peer->srcadr, statstr); |
646 | #ifdef DEBUG | | 647 | #ifdef DEBUG |
647 | if (debug) | | 648 | if (debug) |
648 | printf("crypto_recv: %s\n", statstr); | | 649 | printf("crypto_recv: %s\n", statstr); |
649 | #endif | | 650 | #endif |
650 | break; | | 651 | break; |
651 | | | 652 | |
652 | /* | | 653 | /* |
653 | * Schnorr (IFF)identity scheme. This scheme is designed | | 654 | * Schnorr (IFF)identity scheme. This scheme is designed |
654 | * for use with shared secret group keys and where the | | 655 | * for use with shared secret group keys and where the |
655 | * certificate may be generated by a third party. The | | 656 | * certificate may be generated by a third party. The |
656 | * client sends a challenge to the server, which | | 657 | * client sends a challenge to the server, which |
657 | * performs a calculation and returns the result. A | | 658 | * performs a calculation and returns the result. A |
658 | * positive result is possible only if both client and | | 659 | * positive result is possible only if both client and |
659 | * server contain the same secret group key. | | 660 | * server contain the same secret group key. |
660 | */ | | 661 | */ |
661 | case CRYPTO_IFF | CRYPTO_RESP: | | 662 | case CRYPTO_IFF | CRYPTO_RESP: |
662 | | | 663 | |
663 | /* | | 664 | /* |
664 | * Discard the message if invalid or certificate | | 665 | * Discard the message if invalid or certificate |
665 | * trail not trusted. | | 666 | * trail not trusted. |
666 | */ | | 667 | */ |
667 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { | | 668 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { |
668 | rval = XEVNT_ERR; | | 669 | rval = XEVNT_ERR; |
669 | break; | | 670 | break; |
670 | } | | 671 | } |
671 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 672 | if ((rval = crypto_verify(ep, NULL, peer)) != |
672 | XEVNT_OK) | | 673 | XEVNT_OK) |
673 | break; | | 674 | break; |
674 | | | 675 | |
675 | /* | | 676 | /* |
676 | * If the the challenge matches the response, | | 677 | * If the the challenge matches the response, |
677 | * the certificate public key, as well as the | | 678 | * the certificate public key, as well as the |
678 | * server public key, signatyre and identity are | | 679 | * server public key, signatyre and identity are |
679 | * all verified at the same time. The server is | | 680 | * all verified at the same time. The server is |
680 | * declared trusted, so we skip further | | 681 | * declared trusted, so we skip further |
681 | * certificate stages and move immediately to | | 682 | * certificate stages and move immediately to |
682 | * the cookie stage. | | 683 | * the cookie stage. |
683 | */ | | 684 | */ |
684 | if ((rval = crypto_iff(ep, peer)) != XEVNT_OK) | | 685 | if ((rval = crypto_iff(ep, peer)) != XEVNT_OK) |
685 | break; | | 686 | break; |
686 | | | 687 | |
687 | peer->crypto |= CRYPTO_FLAG_VRFY | | | 688 | peer->crypto |= CRYPTO_FLAG_VRFY | |
688 | CRYPTO_FLAG_PROV; | | 689 | CRYPTO_FLAG_PROV; |
689 | peer->flash &= ~TEST8; | | 690 | peer->flash &= ~TEST8; |
690 | sprintf(statstr, "iff fs %u", | | 691 | snprintf(statstr, NTP_MAXSTRLEN, "iff fs %u", |
691 | ntohl(ep->fstamp)); | | 692 | ntohl(ep->fstamp)); |
692 | record_crypto_stats(&peer->srcadr, statstr); | | 693 | record_crypto_stats(&peer->srcadr, statstr); |
693 | #ifdef DEBUG | | 694 | #ifdef DEBUG |
694 | if (debug) | | 695 | if (debug) |
695 | printf("crypto_recv: %s\n", statstr); | | 696 | printf("crypto_recv: %s\n", statstr); |
696 | #endif | | 697 | #endif |
697 | break; | | 698 | break; |
698 | | | 699 | |
699 | /* | | 700 | /* |
700 | * Guillou-Quisquater (GQ) identity scheme. This scheme | | 701 | * Guillou-Quisquater (GQ) identity scheme. This scheme |
701 | * is designed for use with public certificates carrying | | 702 | * is designed for use with public certificates carrying |
702 | * the GQ public key in an extension field. The client | | 703 | * the GQ public key in an extension field. The client |
703 | * sends a challenge to the server, which performs a | | 704 | * sends a challenge to the server, which performs a |
704 | * calculation and returns the result. A positive result | | 705 | * calculation and returns the result. A positive result |
705 | * is possible only if both client and server contain | | 706 | * is possible only if both client and server contain |
706 | * the same group key and the server has the matching GQ | | 707 | * the same group key and the server has the matching GQ |
707 | * private key. | | 708 | * private key. |
708 | */ | | 709 | */ |
709 | case CRYPTO_GQ | CRYPTO_RESP: | | 710 | case CRYPTO_GQ | CRYPTO_RESP: |
710 | | | 711 | |
711 | /* | | 712 | /* |
712 | * Discard the message if invalid or certificate | | 713 | * Discard the message if invalid or certificate |
713 | * trail not trusted. | | 714 | * trail not trusted. |
714 | */ | | 715 | */ |
715 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { | | 716 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { |
716 | rval = XEVNT_ERR; | | 717 | rval = XEVNT_ERR; |
717 | break; | | 718 | break; |
718 | } | | 719 | } |
719 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 720 | if ((rval = crypto_verify(ep, NULL, peer)) != |
720 | XEVNT_OK) | | 721 | XEVNT_OK) |
721 | break; | | 722 | break; |
722 | | | 723 | |
723 | /* | | 724 | /* |
724 | * If the the challenge matches the response, | | 725 | * If the the challenge matches the response, |
725 | * the certificate public key, as well as the | | 726 | * the certificate public key, as well as the |
726 | * server public key, signatyre and identity are | | 727 | * server public key, signatyre and identity are |
727 | * all verified at the same time. The server is | | 728 | * all verified at the same time. The server is |
728 | * declared trusted, so we skip further | | 729 | * declared trusted, so we skip further |
729 | * certificate stages and move immediately to | | 730 | * certificate stages and move immediately to |
730 | * the cookie stage. | | 731 | * the cookie stage. |
731 | */ | | 732 | */ |
732 | if ((rval = crypto_gq(ep, peer)) != XEVNT_OK) | | 733 | if ((rval = crypto_gq(ep, peer)) != XEVNT_OK) |
733 | break; | | 734 | break; |
734 | | | 735 | |
735 | peer->crypto |= CRYPTO_FLAG_VRFY | | | 736 | peer->crypto |= CRYPTO_FLAG_VRFY | |
736 | CRYPTO_FLAG_PROV; | | 737 | CRYPTO_FLAG_PROV; |
737 | peer->flash &= ~TEST8; | | 738 | peer->flash &= ~TEST8; |
738 | sprintf(statstr, "gq fs %u", | | 739 | snprintf(statstr, NTP_MAXSTRLEN, "gq fs %u", |
739 | ntohl(ep->fstamp)); | | 740 | ntohl(ep->fstamp)); |
740 | record_crypto_stats(&peer->srcadr, statstr); | | 741 | record_crypto_stats(&peer->srcadr, statstr); |
741 | #ifdef DEBUG | | 742 | #ifdef DEBUG |
742 | if (debug) | | 743 | if (debug) |
743 | printf("crypto_recv: %s\n", statstr); | | 744 | printf("crypto_recv: %s\n", statstr); |
744 | #endif | | 745 | #endif |
745 | break; | | 746 | break; |
746 | | | 747 | |
747 | /* | | 748 | /* |
748 | * MV | | 749 | * MV |
749 | */ | | 750 | */ |
750 | case CRYPTO_MV | CRYPTO_RESP: | | 751 | case CRYPTO_MV | CRYPTO_RESP: |
751 | | | 752 | |
752 | /* | | 753 | /* |
753 | * Discard the message if invalid or certificate | | 754 | * Discard the message if invalid or certificate |
754 | * trail not trusted. | | 755 | * trail not trusted. |
755 | */ | | 756 | */ |
756 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { | | 757 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { |
757 | rval = XEVNT_ERR; | | 758 | rval = XEVNT_ERR; |
758 | break; | | 759 | break; |
759 | } | | 760 | } |
760 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 761 | if ((rval = crypto_verify(ep, NULL, peer)) != |
761 | XEVNT_OK) | | 762 | XEVNT_OK) |
762 | break; | | 763 | break; |
763 | | | 764 | |
764 | /* | | 765 | /* |
765 | * If the the challenge matches the response, | | 766 | * If the the challenge matches the response, |
766 | * the certificate public key, as well as the | | 767 | * the certificate public key, as well as the |
767 | * server public key, signatyre and identity are | | 768 | * server public key, signatyre and identity are |
768 | * all verified at the same time. The server is | | 769 | * all verified at the same time. The server is |
769 | * declared trusted, so we skip further | | 770 | * declared trusted, so we skip further |
770 | * certificate stages and move immediately to | | 771 | * certificate stages and move immediately to |
771 | * the cookie stage. | | 772 | * the cookie stage. |
772 | */ | | 773 | */ |
773 | if ((rval = crypto_mv(ep, peer)) != XEVNT_OK) | | 774 | if ((rval = crypto_mv(ep, peer)) != XEVNT_OK) |
774 | break; | | 775 | break; |
775 | | | 776 | |
776 | peer->crypto |= CRYPTO_FLAG_VRFY | | | 777 | peer->crypto |= CRYPTO_FLAG_VRFY | |
777 | CRYPTO_FLAG_PROV; | | 778 | CRYPTO_FLAG_PROV; |
778 | peer->flash &= ~TEST8; | | 779 | peer->flash &= ~TEST8; |
779 | sprintf(statstr, "mv fs %u", | | 780 | snprintf(statstr, NTP_MAXSTRLEN, "mv fs %u", |
780 | ntohl(ep->fstamp)); | | 781 | ntohl(ep->fstamp)); |
781 | record_crypto_stats(&peer->srcadr, statstr); | | 782 | record_crypto_stats(&peer->srcadr, statstr); |
782 | #ifdef DEBUG | | 783 | #ifdef DEBUG |
783 | if (debug) | | 784 | if (debug) |
784 | printf("crypto_recv: %s\n", statstr); | | 785 | printf("crypto_recv: %s\n", statstr); |
785 | #endif | | 786 | #endif |
786 | break; | | 787 | break; |
787 | | | 788 | |
788 | /* | | 789 | /* |
789 | * Cookie request in symmetric modes. Roll a random | | 790 | * Cookie request in symmetric modes. Roll a random |
790 | * cookie and install in symmetric mode. Encrypt for the | | 791 | * cookie and install in symmetric mode. Encrypt for the |
791 | * response, which is transmitted later. | | 792 | * response, which is transmitted later. |
792 | */ | | 793 | */ |
793 | case CRYPTO_COOK: | | 794 | case CRYPTO_COOK: |
794 | | | 795 | |
795 | /* | | 796 | /* |
796 | * Discard the message if invalid or certificate | | 797 | * Discard the message if invalid or certificate |
797 | * trail not trusted. | | 798 | * trail not trusted. |
798 | */ | | 799 | */ |
799 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { | | 800 | if (!(peer->crypto & CRYPTO_FLAG_VALID)) { |
800 | rval = XEVNT_ERR; | | 801 | rval = XEVNT_ERR; |
801 | break; | | 802 | break; |
802 | } | | 803 | } |
803 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 804 | if ((rval = crypto_verify(ep, NULL, peer)) != |
804 | XEVNT_OK) | | 805 | XEVNT_OK) |
805 | break; | | 806 | break; |
806 | | | 807 | |
807 | /* | | 808 | /* |
808 | * Pass the extension field to the transmit | | 809 | * Pass the extension field to the transmit |
809 | * side. If already agreed, walk away. | | 810 | * side. If already agreed, walk away. |
810 | */ | | 811 | */ |
811 | fp = emalloc(len); | | 812 | fp = emalloc(len); |
812 | memcpy(fp, ep, len); | | 813 | memcpy(fp, ep, len); |
813 | temp32 = CRYPTO_RESP; | | 814 | temp32 = CRYPTO_RESP; |
814 | fp->opcode |= htonl(temp32); | | 815 | fp->opcode |= htonl(temp32); |
815 | peer->cmmd = fp; | | 816 | peer->cmmd = fp; |
816 | if (peer->crypto & CRYPTO_FLAG_AGREE) { | | 817 | if (peer->crypto & CRYPTO_FLAG_AGREE) { |
817 | peer->flash &= ~TEST8; | | 818 | peer->flash &= ~TEST8; |
818 | break; | | 819 | break; |
819 | } | | 820 | } |
820 | | | 821 | |
821 | /* | | 822 | /* |
822 | * Install cookie values and light the cookie | | 823 | * Install cookie values and light the cookie |
823 | * bit. The transmit side will pick up and | | 824 | * bit. The transmit side will pick up and |
824 | * encrypt it for the response. | | 825 | * encrypt it for the response. |
825 | */ | | 826 | */ |
826 | key_expire(peer); | | 827 | key_expire(peer); |
827 | peer->cookval.tstamp = ep->tstamp; | | 828 | peer->cookval.tstamp = ep->tstamp; |
828 | peer->cookval.fstamp = ep->fstamp; | | 829 | peer->cookval.fstamp = ep->fstamp; |
829 | RAND_bytes((u_char *)&peer->pcookie, 4); | | 830 | RAND_bytes((u_char *)&peer->pcookie, 4); |
830 | peer->crypto &= ~CRYPTO_FLAG_AUTO; | | 831 | peer->crypto &= ~CRYPTO_FLAG_AUTO; |
831 | peer->crypto |= CRYPTO_FLAG_AGREE; | | 832 | peer->crypto |= CRYPTO_FLAG_AGREE; |
832 | peer->flash &= ~TEST8; | | 833 | peer->flash &= ~TEST8; |
833 | sprintf(statstr, "cook %x ts %u fs %u", | | 834 | snprintf(statstr, NTP_MAXSTRLEN, "cook %x ts %u fs %u", |
834 | peer->pcookie, ntohl(ep->tstamp), | | 835 | peer->pcookie, ntohl(ep->tstamp), |
835 | ntohl(ep->fstamp)); | | 836 | ntohl(ep->fstamp)); |
836 | record_crypto_stats(&peer->srcadr, statstr); | | 837 | record_crypto_stats(&peer->srcadr, statstr); |
837 | #ifdef DEBUG | | 838 | #ifdef DEBUG |
838 | if (debug) | | 839 | if (debug) |
839 | printf("crypto_recv: %s\n", statstr); | | 840 | printf("crypto_recv: %s\n", statstr); |
840 | #endif | | 841 | #endif |
841 | break; | | 842 | break; |
842 | | | 843 | |
843 | /* | | 844 | /* |
844 | * Cookie response in client and symmetric modes. If the | | 845 | * Cookie response in client and symmetric modes. If the |
845 | * cookie bit is set, the working cookie is the EXOR of | | 846 | * cookie bit is set, the working cookie is the EXOR of |
846 | * the current and new values. | | 847 | * the current and new values. |
847 | */ | | 848 | */ |
848 | case CRYPTO_COOK | CRYPTO_RESP: | | 849 | case CRYPTO_COOK | CRYPTO_RESP: |
849 | | | 850 | |
850 | /* | | 851 | /* |
851 | * Discard the message if invalid or identity | | 852 | * Discard the message if invalid or identity |
852 | * not confirmed or signature not verified with | | 853 | * not confirmed or signature not verified with |
853 | * respect to the cookie values. | | 854 | * respect to the cookie values. |
854 | */ | | 855 | */ |
855 | if (!(peer->crypto & CRYPTO_FLAG_VRFY)) { | | 856 | if (!(peer->crypto & CRYPTO_FLAG_VRFY)) { |
856 | rval = XEVNT_ERR; | | 857 | rval = XEVNT_ERR; |
857 | break; | | 858 | break; |
858 | } | | 859 | } |
859 | if ((rval = crypto_verify(ep, &peer->cookval, | | 860 | if ((rval = crypto_verify(ep, &peer->cookval, |
860 | peer)) != XEVNT_OK) | | 861 | peer)) != XEVNT_OK) |
861 | break; | | 862 | break; |
862 | | | 863 | |
863 | /* | | 864 | /* |
864 | * Decrypt the cookie, hunting all the time for | | 865 | * Decrypt the cookie, hunting all the time for |
865 | * errors. | | 866 | * errors. |
866 | */ | | 867 | */ |
867 | if (vallen == (u_int) EVP_PKEY_size(host_pkey)) { | | 868 | if (vallen == (u_int) EVP_PKEY_size(host_pkey)) { |
868 | RSA_private_decrypt(vallen, | | 869 | RSA_private_decrypt(vallen, |
869 | (u_char *)ep->pkt, | | 870 | (u_char *)ep->pkt, |
870 | (u_char *)&temp32, | | 871 | (u_char *)&temp32, |
871 | host_pkey->pkey.rsa, | | 872 | host_pkey->pkey.rsa, |
872 | RSA_PKCS1_OAEP_PADDING); | | 873 | RSA_PKCS1_OAEP_PADDING); |
873 | cookie = ntohl(temp32); | | 874 | cookie = ntohl(temp32); |
874 | } else { | | 875 | } else { |
875 | rval = XEVNT_CKY; | | 876 | rval = XEVNT_CKY; |
876 | break; | | 877 | break; |
877 | } | | 878 | } |
878 | | | 879 | |
879 | /* | | 880 | /* |
880 | * Install cookie values and light the cookie | | 881 | * Install cookie values and light the cookie |
881 | * bit. If this is not broadcast client mode, we | | 882 | * bit. If this is not broadcast client mode, we |
882 | * are done here. | | 883 | * are done here. |
883 | */ | | 884 | */ |
884 | key_expire(peer); | | 885 | key_expire(peer); |
885 | peer->cookval.tstamp = ep->tstamp; | | 886 | peer->cookval.tstamp = ep->tstamp; |
886 | peer->cookval.fstamp = ep->fstamp; | | 887 | peer->cookval.fstamp = ep->fstamp; |
887 | if (peer->crypto & CRYPTO_FLAG_AGREE) | | 888 | if (peer->crypto & CRYPTO_FLAG_AGREE) |
888 | peer->pcookie ^= cookie; | | 889 | peer->pcookie ^= cookie; |
889 | else | | 890 | else |
890 | peer->pcookie = cookie; | | 891 | peer->pcookie = cookie; |
891 | if (peer->hmode == MODE_CLIENT && | | 892 | if (peer->hmode == MODE_CLIENT && |
892 | !(peer->cast_flags & MDF_BCLNT)) | | 893 | !(peer->cast_flags & MDF_BCLNT)) |
893 | peer->crypto |= CRYPTO_FLAG_AUTO; | | 894 | peer->crypto |= CRYPTO_FLAG_AUTO; |
894 | else | | 895 | else |
895 | peer->crypto &= ~CRYPTO_FLAG_AUTO; | | 896 | peer->crypto &= ~CRYPTO_FLAG_AUTO; |
896 | peer->crypto |= CRYPTO_FLAG_AGREE; | | 897 | peer->crypto |= CRYPTO_FLAG_AGREE; |
897 | peer->flash &= ~TEST8; | | 898 | peer->flash &= ~TEST8; |
898 | sprintf(statstr, "cook %x ts %u fs %u", | | 899 | snprintf(statstr, NTP_MAXSTRLEN, "cook %x ts %u fs %u", |
899 | peer->pcookie, ntohl(ep->tstamp), | | 900 | peer->pcookie, ntohl(ep->tstamp), |
900 | ntohl(ep->fstamp)); | | 901 | ntohl(ep->fstamp)); |
901 | record_crypto_stats(&peer->srcadr, statstr); | | 902 | record_crypto_stats(&peer->srcadr, statstr); |
902 | #ifdef DEBUG | | 903 | #ifdef DEBUG |
903 | if (debug) | | 904 | if (debug) |
904 | printf("crypto_recv: %s\n", statstr); | | 905 | printf("crypto_recv: %s\n", statstr); |
905 | #endif | | 906 | #endif |
906 | break; | | 907 | break; |
907 | | | 908 | |
908 | /* | | 909 | /* |
909 | * Install autokey values in broadcast client and | | 910 | * Install autokey values in broadcast client and |
910 | * symmetric modes. We have to do this every time the | | 911 | * symmetric modes. We have to do this every time the |
911 | * sever/peer cookie changes or a new keylist is | | 912 | * sever/peer cookie changes or a new keylist is |
912 | * rolled. Ordinarily, this is automatic as this message | | 913 | * rolled. Ordinarily, this is automatic as this message |
913 | * is piggybacked on the first NTP packet sent upon | | 914 | * is piggybacked on the first NTP packet sent upon |
914 | * either of these events. Note that a broadcast client | | 915 | * either of these events. Note that a broadcast client |
915 | * or symmetric peer can receive this response without a | | 916 | * or symmetric peer can receive this response without a |
916 | * matching request. | | 917 | * matching request. |
917 | */ | | 918 | */ |
918 | case CRYPTO_AUTO | CRYPTO_RESP: | | 919 | case CRYPTO_AUTO | CRYPTO_RESP: |
919 | | | 920 | |
920 | /* | | 921 | /* |
921 | * Discard the message if invalid or identity | | 922 | * Discard the message if invalid or identity |
922 | * not confirmed or signature not verified with | | 923 | * not confirmed or signature not verified with |
923 | * respect to the receive autokey values. | | 924 | * respect to the receive autokey values. |
924 | */ | | 925 | */ |
925 | if (!(peer->crypto & CRYPTO_FLAG_VRFY)) { | | 926 | if (!(peer->crypto & CRYPTO_FLAG_VRFY)) { |
926 | rval = XEVNT_ERR; | | 927 | rval = XEVNT_ERR; |
927 | break; | | 928 | break; |
928 | } | | 929 | } |
929 | if ((rval = crypto_verify(ep, &peer->recval, | | 930 | if ((rval = crypto_verify(ep, &peer->recval, |
930 | peer)) != XEVNT_OK) | | 931 | peer)) != XEVNT_OK) |
931 | break; | | 932 | break; |
932 | | | 933 | |
933 | /* | | 934 | /* |
934 | * Install autokey values and light the | | 935 | * Install autokey values and light the |
935 | * autokey bit. This is not hard. | | 936 | * autokey bit. This is not hard. |
936 | */ | | 937 | */ |
937 | if (peer->recval.ptr == NULL) | | 938 | if (peer->recval.ptr == NULL) |
938 | peer->recval.ptr = | | 939 | peer->recval.ptr = |
939 | emalloc(sizeof(struct autokey)); | | 940 | emalloc(sizeof(struct autokey)); |
940 | bp = (struct autokey *)peer->recval.ptr; | | 941 | bp = (struct autokey *)peer->recval.ptr; |
941 | peer->recval.tstamp = ep->tstamp; | | 942 | peer->recval.tstamp = ep->tstamp; |
942 | peer->recval.fstamp = ep->fstamp; | | 943 | peer->recval.fstamp = ep->fstamp; |
943 | ap = (struct autokey *)ep->pkt; | | 944 | ap = (struct autokey *)ep->pkt; |
944 | bp->seq = ntohl(ap->seq); | | 945 | bp->seq = ntohl(ap->seq); |
945 | bp->key = ntohl(ap->key); | | 946 | bp->key = ntohl(ap->key); |
946 | peer->pkeyid = bp->key; | | 947 | peer->pkeyid = bp->key; |
947 | peer->crypto |= CRYPTO_FLAG_AUTO; | | 948 | peer->crypto |= CRYPTO_FLAG_AUTO; |
948 | peer->flash &= ~TEST8; | | 949 | peer->flash &= ~TEST8; |
949 | sprintf(statstr, | | 950 | snprintf(statstr, NTP_MAXSTRLEN, |
950 | "auto seq %d key %x ts %u fs %u", bp->seq, | | 951 | "auto seq %d key %x ts %u fs %u", bp->seq, |
951 | bp->key, ntohl(ep->tstamp), | | 952 | bp->key, ntohl(ep->tstamp), |
952 | ntohl(ep->fstamp)); | | 953 | ntohl(ep->fstamp)); |
953 | record_crypto_stats(&peer->srcadr, statstr); | | 954 | record_crypto_stats(&peer->srcadr, statstr); |
954 | #ifdef DEBUG | | 955 | #ifdef DEBUG |
955 | if (debug) | | 956 | if (debug) |
956 | printf("crypto_recv: %s\n", statstr); | | 957 | printf("crypto_recv: %s\n", statstr); |
957 | #endif | | 958 | #endif |
958 | break; | | 959 | break; |
959 | | | 960 | |
960 | /* | | 961 | /* |
961 | * X509 certificate sign response. Validate the | | 962 | * X509 certificate sign response. Validate the |
962 | * certificate signed by the server and install. Later | | 963 | * certificate signed by the server and install. Later |
963 | * this can be provided to clients of this server in | | 964 | * this can be provided to clients of this server in |
964 | * lieu of the self signed certificate in order to | | 965 | * lieu of the self signed certificate in order to |
965 | * validate the public key. | | 966 | * validate the public key. |
966 | */ | | 967 | */ |
967 | case CRYPTO_SIGN | CRYPTO_RESP: | | 968 | case CRYPTO_SIGN | CRYPTO_RESP: |
968 | | | 969 | |
969 | /* | | 970 | /* |
970 | * Discard the message if invalid or not | | 971 | * Discard the message if invalid or not |
971 | * proventic. | | 972 | * proventic. |
972 | */ | | 973 | */ |
973 | if (!(peer->crypto & CRYPTO_FLAG_PROV)) { | | 974 | if (!(peer->crypto & CRYPTO_FLAG_PROV)) { |
974 | rval = XEVNT_ERR; | | 975 | rval = XEVNT_ERR; |
975 | break; | | 976 | break; |
976 | } | | 977 | } |
977 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 978 | if ((rval = crypto_verify(ep, NULL, peer)) != |
978 | XEVNT_OK) | | 979 | XEVNT_OK) |
979 | break; | | 980 | break; |
980 | | | 981 | |
981 | /* | | 982 | /* |
982 | * Scan the certificate list to delete old | | 983 | * Scan the certificate list to delete old |
983 | * versions and link the newest version first on | | 984 | * versions and link the newest version first on |
984 | * the list. | | 985 | * the list. |
985 | */ | | 986 | */ |
986 | if ((rval = cert_install(ep, peer)) != XEVNT_OK) | | 987 | if ((rval = cert_install(ep, peer)) != XEVNT_OK) |
987 | break; | | 988 | break; |
988 | | | 989 | |
989 | peer->crypto |= CRYPTO_FLAG_SIGN; | | 990 | peer->crypto |= CRYPTO_FLAG_SIGN; |
990 | peer->flash &= ~TEST8; | | 991 | peer->flash &= ~TEST8; |
991 | temp32 = cinfo->nid; | | 992 | temp32 = cinfo->nid; |
992 | sprintf(statstr, "sign %s 0x%x %s (%u) fs %u", | | 993 | snprintf(statstr, NTP_MAXSTRLEN, |
| | | 994 | "sign %s 0x%x %s (%u) fs %u", |
993 | cinfo->issuer, cinfo->flags, | | 995 | cinfo->issuer, cinfo->flags, |
994 | OBJ_nid2ln(temp32), temp32, | | 996 | OBJ_nid2ln(temp32), temp32, |
995 | ntohl(ep->fstamp)); | | 997 | ntohl(ep->fstamp)); |
996 | record_crypto_stats(&peer->srcadr, statstr); | | 998 | record_crypto_stats(&peer->srcadr, statstr); |
997 | #ifdef DEBUG | | 999 | #ifdef DEBUG |
998 | if (debug) | | 1000 | if (debug) |
999 | printf("crypto_recv: %s\n", statstr); | | 1001 | printf("crypto_recv: %s\n", statstr); |
1000 | #endif | | 1002 | #endif |
1001 | break; | | 1003 | break; |
1002 | | | 1004 | |
1003 | /* | | 1005 | /* |
1004 | * Install leapseconds table in symmetric modes. This | | 1006 | * Install leapseconds table in symmetric modes. This |
1005 | * table is proventicated to the NIST primary servers, | | 1007 | * table is proventicated to the NIST primary servers, |
1006 | * either by copying the file containing the table from | | 1008 | * either by copying the file containing the table from |
1007 | * a NIST server to a trusted server or directly using | | 1009 | * a NIST server to a trusted server or directly using |
1008 | * this protocol. While the entire table is installed at | | 1010 | * this protocol. While the entire table is installed at |
1009 | * the server, presently only the current TAI offset is | | 1011 | * the server, presently only the current TAI offset is |
1010 | * provided via the kernel to other applications. | | 1012 | * provided via the kernel to other applications. |
1011 | */ | | 1013 | */ |
1012 | case CRYPTO_TAI: | | 1014 | case CRYPTO_TAI: |
1013 | | | 1015 | |
1014 | /* | | 1016 | /* |
1015 | * Discard the message if invalid. | | 1017 | * Discard the message if invalid. |
1016 | */ | | 1018 | */ |
1017 | if ((rval = crypto_verify(ep, NULL, peer)) != | | 1019 | if ((rval = crypto_verify(ep, NULL, peer)) != |
1018 | XEVNT_OK) | | 1020 | XEVNT_OK) |
1019 | break; | | 1021 | break; |
1020 | | | 1022 | |
1021 | /* | | 1023 | /* |
1022 | * Pass the extension field to the transmit | | 1024 | * Pass the extension field to the transmit |
1023 | * side. Continue below if a leapseconds table | | 1025 | * side. Continue below if a leapseconds table |
1024 | * accompanies the message. | | 1026 | * accompanies the message. |
1025 | */ | | 1027 | */ |
1026 | fp = emalloc(len); | | 1028 | fp = emalloc(len); |
1027 | memcpy(fp, ep, len); | | 1029 | memcpy(fp, ep, len); |
1028 | temp32 = CRYPTO_RESP; | | 1030 | temp32 = CRYPTO_RESP; |
1029 | fp->opcode |= htonl(temp32); | | 1031 | fp->opcode |= htonl(temp32); |
1030 | peer->cmmd = fp; | | 1032 | peer->cmmd = fp; |
1031 | if (len <= VALUE_LEN) { | | 1033 | if (len <= VALUE_LEN) { |
1032 | peer->flash &= ~TEST8; | | 1034 | peer->flash &= ~TEST8; |
1033 | break; | | 1035 | break; |
1034 | } | | 1036 | } |
1035 | /* fall through */ | | 1037 | /* fall through */ |
1036 | | | 1038 | |
1037 | case CRYPTO_TAI | CRYPTO_RESP: | | 1039 | case CRYPTO_TAI | CRYPTO_RESP: |
1038 | | | 1040 | |
1039 | /* | | 1041 | /* |
1040 | * If this is a response, discard the message if | | 1042 | * If this is a response, discard the message if |
1041 | * signature not verified with respect to the | | 1043 | * signature not verified with respect to the |
1042 | * leapsecond table values. | | 1044 | * leapsecond table values. |
1043 | */ | | 1045 | */ |
1044 | if (peer->cmmd == NULL) { | | 1046 | if (peer->cmmd == NULL) { |
1045 | if ((rval = crypto_verify(ep, | | 1047 | if ((rval = crypto_verify(ep, |
1046 | &peer->tai_leap, peer)) != XEVNT_OK) | | 1048 | &peer->tai_leap, peer)) != XEVNT_OK) |
1047 | break; | | 1049 | break; |
1048 | } | | 1050 | } |
1049 | | | 1051 | |
1050 | /* | | 1052 | /* |
1051 | * Initialize peer variables with latest update. | | 1053 | * Initialize peer variables with latest update. |
1052 | */ | | 1054 | */ |
1053 | peer->tai_leap.tstamp = ep->tstamp; | | 1055 | peer->tai_leap.tstamp = ep->tstamp; |
1054 | peer->tai_leap.fstamp = ep->fstamp; | | 1056 | peer->tai_leap.fstamp = ep->fstamp; |
1055 | peer->tai_leap.vallen = ep->vallen; | | 1057 | peer->tai_leap.vallen = ep->vallen; |
1056 | | | 1058 | |
1057 | /* | | 1059 | /* |
1058 | * Install the new table if there is no stored | | 1060 | * Install the new table if there is no stored |
1059 | * table or the new table is more recent than | | 1061 | * table or the new table is more recent than |
1060 | * the stored table. Since a filestamp may have | | 1062 | * the stored table. Since a filestamp may have |
1061 | * changed, recompute the signatures. | | 1063 | * changed, recompute the signatures. |
1062 | */ | | 1064 | */ |
1063 | if (ntohl(peer->tai_leap.fstamp) > | | 1065 | if (ntohl(peer->tai_leap.fstamp) > |
1064 | ntohl(tai_leap.fstamp)) { | | 1066 | ntohl(tai_leap.fstamp)) { |
1065 | tai_leap.fstamp = ep->fstamp; | | 1067 | tai_leap.fstamp = ep->fstamp; |
1066 | tai_leap.vallen = ep->vallen; | | 1068 | tai_leap.vallen = ep->vallen; |
1067 | if (tai_leap.ptr != NULL) | | 1069 | if (tai_leap.ptr != NULL) |
1068 | free(tai_leap.ptr); | | 1070 | free(tai_leap.ptr); |
1069 | tai_leap.ptr = emalloc(vallen); | | 1071 | tai_leap.ptr = emalloc(vallen); |
1070 | memcpy(tai_leap.ptr, ep->pkt, vallen); | | 1072 | memcpy(tai_leap.ptr, ep->pkt, vallen); |
1071 | crypto_update(); | | 1073 | crypto_update(); |
1072 | } | | 1074 | } |
1073 | crypto_flags |= CRYPTO_FLAG_TAI; | | 1075 | crypto_flags |= CRYPTO_FLAG_TAI; |
1074 | peer->crypto |= CRYPTO_FLAG_LEAP; | | 1076 | peer->crypto |= CRYPTO_FLAG_LEAP; |
1075 | peer->flash &= ~TEST8; | | 1077 | peer->flash &= ~TEST8; |
1076 | sprintf(statstr, "leap %u ts %u fs %u", vallen, | | 1078 | snprintf(statstr, NTP_MAXSTRLEN, |
| | | 1079 | "leap %u ts %u fs %u", vallen, |
1077 | ntohl(ep->tstamp), ntohl(ep->fstamp)); | | 1080 | ntohl(ep->tstamp), ntohl(ep->fstamp)); |
1078 | record_crypto_stats(&peer->srcadr, statstr); | | 1081 | record_crypto_stats(&peer->srcadr, statstr); |
1079 | #ifdef DEBUG | | 1082 | #ifdef DEBUG |
1080 | if (debug) | | 1083 | if (debug) |
1081 | printf("crypto_recv: %s\n", statstr); | | 1084 | printf("crypto_recv: %s\n", statstr); |
1082 | #endif | | 1085 | #endif |
1083 | break; | | 1086 | break; |
1084 | | | 1087 | |
1085 | /* | | 1088 | /* |
1086 | * We come here in symmetric modes for miscellaneous | | 1089 | * We come here in symmetric modes for miscellaneous |
1087 | * commands that have value fields but are processed on | | 1090 | * commands that have value fields but are processed on |
1088 | * the transmit side. All we need do here is check for | | 1091 | * the transmit side. All we need do here is check for |
1089 | * valid field length. Remaining checks are below and on | | 1092 | * valid field length. Remaining checks are below and on |
1090 | * the transmit side. | | 1093 | * the transmit side. |
1091 | */ | | 1094 | */ |
1092 | case CRYPTO_CERT: | | 1095 | case CRYPTO_CERT: |
1093 | case CRYPTO_IFF: | | 1096 | case CRYPTO_IFF: |
1094 | case CRYPTO_GQ: | | 1097 | case CRYPTO_GQ: |
1095 | case CRYPTO_MV: | | 1098 | case CRYPTO_MV: |
1096 | case CRYPTO_SIGN: | | 1099 | case CRYPTO_SIGN: |
1097 | if (len < VALUE_LEN) { | | 1100 | if (len < VALUE_LEN) { |
1098 | rval = XEVNT_LEN; | | 1101 | rval = XEVNT_LEN; |
1099 | break; | | 1102 | break; |
1100 | } | | 1103 | } |
1101 | /* fall through */ | | 1104 | /* fall through */ |
1102 | | | 1105 | |
1103 | /* | | 1106 | /* |
1104 | * We come here for miscellaneous requests and unknown | | 1107 | * We come here for miscellaneous requests and unknown |
1105 | * requests and responses. If an unknown response or | | 1108 | * requests and responses. If an unknown response or |
1106 | * error, forget it. If a request, save the extension | | 1109 | * error, forget it. If a request, save the extension |
1107 | * field for later. Unknown requests will be caught on | | 1110 | * field for later. Unknown requests will be caught on |
1108 | * the transmit side. | | 1111 | * the transmit side. |
1109 | */ | | 1112 | */ |
1110 | default: | | 1113 | default: |
1111 | if (code & (CRYPTO_RESP | CRYPTO_ERROR)) { | | 1114 | if (code & (CRYPTO_RESP | CRYPTO_ERROR)) { |
1112 | rval = XEVNT_ERR; | | 1115 | rval = XEVNT_ERR; |
1113 | } else if ((rval = crypto_verify(ep, NULL, | | 1116 | } else if ((rval = crypto_verify(ep, NULL, |
1114 | peer)) == XEVNT_OK) { | | 1117 | peer)) == XEVNT_OK) { |
1115 | fp = emalloc(len); | | 1118 | fp = emalloc(len); |
1116 | memcpy(fp, ep, len); | | 1119 | memcpy(fp, ep, len); |
1117 | temp32 = CRYPTO_RESP; | | 1120 | temp32 = CRYPTO_RESP; |
1118 | fp->opcode |= htonl(temp32); | | 1121 | fp->opcode |= htonl(temp32); |
1119 | peer->cmmd = fp; | | 1122 | peer->cmmd = fp; |
1120 | } | | 1123 | } |
1121 | } | | 1124 | } |
1122 | | | 1125 | |
1123 | /* | | 1126 | /* |
1124 | * We don't log length/format/timestamp errors and | | 1127 | * We don't log length/format/timestamp errors and |
1125 | * duplicates, which are log clogging vulnerabilities. | | 1128 | * duplicates, which are log clogging vulnerabilities. |
1126 | * The first error found terminates the extension field | | 1129 | * The first error found terminates the extension field |
1127 | * scan and we return the laundry to the caller. A | | 1130 | * scan and we return the laundry to the caller. A |
1128 | * length/format/timestamp error on transmit is | | 1131 | * length/format/timestamp error on transmit is |
1129 | * cheerfully ignored, as the message is not sent. | | 1132 | * cheerfully ignored, as the message is not sent. |
1130 | */ | | 1133 | */ |
1131 | if (rval > XEVNT_TSP) { | | 1134 | if (rval > XEVNT_TSP) { |
1132 | sprintf(statstr, | | 1135 | snprintf(statstr, NTP_MAXSTRLEN, |
1133 | "error %x opcode %x ts %u fs %u", rval, | | 1136 | "error %x opcode %x ts %u fs %u", rval, |
1134 | code, tstamp, fstamp); | | 1137 | code, tstamp, fstamp); |
1135 | record_crypto_stats(&peer->srcadr, statstr); | | 1138 | record_crypto_stats(&peer->srcadr, statstr); |
1136 | report_event(rval, peer); | | 1139 | report_event(rval, peer); |
1137 | #ifdef DEBUG | | 1140 | #ifdef DEBUG |
1138 | if (debug) | | 1141 | if (debug) |
1139 | printf("crypto_recv: %s\n", statstr); | | 1142 | printf("crypto_recv: %s\n", statstr); |
1140 | #endif | | 1143 | #endif |
1141 | break; | | 1144 | break; |
1142 | | | 1145 | |
1143 | } else if (rval > XEVNT_OK && (code & CRYPTO_RESP)) { | | 1146 | } else if (rval > XEVNT_OK && (code & CRYPTO_RESP)) { |
1144 | rval = XEVNT_OK; | | 1147 | rval = XEVNT_OK; |
1145 | } | | 1148 | } |
1146 | authlen += len; | | 1149 | authlen += len; |
1147 | } | | 1150 | } |
1148 | return (rval); | | 1151 | return (rval); |
1149 | } | | 1152 | } |
1150 | | | 1153 | |
1151 | | | 1154 | |
1152 | /* | | 1155 | /* |
1153 | * crypto_xmit - construct extension fields | | 1156 | * crypto_xmit - construct extension fields |
1154 | * | | 1157 | * |
1155 | * This routine is called both when an association is configured and | | 1158 | * This routine is called both when an association is configured and |
1156 | * when one is not. The only case where this matters is to retrieve the | | 1159 | * when one is not. The only case where this matters is to retrieve the |
1157 | * autokey information, in which case the caller has to provide the | | 1160 | * autokey information, in which case the caller has to provide the |
1158 | * association ID to match the association. | | 1161 | * association ID to match the association. |
1159 | * | | 1162 | * |
1160 | * Returns length of extension field. | | 1163 | * Returns length of extension field. |
1161 | */ | | 1164 | */ |
1162 | int | | 1165 | int |
1163 | crypto_xmit( | | 1166 | crypto_xmit( |
1164 | struct pkt *xpkt, /* transmit packet pointer */ | | 1167 | struct pkt *xpkt, /* transmit packet pointer */ |
1165 | struct sockaddr_storage *srcadr_sin, /* active runway */ | | 1168 | struct sockaddr_storage *srcadr_sin, /* active runway */ |
1166 | int start, /* offset to extension field */ | | 1169 | int start, /* offset to extension field */ |
1167 | struct exten *ep, /* extension pointer */ | | 1170 | struct exten *ep, /* extension pointer */ |
1168 | keyid_t cookie /* session cookie */ | | 1171 | keyid_t cookie /* session cookie */ |
1169 | ) | | 1172 | ) |
1170 | { | | 1173 | { |
1171 | u_int32 *pkt; /* packet pointer */ | | 1174 | u_int32 *pkt; /* packet pointer */ |
1172 | struct peer *peer; /* peer structure pointer */ | | 1175 | struct peer *peer; /* peer structure pointer */ |
1173 | u_int opcode; /* extension field opcode */ | | 1176 | u_int opcode; /* extension field opcode */ |
1174 | struct exten *fp; /* extension pointers */ | | 1177 | struct exten *fp; /* extension pointers */ |
1175 | struct cert_info *cp, *xp; /* certificate info/value pointer */ | | 1178 | struct cert_info *cp, *xp; /* certificate info/value pointer */ |
1176 | char certname[MAXHOSTNAME + 1]; /* subject name buffer */ | | 1179 | char certname[MAXHOSTNAME + 1]; /* subject name buffer */ |
1177 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 1180 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
1178 | tstamp_t tstamp; | | 1181 | tstamp_t tstamp; |
1179 | u_int vallen; | | 1182 | u_int vallen; |
1180 | u_int len; | | 1183 | u_int len; |
1181 | struct value vtemp; | | 1184 | struct value vtemp; |
1182 | associd_t associd; | | 1185 | associd_t associd; |
1183 | int rval; | | 1186 | int rval; |
1184 | keyid_t tcookie; | | 1187 | keyid_t tcookie; |
1185 | | | 1188 | |
1186 | /* | | 1189 | /* |
1187 | * Generate the requested extension field request code, length | | 1190 | * Generate the requested extension field request code, length |
1188 | * and association ID. If this is a response and the host is not | | 1191 | * and association ID. If this is a response and the host is not |
1189 | * synchronized, light the error bit and go home. | | 1192 | * synchronized, light the error bit and go home. |
1190 | */ | | 1193 | */ |
1191 | pkt = (u_int32 *)xpkt + start / 4; | | 1194 | pkt = (u_int32 *)xpkt + start / 4; |
1192 | fp = (struct exten *)pkt; | | 1195 | fp = (struct exten *)pkt; |
1193 | opcode = ntohl(ep->opcode); | | 1196 | opcode = ntohl(ep->opcode); |
1194 | associd = (associd_t) ntohl(ep->associd); | | 1197 | associd = (associd_t) ntohl(ep->associd); |
1195 | fp->associd = htonl(associd); | | 1198 | fp->associd = htonl(associd); |
1196 | len = 8; | | 1199 | len = 8; |
1197 | rval = XEVNT_OK; | | 1200 | rval = XEVNT_OK; |
1198 | tstamp = crypto_time(); | | 1201 | tstamp = crypto_time(); |
1199 | switch (opcode & 0xffff0000) { | | 1202 | switch (opcode & 0xffff0000) { |
1200 | | | 1203 | |
1201 | /* | | 1204 | /* |
1202 | * Send association request and response with status word and | | 1205 | * Send association request and response with status word and |
1203 | * host name. Note, this message is not signed and the filestamp | | 1206 | * host name. Note, this message is not signed and the filestamp |
1204 | * contains only the status word. | | 1207 | * contains only the status word. |
1205 | */ | | 1208 | */ |
1206 | case CRYPTO_ASSOC | CRYPTO_RESP: | | 1209 | case CRYPTO_ASSOC | CRYPTO_RESP: |
1207 | len += crypto_send(fp, &hostval); | | 1210 | len += crypto_send(fp, &hostval); |
1208 | fp->fstamp = htonl(crypto_flags); | | 1211 | fp->fstamp = htonl(crypto_flags); |
1209 | break; | | 1212 | break; |
1210 | | | 1213 | |
1211 | case CRYPTO_ASSOC: | | 1214 | case CRYPTO_ASSOC: |
1212 | len += crypto_send(fp, &hostval); | | 1215 | len += crypto_send(fp, &hostval); |
1213 | fp->fstamp = htonl(crypto_flags | ident_scheme); | | 1216 | fp->fstamp = htonl(crypto_flags | ident_scheme); |
1214 | break; | | 1217 | break; |
1215 | | | 1218 | |
1216 | /* | | 1219 | /* |
1217 | * Send certificate request. Use the values from the extension | | 1220 | * Send certificate request. Use the values from the extension |
1218 | * field. | | 1221 | * field. |
1219 | */ | | 1222 | */ |
1220 | case CRYPTO_CERT: | | 1223 | case CRYPTO_CERT: |
1221 | memset(&vtemp, 0, sizeof(vtemp)); | | 1224 | memset(&vtemp, 0, sizeof(vtemp)); |
1222 | vtemp.tstamp = ep->tstamp; | | 1225 | vtemp.tstamp = ep->tstamp; |
1223 | vtemp.fstamp = ep->fstamp; | | 1226 | vtemp.fstamp = ep->fstamp; |
1224 | vtemp.vallen = ep->vallen; | | 1227 | vtemp.vallen = ep->vallen; |
1225 | vtemp.ptr = (u_char *)ep->pkt; | | 1228 | vtemp.ptr = (u_char *)ep->pkt; |
1226 | len += crypto_send(fp, &vtemp); | | 1229 | len += crypto_send(fp, &vtemp); |
1227 | break; | | 1230 | break; |
1228 | | | 1231 | |
1229 | /* | | 1232 | /* |
1230 | * Send certificate response or sign request. Use the values | | 1233 | * Send certificate response or sign request. Use the values |
1231 | * from the certificate cache. If the request contains no | | 1234 | * from the certificate cache. If the request contains no |
1232 | * subject name, assume the name of this host. This is for | | 1235 | * subject name, assume the name of this host. This is for |
1233 | * backwards compatibility. Private certificates are never sent. | | 1236 | * backwards compatibility. Private certificates are never sent. |
1234 | */ | | 1237 | */ |
1235 | case CRYPTO_SIGN: | | 1238 | case CRYPTO_SIGN: |
1236 | case CRYPTO_CERT | CRYPTO_RESP: | | 1239 | case CRYPTO_CERT | CRYPTO_RESP: |
1237 | vallen = ntohl(ep->vallen); | | 1240 | vallen = ntohl(ep->vallen); |
1238 | if (vallen == 8) { | | 1241 | if (vallen == 8) { |
1239 | strcpy(certname, sys_hostname); | | 1242 | strcpy(certname, sys_hostname); |
1240 | } else if (vallen == 0 || vallen > MAXHOSTNAME) { | | 1243 | } else if (vallen == 0 || vallen > MAXHOSTNAME) { |
1241 | rval = XEVNT_LEN; | | 1244 | rval = XEVNT_LEN; |
1242 | break; | | 1245 | break; |
1243 | | | 1246 | |
1244 | } else { | | 1247 | } else { |
1245 | memcpy(certname, ep->pkt, vallen); | | 1248 | memcpy(certname, ep->pkt, vallen); |
1246 | certname[vallen] = '\0'; | | 1249 | certname[vallen] = '\0'; |
1247 | } | | 1250 | } |
1248 | | | 1251 | |
1249 | /* | | 1252 | /* |
1250 | * Find all certificates with matching subject. If a | | 1253 | * Find all certificates with matching subject. If a |
1251 | * self-signed, trusted certificate is found, use that. | | 1254 | * self-signed, trusted certificate is found, use that. |
1252 | * If not, use the first one with matching subject. A | | 1255 | * If not, use the first one with matching subject. A |
1253 | * private certificate is never divulged or signed. | | 1256 | * private certificate is never divulged or signed. |
1254 | */ | | 1257 | */ |
1255 | xp = NULL; | | 1258 | xp = NULL; |
1256 | for (cp = cinfo; cp != NULL; cp = cp->link) { | | 1259 | for (cp = cinfo; cp != NULL; cp = cp->link) { |
1257 | if (cp->flags & CERT_PRIV) | | 1260 | if (cp->flags & CERT_PRIV) |
1258 | continue; | | 1261 | continue; |
1259 | | | 1262 | |
1260 | if (strcmp(certname, cp->subject) == 0) { | | 1263 | if (strcmp(certname, cp->subject) == 0) { |
1261 | if (xp == NULL) | | 1264 | if (xp == NULL) |
1262 | xp = cp; | | 1265 | xp = cp; |
1263 | if (strcmp(certname, cp->issuer) == | | 1266 | if (strcmp(certname, cp->issuer) == |
1264 | 0 && cp->flags & CERT_TRUST) { | | 1267 | 0 && cp->flags & CERT_TRUST) { |
1265 | xp = cp; | | 1268 | xp = cp; |
1266 | break; | | 1269 | break; |
1267 | } | | 1270 | } |
1268 | } | | 1271 | } |
1269 | } | | 1272 | } |
1270 | | | 1273 | |
1271 | /* | | 1274 | /* |
1272 | * Be careful who you trust. If not yet synchronized, | | 1275 | * Be careful who you trust. If not yet synchronized, |
1273 | * give back an empty response. If certificate not found | | 1276 | * give back an empty response. If certificate not found |
1274 | * or beyond the lifetime, return an error. This is to | | 1277 | * or beyond the lifetime, return an error. This is to |
1275 | * avoid a bad dude trying to get an expired certificate | | 1278 | * avoid a bad dude trying to get an expired certificate |
1276 | * re-signed. Otherwise, send it. | | 1279 | * re-signed. Otherwise, send it. |
1277 | * | | 1280 | * |
1278 | * Note the timestamp and filestamp are taken from the | | 1281 | * Note the timestamp and filestamp are taken from the |
1279 | * certificate value structure. For all certificates the | | 1282 | * certificate value structure. For all certificates the |
1280 | * timestamp is the latest signature update time. For | | 1283 | * timestamp is the latest signature update time. For |
1281 | * host and imported certificates the filestamp is the | | 1284 | * host and imported certificates the filestamp is the |
1282 | * creation epoch. For signed certificates the filestamp | | 1285 | * creation epoch. For signed certificates the filestamp |
1283 | * is the creation epoch of the trusted certificate at | | 1286 | * is the creation epoch of the trusted certificate at |
1284 | * the base of the certificate trail. In principle, this | | 1287 | * the base of the certificate trail. In principle, this |
1285 | * allows strong checking for signature masquerade. | | 1288 | * allows strong checking for signature masquerade. |
1286 | */ | | 1289 | */ |
1287 | if (tstamp == 0) | | 1290 | if (tstamp == 0) |
1288 | break; | | 1291 | break; |
1289 | | | 1292 | |
1290 | if (xp == NULL) | | 1293 | if (xp == NULL) |
1291 | rval = XEVNT_CRT; | | 1294 | rval = XEVNT_CRT; |
1292 | else if (tstamp < xp->first || tstamp > xp->last) | | 1295 | else if (tstamp < xp->first || tstamp > xp->last) |
1293 | rval = XEVNT_SRV; | | 1296 | rval = XEVNT_SRV; |
1294 | else | | 1297 | else |
1295 | len += crypto_send(fp, &xp->cert); | | 1298 | len += crypto_send(fp, &xp->cert); |
1296 | break; | | 1299 | break; |
1297 | | | 1300 | |
1298 | /* | | 1301 | /* |
1299 | * Send challenge in Schnorr (IFF) identity scheme. | | 1302 | * Send challenge in Schnorr (IFF) identity scheme. |
1300 | */ | | 1303 | */ |
1301 | case CRYPTO_IFF: | | 1304 | case CRYPTO_IFF: |
1302 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { | | 1305 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { |
1303 | rval = XEVNT_ERR; | | 1306 | rval = XEVNT_ERR; |
1304 | break; | | 1307 | break; |
1305 | } | | 1308 | } |
1306 | if ((rval = crypto_alice(peer, &vtemp)) == XEVNT_OK) { | | 1309 | if ((rval = crypto_alice(peer, &vtemp)) == XEVNT_OK) { |
1307 | len += crypto_send(fp, &vtemp); | | 1310 | len += crypto_send(fp, &vtemp); |
1308 | value_free(&vtemp); | | 1311 | value_free(&vtemp); |
1309 | } | | 1312 | } |
1310 | break; | | 1313 | break; |
1311 | | | 1314 | |
1312 | /* | | 1315 | /* |
1313 | * Send response in Schnorr (IFF) identity scheme. | | 1316 | * Send response in Schnorr (IFF) identity scheme. |
1314 | */ | | 1317 | */ |
1315 | case CRYPTO_IFF | CRYPTO_RESP: | | 1318 | case CRYPTO_IFF | CRYPTO_RESP: |
1316 | if ((rval = crypto_bob(ep, &vtemp)) == XEVNT_OK) { | | 1319 | if ((rval = crypto_bob(ep, &vtemp)) == XEVNT_OK) { |
1317 | len += crypto_send(fp, &vtemp); | | 1320 | len += crypto_send(fp, &vtemp); |
1318 | value_free(&vtemp); | | 1321 | value_free(&vtemp); |
1319 | } | | 1322 | } |
1320 | break; | | 1323 | break; |
1321 | | | 1324 | |
1322 | /* | | 1325 | /* |
1323 | * Send challenge in Guillou-Quisquater (GQ) identity scheme. | | 1326 | * Send challenge in Guillou-Quisquater (GQ) identity scheme. |
1324 | */ | | 1327 | */ |
1325 | case CRYPTO_GQ: | | 1328 | case CRYPTO_GQ: |
1326 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { | | 1329 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { |
1327 | rval = XEVNT_ERR; | | 1330 | rval = XEVNT_ERR; |
1328 | break; | | 1331 | break; |
1329 | } | | 1332 | } |
1330 | if ((rval = crypto_alice2(peer, &vtemp)) == XEVNT_OK) { | | 1333 | if ((rval = crypto_alice2(peer, &vtemp)) == XEVNT_OK) { |
1331 | len += crypto_send(fp, &vtemp); | | 1334 | len += crypto_send(fp, &vtemp); |
1332 | value_free(&vtemp); | | 1335 | value_free(&vtemp); |
1333 | } | | 1336 | } |
1334 | break; | | 1337 | break; |
1335 | | | 1338 | |
1336 | /* | | 1339 | /* |
1337 | * Send response in Guillou-Quisquater (GQ) identity scheme. | | 1340 | * Send response in Guillou-Quisquater (GQ) identity scheme. |
1338 | */ | | 1341 | */ |
1339 | case CRYPTO_GQ | CRYPTO_RESP: | | 1342 | case CRYPTO_GQ | CRYPTO_RESP: |
1340 | if ((rval = crypto_bob2(ep, &vtemp)) == XEVNT_OK) { | | 1343 | if ((rval = crypto_bob2(ep, &vtemp)) == XEVNT_OK) { |
1341 | len += crypto_send(fp, &vtemp); | | 1344 | len += crypto_send(fp, &vtemp); |
1342 | value_free(&vtemp); | | 1345 | value_free(&vtemp); |
1343 | } | | 1346 | } |
1344 | break; | | 1347 | break; |
1345 | | | 1348 | |
1346 | /* | | 1349 | /* |
1347 | * Send challenge in MV identity scheme. | | 1350 | * Send challenge in MV identity scheme. |
1348 | */ | | 1351 | */ |
1349 | case CRYPTO_MV: | | 1352 | case CRYPTO_MV: |
1350 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { | | 1353 | if ((peer = findpeerbyassoc(ep->pkt[0])) == NULL) { |
1351 | rval = XEVNT_ERR; | | 1354 | rval = XEVNT_ERR; |
1352 | break; | | 1355 | break; |
1353 | } | | 1356 | } |
1354 | if ((rval = crypto_alice3(peer, &vtemp)) == XEVNT_OK) { | | 1357 | if ((rval = crypto_alice3(peer, &vtemp)) == XEVNT_OK) { |
1355 | len += crypto_send(fp, &vtemp); | | 1358 | len += crypto_send(fp, &vtemp); |
1356 | value_free(&vtemp); | | 1359 | value_free(&vtemp); |
1357 | } | | 1360 | } |
1358 | break; | | 1361 | break; |
1359 | | | 1362 | |
1360 | /* | | 1363 | /* |
1361 | * Send response in MV identity scheme. | | 1364 | * Send response in MV identity scheme. |
1362 | */ | | 1365 | */ |
1363 | case CRYPTO_MV | CRYPTO_RESP: | | 1366 | case CRYPTO_MV | CRYPTO_RESP: |
1364 | if ((rval = crypto_bob3(ep, &vtemp)) == XEVNT_OK) { | | 1367 | if ((rval = crypto_bob3(ep, &vtemp)) == XEVNT_OK) { |
1365 | len += crypto_send(fp, &vtemp); | | 1368 | len += crypto_send(fp, &vtemp); |
1366 | value_free(&vtemp); | | 1369 | value_free(&vtemp); |
1367 | } | | 1370 | } |
1368 | break; | | 1371 | break; |
1369 | | | 1372 | |
1370 | /* | | 1373 | /* |
1371 | * Send certificate sign response. The integrity of the request | | 1374 | * Send certificate sign response. The integrity of the request |
1372 | * certificate has already been verified on the receive side. | | 1375 | * certificate has already been verified on the receive side. |
1373 | * Sign the response using the local server key. Use the | | 1376 | * Sign the response using the local server key. Use the |
1374 | * filestamp from the request and use the timestamp as the | | 1377 | * filestamp from the request and use the timestamp as the |
1375 | * current time. Light the error bit if the certificate is | | 1378 | * current time. Light the error bit if the certificate is |
1376 | * invalid or contains an unverified signature. | | 1379 | * invalid or contains an unverified signature. |
1377 | */ | | 1380 | */ |
1378 | case CRYPTO_SIGN | CRYPTO_RESP: | | 1381 | case CRYPTO_SIGN | CRYPTO_RESP: |
1379 | if ((rval = cert_sign(ep, &vtemp)) == XEVNT_OK) | | 1382 | if ((rval = cert_sign(ep, &vtemp)) == XEVNT_OK) |
1380 | len += crypto_send(fp, &vtemp); | | 1383 | len += crypto_send(fp, &vtemp); |
1381 | value_free(&vtemp); | | 1384 | value_free(&vtemp); |
1382 | break; | | 1385 | break; |
1383 | | | 1386 | |
1384 | /* | | 1387 | /* |
1385 | * Send public key and signature. Use the values from the public | | 1388 | * Send public key and signature. Use the values from the public |
1386 | * key. | | 1389 | * key. |
1387 | */ | | 1390 | */ |
1388 | case CRYPTO_COOK: | | 1391 | case CRYPTO_COOK: |
1389 | len += crypto_send(fp, &pubkey); | | 1392 | len += crypto_send(fp, &pubkey); |
1390 | break; | | 1393 | break; |
1391 | | | 1394 | |
1392 | /* | | 1395 | /* |
1393 | * Encrypt and send cookie and signature. Light the error bit if | | 1396 | * Encrypt and send cookie and signature. Light the error bit if |
1394 | * anything goes wrong. | | 1397 | * anything goes wrong. |
1395 | */ | | 1398 | */ |
1396 | case CRYPTO_COOK | CRYPTO_RESP: | | 1399 | case CRYPTO_COOK | CRYPTO_RESP: |
1397 | if ((opcode & 0xffff) < VALUE_LEN) { | | 1400 | if ((opcode & 0xffff) < VALUE_LEN) { |
1398 | rval = XEVNT_LEN; | | 1401 | rval = XEVNT_LEN; |
1399 | break; | | 1402 | break; |
1400 | } | | 1403 | } |
1401 | if (PKT_MODE(xpkt->li_vn_mode) == MODE_SERVER) { | | 1404 | if (PKT_MODE(xpkt->li_vn_mode) == MODE_SERVER) { |
1402 | tcookie = cookie; | | 1405 | tcookie = cookie; |
1403 | } else { | | 1406 | } else { |
1404 | if ((peer = findpeerbyassoc(associd)) == NULL) { | | 1407 | if ((peer = findpeerbyassoc(associd)) == NULL) { |
1405 | rval = XEVNT_ERR; | | 1408 | rval = XEVNT_ERR; |
1406 | break; | | 1409 | break; |
1407 | } | | 1410 | } |
1408 | tcookie = peer->pcookie; | | 1411 | tcookie = peer->pcookie; |
1409 | } | | 1412 | } |
1410 | if ((rval = crypto_encrypt(ep, &vtemp, &tcookie)) == | | 1413 | if ((rval = crypto_encrypt(ep, &vtemp, &tcookie)) == |
1411 | XEVNT_OK) | | 1414 | XEVNT_OK) |
1412 | len += crypto_send(fp, &vtemp); | | 1415 | len += crypto_send(fp, &vtemp); |
1413 | value_free(&vtemp); | | 1416 | value_free(&vtemp); |
1414 | break; | | 1417 | break; |
1415 | | | 1418 | |
1416 | /* | | 1419 | /* |
1417 | * Find peer and send autokey data and signature in broadcast | | 1420 | * Find peer and send autokey data and signature in broadcast |
1418 | * server and symmetric modes. Use the values in the autokey | | 1421 | * server and symmetric modes. Use the values in the autokey |
1419 | * structure. If no association is found, either the server has | | 1422 | * structure. If no association is found, either the server has |
1420 | * restarted with new associations or some perp has replayed an | | 1423 | * restarted with new associations or some perp has replayed an |
1421 | * old message, in which case light the error bit. | | 1424 | * old message, in which case light the error bit. |
1422 | */ | | 1425 | */ |
1423 | case CRYPTO_AUTO | CRYPTO_RESP: | | 1426 | case CRYPTO_AUTO | CRYPTO_RESP: |
1424 | if ((peer = findpeerbyassoc(associd)) == NULL) { | | 1427 | if ((peer = findpeerbyassoc(associd)) == NULL) { |
1425 | rval = XEVNT_ERR; | | 1428 | rval = XEVNT_ERR; |
1426 | break; | | 1429 | break; |
1427 | } | | 1430 | } |
1428 | peer->flags &= ~FLAG_ASSOC; | | 1431 | peer->flags &= ~FLAG_ASSOC; |
1429 | len += crypto_send(fp, &peer->sndval); | | 1432 | len += crypto_send(fp, &peer->sndval); |
1430 | break; | | 1433 | break; |
1431 | | | 1434 | |
1432 | /* | | 1435 | /* |
1433 | * Send leapseconds table and signature. Use the values from the | | 1436 | * Send leapseconds table and signature. Use the values from the |
1434 | * tai structure. If no table has been loaded, just send an | | 1437 | * tai structure. If no table has been loaded, just send an |
1435 | * empty request. | | 1438 | * empty request. |
1436 | */ | | 1439 | */ |
1437 | case CRYPTO_TAI: | | 1440 | case CRYPTO_TAI: |
1438 | case CRYPTO_TAI | CRYPTO_RESP: | | 1441 | case CRYPTO_TAI | CRYPTO_RESP: |
1439 | if (crypto_flags & CRYPTO_FLAG_TAI) | | 1442 | if (crypto_flags & CRYPTO_FLAG_TAI) |
1440 | len += crypto_send(fp, &tai_leap); | | 1443 | len += crypto_send(fp, &tai_leap); |
1441 | break; | | 1444 | break; |
1442 | | | 1445 | |
1443 | /* | | 1446 | /* |
1444 | * Default - Fall through for requests; for unknown responses, | | 1447 | * Default - Fall through for requests; for unknown responses, |
1445 | * flag as error. | | 1448 | * flag as error. |
1446 | */ | | 1449 | */ |
1447 | default: | | 1450 | default: |
1448 | if (opcode & CRYPTO_RESP) | | 1451 | if (opcode & CRYPTO_RESP) |
1449 | rval = XEVNT_ERR; | | 1452 | rval = XEVNT_ERR; |
1450 | } | | 1453 | } |
1451 | | | 1454 | |
1452 | /* | | 1455 | /* |
1453 | * In case of error, flame the log. If a request, toss the | | 1456 | * In case of error, flame the log. If a request, toss the |
1454 | * puppy; if a response, return so the sender can flame, too. | | 1457 | * puppy; if a response, return so the sender can flame, too. |
1455 | */ | | 1458 | */ |
1456 | if (rval != XEVNT_OK) { | | 1459 | if (rval != XEVNT_OK) { |
1457 | opcode |= CRYPTO_ERROR; | | 1460 | opcode |= CRYPTO_ERROR; |
1458 | sprintf(statstr, "error %x opcode %x", rval, opcode); | | 1461 | snprintf(statstr, NTP_MAXSTRLEN, |
| | | 1462 | "error %x opcode %x", rval, opcode); |
1459 | record_crypto_stats(srcadr_sin, statstr); | | 1463 | record_crypto_stats(srcadr_sin, statstr); |
1460 | report_event(rval, NULL); | | 1464 | report_event(rval, NULL); |
1461 | #ifdef DEBUG | | 1465 | #ifdef DEBUG |
1462 | if (debug) | | 1466 | if (debug) |
1463 | printf("crypto_xmit: %s\n", statstr); | | 1467 | printf("crypto_xmit: %s\n", statstr); |
1464 | #endif | | 1468 | #endif |
1465 | if (!(opcode & CRYPTO_RESP)) | | 1469 | if (!(opcode & CRYPTO_RESP)) |
1466 | return (0); | | 1470 | return (0); |
1467 | } | | 1471 | } |
1468 | | | 1472 | |
1469 | /* | | 1473 | /* |
1470 | * Round up the field length to a multiple of 8 bytes and save | | 1474 | * Round up the field length to a multiple of 8 bytes and save |
1471 | * the request code and length. | | 1475 | * the request code and length. |
1472 | */ | | 1476 | */ |
1473 | len = ((len + 7) / 8) * 8; | | 1477 | len = ((len + 7) / 8) * 8; |
1474 | fp->opcode = htonl((opcode & 0xffff0000) | len); | | 1478 | fp->opcode = htonl((opcode & 0xffff0000) | len); |
1475 | #ifdef DEBUG | | 1479 | #ifdef DEBUG |
1476 | if (debug) | | 1480 | if (debug) |
1477 | printf( | | 1481 | printf( |
1478 | "crypto_xmit: flags 0x%x ext offset %d len %u code 0x%x assocID %d\n", | | 1482 | "crypto_xmit: flags 0x%x ext offset %d len %u code 0x%x assocID %d\n", |
1479 | crypto_flags, start, len, opcode >> 16, associd); | | 1483 | crypto_flags, start, len, opcode >> 16, associd); |
1480 | #endif | | 1484 | #endif |
1481 | return (len); | | 1485 | return (len); |
1482 | } | | 1486 | } |
1483 | | | 1487 | |
1484 | | | 1488 | |
1485 | /* | | 1489 | /* |
1486 | * crypto_verify - parse and verify the extension field and value | | 1490 | * crypto_verify - parse and verify the extension field and value |
1487 | * | | 1491 | * |
1488 | * Returns | | 1492 | * Returns |
1489 | * XEVNT_OK success | | 1493 | * XEVNT_OK success |
1490 | * XEVNT_LEN bad field format or length | | 1494 | * XEVNT_LEN bad field format or length |
1491 | * XEVNT_TSP bad timestamp | | 1495 | * XEVNT_TSP bad timestamp |
1492 | * XEVNT_FSP bad filestamp | | 1496 | * XEVNT_FSP bad filestamp |
1493 | * XEVNT_PUB bad or missing public key | | 1497 | * XEVNT_PUB bad or missing public key |
1494 | * XEVNT_SGL bad signature length | | 1498 | * XEVNT_SGL bad signature length |
1495 | * XEVNT_SIG signature not verified | | 1499 | * XEVNT_SIG signature not verified |
1496 | * XEVNT_ERR protocol error | | 1500 | * XEVNT_ERR protocol error |
1497 | */ | | 1501 | */ |
1498 | static int | | 1502 | static int |
1499 | crypto_verify( | | 1503 | crypto_verify( |
1500 | struct exten *ep, /* extension pointer */ | | 1504 | struct exten *ep, /* extension pointer */ |
1501 | struct value *vp, /* value pointer */ | | 1505 | struct value *vp, /* value pointer */ |
1502 | struct peer *peer /* peer structure pointer */ | | 1506 | struct peer *peer /* peer structure pointer */ |
1503 | ) | | 1507 | ) |
1504 | { | | 1508 | { |
1505 | EVP_PKEY *pkey; /* server public key */ | | 1509 | EVP_PKEY *pkey; /* server public key */ |
1506 | EVP_MD_CTX ctx; /* signature context */ | | 1510 | EVP_MD_CTX ctx; /* signature context */ |
1507 | tstamp_t tstamp, tstamp1 = 0; /* timestamp */ | | 1511 | tstamp_t tstamp, tstamp1 = 0; /* timestamp */ |
1508 | tstamp_t fstamp, fstamp1 = 0; /* filestamp */ | | 1512 | tstamp_t fstamp, fstamp1 = 0; /* filestamp */ |
1509 | u_int vallen; /* value length */ | | 1513 | u_int vallen; /* value length */ |
1510 | u_int siglen; /* signature length */ | | 1514 | u_int siglen; /* signature length */ |
1511 | u_int opcode, len; | | 1515 | u_int opcode, len; |
1512 | int i; | | 1516 | int i; |
1513 | | | 1517 | |
1514 | /* | | 1518 | /* |
1515 | * We require valid opcode and field lengths, timestamp, | | 1519 | * We require valid opcode and field lengths, timestamp, |
1516 | * filestamp, public key, digest, signature length and | | 1520 | * filestamp, public key, digest, signature length and |
1517 | * signature, where relevant. Note that preliminary length | | 1521 | * signature, where relevant. Note that preliminary length |
1518 | * checks are done in the main loop. | | 1522 | * checks are done in the main loop. |
1519 | */ | | 1523 | */ |
1520 | len = ntohl(ep->opcode) & 0x0000ffff; | | 1524 | len = ntohl(ep->opcode) & 0x0000ffff; |
1521 | opcode = ntohl(ep->opcode) & 0xffff0000; | | 1525 | opcode = ntohl(ep->opcode) & 0xffff0000; |
1522 | | | 1526 | |
1523 | /* | | 1527 | /* |
1524 | * Check for valid operation code and protocol. The opcode must | | 1528 | * Check for valid operation code and protocol. The opcode must |
1525 | * not have the error bit set. If a response, it must have a | | 1529 | * not have the error bit set. If a response, it must have a |
1526 | * value header. If a request and does not contain a value | | 1530 | * value header. If a request and does not contain a value |
1527 | * header, no need for further checking. | | 1531 | * header, no need for further checking. |
1528 | */ | | 1532 | */ |
1529 | if (opcode & CRYPTO_ERROR) | | 1533 | if (opcode & CRYPTO_ERROR) |
1530 | return (XEVNT_ERR); | | 1534 | return (XEVNT_ERR); |
1531 | | | 1535 | |
1532 | if (opcode & CRYPTO_RESP) { | | 1536 | if (opcode & CRYPTO_RESP) { |
1533 | if (len < VALUE_LEN) | | 1537 | if (len < VALUE_LEN) |
1534 | return (XEVNT_LEN); | | 1538 | return (XEVNT_LEN); |
1535 | } else { | | 1539 | } else { |
1536 | if (len < VALUE_LEN) | | 1540 | if (len < VALUE_LEN) |
1537 | return (XEVNT_OK); | | 1541 | return (XEVNT_OK); |
1538 | } | | 1542 | } |
1539 | | | 1543 | |
1540 | /* | | 1544 | /* |
1541 | * We have a value header. Check for valid field lengths. The | | 1545 | * We have a value header. Check for valid field lengths. The |
1542 | * field length must be long enough to contain the value header, | | 1546 | * field length must be long enough to contain the value header, |
1543 | * value and signature. Note both the value and signature fields | | 1547 | * value and signature. Note both the value and signature fields |
1544 | * are rounded up to the next word. | | 1548 | * are rounded up to the next word. |
1545 | */ | | 1549 | */ |
1546 | vallen = ntohl(ep->vallen); | | 1550 | vallen = ntohl(ep->vallen); |
1547 | i = (vallen + 3) / 4; | | 1551 | i = (vallen + 3) / 4; |
1548 | siglen = ntohl(ep->pkt[i++]); | | 1552 | siglen = ntohl(ep->pkt[i++]); |
1549 | if (len < VALUE_LEN + ((vallen + 3) / 4) * 4 + ((siglen + 3) / | | 1553 | if (len < VALUE_LEN + ((vallen + 3) / 4) * 4 + ((siglen + 3) / |
1550 | 4) * 4) | | 1554 | 4) * 4) |
1551 | return (XEVNT_LEN); | | 1555 | return (XEVNT_LEN); |
1552 | | | 1556 | |
1553 | /* | | 1557 | /* |
1554 | * Punt if this is a response with no data. Punt if this is a | | 1558 | * Punt if this is a response with no data. Punt if this is a |
1555 | * request and a previous response is pending. | | 1559 | * request and a previous response is pending. |
1556 | */ | | 1560 | */ |
1557 | if (opcode & CRYPTO_RESP) { | | 1561 | if (opcode & CRYPTO_RESP) { |
1558 | if (vallen == 0) | | 1562 | if (vallen == 0) |
1559 | return (XEVNT_LEN); | | 1563 | return (XEVNT_LEN); |
1560 | } else { | | 1564 | } else { |
1561 | if (peer->cmmd != NULL) | | 1565 | if (peer->cmmd != NULL) |
1562 | return (XEVNT_LEN); | | 1566 | return (XEVNT_LEN); |
1563 | } | | 1567 | } |
1564 | | | 1568 | |
1565 | /* | | 1569 | /* |
1566 | * Check for valid timestamp and filestamp. If the timestamp is | | 1570 | * Check for valid timestamp and filestamp. If the timestamp is |
1567 | * zero, the sender is not synchronized and signatures are | | 1571 | * zero, the sender is not synchronized and signatures are |
1568 | * disregarded. If not, the timestamp must not precede the | | 1572 | * disregarded. If not, the timestamp must not precede the |
1569 | * filestamp. The timestamp and filestamp must not precede the | | 1573 | * filestamp. The timestamp and filestamp must not precede the |
1570 | * corresponding values in the value structure, if present. Once | | 1574 | * corresponding values in the value structure, if present. Once |
1571 | * the autokey values have been installed, the timestamp must | | 1575 | * the autokey values have been installed, the timestamp must |
1572 | * always be later than the corresponding value in the value | | 1576 | * always be later than the corresponding value in the value |
1573 | * structure. Duplicate timestamps are illegal once the cookie | | 1577 | * structure. Duplicate timestamps are illegal once the cookie |
1574 | * has been validated. | | 1578 | * has been validated. |
1575 | */ | | 1579 | */ |
1576 | tstamp = ntohl(ep->tstamp); | | 1580 | tstamp = ntohl(ep->tstamp); |
1577 | fstamp = ntohl(ep->fstamp); | | 1581 | fstamp = ntohl(ep->fstamp); |
1578 | if (tstamp == 0) | | 1582 | if (tstamp == 0) |
1579 | return (XEVNT_OK); | | 1583 | return (XEVNT_OK); |
1580 | | | 1584 | |
1581 | if (tstamp < fstamp) | | 1585 | if (tstamp < fstamp) |
1582 | return (XEVNT_TSP); | | 1586 | return (XEVNT_TSP); |
1583 | | | 1587 | |
1584 | if (vp != NULL) { | | 1588 | if (vp != NULL) { |
1585 | tstamp1 = ntohl(vp->tstamp); | | 1589 | tstamp1 = ntohl(vp->tstamp); |
1586 | fstamp1 = ntohl(vp->fstamp); | | 1590 | fstamp1 = ntohl(vp->fstamp); |
1587 | if ((tstamp < tstamp1 || (tstamp == tstamp1 && | | 1591 | if ((tstamp < tstamp1 || (tstamp == tstamp1 && |
1588 | (peer->crypto & CRYPTO_FLAG_AUTO)))) | | 1592 | (peer->crypto & CRYPTO_FLAG_AUTO)))) |
1589 | return (XEVNT_TSP); | | 1593 | return (XEVNT_TSP); |
1590 | | | 1594 | |
1591 | if ((tstamp < fstamp1 || fstamp < fstamp1)) | | 1595 | if ((tstamp < fstamp1 || fstamp < fstamp1)) |
1592 | return (XEVNT_FSP); | | 1596 | return (XEVNT_FSP); |
1593 | } | | 1597 | } |
1594 | | | 1598 | |
1595 | /* | | 1599 | /* |
1596 | * Check for valid signature length, public key and digest | | 1600 | * Check for valid signature length, public key and digest |
1597 | * algorithm. | | 1601 | * algorithm. |
1598 | */ | | 1602 | */ |
1599 | if (crypto_flags & peer->crypto & CRYPTO_FLAG_PRIV) | | 1603 | if (crypto_flags & peer->crypto & CRYPTO_FLAG_PRIV) |
1600 | pkey = sign_pkey; | | 1604 | pkey = sign_pkey; |
1601 | else | | 1605 | else |
1602 | pkey = peer->pkey; | | 1606 | pkey = peer->pkey; |
1603 | if (siglen == 0 || pkey == NULL || peer->digest == NULL) | | 1607 | if (siglen == 0 || pkey == NULL || peer->digest == NULL) |
1604 | return (XEVNT_OK); | | 1608 | return (XEVNT_OK); |
1605 | | | 1609 | |
1606 | if (siglen != (u_int)EVP_PKEY_size(pkey)) | | 1610 | if (siglen != (u_int)EVP_PKEY_size(pkey)) |
1607 | return (XEVNT_SGL); | | 1611 | return (XEVNT_SGL); |
1608 | | | 1612 | |
1609 | /* | | 1613 | /* |
1610 | * Darn, I thought we would never get here. Verify the | | 1614 | * Darn, I thought we would never get here. Verify the |
1611 | * signature. If the identity exchange is verified, light the | | 1615 | * signature. If the identity exchange is verified, light the |
1612 | * proventic bit. If no client identity scheme is specified, | | 1616 | * proventic bit. If no client identity scheme is specified, |
1613 | * avoid doing the sign exchange. | | 1617 | * avoid doing the sign exchange. |
1614 | */ | | 1618 | */ |
1615 | EVP_VerifyInit(&ctx, peer->digest); | | 1619 | EVP_VerifyInit(&ctx, peer->digest); |
1616 | EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12); | | 1620 | EVP_VerifyUpdate(&ctx, (u_char *)&ep->tstamp, vallen + 12); |
1617 | if (!EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey)) | | 1621 | if (!EVP_VerifyFinal(&ctx, (u_char *)&ep->pkt[i], siglen, pkey)) |
1618 | return (XEVNT_SIG); | | 1622 | return (XEVNT_SIG); |
1619 | | | 1623 | |
1620 | if (peer->crypto & CRYPTO_FLAG_VRFY) { | | 1624 | if (peer->crypto & CRYPTO_FLAG_VRFY) { |
1621 | peer->crypto |= CRYPTO_FLAG_PROV; | | 1625 | peer->crypto |= CRYPTO_FLAG_PROV; |
1622 | if (!(crypto_flags & CRYPTO_FLAG_MASK)) | | 1626 | if (!(crypto_flags & CRYPTO_FLAG_MASK)) |
1623 | peer->crypto |= CRYPTO_FLAG_SIGN; | | 1627 | peer->crypto |= CRYPTO_FLAG_SIGN; |
1624 | } | | 1628 | } |
1625 | return (XEVNT_OK); | | 1629 | return (XEVNT_OK); |
1626 | } | | 1630 | } |
1627 | | | 1631 | |
1628 | | | 1632 | |
1629 | /* | | 1633 | /* |
1630 | * crypto_encrypt - construct encrypted cookie and signature from | | 1634 | * crypto_encrypt - construct encrypted cookie and signature from |
1631 | * extension field and cookie | | 1635 | * extension field and cookie |
1632 | * | | 1636 | * |
1633 | * Returns | | 1637 | * Returns |
1634 | * XEVNT_OK success | | 1638 | * XEVNT_OK success |
1635 | * XEVNT_PUB bad or missing public key | | 1639 | * XEVNT_PUB bad or missing public key |
1636 | * XEVNT_CKY bad or missing cookie | | 1640 | * XEVNT_CKY bad or missing cookie |
1637 | * XEVNT_PER host certificate expired | | 1641 | * XEVNT_PER host certificate expired |
1638 | */ | | 1642 | */ |
1639 | static int | | 1643 | static int |
1640 | crypto_encrypt( | | 1644 | crypto_encrypt( |
1641 | struct exten *ep, /* extension pointer */ | | 1645 | struct exten *ep, /* extension pointer */ |
1642 | struct value *vp, /* value pointer */ | | 1646 | struct value *vp, /* value pointer */ |
1643 | keyid_t *cookie /* server cookie */ | | 1647 | keyid_t *cookie /* server cookie */ |
1644 | ) | | 1648 | ) |
1645 | { | | 1649 | { |
1646 | EVP_PKEY *pkey; /* public key */ | | 1650 | EVP_PKEY *pkey; /* public key */ |
1647 | EVP_MD_CTX ctx; /* signature context */ | | 1651 | EVP_MD_CTX ctx; /* signature context */ |
1648 | tstamp_t tstamp; /* NTP timestamp */ | | 1652 | tstamp_t tstamp; /* NTP timestamp */ |
1649 | u_int32 temp32; | | 1653 | u_int32 temp32; |
1650 | u_int len; | | 1654 | u_int len; |
1651 | const u_char *ptr; | | 1655 | const u_char *ptr; |
1652 | | | 1656 | |
1653 | /* | | 1657 | /* |
1654 | * Extract the public key from the request. | | 1658 | * Extract the public key from the request. |
1655 | */ | | 1659 | */ |
1656 | len = ntohl(ep->vallen); | | 1660 | len = ntohl(ep->vallen); |
1657 | ptr = (u_char *)ep->pkt; | | 1661 | ptr = (u_char *)ep->pkt; |
1658 | pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len); | | 1662 | pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len); |
1659 | if (pkey == NULL) { | | 1663 | if (pkey == NULL) { |
1660 | msyslog(LOG_ERR, "crypto_encrypt %s\n", | | 1664 | msyslog(LOG_ERR, "crypto_encrypt %s\n", |
1661 | ERR_error_string(ERR_get_error(), NULL)); | | 1665 | ERR_error_string(ERR_get_error(), NULL)); |
1662 | return (XEVNT_PUB); | | 1666 | return (XEVNT_PUB); |
1663 | } | | 1667 | } |
1664 | | | 1668 | |
1665 | /* | | 1669 | /* |
1666 | * Encrypt the cookie, encode in ASN.1 and sign. | | 1670 | * Encrypt the cookie, encode in ASN.1 and sign. |
1667 | */ | | 1671 | */ |
1668 | tstamp = crypto_time(); | | 1672 | tstamp = crypto_time(); |
1669 | memset(vp, 0, sizeof(struct value)); | | 1673 | memset(vp, 0, sizeof(struct value)); |
1670 | vp->tstamp = htonl(tstamp); | | 1674 | vp->tstamp = htonl(tstamp); |
1671 | vp->fstamp = hostval.tstamp; | | 1675 | vp->fstamp = hostval.tstamp; |
1672 | len = EVP_PKEY_size(pkey); | | 1676 | len = EVP_PKEY_size(pkey); |
1673 | vp->vallen = htonl(len); | | 1677 | vp->vallen = htonl(len); |
1674 | vp->ptr = emalloc(len); | | 1678 | vp->ptr = emalloc(len); |
1675 | temp32 = htonl(*cookie); | | 1679 | temp32 = htonl(*cookie); |
1676 | if (!RSA_public_encrypt(4, (u_char *)&temp32, vp->ptr, | | 1680 | if (!RSA_public_encrypt(4, (u_char *)&temp32, vp->ptr, |
1677 | pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING)) { | | 1681 | pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING)) { |
1678 | msyslog(LOG_ERR, "crypto_encrypt %s\n", | | 1682 | msyslog(LOG_ERR, "crypto_encrypt %s\n", |
1679 | ERR_error_string(ERR_get_error(), NULL)); | | 1683 | ERR_error_string(ERR_get_error(), NULL)); |
1680 | EVP_PKEY_free(pkey); | | 1684 | EVP_PKEY_free(pkey); |
1681 | return (XEVNT_CKY); | | 1685 | return (XEVNT_CKY); |
1682 | } | | 1686 | } |
1683 | EVP_PKEY_free(pkey); | | 1687 | EVP_PKEY_free(pkey); |
1684 | vp->siglen = 0; | | 1688 | vp->siglen = 0; |
1685 | if (tstamp == 0) | | 1689 | if (tstamp == 0) |
1686 | return (XEVNT_OK); | | 1690 | return (XEVNT_OK); |
1687 | | | 1691 | |
1688 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 1692 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
1689 | return (XEVNT_PER); | | 1693 | return (XEVNT_PER); |
1690 | | | 1694 | |
1691 | vp->sig = emalloc(sign_siglen); | | 1695 | vp->sig = emalloc(sign_siglen); |
1692 | EVP_SignInit(&ctx, sign_digest); | | 1696 | EVP_SignInit(&ctx, sign_digest); |
1693 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 1697 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
1694 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 1698 | EVP_SignUpdate(&ctx, vp->ptr, len); |
1695 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 1699 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
1696 | vp->siglen = htonl(len); | | 1700 | vp->siglen = htonl(len); |
1697 | return (XEVNT_OK); | | 1701 | return (XEVNT_OK); |
1698 | } | | 1702 | } |
1699 | | | 1703 | |
1700 | | | 1704 | |
1701 | /* | | 1705 | /* |
1702 | * crypto_ident - construct extension field for identity scheme | | 1706 | * crypto_ident - construct extension field for identity scheme |
1703 | * | | 1707 | * |
1704 | * This routine determines which identity scheme is in use and | | 1708 | * This routine determines which identity scheme is in use and |
1705 | * constructs an extension field for that scheme. | | 1709 | * constructs an extension field for that scheme. |
1706 | */ | | 1710 | */ |
1707 | u_int | | 1711 | u_int |
1708 | crypto_ident( | | 1712 | crypto_ident( |
1709 | struct peer *peer /* peer structure pointer */ | | 1713 | struct peer *peer /* peer structure pointer */ |
1710 | ) | | 1714 | ) |
1711 | { | | 1715 | { |
1712 | char filename[MAXFILENAME + 1]; | | 1716 | char filename[MAXFILENAME + 1]; |
1713 | | | 1717 | |
1714 | /* | | 1718 | /* |
1715 | * If the server identity has already been verified, no further | | 1719 | * If the server identity has already been verified, no further |
1716 | * action is necessary. Otherwise, try to load the identity file | | 1720 | * action is necessary. Otherwise, try to load the identity file |
1717 | * of the certificate issuer. If the issuer file is not found, | | 1721 | * of the certificate issuer. If the issuer file is not found, |
1718 | * try the host file. If nothing found, declare a cryptobust. | | 1722 | * try the host file. If nothing found, declare a cryptobust. |
1719 | * Note we can't get here unless the trusted certificate has | | 1723 | * Note we can't get here unless the trusted certificate has |
1720 | * been found and the CRYPTO_FLAG_VALID bit is set, so the | | 1724 | * been found and the CRYPTO_FLAG_VALID bit is set, so the |
1721 | * certificate issuer is valid. | | 1725 | * certificate issuer is valid. |
1722 | */ | | 1726 | */ |
1723 | if (peer->ident_pkey != NULL) | | 1727 | if (peer->ident_pkey != NULL) |
1724 | EVP_PKEY_free(peer->ident_pkey); | | 1728 | EVP_PKEY_free(peer->ident_pkey); |
1725 | if (peer->crypto & CRYPTO_FLAG_GQ) { | | 1729 | if (peer->crypto & CRYPTO_FLAG_GQ) { |
1726 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", | | 1730 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", |
1727 | peer->issuer); | | 1731 | peer->issuer); |
1728 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1732 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1729 | if (peer->ident_pkey != NULL) | | 1733 | if (peer->ident_pkey != NULL) |
1730 | return (CRYPTO_GQ); | | 1734 | return (CRYPTO_GQ); |
1731 | | | 1735 | |
1732 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", | | 1736 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", |
1733 | sys_hostname); | | 1737 | sys_hostname); |
1734 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1738 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1735 | if (peer->ident_pkey != NULL) | | 1739 | if (peer->ident_pkey != NULL) |
1736 | return (CRYPTO_GQ); | | 1740 | return (CRYPTO_GQ); |
1737 | } | | 1741 | } |
1738 | if (peer->crypto & CRYPTO_FLAG_IFF) { | | 1742 | if (peer->crypto & CRYPTO_FLAG_IFF) { |
1739 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", | | 1743 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", |
1740 | peer->issuer); | | 1744 | peer->issuer); |
1741 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1745 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1742 | if (peer->ident_pkey != NULL) | | 1746 | if (peer->ident_pkey != NULL) |
1743 | return (CRYPTO_IFF); | | 1747 | return (CRYPTO_IFF); |
1744 | | | 1748 | |
1745 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", | | 1749 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", |
1746 | sys_hostname); | | 1750 | sys_hostname); |
1747 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1751 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1748 | if (peer->ident_pkey != NULL) | | 1752 | if (peer->ident_pkey != NULL) |
1749 | return (CRYPTO_IFF); | | 1753 | return (CRYPTO_IFF); |
1750 | } | | 1754 | } |
1751 | if (peer->crypto & CRYPTO_FLAG_MV) { | | 1755 | if (peer->crypto & CRYPTO_FLAG_MV) { |
1752 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", | | 1756 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", |
1753 | peer->issuer); | | 1757 | peer->issuer); |
1754 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1758 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1755 | if (peer->ident_pkey != NULL) | | 1759 | if (peer->ident_pkey != NULL) |
1756 | return (CRYPTO_MV); | | 1760 | return (CRYPTO_MV); |
1757 | | | 1761 | |
1758 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", | | 1762 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", |
1759 | sys_hostname); | | 1763 | sys_hostname); |
1760 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); | | 1764 | peer->ident_pkey = crypto_key(filename, &peer->fstamp); |
1761 | if (peer->ident_pkey != NULL) | | 1765 | if (peer->ident_pkey != NULL) |
1762 | return (CRYPTO_MV); | | 1766 | return (CRYPTO_MV); |
1763 | } | | 1767 | } |
1764 | | | 1768 | |
1765 | /* | | 1769 | /* |
1766 | * No compatible identity scheme is available. Life is hard. | | 1770 | * No compatible identity scheme is available. Life is hard. |
1767 | */ | | 1771 | */ |
1768 | msyslog(LOG_INFO, | | 1772 | msyslog(LOG_INFO, |
1769 | "crypto_ident: no compatible identity scheme found"); | | 1773 | "crypto_ident: no compatible identity scheme found"); |
1770 | return (0); | | 1774 | return (0); |
1771 | } | | 1775 | } |
1772 | | | 1776 | |
1773 | | | 1777 | |
1774 | /* | | 1778 | /* |
1775 | * crypto_args - construct extension field from arguments | | 1779 | * crypto_args - construct extension field from arguments |
1776 | * | | 1780 | * |
1777 | * This routine creates an extension field with current timestamps and | | 1781 | * This routine creates an extension field with current timestamps and |
1778 | * specified opcode, association ID and optional string. Note that the | | 1782 | * specified opcode, association ID and optional string. Note that the |
1779 | * extension field is created here, but freed after the crypto_xmit() | | 1783 | * extension field is created here, but freed after the crypto_xmit() |
1780 | * call in the protocol module. | | 1784 | * call in the protocol module. |
1781 | * | | 1785 | * |
1782 | * Returns extension field pointer (no errors). | | 1786 | * Returns extension field pointer (no errors). |
1783 | */ | | 1787 | */ |
1784 | struct exten * | | 1788 | struct exten * |
1785 | crypto_args( | | 1789 | crypto_args( |
1786 | struct peer *peer, /* peer structure pointer */ | | 1790 | struct peer *peer, /* peer structure pointer */ |
1787 | u_int opcode, /* operation code */ | | 1791 | u_int opcode, /* operation code */ |
1788 | char *str /* argument string */ | | 1792 | char *str /* argument string */ |
1789 | ) | | 1793 | ) |
1790 | { | | 1794 | { |
1791 | tstamp_t tstamp; /* NTP timestamp */ | | 1795 | tstamp_t tstamp; /* NTP timestamp */ |
1792 | struct exten *ep; /* extension field pointer */ | | 1796 | struct exten *ep; /* extension field pointer */ |
1793 | u_int len; /* extension field length */ | | 1797 | u_int len; /* extension field length */ |
1794 | | | 1798 | |
1795 | tstamp = crypto_time(); | | 1799 | tstamp = crypto_time(); |
1796 | len = sizeof(struct exten); | | 1800 | len = sizeof(struct exten); |
1797 | if (str != NULL) | | 1801 | if (str != NULL) |
1798 | len += strlen(str); | | 1802 | len += strlen(str); |
1799 | ep = emalloc(len); | | 1803 | ep = emalloc(len); |
1800 | memset(ep, 0, len); | | 1804 | memset(ep, 0, len); |
1801 | if (opcode == 0) | | 1805 | if (opcode == 0) |
1802 | return (ep); | | 1806 | return (ep); |
1803 | | | 1807 | |
1804 | ep->opcode = htonl(opcode + len); | | 1808 | ep->opcode = htonl(opcode + len); |
1805 | | | 1809 | |
1806 | /* | | 1810 | /* |
1807 | * If a response, send our ID; if a request, send the | | 1811 | * If a response, send our ID; if a request, send the |
1808 | * responder's ID. | | 1812 | * responder's ID. |
1809 | */ | | 1813 | */ |
1810 | if (opcode & CRYPTO_RESP) | | 1814 | if (opcode & CRYPTO_RESP) |
1811 | ep->associd = htonl(peer->associd); | | 1815 | ep->associd = htonl(peer->associd); |
1812 | else | | 1816 | else |
1813 | ep->associd = htonl(peer->assoc); | | 1817 | ep->associd = htonl(peer->assoc); |
1814 | ep->tstamp = htonl(tstamp); | | 1818 | ep->tstamp = htonl(tstamp); |
1815 | ep->fstamp = hostval.tstamp; | | 1819 | ep->fstamp = hostval.tstamp; |
1816 | ep->vallen = 0; | | 1820 | ep->vallen = 0; |
1817 | if (str != NULL) { | | 1821 | if (str != NULL) { |
1818 | ep->vallen = htonl(strlen(str)); | | 1822 | ep->vallen = htonl(strlen(str)); |
1819 | memcpy((char *)ep->pkt, str, strlen(str)); | | 1823 | memcpy((char *)ep->pkt, str, strlen(str)); |
1820 | } else { | | 1824 | } else { |
1821 | ep->pkt[0] = peer->associd; | | 1825 | ep->pkt[0] = peer->associd; |
1822 | } | | 1826 | } |
1823 | return (ep); | | 1827 | return (ep); |
1824 | } | | 1828 | } |
1825 | | | 1829 | |
1826 | | | 1830 | |
1827 | /* | | 1831 | /* |
1828 | * crypto_send - construct extension field from value components | | 1832 | * crypto_send - construct extension field from value components |
1829 | * | | 1833 | * |
1830 | * Returns extension field length. Note: it is not polite to send a | | 1834 | * Returns extension field length. Note: it is not polite to send a |
1831 | * nonempty signature with zero timestamp or a nonzero timestamp with | | 1835 | * nonempty signature with zero timestamp or a nonzero timestamp with |
1832 | * empty signature, but these rules are not enforced here. | | 1836 | * empty signature, but these rules are not enforced here. |
1833 | */ | | 1837 | */ |
1834 | u_int | | 1838 | u_int |
1835 | crypto_send( | | 1839 | crypto_send( |
1836 | struct exten *ep, /* extension field pointer */ | | 1840 | struct exten *ep, /* extension field pointer */ |
1837 | struct value *vp /* value pointer */ | | 1841 | struct value *vp /* value pointer */ |
1838 | ) | | 1842 | ) |
1839 | { | | 1843 | { |
1840 | u_int len, temp32; | | 1844 | u_int len, temp32; |
1841 | int i; | | 1845 | int i; |
1842 | | | 1846 | |
1843 | /* | | 1847 | /* |
1844 | * Copy data. If the data field is empty or zero length, encode | | 1848 | * Copy data. If the data field is empty or zero length, encode |
1845 | * an empty value with length zero. | | 1849 | * an empty value with length zero. |
1846 | */ | | 1850 | */ |
1847 | ep->tstamp = vp->tstamp; | | 1851 | ep->tstamp = vp->tstamp; |
1848 | ep->fstamp = vp->fstamp; | | 1852 | ep->fstamp = vp->fstamp; |
1849 | ep->vallen = vp->vallen; | | 1853 | ep->vallen = vp->vallen; |
1850 | len = 12; | | 1854 | len = 12; |
1851 | temp32 = ntohl(vp->vallen); | | 1855 | temp32 = ntohl(vp->vallen); |
1852 | if (temp32 > 0 && vp->ptr != NULL) | | 1856 | if (temp32 > 0 && vp->ptr != NULL) |
1853 | memcpy(ep->pkt, vp->ptr, temp32); | | 1857 | memcpy(ep->pkt, vp->ptr, temp32); |
1854 | | | 1858 | |
1855 | /* | | 1859 | /* |
1856 | * Copy signature. If the signature field is empty or zero | | 1860 | * Copy signature. If the signature field is empty or zero |
1857 | * length, encode an empty signature with length zero. | | 1861 | * length, encode an empty signature with length zero. |
1858 | */ | | 1862 | */ |
1859 | i = (temp32 + 3) / 4; | | 1863 | i = (temp32 + 3) / 4; |
1860 | len += i * 4 + 4; | | 1864 | len += i * 4 + 4; |
1861 | ep->pkt[i++] = vp->siglen; | | 1865 | ep->pkt[i++] = vp->siglen; |
1862 | temp32 = ntohl(vp->siglen); | | 1866 | temp32 = ntohl(vp->siglen); |
1863 | if (temp32 > 0 && vp->sig != NULL) | | 1867 | if (temp32 > 0 && vp->sig != NULL) |
1864 | memcpy(&ep->pkt[i], vp->sig, temp32); | | 1868 | memcpy(&ep->pkt[i], vp->sig, temp32); |
1865 | len += temp32; | | 1869 | len += temp32; |
1866 | return (len); | | 1870 | return (len); |
1867 | } | | 1871 | } |
1868 | | | 1872 | |
1869 | | | 1873 | |
1870 | /* | | 1874 | /* |
1871 | * crypto_update - compute new public value and sign extension fields | | 1875 | * crypto_update - compute new public value and sign extension fields |
1872 | * | | 1876 | * |
1873 | * This routine runs periodically, like once a day, and when something | | 1877 | * This routine runs periodically, like once a day, and when something |
1874 | * changes. It updates the timestamps on three value structures and one | | 1878 | * changes. It updates the timestamps on three value structures and one |
1875 | * value structure list, then signs all the structures: | | 1879 | * value structure list, then signs all the structures: |
1876 | * | | 1880 | * |
1877 | * hostval host name (not signed) | | 1881 | * hostval host name (not signed) |
1878 | * pubkey public key | | 1882 | * pubkey public key |
1879 | * cinfo certificate info/value list | | 1883 | * cinfo certificate info/value list |
1880 | * tai_leap leapseconds file | | 1884 | * tai_leap leapseconds file |
1881 | * | | 1885 | * |
1882 | * Filestamps are proventicated data, so this routine is run only when | | 1886 | * Filestamps are proventicated data, so this routine is run only when |
1883 | * the host has been synchronized to a proventicated source. Thus, the | | 1887 | * the host has been synchronized to a proventicated source. Thus, the |
1884 | * timestamp is proventicated, too, and can be used to deflect | | 1888 | * timestamp is proventicated, too, and can be used to deflect |
1885 | * clogging attacks and even cook breakfast. | | 1889 | * clogging attacks and even cook breakfast. |
1886 | * | | 1890 | * |
1887 | * Returns void (no errors) | | 1891 | * Returns void (no errors) |
1888 | */ | | 1892 | */ |
1889 | void | | 1893 | void |
1890 | crypto_update(void) | | 1894 | crypto_update(void) |
1891 | { | | 1895 | { |
1892 | EVP_MD_CTX ctx; /* message digest context */ | | 1896 | EVP_MD_CTX ctx; /* message digest context */ |
1893 | struct cert_info *cp, *cpn; /* certificate info/value */ | | 1897 | struct cert_info *cp, *cpn; /* certificate info/value */ |
1894 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 1898 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
1895 | tstamp_t tstamp; /* NTP timestamp */ | | 1899 | tstamp_t tstamp; /* NTP timestamp */ |
1896 | u_int len; | | 1900 | u_int len; |
1897 | | | 1901 | |
1898 | if ((tstamp = crypto_time()) == 0) | | 1902 | if ((tstamp = crypto_time()) == 0) |
1899 | return; | | 1903 | return; |
1900 | | | 1904 | |
1901 | hostval.tstamp = htonl(tstamp); | | 1905 | hostval.tstamp = htonl(tstamp); |
1902 | | | 1906 | |
1903 | /* | | 1907 | /* |
1904 | * Sign public key and timestamps. The filestamp is derived from | | 1908 | * Sign public key and timestamps. The filestamp is derived from |
1905 | * the host key file extension from wherever the file was | | 1909 | * the host key file extension from wherever the file was |
1906 | * generated. | | 1910 | * generated. |
1907 | */ | | 1911 | */ |
1908 | if (pubkey.vallen != 0) { | | 1912 | if (pubkey.vallen != 0) { |
1909 | pubkey.tstamp = hostval.tstamp; | | 1913 | pubkey.tstamp = hostval.tstamp; |
1910 | pubkey.siglen = 0; | | 1914 | pubkey.siglen = 0; |
1911 | if (pubkey.sig == NULL) | | 1915 | if (pubkey.sig == NULL) |
1912 | pubkey.sig = emalloc(sign_siglen); | | 1916 | pubkey.sig = emalloc(sign_siglen); |
1913 | EVP_SignInit(&ctx, sign_digest); | | 1917 | EVP_SignInit(&ctx, sign_digest); |
1914 | EVP_SignUpdate(&ctx, (u_char *)&pubkey, 12); | | 1918 | EVP_SignUpdate(&ctx, (u_char *)&pubkey, 12); |
1915 | EVP_SignUpdate(&ctx, pubkey.ptr, ntohl(pubkey.vallen)); | | 1919 | EVP_SignUpdate(&ctx, pubkey.ptr, ntohl(pubkey.vallen)); |
1916 | if (EVP_SignFinal(&ctx, pubkey.sig, &len, sign_pkey)) | | 1920 | if (EVP_SignFinal(&ctx, pubkey.sig, &len, sign_pkey)) |
1917 | pubkey.siglen = htonl(len); | | 1921 | pubkey.siglen = htonl(len); |
1918 | } | | 1922 | } |
1919 | | | 1923 | |
1920 | /* | | 1924 | /* |
1921 | * Sign certificates and timestamps. The filestamp is derived | | 1925 | * Sign certificates and timestamps. The filestamp is derived |
1922 | * from the certificate file extension from wherever the file | | 1926 | * from the certificate file extension from wherever the file |
1923 | * was generated. Note we do not throw expired certificates | | 1927 | * was generated. Note we do not throw expired certificates |
1924 | * away; they may have signed younger ones. | | 1928 | * away; they may have signed younger ones. |
1925 | */ | | 1929 | */ |
1926 | for (cp = cinfo; cp != NULL; cp = cpn) { | | 1930 | for (cp = cinfo; cp != NULL; cp = cpn) { |
1927 | cpn = cp->link; | | 1931 | cpn = cp->link; |
1928 | cp->cert.tstamp = hostval.tstamp; | | 1932 | cp->cert.tstamp = hostval.tstamp; |
1929 | cp->cert.siglen = 0; | | 1933 | cp->cert.siglen = 0; |
1930 | if (cp->cert.sig == NULL) | | 1934 | if (cp->cert.sig == NULL) |
1931 | cp->cert.sig = emalloc(sign_siglen); | | 1935 | cp->cert.sig = emalloc(sign_siglen); |
1932 | EVP_SignInit(&ctx, sign_digest); | | 1936 | EVP_SignInit(&ctx, sign_digest); |
1933 | EVP_SignUpdate(&ctx, (u_char *)&cp->cert, 12); | | 1937 | EVP_SignUpdate(&ctx, (u_char *)&cp->cert, 12); |
1934 | EVP_SignUpdate(&ctx, cp->cert.ptr, | | 1938 | EVP_SignUpdate(&ctx, cp->cert.ptr, |
1935 | ntohl(cp->cert.vallen)); | | 1939 | ntohl(cp->cert.vallen)); |
1936 | if (EVP_SignFinal(&ctx, cp->cert.sig, &len, sign_pkey)) | | 1940 | if (EVP_SignFinal(&ctx, cp->cert.sig, &len, sign_pkey)) |
1937 | cp->cert.siglen = htonl(len); | | 1941 | cp->cert.siglen = htonl(len); |
1938 | } | | 1942 | } |
1939 | | | 1943 | |
1940 | /* | | 1944 | /* |
1941 | * Sign leapseconds table and timestamps. The filestamp is | | 1945 | * Sign leapseconds table and timestamps. The filestamp is |
1942 | * derived from the leapsecond file extension from wherever the | | 1946 | * derived from the leapsecond file extension from wherever the |
1943 | * file was generated. | | 1947 | * file was generated. |
1944 | */ | | 1948 | */ |
1945 | if (tai_leap.vallen != 0) { | | 1949 | if (tai_leap.vallen != 0) { |
1946 | tai_leap.tstamp = hostval.tstamp; | | 1950 | tai_leap.tstamp = hostval.tstamp; |
1947 | tai_leap.siglen = 0; | | 1951 | tai_leap.siglen = 0; |
1948 | if (tai_leap.sig == NULL) | | 1952 | if (tai_leap.sig == NULL) |
1949 | tai_leap.sig = emalloc(sign_siglen); | | 1953 | tai_leap.sig = emalloc(sign_siglen); |
1950 | EVP_SignInit(&ctx, sign_digest); | | 1954 | EVP_SignInit(&ctx, sign_digest); |
1951 | EVP_SignUpdate(&ctx, (u_char *)&tai_leap, 12); | | 1955 | EVP_SignUpdate(&ctx, (u_char *)&tai_leap, 12); |
1952 | EVP_SignUpdate(&ctx, tai_leap.ptr, | | 1956 | EVP_SignUpdate(&ctx, tai_leap.ptr, |
1953 | ntohl(tai_leap.vallen)); | | 1957 | ntohl(tai_leap.vallen)); |
1954 | if (EVP_SignFinal(&ctx, tai_leap.sig, &len, sign_pkey)) | | 1958 | if (EVP_SignFinal(&ctx, tai_leap.sig, &len, sign_pkey)) |
1955 | tai_leap.siglen = htonl(len); | | 1959 | tai_leap.siglen = htonl(len); |
1956 | } | | 1960 | } |
1957 | sprintf(statstr, "update ts %u", ntohl(hostval.tstamp)); | | 1961 | snprintf(statstr, NTP_MAXSTRLEN, |
| | | 1962 | "update ts %u", ntohl(hostval.tstamp)); |
1958 | record_crypto_stats(NULL, statstr); | | 1963 | record_crypto_stats(NULL, statstr); |
1959 | #ifdef DEBUG | | 1964 | #ifdef DEBUG |
1960 | if (debug) | | 1965 | if (debug) |
1961 | printf("crypto_update: %s\n", statstr); | | 1966 | printf("crypto_update: %s\n", statstr); |
1962 | #endif | | 1967 | #endif |
1963 | } | | 1968 | } |
1964 | | | 1969 | |
1965 | | | 1970 | |
1966 | /* | | 1971 | /* |
1967 | * value_free - free value structure components. | | 1972 | * value_free - free value structure components. |
1968 | * | | 1973 | * |
1969 | * Returns void (no errors) | | 1974 | * Returns void (no errors) |
1970 | */ | | 1975 | */ |
1971 | void | | 1976 | void |
1972 | value_free( | | 1977 | value_free( |
1973 | struct value *vp /* value structure */ | | 1978 | struct value *vp /* value structure */ |
1974 | ) | | 1979 | ) |
1975 | { | | 1980 | { |
1976 | if (vp->ptr != NULL) | | 1981 | if (vp->ptr != NULL) |
1977 | free(vp->ptr); | | 1982 | free(vp->ptr); |
1978 | if (vp->sig != NULL) | | 1983 | if (vp->sig != NULL) |
1979 | free(vp->sig); | | 1984 | free(vp->sig); |
1980 | memset(vp, 0, sizeof(struct value)); | | 1985 | memset(vp, 0, sizeof(struct value)); |
1981 | } | | 1986 | } |
1982 | | | 1987 | |
1983 | | | 1988 | |
1984 | /* | | 1989 | /* |
1985 | * crypto_time - returns current NTP time in seconds. | | 1990 | * crypto_time - returns current NTP time in seconds. |
1986 | */ | | 1991 | */ |
1987 | tstamp_t | | 1992 | tstamp_t |
1988 | crypto_time() | | 1993 | crypto_time() |
1989 | { | | 1994 | { |
1990 | l_fp tstamp; /* NTP time */ L_CLR(&tstamp); | | 1995 | l_fp tstamp; /* NTP time */ L_CLR(&tstamp); |
1991 | | | 1996 | |
1992 | L_CLR(&tstamp); | | 1997 | L_CLR(&tstamp); |
1993 | if (sys_leap != LEAP_NOTINSYNC) | | 1998 | if (sys_leap != LEAP_NOTINSYNC) |
1994 | get_systime(&tstamp); | | 1999 | get_systime(&tstamp); |
1995 | return (tstamp.l_ui); | | 2000 | return (tstamp.l_ui); |
1996 | } | | 2001 | } |
1997 | | | 2002 | |
1998 | | | 2003 | |
1999 | /* | | 2004 | /* |
2000 | * asn2ntp - convert ASN1_TIME time structure to NTP time in seconds. | | 2005 | * asn2ntp - convert ASN1_TIME time structure to NTP time in seconds. |
2001 | */ | | 2006 | */ |
2002 | u_long | | 2007 | u_long |
2003 | asn2ntp ( | | 2008 | asn2ntp ( |
2004 | ASN1_TIME *asn1time /* pointer to ASN1_TIME structure */ | | 2009 | ASN1_TIME *asn1time /* pointer to ASN1_TIME structure */ |
2005 | ) | | 2010 | ) |
2006 | { | | 2011 | { |
2007 | char *v; /* pointer to ASN1_TIME string */ | | 2012 | char *v; /* pointer to ASN1_TIME string */ |
2008 | struct tm tm; /* used to convert to NTP time */ | | 2013 | struct tm tm; /* used to convert to NTP time */ |
2009 | | | 2014 | |
2010 | /* | | 2015 | /* |
2011 | * Extract time string YYMMDDHHMMSSZ from ASN1 time structure. | | 2016 | * Extract time string YYMMDDHHMMSSZ from ASN1 time structure. |
2012 | * Note that the YY, MM, DD fields start with one, the HH, MM, | | 2017 | * Note that the YY, MM, DD fields start with one, the HH, MM, |
2013 | * SS fiels start with zero and the Z character should be 'Z' | | 2018 | * SS fiels start with zero and the Z character should be 'Z' |
2014 | * for UTC. Also note that years less than 50 map to years | | 2019 | * for UTC. Also note that years less than 50 map to years |
2015 | * greater than 100. Dontcha love ASN.1? Better than MIL-188. | | 2020 | * greater than 100. Dontcha love ASN.1? Better than MIL-188. |
2016 | */ | | 2021 | */ |
2017 | if (asn1time->length > 13) | | 2022 | if (asn1time->length > 13) |
2018 | return ((u_long)(~0)); /* We can't use -1 here. It's invalid */ | | 2023 | return ((u_long)(~0)); /* We can't use -1 here. It's invalid */ |
2019 | | | 2024 | |
2020 | v = (char *)asn1time->data; | | 2025 | v = (char *)asn1time->data; |
2021 | tm.tm_year = (v[0] - '0') * 10 + v[1] - '0'; | | 2026 | tm.tm_year = (v[0] - '0') * 10 + v[1] - '0'; |
2022 | if (tm.tm_year < 50) | | 2027 | if (tm.tm_year < 50) |
2023 | tm.tm_year += 100; | | 2028 | tm.tm_year += 100; |
2024 | tm.tm_mon = (v[2] - '0') * 10 + v[3] - '0' - 1; | | 2029 | tm.tm_mon = (v[2] - '0') * 10 + v[3] - '0' - 1; |
2025 | tm.tm_mday = (v[4] - '0') * 10 + v[5] - '0'; | | 2030 | tm.tm_mday = (v[4] - '0') * 10 + v[5] - '0'; |
2026 | tm.tm_hour = (v[6] - '0') * 10 + v[7] - '0'; | | 2031 | tm.tm_hour = (v[6] - '0') * 10 + v[7] - '0'; |
2027 | tm.tm_min = (v[8] - '0') * 10 + v[9] - '0'; | | 2032 | tm.tm_min = (v[8] - '0') * 10 + v[9] - '0'; |
2028 | tm.tm_sec = (v[10] - '0') * 10 + v[11] - '0'; | | 2033 | tm.tm_sec = (v[10] - '0') * 10 + v[11] - '0'; |
2029 | tm.tm_wday = 0; | | 2034 | tm.tm_wday = 0; |
2030 | tm.tm_yday = 0; | | 2035 | tm.tm_yday = 0; |
2031 | tm.tm_isdst = 0; | | 2036 | tm.tm_isdst = 0; |
2032 | return (timegm(&tm) + JAN_1970); | | 2037 | return (timegm(&tm) + JAN_1970); |
2033 | } | | 2038 | } |
2034 | | | 2039 | |
2035 | | | 2040 | |
2036 | /* | | 2041 | /* |
2037 | * bigdig() - compute a BIGNUM MD5 hash of a BIGNUM number. | | 2042 | * bigdig() - compute a BIGNUM MD5 hash of a BIGNUM number. |
2038 | */ | | 2043 | */ |
2039 | static int | | 2044 | static int |
2040 | bighash( | | 2045 | bighash( |
2041 | BIGNUM *bn, /* BIGNUM * from */ | | 2046 | BIGNUM *bn, /* BIGNUM * from */ |
2042 | BIGNUM *bk /* BIGNUM * to */ | | 2047 | BIGNUM *bk /* BIGNUM * to */ |
2043 | ) | | 2048 | ) |
2044 | { | | 2049 | { |
2045 | EVP_MD_CTX ctx; /* message digest context */ | | 2050 | EVP_MD_CTX ctx; /* message digest context */ |
2046 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ | | 2051 | u_char dgst[EVP_MAX_MD_SIZE]; /* message digest */ |
2047 | u_char *ptr; /* a BIGNUM as binary string */ | | 2052 | u_char *ptr; /* a BIGNUM as binary string */ |
2048 | u_int len; | | 2053 | u_int len; |
2049 | | | 2054 | |
2050 | len = BN_num_bytes(bn); | | 2055 | len = BN_num_bytes(bn); |
2051 | ptr = emalloc(len); | | 2056 | ptr = emalloc(len); |
2052 | BN_bn2bin(bn, ptr); | | 2057 | BN_bn2bin(bn, ptr); |
2053 | EVP_DigestInit(&ctx, EVP_md5()); | | 2058 | EVP_DigestInit(&ctx, EVP_md5()); |
2054 | EVP_DigestUpdate(&ctx, ptr, len); | | 2059 | EVP_DigestUpdate(&ctx, ptr, len); |
2055 | EVP_DigestFinal(&ctx, dgst, &len); | | 2060 | EVP_DigestFinal(&ctx, dgst, &len); |
2056 | BN_bin2bn(dgst, len, bk); | | 2061 | BN_bin2bn(dgst, len, bk); |
2057 | | | 2062 | |
2058 | /* XXX MEMLEAK? free ptr? */ | | 2063 | /* XXX MEMLEAK? free ptr? */ |
2059 | | | 2064 | |
2060 | return (1); | | 2065 | return (1); |
2061 | } | | 2066 | } |
2062 | | | 2067 | |
2063 | | | 2068 | |
2064 | /* | | 2069 | /* |
2065 | *********************************************************************** | | 2070 | *********************************************************************** |
2066 | * * | | 2071 | * * |
2067 | * The following routines implement the Schnorr (IFF) identity scheme * | | 2072 | * The following routines implement the Schnorr (IFF) identity scheme * |
2068 | * * | | 2073 | * * |
2069 | *********************************************************************** | | 2074 | *********************************************************************** |
2070 | * | | 2075 | * |
2071 | * The Schnorr (IFF) identity scheme is intended for use when | | 2076 | * The Schnorr (IFF) identity scheme is intended for use when |
2072 | * the ntp-genkeys program does not generate the certificates used in | | 2077 | * the ntp-genkeys program does not generate the certificates used in |
2073 | * the protocol and the group key cannot be conveyed in the certificate | | 2078 | * the protocol and the group key cannot be conveyed in the certificate |
2074 | * itself. For this purpose, new generations of IFF values must be | | 2079 | * itself. For this purpose, new generations of IFF values must be |
2075 | * securely transmitted to all members of the group before use. The | | 2080 | * securely transmitted to all members of the group before use. The |
2076 | * scheme is self contained and independent of new generations of host | | 2081 | * scheme is self contained and independent of new generations of host |
2077 | * keys, sign keys and certificates. | | 2082 | * keys, sign keys and certificates. |
2078 | * | | 2083 | * |
2079 | * The IFF identity scheme is based on DSA cryptography and algorithms | | 2084 | * The IFF identity scheme is based on DSA cryptography and algorithms |
2080 | * described in Stinson p. 285. The IFF values hide in a DSA cuckoo | | 2085 | * described in Stinson p. 285. The IFF values hide in a DSA cuckoo |
2081 | * structure, but only the primes and generator are used. The p is a | | 2086 | * structure, but only the primes and generator are used. The p is a |
2082 | * 512-bit prime, q a 160-bit prime that divides p - 1 and is a qth root | | 2087 | * 512-bit prime, q a 160-bit prime that divides p - 1 and is a qth root |
2083 | * of 1 mod p; that is, g^q = 1 mod p. The TA rolls primvate random | | 2088 | * of 1 mod p; that is, g^q = 1 mod p. The TA rolls primvate random |
2084 | * group key b disguised as a DSA structure member, then computes public | | 2089 | * group key b disguised as a DSA structure member, then computes public |
2085 | * key g^(q - b). These values are shared only among group members and | | 2090 | * key g^(q - b). These values are shared only among group members and |
2086 | * never revealed in messages. Alice challenges Bob to confirm identity | | 2091 | * never revealed in messages. Alice challenges Bob to confirm identity |
2087 | * using the protocol described below. | | 2092 | * using the protocol described below. |
2088 | * | | 2093 | * |
2089 | * How it works | | 2094 | * How it works |
2090 | * | | 2095 | * |
2091 | * The scheme goes like this. Both Alice and Bob have the public primes | | 2096 | * The scheme goes like this. Both Alice and Bob have the public primes |
2092 | * p, q and generator g. The TA gives private key b to Bob and public | | 2097 | * p, q and generator g. The TA gives private key b to Bob and public |
2093 | * key v = g^(q - a) mod p to Alice. | | 2098 | * key v = g^(q - a) mod p to Alice. |
2094 | * | | 2099 | * |
2095 | * Alice rolls new random challenge r and sends to Bob in the IFF | | 2100 | * Alice rolls new random challenge r and sends to Bob in the IFF |
2096 | * request message. Bob rolls new random k, then computes y = k + b r | | 2101 | * request message. Bob rolls new random k, then computes y = k + b r |
2097 | * mod q and x = g^k mod p and sends (y, hash(x)) to Alice in the | | 2102 | * mod q and x = g^k mod p and sends (y, hash(x)) to Alice in the |
2098 | * response message. Besides making the response shorter, the hash makes | | 2103 | * response message. Besides making the response shorter, the hash makes |
2099 | * it effectivey impossible for an intruder to solve for b by observing | | 2104 | * it effectivey impossible for an intruder to solve for b by observing |
2100 | * a number of these messages. | | 2105 | * a number of these messages. |
2101 | * | | 2106 | * |
2102 | * Alice receives the response and computes g^y v^r mod p. After a bit | | 2107 | * Alice receives the response and computes g^y v^r mod p. After a bit |
2103 | * of algebra, this simplifies to g^k. If the hash of this result | | 2108 | * of algebra, this simplifies to g^k. If the hash of this result |
2104 | * matches hash(x), Alice knows that Bob has the group key b. The signed | | 2109 | * matches hash(x), Alice knows that Bob has the group key b. The signed |
2105 | * response binds this knowledge to Bob's private key and the public key | | 2110 | * response binds this knowledge to Bob's private key and the public key |
2106 | * previously received in his certificate. | | 2111 | * previously received in his certificate. |
2107 | * | | 2112 | * |
2108 | * crypto_alice - construct Alice's challenge in IFF scheme | | 2113 | * crypto_alice - construct Alice's challenge in IFF scheme |
2109 | * | | 2114 | * |
2110 | * Returns | | 2115 | * Returns |
2111 | * XEVNT_OK success | | 2116 | * XEVNT_OK success |
2112 | * XEVNT_PUB bad or missing public key | | 2117 | * XEVNT_PUB bad or missing public key |
2113 | * XEVNT_ID bad or missing group key | | 2118 | * XEVNT_ID bad or missing group key |
2114 | */ | | 2119 | */ |
2115 | static int | | 2120 | static int |
2116 | crypto_alice( | | 2121 | crypto_alice( |
2117 | struct peer *peer, /* peer pointer */ | | 2122 | struct peer *peer, /* peer pointer */ |
2118 | struct value *vp /* value pointer */ | | 2123 | struct value *vp /* value pointer */ |
2119 | ) | | 2124 | ) |
2120 | { | | 2125 | { |
2121 | DSA *dsa; /* IFF parameters */ | | 2126 | DSA *dsa; /* IFF parameters */ |
2122 | BN_CTX *bctx; /* BIGNUM context */ | | 2127 | BN_CTX *bctx; /* BIGNUM context */ |
2123 | EVP_MD_CTX ctx; /* signature context */ | | 2128 | EVP_MD_CTX ctx; /* signature context */ |
2124 | tstamp_t tstamp; | | 2129 | tstamp_t tstamp; |
2125 | u_int len; | | 2130 | u_int len; |
2126 | | | 2131 | |
2127 | /* | | 2132 | /* |
2128 | * The identity parameters must have correct format and content. | | 2133 | * The identity parameters must have correct format and content. |
2129 | */ | | 2134 | */ |
2130 | if (peer->ident_pkey == NULL) | | 2135 | if (peer->ident_pkey == NULL) |
2131 | return (XEVNT_ID); | | 2136 | return (XEVNT_ID); |
2132 | | | 2137 | |
2133 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { | | 2138 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { |
2134 | msyslog(LOG_INFO, "crypto_alice: defective key"); | | 2139 | msyslog(LOG_INFO, "crypto_alice: defective key"); |
2135 | return (XEVNT_PUB); | | 2140 | return (XEVNT_PUB); |
2136 | } | | 2141 | } |
2137 | | | 2142 | |
2138 | /* | | 2143 | /* |
2139 | * Roll new random r (0 < r < q). The OpenSSL library has a bug | | 2144 | * Roll new random r (0 < r < q). The OpenSSL library has a bug |
2140 | * omitting BN_rand_range, so we have to do it the hard way. | | 2145 | * omitting BN_rand_range, so we have to do it the hard way. |
2141 | */ | | 2146 | */ |
2142 | bctx = BN_CTX_new(); | | 2147 | bctx = BN_CTX_new(); |
2143 | len = BN_num_bytes(dsa->q); | | 2148 | len = BN_num_bytes(dsa->q); |
2144 | if (peer->iffval != NULL) | | 2149 | if (peer->iffval != NULL) |
2145 | BN_free(peer->iffval); | | 2150 | BN_free(peer->iffval); |
2146 | peer->iffval = BN_new(); | | 2151 | peer->iffval = BN_new(); |
2147 | BN_rand(peer->iffval, len * 8, -1, 1); /* r */ | | 2152 | BN_rand(peer->iffval, len * 8, -1, 1); /* r */ |
2148 | BN_mod(peer->iffval, peer->iffval, dsa->q, bctx); | | 2153 | BN_mod(peer->iffval, peer->iffval, dsa->q, bctx); |
2149 | BN_CTX_free(bctx); | | 2154 | BN_CTX_free(bctx); |
2150 | | | 2155 | |
2151 | /* | | 2156 | /* |
2152 | * Sign and send to Bob. The filestamp is from the local file. | | 2157 | * Sign and send to Bob. The filestamp is from the local file. |
2153 | */ | | 2158 | */ |
2154 | tstamp = crypto_time(); | | 2159 | tstamp = crypto_time(); |
2155 | memset(vp, 0, sizeof(struct value)); | | 2160 | memset(vp, 0, sizeof(struct value)); |
2156 | vp->tstamp = htonl(tstamp); | | 2161 | vp->tstamp = htonl(tstamp); |
2157 | vp->fstamp = htonl(peer->fstamp); | | 2162 | vp->fstamp = htonl(peer->fstamp); |
2158 | vp->vallen = htonl(len); | | 2163 | vp->vallen = htonl(len); |
2159 | vp->ptr = emalloc(len); | | 2164 | vp->ptr = emalloc(len); |
2160 | BN_bn2bin(peer->iffval, vp->ptr); | | 2165 | BN_bn2bin(peer->iffval, vp->ptr); |
2161 | vp->siglen = 0; | | 2166 | vp->siglen = 0; |
2162 | if (tstamp == 0) | | 2167 | if (tstamp == 0) |
2163 | return (XEVNT_OK); | | 2168 | return (XEVNT_OK); |
2164 | | | 2169 | |
2165 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2170 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2166 | return (XEVNT_PER); | | 2171 | return (XEVNT_PER); |
2167 | | | 2172 | |
2168 | vp->sig = emalloc(sign_siglen); | | 2173 | vp->sig = emalloc(sign_siglen); |
2169 | EVP_SignInit(&ctx, sign_digest); | | 2174 | EVP_SignInit(&ctx, sign_digest); |
2170 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2175 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2171 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2176 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2172 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2177 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2173 | vp->siglen = htonl(len); | | 2178 | vp->siglen = htonl(len); |
2174 | return (XEVNT_OK); | | 2179 | return (XEVNT_OK); |
2175 | } | | 2180 | } |
2176 | | | 2181 | |
2177 | | | 2182 | |
2178 | /* | | 2183 | /* |
2179 | * crypto_bob - construct Bob's response to Alice's challenge | | 2184 | * crypto_bob - construct Bob's response to Alice's challenge |
2180 | * | | 2185 | * |
2181 | * Returns | | 2186 | * Returns |
2182 | * XEVNT_OK success | | 2187 | * XEVNT_OK success |
2183 | * XEVNT_ID bad or missing group key | | 2188 | * XEVNT_ID bad or missing group key |
2184 | * XEVNT_ERR protocol error | | 2189 | * XEVNT_ERR protocol error |
2185 | * XEVNT_PER host expired certificate | | 2190 | * XEVNT_PER host expired certificate |
2186 | */ | | 2191 | */ |
2187 | static int | | 2192 | static int |
2188 | crypto_bob( | | 2193 | crypto_bob( |
2189 | struct exten *ep, /* extension pointer */ | | 2194 | struct exten *ep, /* extension pointer */ |
2190 | struct value *vp /* value pointer */ | | 2195 | struct value *vp /* value pointer */ |
2191 | ) | | 2196 | ) |
2192 | { | | 2197 | { |
2193 | DSA *dsa; /* IFF parameters */ | | 2198 | DSA *dsa; /* IFF parameters */ |
2194 | DSA_SIG *sdsa; /* DSA signature context fake */ | | 2199 | DSA_SIG *sdsa; /* DSA signature context fake */ |
2195 | BN_CTX *bctx; /* BIGNUM context */ | | 2200 | BN_CTX *bctx; /* BIGNUM context */ |
2196 | EVP_MD_CTX ctx; /* signature context */ | | 2201 | EVP_MD_CTX ctx; /* signature context */ |
2197 | tstamp_t tstamp; /* NTP timestamp */ | | 2202 | tstamp_t tstamp; /* NTP timestamp */ |
2198 | BIGNUM *bn, *bk, *r; | | 2203 | BIGNUM *bn, *bk, *r; |
2199 | u_char *ptr; | | 2204 | u_char *ptr; |
2200 | u_int len; | | 2205 | u_int len; |
2201 | | | 2206 | |
2202 | /* | | 2207 | /* |
2203 | * If the IFF parameters are not valid, something awful | | 2208 | * If the IFF parameters are not valid, something awful |
2204 | * happened or we are being tormented. | | 2209 | * happened or we are being tormented. |
2205 | */ | | 2210 | */ |
2206 | if (iffpar_pkey == NULL) { | | 2211 | if (iffpar_pkey == NULL) { |
2207 | msyslog(LOG_INFO, "crypto_bob: scheme unavailable"); | | 2212 | msyslog(LOG_INFO, "crypto_bob: scheme unavailable"); |
2208 | return (XEVNT_ID); | | 2213 | return (XEVNT_ID); |
2209 | } | | 2214 | } |
2210 | dsa = iffpar_pkey->pkey.dsa; | | 2215 | dsa = iffpar_pkey->pkey.dsa; |
2211 | | | 2216 | |
2212 | /* | | 2217 | /* |
2213 | * Extract r from the challenge. | | 2218 | * Extract r from the challenge. |
2214 | */ | | 2219 | */ |
2215 | len = ntohl(ep->vallen); | | 2220 | len = ntohl(ep->vallen); |
2216 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { | | 2221 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2217 | msyslog(LOG_ERR, "crypto_bob %s\n", | | 2222 | msyslog(LOG_ERR, "crypto_bob %s\n", |
2218 | ERR_error_string(ERR_get_error(), NULL)); | | 2223 | ERR_error_string(ERR_get_error(), NULL)); |
2219 | return (XEVNT_ERR); | | 2224 | return (XEVNT_ERR); |
2220 | } | | 2225 | } |
2221 | | | 2226 | |
2222 | /* | | 2227 | /* |
2223 | * Bob rolls random k (0 < k < q), computes y = k + b r mod q | | 2228 | * Bob rolls random k (0 < k < q), computes y = k + b r mod q |
2224 | * and x = g^k mod p, then sends (y, hash(x)) to Alice. | | 2229 | * and x = g^k mod p, then sends (y, hash(x)) to Alice. |
2225 | */ | | 2230 | */ |
2226 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); | | 2231 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); |
2227 | sdsa = DSA_SIG_new(); | | 2232 | sdsa = DSA_SIG_new(); |
2228 | BN_rand(bk, len * 8, -1, 1); /* k */ | | 2233 | BN_rand(bk, len * 8, -1, 1); /* k */ |
2229 | BN_mod_mul(bn, dsa->priv_key, r, dsa->q, bctx); /* b r mod q */ | | 2234 | BN_mod_mul(bn, dsa->priv_key, r, dsa->q, bctx); /* b r mod q */ |
2230 | BN_add(bn, bn, bk); | | 2235 | BN_add(bn, bn, bk); |
2231 | BN_mod(bn, bn, dsa->q, bctx); /* k + b r mod q */ | | 2236 | BN_mod(bn, bn, dsa->q, bctx); /* k + b r mod q */ |
2232 | sdsa->r = BN_dup(bn); | | 2237 | sdsa->r = BN_dup(bn); |
2233 | BN_mod_exp(bk, dsa->g, bk, dsa->p, bctx); /* g^k mod p */ | | 2238 | BN_mod_exp(bk, dsa->g, bk, dsa->p, bctx); /* g^k mod p */ |
2234 | bighash(bk, bk); | | 2239 | bighash(bk, bk); |
2235 | sdsa->s = BN_dup(bk); | | 2240 | sdsa->s = BN_dup(bk); |
2236 | BN_CTX_free(bctx); | | 2241 | BN_CTX_free(bctx); |
2237 | BN_free(r); BN_free(bn); BN_free(bk); | | 2242 | BN_free(r); BN_free(bn); BN_free(bk); |
2238 | | | 2243 | |
2239 | /* | | 2244 | /* |
2240 | * Encode the values in ASN.1 and sign. | | 2245 | * Encode the values in ASN.1 and sign. |
2241 | */ | | 2246 | */ |
2242 | tstamp = crypto_time(); | | 2247 | tstamp = crypto_time(); |
2243 | memset(vp, 0, sizeof(struct value)); | | 2248 | memset(vp, 0, sizeof(struct value)); |
2244 | vp->tstamp = htonl(tstamp); | | 2249 | vp->tstamp = htonl(tstamp); |
2245 | vp->fstamp = htonl(if_fstamp); | | 2250 | vp->fstamp = htonl(if_fstamp); |
2246 | len = i2d_DSA_SIG(sdsa, NULL); | | 2251 | len = i2d_DSA_SIG(sdsa, NULL); |
2247 | if (len <= 0) { | | 2252 | if (len <= 0) { |
2248 | msyslog(LOG_ERR, "crypto_bob %s\n", | | 2253 | msyslog(LOG_ERR, "crypto_bob %s\n", |
2249 | ERR_error_string(ERR_get_error(), NULL)); | | 2254 | ERR_error_string(ERR_get_error(), NULL)); |
2250 | DSA_SIG_free(sdsa); | | 2255 | DSA_SIG_free(sdsa); |
2251 | return (XEVNT_ERR); | | 2256 | return (XEVNT_ERR); |
2252 | } | | 2257 | } |
2253 | vp->vallen = htonl(len); | | 2258 | vp->vallen = htonl(len); |
2254 | ptr = emalloc(len); | | 2259 | ptr = emalloc(len); |
2255 | vp->ptr = ptr; | | 2260 | vp->ptr = ptr; |
2256 | i2d_DSA_SIG(sdsa, &ptr); | | 2261 | i2d_DSA_SIG(sdsa, &ptr); |
2257 | DSA_SIG_free(sdsa); | | 2262 | DSA_SIG_free(sdsa); |
2258 | vp->siglen = 0; | | 2263 | vp->siglen = 0; |
2259 | if (tstamp == 0) | | 2264 | if (tstamp == 0) |
2260 | return (XEVNT_OK); | | 2265 | return (XEVNT_OK); |
2261 | | | 2266 | |
2262 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2267 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2263 | return (XEVNT_PER); | | 2268 | return (XEVNT_PER); |
2264 | | | 2269 | |
2265 | vp->sig = emalloc(sign_siglen); | | 2270 | vp->sig = emalloc(sign_siglen); |
2266 | EVP_SignInit(&ctx, sign_digest); | | 2271 | EVP_SignInit(&ctx, sign_digest); |
2267 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2272 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2268 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2273 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2269 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2274 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2270 | vp->siglen = htonl(len); | | 2275 | vp->siglen = htonl(len); |
2271 | return (XEVNT_OK); | | 2276 | return (XEVNT_OK); |
2272 | } | | 2277 | } |
2273 | | | 2278 | |
2274 | | | 2279 | |
2275 | /* | | 2280 | /* |
2276 | * crypto_iff - verify Bob's response to Alice's challenge | | 2281 | * crypto_iff - verify Bob's response to Alice's challenge |
2277 | * | | 2282 | * |
2278 | * Returns | | 2283 | * Returns |
2279 | * XEVNT_OK success | | 2284 | * XEVNT_OK success |
2280 | * XEVNT_PUB bad or missing public key | | 2285 | * XEVNT_PUB bad or missing public key |
2281 | * XEVNT_ID bad or missing group key | | 2286 | * XEVNT_ID bad or missing group key |
2282 | * XEVNT_FSP bad filestamp | | 2287 | * XEVNT_FSP bad filestamp |
2283 | */ | | 2288 | */ |
2284 | int | | 2289 | int |
2285 | crypto_iff( | | 2290 | crypto_iff( |
2286 | struct exten *ep, /* extension pointer */ | | 2291 | struct exten *ep, /* extension pointer */ |
2287 | struct peer *peer /* peer structure pointer */ | | 2292 | struct peer *peer /* peer structure pointer */ |
2288 | ) | | 2293 | ) |
2289 | { | | 2294 | { |
2290 | DSA *dsa; /* IFF parameters */ | | 2295 | DSA *dsa; /* IFF parameters */ |
2291 | BN_CTX *bctx; /* BIGNUM context */ | | 2296 | BN_CTX *bctx; /* BIGNUM context */ |
2292 | DSA_SIG *sdsa; /* DSA parameters */ | | 2297 | DSA_SIG *sdsa; /* DSA parameters */ |
2293 | BIGNUM *bn, *bk; | | 2298 | BIGNUM *bn, *bk; |
2294 | u_int len; | | 2299 | u_int len; |
2295 | const u_char *ptr; | | 2300 | const u_char *ptr; |
2296 | int temp; | | 2301 | int temp; |
2297 | | | 2302 | |
2298 | /* | | 2303 | /* |
2299 | * If the IFF parameters are not valid or no challenge was sent, | | 2304 | * If the IFF parameters are not valid or no challenge was sent, |
2300 | * something awful happened or we are being tormented. | | 2305 | * something awful happened or we are being tormented. |
2301 | */ | | 2306 | */ |
2302 | if (peer->ident_pkey == NULL) { | | 2307 | if (peer->ident_pkey == NULL) { |
2303 | msyslog(LOG_INFO, "crypto_iff: scheme unavailable"); | | 2308 | msyslog(LOG_INFO, "crypto_iff: scheme unavailable"); |
2304 | return (XEVNT_ID); | | 2309 | return (XEVNT_ID); |
2305 | } | | 2310 | } |
2306 | if (ntohl(ep->fstamp) != peer->fstamp) { | | 2311 | if (ntohl(ep->fstamp) != peer->fstamp) { |
2307 | msyslog(LOG_INFO, "crypto_iff: invalid filestamp %u", | | 2312 | msyslog(LOG_INFO, "crypto_iff: invalid filestamp %u", |
2308 | ntohl(ep->fstamp)); | | 2313 | ntohl(ep->fstamp)); |
2309 | return (XEVNT_FSP); | | 2314 | return (XEVNT_FSP); |
2310 | } | | 2315 | } |
2311 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { | | 2316 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { |
2312 | msyslog(LOG_INFO, "crypto_iff: defective key"); | | 2317 | msyslog(LOG_INFO, "crypto_iff: defective key"); |
2313 | return (XEVNT_PUB); | | 2318 | return (XEVNT_PUB); |
2314 | } | | 2319 | } |
2315 | if (peer->iffval == NULL) { | | 2320 | if (peer->iffval == NULL) { |
2316 | msyslog(LOG_INFO, "crypto_iff: missing challenge"); | | 2321 | msyslog(LOG_INFO, "crypto_iff: missing challenge"); |
2317 | return (XEVNT_ID); | | 2322 | return (XEVNT_ID); |
2318 | } | | 2323 | } |
2319 | | | 2324 | |
2320 | /* | | 2325 | /* |
2321 | * Extract the k + b r and g^k values from the response. | | 2326 | * Extract the k + b r and g^k values from the response. |
2322 | */ | | 2327 | */ |
2323 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); | | 2328 | bctx = BN_CTX_new(); bk = BN_new(); bn = BN_new(); |
2324 | len = ntohl(ep->vallen); | | 2329 | len = ntohl(ep->vallen); |
2325 | ptr = (const u_char *)ep->pkt; | | 2330 | ptr = (const u_char *)ep->pkt; |
2326 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { | | 2331 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { |
2327 | msyslog(LOG_ERR, "crypto_iff %s\n", | | 2332 | msyslog(LOG_ERR, "crypto_iff %s\n", |
2328 | ERR_error_string(ERR_get_error(), NULL)); | | 2333 | ERR_error_string(ERR_get_error(), NULL)); |
2329 | return (XEVNT_ERR); | | 2334 | return (XEVNT_ERR); |
2330 | } | | 2335 | } |
2331 | | | 2336 | |
2332 | /* | | 2337 | /* |
2333 | * Compute g^(k + b r) g^(q - b)r mod p. | | 2338 | * Compute g^(k + b r) g^(q - b)r mod p. |
2334 | */ | | 2339 | */ |
2335 | BN_mod_exp(bn, dsa->pub_key, peer->iffval, dsa->p, bctx); | | 2340 | BN_mod_exp(bn, dsa->pub_key, peer->iffval, dsa->p, bctx); |
2336 | BN_mod_exp(bk, dsa->g, sdsa->r, dsa->p, bctx); | | 2341 | BN_mod_exp(bk, dsa->g, sdsa->r, dsa->p, bctx); |
2337 | BN_mod_mul(bn, bn, bk, dsa->p, bctx); | | 2342 | BN_mod_mul(bn, bn, bk, dsa->p, bctx); |
2338 | | | 2343 | |
2339 | /* | | 2344 | /* |
2340 | * Verify the hash of the result matches hash(x). | | 2345 | * Verify the hash of the result matches hash(x). |
2341 | */ | | 2346 | */ |
2342 | bighash(bn, bn); | | 2347 | bighash(bn, bn); |
2343 | temp = BN_cmp(bn, sdsa->s); | | 2348 | temp = BN_cmp(bn, sdsa->s); |
2344 | BN_free(bn); BN_free(bk); BN_CTX_free(bctx); | | 2349 | BN_free(bn); BN_free(bk); BN_CTX_free(bctx); |
2345 | BN_free(peer->iffval); | | 2350 | BN_free(peer->iffval); |
2346 | peer->iffval = NULL; | | 2351 | peer->iffval = NULL; |
2347 | DSA_SIG_free(sdsa); | | 2352 | DSA_SIG_free(sdsa); |
2348 | if (temp == 0) | | 2353 | if (temp == 0) |
2349 | return (XEVNT_OK); | | 2354 | return (XEVNT_OK); |
2350 | | | 2355 | |
2351 | else | | 2356 | else |
2352 | return (XEVNT_ID); | | 2357 | return (XEVNT_ID); |
2353 | } | | 2358 | } |
2354 | | | 2359 | |
2355 | | | 2360 | |
2356 | /* | | 2361 | /* |
2357 | *********************************************************************** | | 2362 | *********************************************************************** |
2358 | * * | | 2363 | * * |
2359 | * The following routines implement the Guillou-Quisquater (GQ) * | | 2364 | * The following routines implement the Guillou-Quisquater (GQ) * |
2360 | * identity scheme * | | 2365 | * identity scheme * |
2361 | * * | | 2366 | * * |
2362 | *********************************************************************** | | 2367 | *********************************************************************** |
2363 | * | | 2368 | * |
2364 | * The Guillou-Quisquater (GQ) identity scheme is intended for use when | | 2369 | * The Guillou-Quisquater (GQ) identity scheme is intended for use when |
2365 | * the ntp-genkeys program generates the certificates used in the | | 2370 | * the ntp-genkeys program generates the certificates used in the |
2366 | * protocol and the group key can be conveyed in a certificate extension | | 2371 | * protocol and the group key can be conveyed in a certificate extension |
2367 | * field. The scheme is self contained and independent of new | | 2372 | * field. The scheme is self contained and independent of new |
2368 | * generations of host keys, sign keys and certificates. | | 2373 | * generations of host keys, sign keys and certificates. |
2369 | * | | 2374 | * |
2370 | * The GQ identity scheme is based on RSA cryptography and algorithms | | 2375 | * The GQ identity scheme is based on RSA cryptography and algorithms |
2371 | * described in Stinson p. 300 (with errors). The GQ values hide in a | | 2376 | * described in Stinson p. 300 (with errors). The GQ values hide in a |
2372 | * RSA cuckoo structure, but only the modulus is used. The 512-bit | | 2377 | * RSA cuckoo structure, but only the modulus is used. The 512-bit |
2373 | * public modulus is n = p q, where p and q are secret large primes. The | | 2378 | * public modulus is n = p q, where p and q are secret large primes. The |
2374 | * TA rolls random group key b disguised as a RSA structure member. | | 2379 | * TA rolls random group key b disguised as a RSA structure member. |
2375 | * Except for the public key, these values are shared only among group | | 2380 | * Except for the public key, these values are shared only among group |
2376 | * members and never revealed in messages. | | 2381 | * members and never revealed in messages. |
2377 | * | | 2382 | * |
2378 | * When rolling new certificates, Bob recomputes the private and | | 2383 | * When rolling new certificates, Bob recomputes the private and |
2379 | * public keys. The private key u is a random roll, while the public key | | 2384 | * public keys. The private key u is a random roll, while the public key |
2380 | * is the inverse obscured by the group key v = (u^-1)^b. These values | | 2385 | * is the inverse obscured by the group key v = (u^-1)^b. These values |
2381 | * replace the private and public keys normally generated by the RSA | | 2386 | * replace the private and public keys normally generated by the RSA |
2382 | * scheme. Alice challenges Bob to confirm identity using the protocol | | 2387 | * scheme. Alice challenges Bob to confirm identity using the protocol |
2383 | * described below. | | 2388 | * described below. |
2384 | * | | 2389 | * |
2385 | * How it works | | 2390 | * How it works |
2386 | * | | 2391 | * |
2387 | * The scheme goes like this. Both Alice and Bob have the same modulus n | | 2392 | * The scheme goes like this. Both Alice and Bob have the same modulus n |
2388 | * and some random b as the group key. These values are computed and | | 2393 | * and some random b as the group key. These values are computed and |
2389 | * distributed in advance via secret means, although only the group key | | 2394 | * distributed in advance via secret means, although only the group key |
2390 | * b is truly secret. Each has a private random private key u and public | | 2395 | * b is truly secret. Each has a private random private key u and public |
2391 | * key (u^-1)^b, although not necessarily the same ones. Bob and Alice | | 2396 | * key (u^-1)^b, although not necessarily the same ones. Bob and Alice |
2392 | * can regenerate the key pair from time to time without affecting | | 2397 | * can regenerate the key pair from time to time without affecting |
2393 | * operations. The public key is conveyed on the certificate in an | | 2398 | * operations. The public key is conveyed on the certificate in an |
2394 | * extension field; the private key is never revealed. | | 2399 | * extension field; the private key is never revealed. |
2395 | * | | 2400 | * |
2396 | * Alice rolls new random challenge r and sends to Bob in the GQ | | 2401 | * Alice rolls new random challenge r and sends to Bob in the GQ |
2397 | * request message. Bob rolls new random k, then computes y = k u^r mod | | 2402 | * request message. Bob rolls new random k, then computes y = k u^r mod |
2398 | * n and x = k^b mod n and sends (y, hash(x)) to Alice in the response | | 2403 | * n and x = k^b mod n and sends (y, hash(x)) to Alice in the response |
2399 | * message. Besides making the response shorter, the hash makes it | | 2404 | * message. Besides making the response shorter, the hash makes it |
2400 | * effectivey impossible for an intruder to solve for b by observing | | 2405 | * effectivey impossible for an intruder to solve for b by observing |
2401 | * a number of these messages. | | 2406 | * a number of these messages. |
2402 | * | | 2407 | * |
2403 | * Alice receives the response and computes y^b v^r mod n. After a bit | | 2408 | * Alice receives the response and computes y^b v^r mod n. After a bit |
2404 | * of algebra, this simplifies to k^b. If the hash of this result | | 2409 | * of algebra, this simplifies to k^b. If the hash of this result |
2405 | * matches hash(x), Alice knows that Bob has the group key b. The signed | | 2410 | * matches hash(x), Alice knows that Bob has the group key b. The signed |
2406 | * response binds this knowledge to Bob's private key and the public key | | 2411 | * response binds this knowledge to Bob's private key and the public key |
2407 | * previously received in his certificate. | | 2412 | * previously received in his certificate. |
2408 | * | | 2413 | * |
2409 | * crypto_alice2 - construct Alice's challenge in GQ scheme | | 2414 | * crypto_alice2 - construct Alice's challenge in GQ scheme |
2410 | * | | 2415 | * |
2411 | * Returns | | 2416 | * Returns |
2412 | * XEVNT_OK success | | 2417 | * XEVNT_OK success |
2413 | * XEVNT_PUB bad or missing public key | | 2418 | * XEVNT_PUB bad or missing public key |
2414 | * XEVNT_ID bad or missing group key | | 2419 | * XEVNT_ID bad or missing group key |
2415 | * XEVNT_PER host certificate expired | | 2420 | * XEVNT_PER host certificate expired |
2416 | */ | | 2421 | */ |
2417 | static int | | 2422 | static int |
2418 | crypto_alice2( | | 2423 | crypto_alice2( |
2419 | struct peer *peer, /* peer pointer */ | | 2424 | struct peer *peer, /* peer pointer */ |
2420 | struct value *vp /* value pointer */ | | 2425 | struct value *vp /* value pointer */ |
2421 | ) | | 2426 | ) |
2422 | { | | 2427 | { |
2423 | RSA *rsa; /* GQ parameters */ | | 2428 | RSA *rsa; /* GQ parameters */ |
2424 | BN_CTX *bctx; /* BIGNUM context */ | | 2429 | BN_CTX *bctx; /* BIGNUM context */ |
2425 | EVP_MD_CTX ctx; /* signature context */ | | 2430 | EVP_MD_CTX ctx; /* signature context */ |
2426 | tstamp_t tstamp; | | 2431 | tstamp_t tstamp; |
2427 | u_int len; | | 2432 | u_int len; |
2428 | | | 2433 | |
2429 | /* | | 2434 | /* |
2430 | * The identity parameters must have correct format and content. | | 2435 | * The identity parameters must have correct format and content. |
2431 | */ | | 2436 | */ |
2432 | if (peer->ident_pkey == NULL) | | 2437 | if (peer->ident_pkey == NULL) |
2433 | return (XEVNT_ID); | | 2438 | return (XEVNT_ID); |
2434 | | | 2439 | |
2435 | if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) { | | 2440 | if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) { |
2436 | msyslog(LOG_INFO, "crypto_alice2: defective key"); | | 2441 | msyslog(LOG_INFO, "crypto_alice2: defective key"); |
2437 | return (XEVNT_PUB); | | 2442 | return (XEVNT_PUB); |
2438 | } | | 2443 | } |
2439 | | | 2444 | |
2440 | /* | | 2445 | /* |
2441 | * Roll new random r (0 < r < n). The OpenSSL library has a bug | | 2446 | * Roll new random r (0 < r < n). The OpenSSL library has a bug |
2442 | * omitting BN_rand_range, so we have to do it the hard way. | | 2447 | * omitting BN_rand_range, so we have to do it the hard way. |
2443 | */ | | 2448 | */ |
2444 | bctx = BN_CTX_new(); | | 2449 | bctx = BN_CTX_new(); |
2445 | len = BN_num_bytes(rsa->n); | | 2450 | len = BN_num_bytes(rsa->n); |
2446 | if (peer->iffval != NULL) | | 2451 | if (peer->iffval != NULL) |
2447 | BN_free(peer->iffval); | | 2452 | BN_free(peer->iffval); |
2448 | peer->iffval = BN_new(); | | 2453 | peer->iffval = BN_new(); |
2449 | BN_rand(peer->iffval, len * 8, -1, 1); /* r mod n */ | | 2454 | BN_rand(peer->iffval, len * 8, -1, 1); /* r mod n */ |
2450 | BN_mod(peer->iffval, peer->iffval, rsa->n, bctx); | | 2455 | BN_mod(peer->iffval, peer->iffval, rsa->n, bctx); |
2451 | BN_CTX_free(bctx); | | 2456 | BN_CTX_free(bctx); |
2452 | | | 2457 | |
2453 | /* | | 2458 | /* |
2454 | * Sign and send to Bob. The filestamp is from the local file. | | 2459 | * Sign and send to Bob. The filestamp is from the local file. |
2455 | */ | | 2460 | */ |
2456 | tstamp = crypto_time(); | | 2461 | tstamp = crypto_time(); |
2457 | memset(vp, 0, sizeof(struct value)); | | 2462 | memset(vp, 0, sizeof(struct value)); |
2458 | vp->tstamp = htonl(tstamp); | | 2463 | vp->tstamp = htonl(tstamp); |
2459 | vp->fstamp = htonl(peer->fstamp); | | 2464 | vp->fstamp = htonl(peer->fstamp); |
2460 | vp->vallen = htonl(len); | | 2465 | vp->vallen = htonl(len); |
2461 | vp->ptr = emalloc(len); | | 2466 | vp->ptr = emalloc(len); |
2462 | BN_bn2bin(peer->iffval, vp->ptr); | | 2467 | BN_bn2bin(peer->iffval, vp->ptr); |
2463 | vp->siglen = 0; | | 2468 | vp->siglen = 0; |
2464 | if (tstamp == 0) | | 2469 | if (tstamp == 0) |
2465 | return (XEVNT_OK); | | 2470 | return (XEVNT_OK); |
2466 | | | 2471 | |
2467 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2472 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2468 | return (XEVNT_PER); | | 2473 | return (XEVNT_PER); |
2469 | | | 2474 | |
2470 | vp->sig = emalloc(sign_siglen); | | 2475 | vp->sig = emalloc(sign_siglen); |
2471 | EVP_SignInit(&ctx, sign_digest); | | 2476 | EVP_SignInit(&ctx, sign_digest); |
2472 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2477 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2473 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2478 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2474 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2479 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2475 | vp->siglen = htonl(len); | | 2480 | vp->siglen = htonl(len); |
2476 | return (XEVNT_OK); | | 2481 | return (XEVNT_OK); |
2477 | } | | 2482 | } |
2478 | | | 2483 | |
2479 | | | 2484 | |
2480 | /* | | 2485 | /* |
2481 | * crypto_bob2 - construct Bob's response to Alice's challenge | | 2486 | * crypto_bob2 - construct Bob's response to Alice's challenge |
2482 | * | | 2487 | * |
2483 | * Returns | | 2488 | * Returns |
2484 | * XEVNT_OK success | | 2489 | * XEVNT_OK success |
2485 | * XEVNT_ID bad or missing group key | | 2490 | * XEVNT_ID bad or missing group key |
2486 | * XEVNT_ERR protocol error | | 2491 | * XEVNT_ERR protocol error |
2487 | * XEVNT_PER host certificate expired | | 2492 | * XEVNT_PER host certificate expired |
2488 | */ | | 2493 | */ |
2489 | static int | | 2494 | static int |
2490 | crypto_bob2( | | 2495 | crypto_bob2( |
2491 | struct exten *ep, /* extension pointer */ | | 2496 | struct exten *ep, /* extension pointer */ |
2492 | struct value *vp /* value pointer */ | | 2497 | struct value *vp /* value pointer */ |
2493 | ) | | 2498 | ) |
2494 | { | | 2499 | { |
2495 | RSA *rsa; /* GQ parameters */ | | 2500 | RSA *rsa; /* GQ parameters */ |
2496 | DSA_SIG *sdsa; /* DSA parameters */ | | 2501 | DSA_SIG *sdsa; /* DSA parameters */ |
2497 | BN_CTX *bctx; /* BIGNUM context */ | | 2502 | BN_CTX *bctx; /* BIGNUM context */ |
2498 | EVP_MD_CTX ctx; /* signature context */ | | 2503 | EVP_MD_CTX ctx; /* signature context */ |
2499 | tstamp_t tstamp; /* NTP timestamp */ | | 2504 | tstamp_t tstamp; /* NTP timestamp */ |
2500 | BIGNUM *r, *k, *g, *y; | | 2505 | BIGNUM *r, *k, *g, *y; |
2501 | u_char *ptr; | | 2506 | u_char *ptr; |
2502 | u_int len; | | 2507 | u_int len; |
2503 | | | 2508 | |
2504 | /* | | 2509 | /* |
2505 | * If the GQ parameters are not valid, something awful | | 2510 | * If the GQ parameters are not valid, something awful |
2506 | * happened or we are being tormented. | | 2511 | * happened or we are being tormented. |
2507 | */ | | 2512 | */ |
2508 | if (gqpar_pkey == NULL) { | | 2513 | if (gqpar_pkey == NULL) { |
2509 | msyslog(LOG_INFO, "crypto_bob2: scheme unavailable"); | | 2514 | msyslog(LOG_INFO, "crypto_bob2: scheme unavailable"); |
2510 | return (XEVNT_ID); | | 2515 | return (XEVNT_ID); |
2511 | } | | 2516 | } |
2512 | rsa = gqpar_pkey->pkey.rsa; | | 2517 | rsa = gqpar_pkey->pkey.rsa; |
2513 | | | 2518 | |
2514 | /* | | 2519 | /* |
2515 | * Extract r from the challenge. | | 2520 | * Extract r from the challenge. |
2516 | */ | | 2521 | */ |
2517 | len = ntohl(ep->vallen); | | 2522 | len = ntohl(ep->vallen); |
2518 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { | | 2523 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2519 | msyslog(LOG_ERR, "crypto_bob2 %s\n", | | 2524 | msyslog(LOG_ERR, "crypto_bob2 %s\n", |
2520 | ERR_error_string(ERR_get_error(), NULL)); | | 2525 | ERR_error_string(ERR_get_error(), NULL)); |
2521 | return (XEVNT_ERR); | | 2526 | return (XEVNT_ERR); |
2522 | } | | 2527 | } |
2523 | | | 2528 | |
2524 | /* | | 2529 | /* |
2525 | * Bob rolls random k (0 < k < n), computes y = k u^r mod n and | | 2530 | * Bob rolls random k (0 < k < n), computes y = k u^r mod n and |
2526 | * x = k^b mod n, then sends (y, hash(x)) to Alice. | | 2531 | * x = k^b mod n, then sends (y, hash(x)) to Alice. |
2527 | */ | | 2532 | */ |
2528 | bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new(); | | 2533 | bctx = BN_CTX_new(); k = BN_new(); g = BN_new(); y = BN_new(); |
2529 | sdsa = DSA_SIG_new(); | | 2534 | sdsa = DSA_SIG_new(); |
2530 | BN_rand(k, len * 8, -1, 1); /* k */ | | 2535 | BN_rand(k, len * 8, -1, 1); /* k */ |
2531 | BN_mod(k, k, rsa->n, bctx); | | 2536 | BN_mod(k, k, rsa->n, bctx); |
2532 | BN_mod_exp(y, rsa->p, r, rsa->n, bctx); /* u^r mod n */ | | 2537 | BN_mod_exp(y, rsa->p, r, rsa->n, bctx); /* u^r mod n */ |
2533 | BN_mod_mul(y, k, y, rsa->n, bctx); /* k u^r mod n */ | | 2538 | BN_mod_mul(y, k, y, rsa->n, bctx); /* k u^r mod n */ |
2534 | sdsa->r = BN_dup(y); | | 2539 | sdsa->r = BN_dup(y); |
2535 | BN_mod_exp(g, k, rsa->e, rsa->n, bctx); /* k^b mod n */ | | 2540 | BN_mod_exp(g, k, rsa->e, rsa->n, bctx); /* k^b mod n */ |
2536 | bighash(g, g); | | 2541 | bighash(g, g); |
2537 | sdsa->s = BN_dup(g); | | 2542 | sdsa->s = BN_dup(g); |
2538 | BN_CTX_free(bctx); | | 2543 | BN_CTX_free(bctx); |
2539 | BN_free(r); BN_free(k); BN_free(g); BN_free(y); | | 2544 | BN_free(r); BN_free(k); BN_free(g); BN_free(y); |
2540 | | | 2545 | |
2541 | /* | | 2546 | /* |
2542 | * Encode the values in ASN.1 and sign. | | 2547 | * Encode the values in ASN.1 and sign. |
2543 | */ | | 2548 | */ |
2544 | tstamp = crypto_time(); | | 2549 | tstamp = crypto_time(); |
2545 | memset(vp, 0, sizeof(struct value)); | | 2550 | memset(vp, 0, sizeof(struct value)); |
2546 | vp->tstamp = htonl(tstamp); | | 2551 | vp->tstamp = htonl(tstamp); |
2547 | vp->fstamp = htonl(gq_fstamp); | | 2552 | vp->fstamp = htonl(gq_fstamp); |
2548 | len = i2d_DSA_SIG(sdsa, NULL); | | 2553 | len = i2d_DSA_SIG(sdsa, NULL); |
2549 | if (len <= 0) { | | 2554 | if (len <= 0) { |
2550 | msyslog(LOG_ERR, "crypto_bob2 %s\n", | | 2555 | msyslog(LOG_ERR, "crypto_bob2 %s\n", |
2551 | ERR_error_string(ERR_get_error(), NULL)); | | 2556 | ERR_error_string(ERR_get_error(), NULL)); |
2552 | DSA_SIG_free(sdsa); | | 2557 | DSA_SIG_free(sdsa); |
2553 | return (XEVNT_ERR); | | 2558 | return (XEVNT_ERR); |
2554 | } | | 2559 | } |
2555 | vp->vallen = htonl(len); | | 2560 | vp->vallen = htonl(len); |
2556 | ptr = emalloc(len); | | 2561 | ptr = emalloc(len); |
2557 | vp->ptr = ptr; | | 2562 | vp->ptr = ptr; |
2558 | i2d_DSA_SIG(sdsa, &ptr); | | 2563 | i2d_DSA_SIG(sdsa, &ptr); |
2559 | DSA_SIG_free(sdsa); | | 2564 | DSA_SIG_free(sdsa); |
2560 | vp->siglen = 0; | | 2565 | vp->siglen = 0; |
2561 | if (tstamp == 0) | | 2566 | if (tstamp == 0) |
2562 | return (XEVNT_OK); | | 2567 | return (XEVNT_OK); |
2563 | | | 2568 | |
2564 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2569 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2565 | return (XEVNT_PER); | | 2570 | return (XEVNT_PER); |
2566 | | | 2571 | |
2567 | vp->sig = emalloc(sign_siglen); | | 2572 | vp->sig = emalloc(sign_siglen); |
2568 | EVP_SignInit(&ctx, sign_digest); | | 2573 | EVP_SignInit(&ctx, sign_digest); |
2569 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2574 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2570 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2575 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2571 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2576 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2572 | vp->siglen = htonl(len); | | 2577 | vp->siglen = htonl(len); |
2573 | return (XEVNT_OK); | | 2578 | return (XEVNT_OK); |
2574 | } | | 2579 | } |
2575 | | | 2580 | |
2576 | | | 2581 | |
2577 | /* | | 2582 | /* |
2578 | * crypto_gq - verify Bob's response to Alice's challenge | | 2583 | * crypto_gq - verify Bob's response to Alice's challenge |
2579 | * | | 2584 | * |
2580 | * Returns | | 2585 | * Returns |
2581 | * XEVNT_OK success | | 2586 | * XEVNT_OK success |
2582 | * XEVNT_PUB bad or missing public key | | 2587 | * XEVNT_PUB bad or missing public key |
2583 | * XEVNT_ID bad or missing group keys | | 2588 | * XEVNT_ID bad or missing group keys |
2584 | * XEVNT_ERR protocol error | | 2589 | * XEVNT_ERR protocol error |
2585 | * XEVNT_FSP bad filestamp | | 2590 | * XEVNT_FSP bad filestamp |
2586 | */ | | 2591 | */ |
2587 | int | | 2592 | int |
2588 | crypto_gq( | | 2593 | crypto_gq( |
2589 | struct exten *ep, /* extension pointer */ | | 2594 | struct exten *ep, /* extension pointer */ |
2590 | struct peer *peer /* peer structure pointer */ | | 2595 | struct peer *peer /* peer structure pointer */ |
2591 | ) | | 2596 | ) |
2592 | { | | 2597 | { |
2593 | RSA *rsa; /* GQ parameters */ | | 2598 | RSA *rsa; /* GQ parameters */ |
2594 | BN_CTX *bctx; /* BIGNUM context */ | | 2599 | BN_CTX *bctx; /* BIGNUM context */ |
2595 | DSA_SIG *sdsa; /* RSA signature context fake */ | | 2600 | DSA_SIG *sdsa; /* RSA signature context fake */ |
2596 | BIGNUM *y, *v; | | 2601 | BIGNUM *y, *v; |
2597 | const u_char *ptr; | | 2602 | const u_char *ptr; |
2598 | u_int len; | | 2603 | u_int len; |
2599 | int temp; | | 2604 | int temp; |
2600 | | | 2605 | |
2601 | /* | | 2606 | /* |
2602 | * If the GQ parameters are not valid or no challenge was sent, | | 2607 | * If the GQ parameters are not valid or no challenge was sent, |
2603 | * something awful happened or we are being tormented. | | 2608 | * something awful happened or we are being tormented. |
2604 | */ | | 2609 | */ |
2605 | if (peer->ident_pkey == NULL) { | | 2610 | if (peer->ident_pkey == NULL) { |
2606 | msyslog(LOG_INFO, "crypto_gq: scheme unavailable"); | | 2611 | msyslog(LOG_INFO, "crypto_gq: scheme unavailable"); |
2607 | return (XEVNT_ID); | | 2612 | return (XEVNT_ID); |
2608 | } | | 2613 | } |
2609 | if (ntohl(ep->fstamp) != peer->fstamp) { | | 2614 | if (ntohl(ep->fstamp) != peer->fstamp) { |
2610 | msyslog(LOG_INFO, "crypto_gq: invalid filestamp %u", | | 2615 | msyslog(LOG_INFO, "crypto_gq: invalid filestamp %u", |
2611 | ntohl(ep->fstamp)); | | 2616 | ntohl(ep->fstamp)); |
2612 | return (XEVNT_FSP); | | 2617 | return (XEVNT_FSP); |
2613 | } | | 2618 | } |
2614 | if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) { | | 2619 | if ((rsa = peer->ident_pkey->pkey.rsa) == NULL) { |
2615 | msyslog(LOG_INFO, "crypto_gq: defective key"); | | 2620 | msyslog(LOG_INFO, "crypto_gq: defective key"); |
2616 | return (XEVNT_PUB); | | 2621 | return (XEVNT_PUB); |
2617 | } | | 2622 | } |
2618 | if (peer->iffval == NULL) { | | 2623 | if (peer->iffval == NULL) { |
2619 | msyslog(LOG_INFO, "crypto_gq: missing challenge"); | | 2624 | msyslog(LOG_INFO, "crypto_gq: missing challenge"); |
2620 | return (XEVNT_ID); | | 2625 | return (XEVNT_ID); |
2621 | } | | 2626 | } |
2622 | | | 2627 | |
2623 | /* | | 2628 | /* |
2624 | * Extract the y = k u^r and hash(x = k^b) values from the | | 2629 | * Extract the y = k u^r and hash(x = k^b) values from the |
2625 | * response. | | 2630 | * response. |
2626 | */ | | 2631 | */ |
2627 | bctx = BN_CTX_new(); y = BN_new(); v = BN_new(); | | 2632 | bctx = BN_CTX_new(); y = BN_new(); v = BN_new(); |
2628 | len = ntohl(ep->vallen); | | 2633 | len = ntohl(ep->vallen); |
2629 | ptr = (const u_char *)ep->pkt; | | 2634 | ptr = (const u_char *)ep->pkt; |
2630 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { | | 2635 | if ((sdsa = d2i_DSA_SIG(NULL, &ptr, len)) == NULL) { |
2631 | msyslog(LOG_ERR, "crypto_gq %s\n", | | 2636 | msyslog(LOG_ERR, "crypto_gq %s\n", |
2632 | ERR_error_string(ERR_get_error(), NULL)); | | 2637 | ERR_error_string(ERR_get_error(), NULL)); |
2633 | return (XEVNT_ERR); | | 2638 | return (XEVNT_ERR); |
2634 | } | | 2639 | } |
2635 | | | 2640 | |
2636 | /* | | 2641 | /* |
2637 | * Compute v^r y^b mod n. | | 2642 | * Compute v^r y^b mod n. |
2638 | */ | | 2643 | */ |
2639 | BN_mod_exp(v, peer->grpkey, peer->iffval, rsa->n, bctx); | | 2644 | BN_mod_exp(v, peer->grpkey, peer->iffval, rsa->n, bctx); |
2640 | /* v^r mod n */ | | 2645 | /* v^r mod n */ |
2641 | BN_mod_exp(y, sdsa->r, rsa->e, rsa->n, bctx); /* y^b mod n */ | | 2646 | BN_mod_exp(y, sdsa->r, rsa->e, rsa->n, bctx); /* y^b mod n */ |
2642 | BN_mod_mul(y, v, y, rsa->n, bctx); /* v^r y^b mod n */ | | 2647 | BN_mod_mul(y, v, y, rsa->n, bctx); /* v^r y^b mod n */ |
2643 | | | 2648 | |
2644 | /* | | 2649 | /* |
2645 | * Verify the hash of the result matches hash(x). | | 2650 | * Verify the hash of the result matches hash(x). |
2646 | */ | | 2651 | */ |
2647 | bighash(y, y); | | 2652 | bighash(y, y); |
2648 | temp = BN_cmp(y, sdsa->s); | | 2653 | temp = BN_cmp(y, sdsa->s); |
2649 | BN_CTX_free(bctx); BN_free(y); BN_free(v); | | 2654 | BN_CTX_free(bctx); BN_free(y); BN_free(v); |
2650 | BN_free(peer->iffval); | | 2655 | BN_free(peer->iffval); |
2651 | peer->iffval = NULL; | | 2656 | peer->iffval = NULL; |
2652 | DSA_SIG_free(sdsa); | | 2657 | DSA_SIG_free(sdsa); |
2653 | if (temp == 0) | | 2658 | if (temp == 0) |
2654 | return (XEVNT_OK); | | 2659 | return (XEVNT_OK); |
2655 | | | 2660 | |
2656 | else | | 2661 | else |
2657 | return (XEVNT_ID); | | 2662 | return (XEVNT_ID); |
2658 | } | | 2663 | } |
2659 | | | 2664 | |
2660 | | | 2665 | |
2661 | /* | | 2666 | /* |
2662 | *********************************************************************** | | 2667 | *********************************************************************** |
2663 | * * | | 2668 | * * |
2664 | * The following routines implement the Mu-Varadharajan (MV) identity * | | 2669 | * The following routines implement the Mu-Varadharajan (MV) identity * |
2665 | * scheme * | | 2670 | * scheme * |
2666 | * * | | 2671 | * * |
2667 | *********************************************************************** | | 2672 | *********************************************************************** |
2668 | */ | | 2673 | */ |
2669 | /* | | 2674 | /* |
2670 | * The Mu-Varadharajan (MV) cryptosystem was originally intended when | | 2675 | * The Mu-Varadharajan (MV) cryptosystem was originally intended when |
2671 | * servers broadcast messages to clients, but clients never send | | 2676 | * servers broadcast messages to clients, but clients never send |
2672 | * messages to servers. There is one encryption key for the server and a | | 2677 | * messages to servers. There is one encryption key for the server and a |
2673 | * separate decryption key for each client. It operated something like a | | 2678 | * separate decryption key for each client. It operated something like a |
2674 | * pay-per-view satellite broadcasting system where the session key is | | 2679 | * pay-per-view satellite broadcasting system where the session key is |
2675 | * encrypted by the broadcaster and the decryption keys are held in a | | 2680 | * encrypted by the broadcaster and the decryption keys are held in a |
2676 | * tamperproof set-top box. | | 2681 | * tamperproof set-top box. |
2677 | * | | 2682 | * |
2678 | * The MV parameters and private encryption key hide in a DSA cuckoo | | 2683 | * The MV parameters and private encryption key hide in a DSA cuckoo |
2679 | * structure which uses the same parameters, but generated in a | | 2684 | * structure which uses the same parameters, but generated in a |
2680 | * different way. The values are used in an encryption scheme similar to | | 2685 | * different way. The values are used in an encryption scheme similar to |
2681 | * El Gamal cryptography and a polynomial formed from the expansion of | | 2686 | * El Gamal cryptography and a polynomial formed from the expansion of |
2682 | * product terms (x - x[j]), as described in Mu, Y., and V. | | 2687 | * product terms (x - x[j]), as described in Mu, Y., and V. |
2683 | * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001, | | 2688 | * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001, |
2684 | * 223-231. The paper has significant errors and serious omissions. | | 2689 | * 223-231. The paper has significant errors and serious omissions. |
2685 | * | | 2690 | * |
2686 | * Let q be the product of n distinct primes s'[j] (j = 1...n), where | | 2691 | * Let q be the product of n distinct primes s'[j] (j = 1...n), where |
2687 | * each s'[j] has m significant bits. Let p be a prime p = 2 * q + 1, so | | 2692 | * each s'[j] has m significant bits. Let p be a prime p = 2 * q + 1, so |
2688 | * that q and each s'[j] divide p - 1 and p has M = n * m + 1 | | 2693 | * that q and each s'[j] divide p - 1 and p has M = n * m + 1 |
2689 | * significant bits. The elements x mod q of Zq with the elements 2 and | | 2694 | * significant bits. The elements x mod q of Zq with the elements 2 and |
2690 | * the primes removed form a field Zq* valid for polynomial arithetic. | | 2695 | * the primes removed form a field Zq* valid for polynomial arithetic. |
2691 | * Let g be a generator of Zp; that is, gcd(g, p - 1) = 1 and g^q = 1 | | 2696 | * Let g be a generator of Zp; that is, gcd(g, p - 1) = 1 and g^q = 1 |
2692 | * mod p. We expect M to be in the 500-bit range and n relatively small, | | 2697 | * mod p. We expect M to be in the 500-bit range and n relatively small, |
2693 | * like 25, so the likelihood of a randomly generated element of x mod q | | 2698 | * like 25, so the likelihood of a randomly generated element of x mod q |
2694 | * of Zq colliding with a factor of p - 1 is very small and can be | | 2699 | * of Zq colliding with a factor of p - 1 is very small and can be |
2695 | * avoided. Associated with each s'[j] is an element s[j] such that s[j] | | 2700 | * avoided. Associated with each s'[j] is an element s[j] such that s[j] |
2696 | * s'[j] = s'[j] mod q. We find s[j] as the quotient (q + s'[j]) / | | 2701 | * s'[j] = s'[j] mod q. We find s[j] as the quotient (q + s'[j]) / |
2697 | * s'[j]. These are the parameters of the scheme and they are expensive | | 2702 | * s'[j]. These are the parameters of the scheme and they are expensive |
2698 | * to compute. | | 2703 | * to compute. |
2699 | * | | 2704 | * |
2700 | * We set up an instance of the scheme as follows. A set of random | | 2705 | * We set up an instance of the scheme as follows. A set of random |
2701 | * values x[j] mod q (j = 1...n), are generated as the zeros of a | | 2706 | * values x[j] mod q (j = 1...n), are generated as the zeros of a |
2702 | * polynomial of order n. The product terms (x - x[j]) are expanded to | | 2707 | * polynomial of order n. The product terms (x - x[j]) are expanded to |
2703 | * form coefficients a[i] mod q (i = 0...n) in powers of x. These are | | 2708 | * form coefficients a[i] mod q (i = 0...n) in powers of x. These are |
2704 | * used as exponents of the generator g mod p to generate the private | | 2709 | * used as exponents of the generator g mod p to generate the private |
2705 | * encryption key A. The pair (gbar, ghat) of public server keys and the | | 2710 | * encryption key A. The pair (gbar, ghat) of public server keys and the |
2706 | * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used | | 2711 | * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used |
2707 | * to construct the decryption keys. The devil is in the details. | | 2712 | * to construct the decryption keys. The devil is in the details. |
2708 | * | | 2713 | * |
2709 | * The distinguishing characteristic of this scheme is the capability to | | 2714 | * The distinguishing characteristic of this scheme is the capability to |
2710 | * revoke keys. Included in the calculation of E, gbar and ghat is the | | 2715 | * revoke keys. Included in the calculation of E, gbar and ghat is the |
2711 | * product s = prod(s'[j]) (j = 1...n) above. If the factor s'[j] is | | 2716 | * product s = prod(s'[j]) (j = 1...n) above. If the factor s'[j] is |
2712 | * subsequently removed from the product and E, gbar and ghat | | 2717 | * subsequently removed from the product and E, gbar and ghat |
2713 | * recomputed, the jth client will no longer be able to compute E^-1 and | | 2718 | * recomputed, the jth client will no longer be able to compute E^-1 and |
2714 | * thus unable to decrypt the block. | | 2719 | * thus unable to decrypt the block. |
2715 | * | | 2720 | * |
2716 | * How it works | | 2721 | * How it works |
2717 | * | | 2722 | * |
2718 | * The scheme goes like this. Bob has the server values (p, A, q, gbar, | | 2723 | * The scheme goes like this. Bob has the server values (p, A, q, gbar, |
2719 | * ghat) and Alice the client values (p, xbar, xhat). | | 2724 | * ghat) and Alice the client values (p, xbar, xhat). |
2720 | * | | 2725 | * |
2721 | * Alice rolls new random challenge r (0 < r < p) and sends to Bob in | | 2726 | * Alice rolls new random challenge r (0 < r < p) and sends to Bob in |
2722 | * the MV request message. Bob rolls new random k (0 < k < q), encrypts | | 2727 | * the MV request message. Bob rolls new random k (0 < k < q), encrypts |
2723 | * y = A^k mod p (a permutation) and sends (hash(y), gbar^k, ghat^k) to | | 2728 | * y = A^k mod p (a permutation) and sends (hash(y), gbar^k, ghat^k) to |
2724 | * Alice. | | 2729 | * Alice. |
2725 | * | | 2730 | * |
2726 | * Alice receives the response and computes the decryption key (the | | 2731 | * Alice receives the response and computes the decryption key (the |
2727 | * inverse permutation) from previously obtained (xbar, xhat) and | | 2732 | * inverse permutation) from previously obtained (xbar, xhat) and |
2728 | * (gbar^k, ghat^k) in the message. She computes the inverse, which is | | 2733 | * (gbar^k, ghat^k) in the message. She computes the inverse, which is |
2729 | * unique by reasons explained in the ntp-keygen.c program sources. If | | 2734 | * unique by reasons explained in the ntp-keygen.c program sources. If |
2730 | * the hash of this result matches hash(y), Alice knows that Bob has the | | 2735 | * the hash of this result matches hash(y), Alice knows that Bob has the |
2731 | * group key b. The signed response binds this knowledge to Bob's | | 2736 | * group key b. The signed response binds this knowledge to Bob's |
2732 | * private key and the public key previously received in his | | 2737 | * private key and the public key previously received in his |
2733 | * certificate. | | 2738 | * certificate. |
2734 | * | | 2739 | * |
2735 | * crypto_alice3 - construct Alice's challenge in MV scheme | | 2740 | * crypto_alice3 - construct Alice's challenge in MV scheme |
2736 | * | | 2741 | * |
2737 | * Returns | | 2742 | * Returns |
2738 | * XEVNT_OK success | | 2743 | * XEVNT_OK success |
2739 | * XEVNT_PUB bad or missing public key | | 2744 | * XEVNT_PUB bad or missing public key |
2740 | * XEVNT_ID bad or missing group key | | 2745 | * XEVNT_ID bad or missing group key |
2741 | * XEVNT_PER host certificate expired | | 2746 | * XEVNT_PER host certificate expired |
2742 | */ | | 2747 | */ |
2743 | static int | | 2748 | static int |
2744 | crypto_alice3( | | 2749 | crypto_alice3( |
2745 | struct peer *peer, /* peer pointer */ | | 2750 | struct peer *peer, /* peer pointer */ |
2746 | struct value *vp /* value pointer */ | | 2751 | struct value *vp /* value pointer */ |
2747 | ) | | 2752 | ) |
2748 | { | | 2753 | { |
2749 | DSA *dsa; /* MV parameters */ | | 2754 | DSA *dsa; /* MV parameters */ |
2750 | BN_CTX *bctx; /* BIGNUM context */ | | 2755 | BN_CTX *bctx; /* BIGNUM context */ |
2751 | EVP_MD_CTX ctx; /* signature context */ | | 2756 | EVP_MD_CTX ctx; /* signature context */ |
2752 | tstamp_t tstamp; | | 2757 | tstamp_t tstamp; |
2753 | u_int len; | | 2758 | u_int len; |
2754 | | | 2759 | |
2755 | /* | | 2760 | /* |
2756 | * The identity parameters must have correct format and content. | | 2761 | * The identity parameters must have correct format and content. |
2757 | */ | | 2762 | */ |
2758 | if (peer->ident_pkey == NULL) | | 2763 | if (peer->ident_pkey == NULL) |
2759 | return (XEVNT_ID); | | 2764 | return (XEVNT_ID); |
2760 | | | 2765 | |
2761 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { | | 2766 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { |
2762 | msyslog(LOG_INFO, "crypto_alice3: defective key"); | | 2767 | msyslog(LOG_INFO, "crypto_alice3: defective key"); |
2763 | return (XEVNT_PUB); | | 2768 | return (XEVNT_PUB); |
2764 | } | | 2769 | } |
2765 | | | 2770 | |
2766 | /* | | 2771 | /* |
2767 | * Roll new random r (0 < r < q). The OpenSSL library has a bug | | 2772 | * Roll new random r (0 < r < q). The OpenSSL library has a bug |
2768 | * omitting BN_rand_range, so we have to do it the hard way. | | 2773 | * omitting BN_rand_range, so we have to do it the hard way. |
2769 | */ | | 2774 | */ |
2770 | bctx = BN_CTX_new(); | | 2775 | bctx = BN_CTX_new(); |
2771 | len = BN_num_bytes(dsa->p); | | 2776 | len = BN_num_bytes(dsa->p); |
2772 | if (peer->iffval != NULL) | | 2777 | if (peer->iffval != NULL) |
2773 | BN_free(peer->iffval); | | 2778 | BN_free(peer->iffval); |
2774 | peer->iffval = BN_new(); | | 2779 | peer->iffval = BN_new(); |
2775 | BN_rand(peer->iffval, len * 8, -1, 1); /* r */ | | 2780 | BN_rand(peer->iffval, len * 8, -1, 1); /* r */ |
2776 | BN_mod(peer->iffval, peer->iffval, dsa->p, bctx); | | 2781 | BN_mod(peer->iffval, peer->iffval, dsa->p, bctx); |
2777 | BN_CTX_free(bctx); | | 2782 | BN_CTX_free(bctx); |
2778 | | | 2783 | |
2779 | /* | | 2784 | /* |
2780 | * Sign and send to Bob. The filestamp is from the local file. | | 2785 | * Sign and send to Bob. The filestamp is from the local file. |
2781 | */ | | 2786 | */ |
2782 | tstamp = crypto_time(); | | 2787 | tstamp = crypto_time(); |
2783 | memset(vp, 0, sizeof(struct value)); | | 2788 | memset(vp, 0, sizeof(struct value)); |
2784 | vp->tstamp = htonl(tstamp); | | 2789 | vp->tstamp = htonl(tstamp); |
2785 | vp->fstamp = htonl(peer->fstamp); | | 2790 | vp->fstamp = htonl(peer->fstamp); |
2786 | vp->vallen = htonl(len); | | 2791 | vp->vallen = htonl(len); |
2787 | vp->ptr = emalloc(len); | | 2792 | vp->ptr = emalloc(len); |
2788 | BN_bn2bin(peer->iffval, vp->ptr); | | 2793 | BN_bn2bin(peer->iffval, vp->ptr); |
2789 | vp->siglen = 0; | | 2794 | vp->siglen = 0; |
2790 | if (tstamp == 0) | | 2795 | if (tstamp == 0) |
2791 | return (XEVNT_OK); | | 2796 | return (XEVNT_OK); |
2792 | | | 2797 | |
2793 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2798 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2794 | return (XEVNT_PER); | | 2799 | return (XEVNT_PER); |
2795 | | | 2800 | |
2796 | vp->sig = emalloc(sign_siglen); | | 2801 | vp->sig = emalloc(sign_siglen); |
2797 | EVP_SignInit(&ctx, sign_digest); | | 2802 | EVP_SignInit(&ctx, sign_digest); |
2798 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2803 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2799 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2804 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2800 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2805 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2801 | vp->siglen = htonl(len); | | 2806 | vp->siglen = htonl(len); |
2802 | return (XEVNT_OK); | | 2807 | return (XEVNT_OK); |
2803 | } | | 2808 | } |
2804 | | | 2809 | |
2805 | | | 2810 | |
2806 | /* | | 2811 | /* |
2807 | * crypto_bob3 - construct Bob's response to Alice's challenge | | 2812 | * crypto_bob3 - construct Bob's response to Alice's challenge |
2808 | * | | 2813 | * |
2809 | * Returns | | 2814 | * Returns |
2810 | * XEVNT_OK success | | 2815 | * XEVNT_OK success |
2811 | * XEVNT_ERR protocol error | | 2816 | * XEVNT_ERR protocol error |
2812 | * XEVNT_PER host certificate expired | | 2817 | * XEVNT_PER host certificate expired |
2813 | */ | | 2818 | */ |
2814 | static int | | 2819 | static int |
2815 | crypto_bob3( | | 2820 | crypto_bob3( |
2816 | struct exten *ep, /* extension pointer */ | | 2821 | struct exten *ep, /* extension pointer */ |
2817 | struct value *vp /* value pointer */ | | 2822 | struct value *vp /* value pointer */ |
2818 | ) | | 2823 | ) |
2819 | { | | 2824 | { |
2820 | DSA *dsa; /* MV parameters */ | | 2825 | DSA *dsa; /* MV parameters */ |
2821 | DSA *sdsa; /* DSA signature context fake */ | | 2826 | DSA *sdsa; /* DSA signature context fake */ |
2822 | BN_CTX *bctx; /* BIGNUM context */ | | 2827 | BN_CTX *bctx; /* BIGNUM context */ |
2823 | EVP_MD_CTX ctx; /* signature context */ | | 2828 | EVP_MD_CTX ctx; /* signature context */ |
2824 | tstamp_t tstamp; /* NTP timestamp */ | | 2829 | tstamp_t tstamp; /* NTP timestamp */ |
2825 | BIGNUM *r, *k, *u; | | 2830 | BIGNUM *r, *k, *u; |
2826 | u_char *ptr; | | 2831 | u_char *ptr; |
2827 | u_int len; | | 2832 | u_int len; |
2828 | | | 2833 | |
2829 | /* | | 2834 | /* |
2830 | * If the MV parameters are not valid, something awful | | 2835 | * If the MV parameters are not valid, something awful |
2831 | * happened or we are being tormented. | | 2836 | * happened or we are being tormented. |
2832 | */ | | 2837 | */ |
2833 | if (mvpar_pkey == NULL) { | | 2838 | if (mvpar_pkey == NULL) { |
2834 | msyslog(LOG_INFO, "crypto_bob3: scheme unavailable"); | | 2839 | msyslog(LOG_INFO, "crypto_bob3: scheme unavailable"); |
2835 | return (XEVNT_ID); | | 2840 | return (XEVNT_ID); |
2836 | } | | 2841 | } |
2837 | dsa = mvpar_pkey->pkey.dsa; | | 2842 | dsa = mvpar_pkey->pkey.dsa; |
2838 | | | 2843 | |
2839 | /* | | 2844 | /* |
2840 | * Extract r from the challenge. | | 2845 | * Extract r from the challenge. |
2841 | */ | | 2846 | */ |
2842 | len = ntohl(ep->vallen); | | 2847 | len = ntohl(ep->vallen); |
2843 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { | | 2848 | if ((r = BN_bin2bn((u_char *)ep->pkt, len, NULL)) == NULL) { |
2844 | msyslog(LOG_ERR, "crypto_bob3 %s\n", | | 2849 | msyslog(LOG_ERR, "crypto_bob3 %s\n", |
2845 | ERR_error_string(ERR_get_error(), NULL)); | | 2850 | ERR_error_string(ERR_get_error(), NULL)); |
2846 | return (XEVNT_ERR); | | 2851 | return (XEVNT_ERR); |
2847 | } | | 2852 | } |
2848 | | | 2853 | |
2849 | /* | | 2854 | /* |
2850 | * Bob rolls random k (0 < k < q), making sure it is not a | | 2855 | * Bob rolls random k (0 < k < q), making sure it is not a |
2851 | * factor of q. He then computes y = A^k r and sends (hash(y), | | 2856 | * factor of q. He then computes y = A^k r and sends (hash(y), |
2852 | * gbar^k, ghat^k) to Alice. | | 2857 | * gbar^k, ghat^k) to Alice. |
2853 | */ | | 2858 | */ |
2854 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); | | 2859 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); |
2855 | sdsa = DSA_new(); | | 2860 | sdsa = DSA_new(); |
2856 | sdsa->p = BN_new(); sdsa->q = BN_new(); sdsa->g = BN_new(); | | 2861 | sdsa->p = BN_new(); sdsa->q = BN_new(); sdsa->g = BN_new(); |
2857 | while (1) { | | 2862 | while (1) { |
2858 | BN_rand(k, BN_num_bits(dsa->q), 0, 0); | | 2863 | BN_rand(k, BN_num_bits(dsa->q), 0, 0); |
2859 | BN_mod(k, k, dsa->q, bctx); | | 2864 | BN_mod(k, k, dsa->q, bctx); |
2860 | BN_gcd(u, k, dsa->q, bctx); | | 2865 | BN_gcd(u, k, dsa->q, bctx); |
2861 | if (BN_is_one(u)) | | 2866 | if (BN_is_one(u)) |
2862 | break; | | 2867 | break; |
2863 | } | | 2868 | } |
2864 | BN_mod_exp(u, dsa->g, k, dsa->p, bctx); /* A r */ | | 2869 | BN_mod_exp(u, dsa->g, k, dsa->p, bctx); /* A r */ |
2865 | BN_mod_mul(u, u, r, dsa->p, bctx); | | 2870 | BN_mod_mul(u, u, r, dsa->p, bctx); |
2866 | bighash(u, sdsa->p); | | 2871 | bighash(u, sdsa->p); |
2867 | BN_mod_exp(sdsa->q, dsa->priv_key, k, dsa->p, bctx); /* gbar */ | | 2872 | BN_mod_exp(sdsa->q, dsa->priv_key, k, dsa->p, bctx); /* gbar */ |
2868 | BN_mod_exp(sdsa->g, dsa->pub_key, k, dsa->p, bctx); /* ghat */ | | 2873 | BN_mod_exp(sdsa->g, dsa->pub_key, k, dsa->p, bctx); /* ghat */ |
2869 | BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u); | | 2874 | BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u); |
2870 | | | 2875 | |
2871 | /* | | 2876 | /* |
2872 | * Encode the values in ASN.1 and sign. | | 2877 | * Encode the values in ASN.1 and sign. |
2873 | */ | | 2878 | */ |
2874 | tstamp = crypto_time(); | | 2879 | tstamp = crypto_time(); |
2875 | memset(vp, 0, sizeof(struct value)); | | 2880 | memset(vp, 0, sizeof(struct value)); |
2876 | vp->tstamp = htonl(tstamp); | | 2881 | vp->tstamp = htonl(tstamp); |
2877 | vp->fstamp = htonl(mv_fstamp); | | 2882 | vp->fstamp = htonl(mv_fstamp); |
2878 | len = i2d_DSAparams(sdsa, NULL); | | 2883 | len = i2d_DSAparams(sdsa, NULL); |
2879 | if (len <= 0) { | | 2884 | if (len <= 0) { |
2880 | msyslog(LOG_ERR, "crypto_bob3 %s\n", | | 2885 | msyslog(LOG_ERR, "crypto_bob3 %s\n", |
2881 | ERR_error_string(ERR_get_error(), NULL)); | | 2886 | ERR_error_string(ERR_get_error(), NULL)); |
2882 | DSA_free(sdsa); | | 2887 | DSA_free(sdsa); |
2883 | return (XEVNT_ERR); | | 2888 | return (XEVNT_ERR); |
2884 | } | | 2889 | } |
2885 | vp->vallen = htonl(len); | | 2890 | vp->vallen = htonl(len); |
2886 | ptr = emalloc(len); | | 2891 | ptr = emalloc(len); |
2887 | vp->ptr = ptr; | | 2892 | vp->ptr = ptr; |
2888 | i2d_DSAparams(sdsa, &ptr); | | 2893 | i2d_DSAparams(sdsa, &ptr); |
2889 | DSA_free(sdsa); | | 2894 | DSA_free(sdsa); |
2890 | vp->siglen = 0; | | 2895 | vp->siglen = 0; |
2891 | if (tstamp == 0) | | 2896 | if (tstamp == 0) |
2892 | return (XEVNT_OK); | | 2897 | return (XEVNT_OK); |
2893 | | | 2898 | |
2894 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 2899 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
2895 | return (XEVNT_PER); | | 2900 | return (XEVNT_PER); |
2896 | | | 2901 | |
2897 | vp->sig = emalloc(sign_siglen); | | 2902 | vp->sig = emalloc(sign_siglen); |
2898 | EVP_SignInit(&ctx, sign_digest); | | 2903 | EVP_SignInit(&ctx, sign_digest); |
2899 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); | | 2904 | EVP_SignUpdate(&ctx, (u_char *)&vp->tstamp, 12); |
2900 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 2905 | EVP_SignUpdate(&ctx, vp->ptr, len); |
2901 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 2906 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
2902 | vp->siglen = htonl(len); | | 2907 | vp->siglen = htonl(len); |
2903 | return (XEVNT_OK); | | 2908 | return (XEVNT_OK); |
2904 | } | | 2909 | } |
2905 | | | 2910 | |
2906 | | | 2911 | |
2907 | /* | | 2912 | /* |
2908 | * crypto_mv - verify Bob's response to Alice's challenge | | 2913 | * crypto_mv - verify Bob's response to Alice's challenge |
2909 | * | | 2914 | * |
2910 | * Returns | | 2915 | * Returns |
2911 | * XEVNT_OK success | | 2916 | * XEVNT_OK success |
2912 | * XEVNT_PUB bad or missing public key | | 2917 | * XEVNT_PUB bad or missing public key |
2913 | * XEVNT_ID bad or missing group key | | 2918 | * XEVNT_ID bad or missing group key |
2914 | * XEVNT_ERR protocol error | | 2919 | * XEVNT_ERR protocol error |
2915 | * XEVNT_FSP bad filestamp | | 2920 | * XEVNT_FSP bad filestamp |
2916 | */ | | 2921 | */ |
2917 | int | | 2922 | int |
2918 | crypto_mv( | | 2923 | crypto_mv( |
2919 | struct exten *ep, /* extension pointer */ | | 2924 | struct exten *ep, /* extension pointer */ |
2920 | struct peer *peer /* peer structure pointer */ | | 2925 | struct peer *peer /* peer structure pointer */ |
2921 | ) | | 2926 | ) |
2922 | { | | 2927 | { |
2923 | DSA *dsa; /* MV parameters */ | | 2928 | DSA *dsa; /* MV parameters */ |
2924 | DSA *sdsa; /* DSA parameters */ | | 2929 | DSA *sdsa; /* DSA parameters */ |
2925 | BN_CTX *bctx; /* BIGNUM context */ | | 2930 | BN_CTX *bctx; /* BIGNUM context */ |
2926 | BIGNUM *k, *u, *v; | | 2931 | BIGNUM *k, *u, *v; |
2927 | u_int len; | | 2932 | u_int len; |
2928 | const u_char *ptr; | | 2933 | const u_char *ptr; |
2929 | int temp; | | 2934 | int temp; |
2930 | | | 2935 | |
2931 | /* | | 2936 | /* |
2932 | * If the MV parameters are not valid or no challenge was sent, | | 2937 | * If the MV parameters are not valid or no challenge was sent, |
2933 | * something awful happened or we are being tormented. | | 2938 | * something awful happened or we are being tormented. |
2934 | */ | | 2939 | */ |
2935 | if (peer->ident_pkey == NULL) { | | 2940 | if (peer->ident_pkey == NULL) { |
2936 | msyslog(LOG_INFO, "crypto_mv: scheme unavailable"); | | 2941 | msyslog(LOG_INFO, "crypto_mv: scheme unavailable"); |
2937 | return (XEVNT_ID); | | 2942 | return (XEVNT_ID); |
2938 | } | | 2943 | } |
2939 | if (ntohl(ep->fstamp) != peer->fstamp) { | | 2944 | if (ntohl(ep->fstamp) != peer->fstamp) { |
2940 | msyslog(LOG_INFO, "crypto_mv: invalid filestamp %u", | | 2945 | msyslog(LOG_INFO, "crypto_mv: invalid filestamp %u", |
2941 | ntohl(ep->fstamp)); | | 2946 | ntohl(ep->fstamp)); |
2942 | return (XEVNT_FSP); | | 2947 | return (XEVNT_FSP); |
2943 | } | | 2948 | } |
2944 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { | | 2949 | if ((dsa = peer->ident_pkey->pkey.dsa) == NULL) { |
2945 | msyslog(LOG_INFO, "crypto_mv: defective key"); | | 2950 | msyslog(LOG_INFO, "crypto_mv: defective key"); |
2946 | return (XEVNT_PUB); | | 2951 | return (XEVNT_PUB); |
2947 | } | | 2952 | } |
2948 | if (peer->iffval == NULL) { | | 2953 | if (peer->iffval == NULL) { |
2949 | msyslog(LOG_INFO, "crypto_mv: missing challenge"); | | 2954 | msyslog(LOG_INFO, "crypto_mv: missing challenge"); |
2950 | return (XEVNT_ID); | | 2955 | return (XEVNT_ID); |
2951 | } | | 2956 | } |
2952 | | | 2957 | |
2953 | /* | | 2958 | /* |
2954 | * Extract the (hash(y), gbar, ghat) values from the response. | | 2959 | * Extract the (hash(y), gbar, ghat) values from the response. |
2955 | */ | | 2960 | */ |
2956 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new(); | | 2961 | bctx = BN_CTX_new(); k = BN_new(); u = BN_new(); v = BN_new(); |
2957 | len = ntohl(ep->vallen); | | 2962 | len = ntohl(ep->vallen); |
2958 | ptr = (const u_char *)ep->pkt; | | 2963 | ptr = (const u_char *)ep->pkt; |
2959 | if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) { | | 2964 | if ((sdsa = d2i_DSAparams(NULL, &ptr, len)) == NULL) { |
2960 | msyslog(LOG_ERR, "crypto_mv %s\n", | | 2965 | msyslog(LOG_ERR, "crypto_mv %s\n", |
2961 | ERR_error_string(ERR_get_error(), NULL)); | | 2966 | ERR_error_string(ERR_get_error(), NULL)); |
2962 | return (XEVNT_ERR); | | 2967 | return (XEVNT_ERR); |
2963 | } | | 2968 | } |
2964 | | | 2969 | |
2965 | /* | | 2970 | /* |
2966 | * Compute (gbar^xhat ghat^xbar)^-1 mod p. | | 2971 | * Compute (gbar^xhat ghat^xbar)^-1 mod p. |
2967 | */ | | 2972 | */ |
2968 | BN_mod_exp(u, sdsa->q, dsa->pub_key, dsa->p, bctx); | | 2973 | BN_mod_exp(u, sdsa->q, dsa->pub_key, dsa->p, bctx); |
2969 | BN_mod_exp(v, sdsa->g, dsa->priv_key, dsa->p, bctx); | | 2974 | BN_mod_exp(v, sdsa->g, dsa->priv_key, dsa->p, bctx); |
2970 | BN_mod_mul(u, u, v, dsa->p, bctx); | | 2975 | BN_mod_mul(u, u, v, dsa->p, bctx); |
2971 | BN_mod_inverse(u, u, dsa->p, bctx); | | 2976 | BN_mod_inverse(u, u, dsa->p, bctx); |
2972 | BN_mod_mul(v, u, peer->iffval, dsa->p, bctx); | | 2977 | BN_mod_mul(v, u, peer->iffval, dsa->p, bctx); |
2973 | | | 2978 | |
2974 | /* | | 2979 | /* |
2975 | * The result should match the hash of r mod p. | | 2980 | * The result should match the hash of r mod p. |
2976 | */ | | 2981 | */ |
2977 | bighash(v, v); | | 2982 | bighash(v, v); |
2978 | temp = BN_cmp(v, sdsa->p); | | 2983 | temp = BN_cmp(v, sdsa->p); |
2979 | BN_CTX_free(bctx); BN_free(k); BN_free(u); BN_free(v); | | 2984 | BN_CTX_free(bctx); BN_free(k); BN_free(u); BN_free(v); |
2980 | BN_free(peer->iffval); | | 2985 | BN_free(peer->iffval); |
2981 | peer->iffval = NULL; | | 2986 | peer->iffval = NULL; |
2982 | DSA_free(sdsa); | | 2987 | DSA_free(sdsa); |
2983 | if (temp == 0) | | 2988 | if (temp == 0) |
2984 | return (XEVNT_OK); | | 2989 | return (XEVNT_OK); |
2985 | | | 2990 | |
2986 | else | | 2991 | else |
2987 | return (XEVNT_ID); | | 2992 | return (XEVNT_ID); |
2988 | } | | 2993 | } |
2989 | | | 2994 | |
2990 | | | 2995 | |
2991 | /* | | 2996 | /* |
2992 | *********************************************************************** | | 2997 | *********************************************************************** |
2993 | * * | | 2998 | * * |
2994 | * The following routines are used to manipulate certificates * | | 2999 | * The following routines are used to manipulate certificates * |
2995 | * * | | 3000 | * * |
2996 | *********************************************************************** | | 3001 | *********************************************************************** |
2997 | */ | | 3002 | */ |
2998 | /* | | 3003 | /* |
2999 | * cert_parse - parse x509 certificate and create info/value structures. | | 3004 | * cert_parse - parse x509 certificate and create info/value structures. |
3000 | * | | 3005 | * |
3001 | * The server certificate includes the version number, issuer name, | | 3006 | * The server certificate includes the version number, issuer name, |
3002 | * subject name, public key and valid date interval. If the issuer name | | 3007 | * subject name, public key and valid date interval. If the issuer name |
3003 | * is the same as the subject name, the certificate is self signed and | | 3008 | * is the same as the subject name, the certificate is self signed and |
3004 | * valid only if the server is configured as trustable. If the names are | | 3009 | * valid only if the server is configured as trustable. If the names are |
3005 | * different, another issuer has signed the server certificate and | | 3010 | * different, another issuer has signed the server certificate and |
3006 | * vouched for it. In this case the server certificate is valid if | | 3011 | * vouched for it. In this case the server certificate is valid if |
3007 | * verified by the issuer public key. | | 3012 | * verified by the issuer public key. |
3008 | * | | 3013 | * |
3009 | * Returns certificate info/value pointer if valid, NULL if not. | | 3014 | * Returns certificate info/value pointer if valid, NULL if not. |
3010 | */ | | 3015 | */ |
3011 | struct cert_info * /* certificate information structure */ | | 3016 | struct cert_info * /* certificate information structure */ |
3012 | cert_parse( | | 3017 | cert_parse( |
3013 | u_char *asn1cert, /* X509 certificate */ | | 3018 | u_char *asn1cert, /* X509 certificate */ |
3014 | u_int len, /* certificate length */ | | 3019 | u_int len, /* certificate length */ |
3015 | tstamp_t fstamp /* filestamp */ | | 3020 | tstamp_t fstamp /* filestamp */ |
3016 | ) | | 3021 | ) |
3017 | { | | 3022 | { |
3018 | X509 *cert; /* X509 certificate */ | | 3023 | X509 *cert; /* X509 certificate */ |
3019 | X509_EXTENSION *ext; /* X509v3 extension */ | | 3024 | X509_EXTENSION *ext; /* X509v3 extension */ |
3020 | struct cert_info *ret; /* certificate info/value */ | | 3025 | struct cert_info *ret; /* certificate info/value */ |
3021 | BIO *bp; | | 3026 | BIO *bp; |
3022 | X509V3_EXT_METHOD *method; | | 3027 | X509V3_EXT_METHOD *method; |
3023 | char pathbuf[MAXFILENAME]; | | 3028 | char pathbuf[MAXFILENAME]; |
3024 | const u_char *uptr; | | 3029 | const u_char *uptr; |
3025 | char *ptr; | | 3030 | char *ptr; |
3026 | int temp, cnt, i; | | 3031 | int temp, cnt, i; |
3027 | | | 3032 | |
3028 | /* | | 3033 | /* |
3029 | * Decode ASN.1 objects and construct certificate structure. | | 3034 | * Decode ASN.1 objects and construct certificate structure. |
3030 | */ | | 3035 | */ |
3031 | uptr = asn1cert; | | 3036 | uptr = asn1cert; |
3032 | if ((cert = d2i_X509(NULL, &uptr, len)) == NULL) { | | 3037 | if ((cert = d2i_X509(NULL, &uptr, len)) == NULL) { |
3033 | msyslog(LOG_ERR, "cert_parse %s\n", | | 3038 | msyslog(LOG_ERR, "cert_parse %s\n", |
3034 | ERR_error_string(ERR_get_error(), NULL)); | | 3039 | ERR_error_string(ERR_get_error(), NULL)); |
3035 | return (NULL); | | 3040 | return (NULL); |
3036 | } | | 3041 | } |
3037 | | | 3042 | |
3038 | /* | | 3043 | /* |
3039 | * Extract version, subject name and public key. | | 3044 | * Extract version, subject name and public key. |
3040 | */ | | 3045 | */ |
3041 | ret = emalloc(sizeof(struct cert_info)); | | 3046 | ret = emalloc(sizeof(struct cert_info)); |
3042 | memset(ret, 0, sizeof(struct cert_info)); | | 3047 | memset(ret, 0, sizeof(struct cert_info)); |
3043 | if ((ret->pkey = X509_get_pubkey(cert)) == NULL) { | | 3048 | if ((ret->pkey = X509_get_pubkey(cert)) == NULL) { |
3044 | msyslog(LOG_ERR, "cert_parse %s\n", | | 3049 | msyslog(LOG_ERR, "cert_parse %s\n", |
3045 | ERR_error_string(ERR_get_error(), NULL)); | | 3050 | ERR_error_string(ERR_get_error(), NULL)); |
3046 | cert_free(ret); | | 3051 | cert_free(ret); |
3047 | X509_free(cert); | | 3052 | X509_free(cert); |
3048 | return (NULL); | | 3053 | return (NULL); |
3049 | } | | 3054 | } |
3050 | ret->version = X509_get_version(cert); | | 3055 | ret->version = X509_get_version(cert); |
3051 | X509_NAME_oneline(X509_get_subject_name(cert), pathbuf, | | 3056 | X509_NAME_oneline(X509_get_subject_name(cert), pathbuf, |
3052 | MAXFILENAME - 1); | | 3057 | MAXFILENAME - 1); |
3053 | ptr = strstr(pathbuf, "CN="); | | 3058 | ptr = strstr(pathbuf, "CN="); |
3054 | if (ptr == NULL) { | | 3059 | if (ptr == NULL) { |
3055 | msyslog(LOG_INFO, "cert_parse: invalid subject %s", | | 3060 | msyslog(LOG_INFO, "cert_parse: invalid subject %s", |
3056 | pathbuf); | | 3061 | pathbuf); |
3057 | cert_free(ret); | | 3062 | cert_free(ret); |
3058 | X509_free(cert); | | 3063 | X509_free(cert); |
3059 | return (NULL); | | 3064 | return (NULL); |
3060 | } | | 3065 | } |
3061 | ret->subject = emalloc(strlen(ptr) + 1); | | 3066 | ret->subject = emalloc(strlen(ptr) + 1); |
3062 | strcpy(ret->subject, ptr + 3); | | 3067 | strcpy(ret->subject, ptr + 3); |
3063 | | | 3068 | |
3064 | /* | | 3069 | /* |
3065 | * Extract remaining objects. Note that the NTP serial number is | | 3070 | * Extract remaining objects. Note that the NTP serial number is |
3066 | * the NTP seconds at the time of signing, but this might not be | | 3071 | * the NTP seconds at the time of signing, but this might not be |
3067 | * the case for other authority. We don't bother to check the | | 3072 | * the case for other authority. We don't bother to check the |
3068 | * objects at this time, since the real crunch can happen only | | 3073 | * objects at this time, since the real crunch can happen only |
3069 | * when the time is valid but not yet certificated. | | 3074 | * when the time is valid but not yet certificated. |
3070 | */ | | 3075 | */ |
3071 | ret->nid = OBJ_obj2nid(cert->cert_info->signature->algorithm); | | 3076 | ret->nid = OBJ_obj2nid(cert->cert_info->signature->algorithm); |
3072 | ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid); | | 3077 | ret->digest = (const EVP_MD *)EVP_get_digestbynid(ret->nid); |
3073 | ret->serial = | | 3078 | ret->serial = |
3074 | (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert)); | | 3079 | (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert)); |
3075 | X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf, | | 3080 | X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf, |
3076 | MAXFILENAME); | | 3081 | MAXFILENAME); |
3077 | if ((ptr = strstr(pathbuf, "CN=")) == NULL) { | | 3082 | if ((ptr = strstr(pathbuf, "CN=")) == NULL) { |
3078 | msyslog(LOG_INFO, "cert_parse: invalid issuer %s", | | 3083 | msyslog(LOG_INFO, "cert_parse: invalid issuer %s", |
3079 | pathbuf); | | 3084 | pathbuf); |
3080 | cert_free(ret); | | 3085 | cert_free(ret); |
3081 | X509_free(cert); | | 3086 | X509_free(cert); |
3082 | return (NULL); | | 3087 | return (NULL); |
3083 | } | | 3088 | } |
3084 | ret->issuer = emalloc(strlen(ptr) + 1); | | 3089 | ret->issuer = emalloc(strlen(ptr) + 1); |
3085 | strcpy(ret->issuer, ptr + 3); | | 3090 | strcpy(ret->issuer, ptr + 3); |
3086 | ret->first = asn2ntp(X509_get_notBefore(cert)); | | 3091 | ret->first = asn2ntp(X509_get_notBefore(cert)); |
3087 | ret->last = asn2ntp(X509_get_notAfter(cert)); | | 3092 | ret->last = asn2ntp(X509_get_notAfter(cert)); |
3088 | | | 3093 | |
3089 | /* | | 3094 | /* |
3090 | * Extract extension fields. These are ad hoc ripoffs of | | 3095 | * Extract extension fields. These are ad hoc ripoffs of |
3091 | * currently assigned functions and will certainly be changed | | 3096 | * currently assigned functions and will certainly be changed |
3092 | * before prime time. | | 3097 | * before prime time. |
3093 | */ | | 3098 | */ |
3094 | cnt = X509_get_ext_count(cert); | | 3099 | cnt = X509_get_ext_count(cert); |
3095 | for (i = 0; i < cnt; i++) { | | 3100 | for (i = 0; i < cnt; i++) { |
3096 | ext = X509_get_ext(cert, i); | | 3101 | ext = X509_get_ext(cert, i); |
3097 | method = X509V3_EXT_get(ext); | | 3102 | method = X509V3_EXT_get(ext); |
3098 | temp = OBJ_obj2nid(ext->object); | | 3103 | temp = OBJ_obj2nid(ext->object); |
3099 | switch (temp) { | | 3104 | switch (temp) { |
3100 | | | 3105 | |
3101 | /* | | 3106 | /* |
3102 | * If a key_usage field is present, we decode whether | | 3107 | * If a key_usage field is present, we decode whether |
3103 | * this is a trusted or private certificate. This is | | 3108 | * this is a trusted or private certificate. This is |
3104 | * dorky; all we want is to compare NIDs, but OpenSSL | | 3109 | * dorky; all we want is to compare NIDs, but OpenSSL |
3105 | * insists on BIO text strings. | | 3110 | * insists on BIO text strings. |
3106 | */ | | 3111 | */ |
3107 | case NID_ext_key_usage: | | 3112 | case NID_ext_key_usage: |
3108 | bp = BIO_new(BIO_s_mem()); | | 3113 | bp = BIO_new(BIO_s_mem()); |
3109 | X509V3_EXT_print(bp, ext, 0, 0); | | 3114 | X509V3_EXT_print(bp, ext, 0, 0); |
3110 | BIO_gets(bp, pathbuf, MAXFILENAME); | | 3115 | BIO_gets(bp, pathbuf, MAXFILENAME); |
3111 | BIO_free(bp); | | 3116 | BIO_free(bp); |
3112 | #if DEBUG | | 3117 | #if DEBUG |
3113 | if (debug) | | 3118 | if (debug) |
3114 | printf("cert_parse: %s: %s\n", | | 3119 | printf("cert_parse: %s: %s\n", |
3115 | OBJ_nid2ln(temp), pathbuf); | | 3120 | OBJ_nid2ln(temp), pathbuf); |
3116 | #endif | | 3121 | #endif |
3117 | if (strcmp(pathbuf, "Trust Root") == 0) | | 3122 | if (strcmp(pathbuf, "Trust Root") == 0) |
3118 | ret->flags |= CERT_TRUST; | | 3123 | ret->flags |= CERT_TRUST; |
3119 | else if (strcmp(pathbuf, "Private") == 0) | | 3124 | else if (strcmp(pathbuf, "Private") == 0) |
3120 | ret->flags |= CERT_PRIV; | | 3125 | ret->flags |= CERT_PRIV; |
3121 | break; | | 3126 | break; |
3122 | | | 3127 | |
3123 | /* | | 3128 | /* |
3124 | * If a NID_subject_key_identifier field is present, it | | 3129 | * If a NID_subject_key_identifier field is present, it |
3125 | * contains the GQ public key. | | 3130 | * contains the GQ public key. |
3126 | */ | | 3131 | */ |
3127 | case NID_subject_key_identifier: | | 3132 | case NID_subject_key_identifier: |
3128 | ret->grplen = ext->value->length - 2; | | 3133 | ret->grplen = ext->value->length - 2; |
3129 | ret->grpkey = emalloc(ret->grplen); | | 3134 | ret->grpkey = emalloc(ret->grplen); |
3130 | memcpy(ret->grpkey, &ext->value->data[2], | | 3135 | memcpy(ret->grpkey, &ext->value->data[2], |
3131 | ret->grplen); | | 3136 | ret->grplen); |
3132 | break; | | 3137 | break; |
3133 | } | | 3138 | } |
3134 | } | | 3139 | } |
3135 | | | 3140 | |
3136 | /* | | 3141 | /* |
3137 | * If certificate is self signed, verify signature. | | 3142 | * If certificate is self signed, verify signature. |
3138 | */ | | 3143 | */ |
3139 | if (strcmp(ret->subject, ret->issuer) == 0) { | | 3144 | if (strcmp(ret->subject, ret->issuer) == 0) { |
3140 | if (!X509_verify(cert, ret->pkey)) { | | 3145 | if (!X509_verify(cert, ret->pkey)) { |
3141 | msyslog(LOG_INFO, | | 3146 | msyslog(LOG_INFO, |
3142 | "cert_parse: signature not verified %s", | | 3147 | "cert_parse: signature not verified %s", |
3143 | pathbuf); | | 3148 | pathbuf); |
3144 | cert_free(ret); | | 3149 | cert_free(ret); |
3145 | X509_free(cert); | | 3150 | X509_free(cert); |
3146 | return (NULL); | | 3151 | return (NULL); |
3147 | } | | 3152 | } |
3148 | } | | 3153 | } |
3149 | | | 3154 | |
3150 | /* | | 3155 | /* |
3151 | * Verify certificate valid times. Note that certificates cannot | | 3156 | * Verify certificate valid times. Note that certificates cannot |
3152 | * be retroactive. | | 3157 | * be retroactive. |
3153 | */ | | 3158 | */ |
3154 | if (ret->first > ret->last || ret->first < fstamp) { | | 3159 | if (ret->first > ret->last || ret->first < fstamp) { |
3155 | msyslog(LOG_INFO, | | 3160 | msyslog(LOG_INFO, |
3156 | "cert_parse: invalid certificate %s first %u last %u fstamp %u", | | 3161 | "cert_parse: invalid certificate %s first %u last %u fstamp %u", |
3157 | ret->subject, ret->first, ret->last, fstamp); | | 3162 | ret->subject, ret->first, ret->last, fstamp); |
3158 | cert_free(ret); | | 3163 | cert_free(ret); |
3159 | X509_free(cert); | | 3164 | X509_free(cert); |
3160 | return (NULL); | | 3165 | return (NULL); |
3161 | } | | 3166 | } |
3162 | | | 3167 | |
3163 | /* | | 3168 | /* |
3164 | * Build the value structure to sign and send later. | | 3169 | * Build the value structure to sign and send later. |
3165 | */ | | 3170 | */ |
3166 | ret->cert.fstamp = htonl(fstamp); | | 3171 | ret->cert.fstamp = htonl(fstamp); |
3167 | ret->cert.vallen = htonl(len); | | 3172 | ret->cert.vallen = htonl(len); |
3168 | ret->cert.ptr = emalloc(len); | | 3173 | ret->cert.ptr = emalloc(len); |
3169 | memcpy(ret->cert.ptr, asn1cert, len); | | 3174 | memcpy(ret->cert.ptr, asn1cert, len); |
3170 | #ifdef DEBUG | | 3175 | #ifdef DEBUG |
3171 | if (debug > 1) | | 3176 | if (debug > 1) |
3172 | X509_print_fp(stdout, cert); | | 3177 | X509_print_fp(stdout, cert); |
3173 | #endif | | 3178 | #endif |
3174 | X509_free(cert); | | 3179 | X509_free(cert); |
3175 | return (ret); | | 3180 | return (ret); |
3176 | } | | 3181 | } |
3177 | | | 3182 | |
3178 | | | 3183 | |
3179 | /* | | 3184 | /* |
3180 | * cert_sign - sign x509 certificate equest and update value structure. | | 3185 | * cert_sign - sign x509 certificate equest and update value structure. |
3181 | * | | 3186 | * |
3182 | * The certificate request includes a copy of the host certificate, | | 3187 | * The certificate request includes a copy of the host certificate, |
3183 | * which includes the version number, subject name and public key of the | | 3188 | * which includes the version number, subject name and public key of the |
3184 | * host. The resulting certificate includes these values plus the | | 3189 | * host. The resulting certificate includes these values plus the |
3185 | * serial number, issuer name and valid interval of the server. The | | 3190 | * serial number, issuer name and valid interval of the server. The |
3186 | * valid interval extends from the current time to the same time one | | 3191 | * valid interval extends from the current time to the same time one |
3187 | * year hence. This may extend the life of the signed certificate beyond | | 3192 | * year hence. This may extend the life of the signed certificate beyond |
3188 | * that of the signer certificate. | | 3193 | * that of the signer certificate. |
3189 | * | | 3194 | * |
3190 | * It is convenient to use the NTP seconds of the current time as the | | 3195 | * It is convenient to use the NTP seconds of the current time as the |
3191 | * serial number. In the value structure the timestamp is the current | | 3196 | * serial number. In the value structure the timestamp is the current |
3192 | * time and the filestamp is taken from the extension field. Note this | | 3197 | * time and the filestamp is taken from the extension field. Note this |
3193 | * routine is called only when the client clock is synchronized to a | | 3198 | * routine is called only when the client clock is synchronized to a |
3194 | * proventic source, so timestamp comparisons are valid. | | 3199 | * proventic source, so timestamp comparisons are valid. |
3195 | * | | 3200 | * |
3196 | * The host certificate is valid from the time it was generated for a | | 3201 | * The host certificate is valid from the time it was generated for a |
3197 | * period of one year. A signed certificate is valid from the time of | | 3202 | * period of one year. A signed certificate is valid from the time of |
3198 | * signature for a period of one year, but only the host certificate (or | | 3203 | * signature for a period of one year, but only the host certificate (or |
3199 | * sign certificate if used) is actually used to encrypt and decrypt | | 3204 | * sign certificate if used) is actually used to encrypt and decrypt |
3200 | * signatures. The signature trail is built from the client via the | | 3205 | * signatures. The signature trail is built from the client via the |
3201 | * intermediate servers to the trusted server. Each signature on the | | 3206 | * intermediate servers to the trusted server. Each signature on the |
3202 | * trail must be valid at the time of signature, but it could happen | | 3207 | * trail must be valid at the time of signature, but it could happen |
3203 | * that a signer certificate expire before the signed certificate, which | | 3208 | * that a signer certificate expire before the signed certificate, which |
3204 | * remains valid until its expiration. | | 3209 | * remains valid until its expiration. |
3205 | * | | 3210 | * |
3206 | * Returns | | 3211 | * Returns |
3207 | * XEVNT_OK success | | 3212 | * XEVNT_OK success |
3208 | * XEVNT_PUB bad or missing public key | | 3213 | * XEVNT_PUB bad or missing public key |
3209 | * XEVNT_CRT bad or missing certificate | | 3214 | * XEVNT_CRT bad or missing certificate |
3210 | * XEVNT_VFY certificate not verified | | 3215 | * XEVNT_VFY certificate not verified |
3211 | * XEVNT_PER host certificate expired | | 3216 | * XEVNT_PER host certificate expired |
3212 | */ | | 3217 | */ |
3213 | static int | | 3218 | static int |
3214 | cert_sign( | | 3219 | cert_sign( |
3215 | struct exten *ep, /* extension field pointer */ | | 3220 | struct exten *ep, /* extension field pointer */ |
3216 | struct value *vp /* value pointer */ | | 3221 | struct value *vp /* value pointer */ |
3217 | ) | | 3222 | ) |
3218 | { | | 3223 | { |
3219 | X509 *req; /* X509 certificate request */ | | 3224 | X509 *req; /* X509 certificate request */ |
3220 | X509 *cert; /* X509 certificate */ | | 3225 | X509 *cert; /* X509 certificate */ |
3221 | X509_EXTENSION *ext; /* certificate extension */ | | 3226 | X509_EXTENSION *ext; /* certificate extension */ |
3222 | ASN1_INTEGER *serial; /* serial number */ | | 3227 | ASN1_INTEGER *serial; /* serial number */ |
3223 | X509_NAME *subj; /* distinguished (common) name */ | | 3228 | X509_NAME *subj; /* distinguished (common) name */ |
3224 | EVP_PKEY *pkey; /* public key */ | | 3229 | EVP_PKEY *pkey; /* public key */ |
3225 | EVP_MD_CTX ctx; /* message digest context */ | | 3230 | EVP_MD_CTX ctx; /* message digest context */ |
3226 | tstamp_t tstamp; /* NTP timestamp */ | | 3231 | tstamp_t tstamp; /* NTP timestamp */ |
3227 | u_int len; | | 3232 | u_int len; |
3228 | const u_char *ptr; | | 3233 | const u_char *ptr; |
3229 | int i, temp; | | 3234 | int i, temp; |
3230 | | | 3235 | |
3231 | /* | | 3236 | /* |
3232 | * Decode ASN.1 objects and construct certificate structure. | | 3237 | * Decode ASN.1 objects and construct certificate structure. |
3233 | * Make sure the system clock is synchronized to a proventic | | 3238 | * Make sure the system clock is synchronized to a proventic |
3234 | * source. | | 3239 | * source. |
3235 | */ | | 3240 | */ |
3236 | tstamp = crypto_time(); | | 3241 | tstamp = crypto_time(); |
3237 | if (tstamp == 0) | | 3242 | if (tstamp == 0) |
3238 | return (XEVNT_TSP); | | 3243 | return (XEVNT_TSP); |
3239 | | | 3244 | |
3240 | if (tstamp < cinfo->first || tstamp > cinfo->last) | | 3245 | if (tstamp < cinfo->first || tstamp > cinfo->last) |
3241 | return (XEVNT_PER); | | 3246 | return (XEVNT_PER); |
3242 | | | 3247 | |
3243 | ptr = (u_char *)ep->pkt; | | 3248 | ptr = (u_char *)ep->pkt; |
3244 | if ((req = d2i_X509(NULL, &ptr, ntohl(ep->vallen))) == NULL) { | | 3249 | if ((req = d2i_X509(NULL, &ptr, ntohl(ep->vallen))) == NULL) { |
3245 | msyslog(LOG_ERR, "cert_sign %s\n", | | 3250 | msyslog(LOG_ERR, "cert_sign %s\n", |
3246 | ERR_error_string(ERR_get_error(), NULL)); | | 3251 | ERR_error_string(ERR_get_error(), NULL)); |
3247 | return (XEVNT_CRT); | | 3252 | return (XEVNT_CRT); |
3248 | } | | 3253 | } |
3249 | /* | | 3254 | /* |
3250 | * Extract public key and check for errors. | | 3255 | * Extract public key and check for errors. |
3251 | */ | | 3256 | */ |
3252 | if ((pkey = X509_get_pubkey(req)) == NULL) { | | 3257 | if ((pkey = X509_get_pubkey(req)) == NULL) { |
3253 | msyslog(LOG_ERR, "cert_sign %s\n", | | 3258 | msyslog(LOG_ERR, "cert_sign %s\n", |
3254 | ERR_error_string(ERR_get_error(), NULL)); | | 3259 | ERR_error_string(ERR_get_error(), NULL)); |
3255 | X509_free(req); | | 3260 | X509_free(req); |
3256 | return (XEVNT_PUB); | | 3261 | return (XEVNT_PUB); |
3257 | } | | 3262 | } |
3258 | | | 3263 | |
3259 | /* | | 3264 | /* |
3260 | * Generate X509 certificate signed by this server. For this | | 3265 | * Generate X509 certificate signed by this server. For this |
3261 | * purpose the issuer name is the server name. Also copy any | | 3266 | * purpose the issuer name is the server name. Also copy any |
3262 | * extensions that might be present. | | 3267 | * extensions that might be present. |
3263 | */ | | 3268 | */ |
3264 | cert = X509_new(); | | 3269 | cert = X509_new(); |
3265 | X509_set_version(cert, X509_get_version(req)); | | 3270 | X509_set_version(cert, X509_get_version(req)); |
3266 | serial = ASN1_INTEGER_new(); | | 3271 | serial = ASN1_INTEGER_new(); |
3267 | ASN1_INTEGER_set(serial, tstamp); | | 3272 | ASN1_INTEGER_set(serial, tstamp); |
3268 | X509_set_serialNumber(cert, serial); | | 3273 | X509_set_serialNumber(cert, serial); |
3269 | X509_gmtime_adj(X509_get_notBefore(cert), 0L); | | 3274 | X509_gmtime_adj(X509_get_notBefore(cert), 0L); |
3270 | X509_gmtime_adj(X509_get_notAfter(cert), YEAR); | | 3275 | X509_gmtime_adj(X509_get_notAfter(cert), YEAR); |
3271 | subj = X509_get_issuer_name(cert); | | 3276 | subj = X509_get_issuer_name(cert); |
3272 | X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC, | | 3277 | X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC, |
3273 | (u_char *)sys_hostname, strlen(sys_hostname), -1, 0); | | 3278 | (u_char *)sys_hostname, strlen(sys_hostname), -1, 0); |
3274 | subj = X509_get_subject_name(req); | | 3279 | subj = X509_get_subject_name(req); |
3275 | X509_set_subject_name(cert, subj); | | 3280 | X509_set_subject_name(cert, subj); |
3276 | X509_set_pubkey(cert, pkey); | | 3281 | X509_set_pubkey(cert, pkey); |
3277 | ext = X509_get_ext(req, 0); | | 3282 | ext = X509_get_ext(req, 0); |
3278 | temp = X509_get_ext_count(req); | | 3283 | temp = X509_get_ext_count(req); |
3279 | for (i = 0; i < temp; i++) { | | 3284 | for (i = 0; i < temp; i++) { |
3280 | ext = X509_get_ext(req, i); | | 3285 | ext = X509_get_ext(req, i); |
3281 | X509_add_ext(cert, ext, -1); | | 3286 | X509_add_ext(cert, ext, -1); |
3282 | } | | 3287 | } |
3283 | X509_free(req); | | 3288 | X509_free(req); |
3284 | | | 3289 | |
3285 | /* | | 3290 | /* |
3286 | * Sign and verify the certificate. | | 3291 | * Sign and verify the certificate. |
3287 | */ | | 3292 | */ |
3288 | X509_sign(cert, sign_pkey, sign_digest); | | 3293 | X509_sign(cert, sign_pkey, sign_digest); |
3289 | if (!X509_verify(cert, sign_pkey)) { | | 3294 | if (!X509_verify(cert, sign_pkey)) { |
3290 | printf("cert_sign\n%s\n", | | 3295 | printf("cert_sign\n%s\n", |
3291 | ERR_error_string(ERR_get_error(), NULL)); | | 3296 | ERR_error_string(ERR_get_error(), NULL)); |
3292 | X509_free(cert); | | 3297 | X509_free(cert); |
3293 | return (XEVNT_VFY); | | 3298 | return (XEVNT_VFY); |
3294 | } | | 3299 | } |
3295 | len = i2d_X509(cert, NULL); | | 3300 | len = i2d_X509(cert, NULL); |
3296 | | | 3301 | |
3297 | /* | | 3302 | /* |
3298 | * Build and sign the value structure. We have to sign it here, | | 3303 | * Build and sign the value structure. We have to sign it here, |
3299 | * since the response has to be returned right away. This is a | | 3304 | * since the response has to be returned right away. This is a |
3300 | * clogging hazard. | | 3305 | * clogging hazard. |
3301 | */ | | 3306 | */ |
3302 | memset(vp, 0, sizeof(struct value)); | | 3307 | memset(vp, 0, sizeof(struct value)); |
3303 | vp->tstamp = htonl(tstamp); | | 3308 | vp->tstamp = htonl(tstamp); |
3304 | vp->fstamp = ep->fstamp; | | 3309 | vp->fstamp = ep->fstamp; |
3305 | vp->vallen = htonl(len); | | 3310 | vp->vallen = htonl(len); |
3306 | vp->ptr = emalloc(len); | | 3311 | vp->ptr = emalloc(len); |
3307 | ptr = vp->ptr; | | 3312 | ptr = vp->ptr; |
3308 | i2d_X509(cert, (unsigned char **)&ptr); | | 3313 | i2d_X509(cert, (unsigned char **)&ptr); |
3309 | vp->siglen = 0; | | 3314 | vp->siglen = 0; |
3310 | vp->sig = emalloc(sign_siglen); | | 3315 | vp->sig = emalloc(sign_siglen); |
3311 | EVP_SignInit(&ctx, sign_digest); | | 3316 | EVP_SignInit(&ctx, sign_digest); |
3312 | EVP_SignUpdate(&ctx, (u_char *)vp, 12); | | 3317 | EVP_SignUpdate(&ctx, (u_char *)vp, 12); |
3313 | EVP_SignUpdate(&ctx, vp->ptr, len); | | 3318 | EVP_SignUpdate(&ctx, vp->ptr, len); |
3314 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) | | 3319 | if (EVP_SignFinal(&ctx, vp->sig, &len, sign_pkey)) |
3315 | vp->siglen = htonl(len); | | 3320 | vp->siglen = htonl(len); |
3316 | #ifdef DEBUG | | 3321 | #ifdef DEBUG |
3317 | if (debug > 1) | | 3322 | if (debug > 1) |
3318 | X509_print_fp(stdout, cert); | | 3323 | X509_print_fp(stdout, cert); |
3319 | #endif | | 3324 | #endif |
3320 | X509_free(cert); | | 3325 | X509_free(cert); |
3321 | return (XEVNT_OK); | | 3326 | return (XEVNT_OK); |
3322 | } | | 3327 | } |
3323 | | | 3328 | |
3324 | | | 3329 | |
3325 | /* | | 3330 | /* |
3326 | * cert_valid - verify certificate with given public key | | 3331 | * cert_valid - verify certificate with given public key |
3327 | * | | 3332 | * |
3328 | * This is pretty ugly, as the certificate has to be verified in the | | 3333 | * This is pretty ugly, as the certificate has to be verified in the |
3329 | * OpenSSL X509 structure, not in the DER format in the info/value | | 3334 | * OpenSSL X509 structure, not in the DER format in the info/value |
3330 | * structure. | | 3335 | * structure. |
3331 | * | | 3336 | * |
3332 | * Returns | | 3337 | * Returns |
3333 | * XEVNT_OK success | | 3338 | * XEVNT_OK success |
3334 | * XEVNT_VFY certificate not verified | | 3339 | * XEVNT_VFY certificate not verified |
3335 | */ | | 3340 | */ |
3336 | int | | 3341 | int |
3337 | cert_valid( | | 3342 | cert_valid( |
3338 | struct cert_info *cinf, /* certificate information structure */ | | 3343 | struct cert_info *cinf, /* certificate information structure */ |
3339 | EVP_PKEY *pkey /* public key */ | | 3344 | EVP_PKEY *pkey /* public key */ |
3340 | ) | | 3345 | ) |
3341 | { | | 3346 | { |
3342 | X509 *cert; /* X509 certificate */ | | 3347 | X509 *cert; /* X509 certificate */ |
3343 | const u_char *ptr; | | 3348 | const u_char *ptr; |
3344 | | | 3349 | |
3345 | if (cinf->flags & CERT_SIGN) | | 3350 | if (cinf->flags & CERT_SIGN) |
3346 | return (XEVNT_OK); | | 3351 | return (XEVNT_OK); |
3347 | | | 3352 | |
3348 | ptr = (u_char *)cinf->cert.ptr; | | 3353 | ptr = (u_char *)cinf->cert.ptr; |
3349 | cert = d2i_X509(NULL, &ptr, ntohl(cinf->cert.vallen)); | | 3354 | cert = d2i_X509(NULL, &ptr, ntohl(cinf->cert.vallen)); |
3350 | if (cert == NULL || !X509_verify(cert, pkey)) | | 3355 | if (cert == NULL || !X509_verify(cert, pkey)) |
3351 | return (XEVNT_VFY); | | 3356 | return (XEVNT_VFY); |
3352 | | | 3357 | |
3353 | X509_free(cert); | | 3358 | X509_free(cert); |
3354 | return (XEVNT_OK); | | 3359 | return (XEVNT_OK); |
3355 | } | | 3360 | } |
3356 | | | 3361 | |
3357 | | | 3362 | |
3358 | /* | | 3363 | /* |
3359 | * cert - install certificate in certificate list | | 3364 | * cert - install certificate in certificate list |
3360 | * | | 3365 | * |
3361 | * This routine encodes an extension field into a certificate info/value | | 3366 | * This routine encodes an extension field into a certificate info/value |
3362 | * structure. It searches the certificate list for duplicates and | | 3367 | * structure. It searches the certificate list for duplicates and |
3363 | * expunges whichever is older. It then searches the list for other | | 3368 | * expunges whichever is older. It then searches the list for other |
3364 | * certificates that might be verified by this latest one. Finally, it | | 3369 | * certificates that might be verified by this latest one. Finally, it |
3365 | * inserts this certificate first on the list. | | 3370 | * inserts this certificate first on the list. |
3366 | * | | 3371 | * |
3367 | * Returns | | 3372 | * Returns |
3368 | * XEVNT_OK success | | 3373 | * XEVNT_OK success |
3369 | * XEVNT_FSP bad or missing filestamp | | 3374 | * XEVNT_FSP bad or missing filestamp |
3370 | * XEVNT_CRT bad or missing certificate | | 3375 | * XEVNT_CRT bad or missing certificate |
3371 | */ | | 3376 | */ |
3372 | int | | 3377 | int |
3373 | cert_install( | | 3378 | cert_install( |
3374 | struct exten *ep, /* cert info/value */ | | 3379 | struct exten *ep, /* cert info/value */ |
3375 | struct peer *peer /* peer structure */ | | 3380 | struct peer *peer /* peer structure */ |
3376 | ) | | 3381 | ) |
3377 | { | | 3382 | { |
3378 | struct cert_info *cp, *xp, *yp, **zp; | | 3383 | struct cert_info *cp, *xp, *yp, **zp; |
3379 | | | 3384 | |
3380 | /* | | 3385 | /* |
3381 | * Parse and validate the signed certificate. If valid, | | 3386 | * Parse and validate the signed certificate. If valid, |
3382 | * construct the info/value structure; otherwise, scamper home. | | 3387 | * construct the info/value structure; otherwise, scamper home. |
3383 | */ | | 3388 | */ |
3384 | if ((cp = cert_parse((u_char *)ep->pkt, ntohl(ep->vallen), | | 3389 | if ((cp = cert_parse((u_char *)ep->pkt, ntohl(ep->vallen), |
3385 | ntohl(ep->fstamp))) == NULL) | | 3390 | ntohl(ep->fstamp))) == NULL) |
3386 | return (XEVNT_CRT); | | 3391 | return (XEVNT_CRT); |
3387 | | | 3392 | |
3388 | /* | | 3393 | /* |
3389 | * Scan certificate list looking for another certificate with | | 3394 | * Scan certificate list looking for another certificate with |
3390 | * the same subject and issuer. If another is found with the | | 3395 | * the same subject and issuer. If another is found with the |
3391 | * same or older filestamp, unlink it and return the goodies to | | 3396 | * same or older filestamp, unlink it and return the goodies to |
3392 | * the heap. If another is found with a later filestamp, discard | | 3397 | * the heap. If another is found with a later filestamp, discard |
3393 | * the new one and leave the building. | | 3398 | * the new one and leave the building. |
3394 | * | | 3399 | * |
3395 | * Make a note to study this issue again. An earlier certificate | | 3400 | * Make a note to study this issue again. An earlier certificate |
3396 | * with a long lifetime might be overtaken by a later | | 3401 | * with a long lifetime might be overtaken by a later |
3397 | * certificate with a short lifetime, thus invalidating the | | 3402 | * certificate with a short lifetime, thus invalidating the |
3398 | * earlier signature. However, we gotta find a way to leak old | | 3403 | * earlier signature. However, we gotta find a way to leak old |
3399 | * stuff from the cache, so we do it anyway. | | 3404 | * stuff from the cache, so we do it anyway. |
3400 | */ | | 3405 | */ |
3401 | yp = cp; | | 3406 | yp = cp; |
3402 | zp = &cinfo; | | 3407 | zp = &cinfo; |
3403 | for (xp = cinfo; xp != NULL; xp = xp->link) { | | 3408 | for (xp = cinfo; xp != NULL; xp = xp->link) { |
3404 | if (strcmp(cp->subject, xp->subject) == 0 && | | 3409 | if (strcmp(cp->subject, xp->subject) == 0 && |
3405 | strcmp(cp->issuer, xp->issuer) == 0) { | | 3410 | strcmp(cp->issuer, xp->issuer) == 0) { |
3406 | if (ntohl(cp->cert.fstamp) <= | | 3411 | if (ntohl(cp->cert.fstamp) <= |
3407 | ntohl(xp->cert.fstamp)) { | | 3412 | ntohl(xp->cert.fstamp)) { |
3408 | *zp = xp->link;; | | 3413 | *zp = xp->link;; |
3409 | cert_free(xp); | | 3414 | cert_free(xp); |
3410 | } else { | | 3415 | } else { |
3411 | cert_free(cp); | | 3416 | cert_free(cp); |
3412 | return (XEVNT_FSP); | | 3417 | return (XEVNT_FSP); |
3413 | } | | 3418 | } |
3414 | break; | | 3419 | break; |
3415 | } | | 3420 | } |
3416 | zp = &xp->link; | | 3421 | zp = &xp->link; |
3417 | } | | 3422 | } |
3418 | yp->link = cinfo; | | 3423 | yp->link = cinfo; |
3419 | cinfo = yp; | | 3424 | cinfo = yp; |
3420 | | | 3425 | |
3421 | /* | | 3426 | /* |
3422 | * Scan the certificate list to see if Y is signed by X. This is | | 3427 | * Scan the certificate list to see if Y is signed by X. This is |
3423 | * independent of order. | | 3428 | * independent of order. |
3424 | */ | | 3429 | */ |
3425 | for (yp = cinfo; yp != NULL; yp = yp->link) { | | 3430 | for (yp = cinfo; yp != NULL; yp = yp->link) { |
3426 | for (xp = cinfo; xp != NULL; xp = xp->link) { | | 3431 | for (xp = cinfo; xp != NULL; xp = xp->link) { |
3427 | | | 3432 | |
3428 | /* | | 3433 | /* |
3429 | * If the issuer of certificate Y matches the | | 3434 | * If the issuer of certificate Y matches the |
3430 | * subject of certificate X, verify the | | 3435 | * subject of certificate X, verify the |
3431 | * signature of Y using the public key of X. If | | 3436 | * signature of Y using the public key of X. If |
3432 | * so, X signs Y. | | 3437 | * so, X signs Y. |
3433 | */ | | 3438 | */ |
3434 | if (strcmp(yp->issuer, xp->subject) != 0 || | | 3439 | if (strcmp(yp->issuer, xp->subject) != 0 || |
3435 | xp->flags & CERT_ERROR) | | 3440 | xp->flags & CERT_ERROR) |
3436 | continue; | | 3441 | continue; |
3437 | | | 3442 | |
3438 | if (cert_valid(yp, xp->pkey) != XEVNT_OK) { | | 3443 | if (cert_valid(yp, xp->pkey) != XEVNT_OK) { |
3439 | yp->flags |= CERT_ERROR; | | 3444 | yp->flags |= CERT_ERROR; |
3440 | continue; | | 3445 | continue; |
3441 | } | | 3446 | } |
3442 | | | 3447 | |
3443 | /* | | 3448 | /* |
3444 | * The signature Y is valid only if it begins | | 3449 | * The signature Y is valid only if it begins |
3445 | * during the lifetime of X; however, it is not | | 3450 | * during the lifetime of X; however, it is not |
3446 | * necessarily an error, since some other | | 3451 | * necessarily an error, since some other |
3447 | * certificate might sign Y. | | 3452 | * certificate might sign Y. |
3448 | */ | | 3453 | */ |
3449 | if (yp->first < xp->first || yp->first > | | 3454 | if (yp->first < xp->first || yp->first > |
3450 | xp->last) | | 3455 | xp->last) |
3451 | continue; | | 3456 | continue; |
3452 | | | 3457 | |
3453 | yp->flags |= CERT_SIGN; | | 3458 | yp->flags |= CERT_SIGN; |
3454 | | | 3459 | |
3455 | /* | | 3460 | /* |
3456 | * If X is trusted, then Y is trusted. Note that | | 3461 | * If X is trusted, then Y is trusted. Note that |
3457 | * we might stumble over a self-signed | | 3462 | * we might stumble over a self-signed |
3458 | * certificate that is not trusted, at least | | 3463 | * certificate that is not trusted, at least |
3459 | * temporarily. This can happen when a dude | | 3464 | * temporarily. This can happen when a dude |
3460 | * first comes up, but has not synchronized the | | 3465 | * first comes up, but has not synchronized the |
3461 | * clock and had its certificate signed by its | | 3466 | * clock and had its certificate signed by its |
3462 | * server. In case of broken certificate trail, | | 3467 | * server. In case of broken certificate trail, |
3463 | * this might result in a loop that could | | 3468 | * this might result in a loop that could |
3464 | * persist until timeout. | | 3469 | * persist until timeout. |
3465 | */ | | 3470 | */ |
3466 | if (!(xp->flags & (CERT_TRUST | CERT_VALID))) | | 3471 | if (!(xp->flags & (CERT_TRUST | CERT_VALID))) |
3467 | continue; | | 3472 | continue; |
3468 | | | 3473 | |
3469 | yp->flags |= CERT_VALID; | | 3474 | yp->flags |= CERT_VALID; |
3470 | | | 3475 | |
3471 | /* | | 3476 | /* |
3472 | * If subject Y matches the server subject name, | | 3477 | * If subject Y matches the server subject name, |
3473 | * then Y has completed the certificate trail. | | 3478 | * then Y has completed the certificate trail. |
3474 | * Save the group key and light the valid bit. | | 3479 | * Save the group key and light the valid bit. |
3475 | */ | | 3480 | */ |
3476 | if (strcmp(yp->subject, peer->subject) != 0) | | 3481 | if (strcmp(yp->subject, peer->subject) != 0) |
3477 | continue; | | 3482 | continue; |
3478 | | | 3483 | |
3479 | if (yp->grpkey != NULL) { | | 3484 | if (yp->grpkey != NULL) { |
3480 | if (peer->grpkey != NULL) | | 3485 | if (peer->grpkey != NULL) |
3481 | BN_free(peer->grpkey); | | 3486 | BN_free(peer->grpkey); |
3482 | peer->grpkey = BN_bin2bn(yp->grpkey, | | 3487 | peer->grpkey = BN_bin2bn(yp->grpkey, |
3483 | yp->grplen, NULL); | | 3488 | yp->grplen, NULL); |
3484 | } | | 3489 | } |
3485 | peer->crypto |= CRYPTO_FLAG_VALID; | | 3490 | peer->crypto |= CRYPTO_FLAG_VALID; |
3486 | | | 3491 | |
3487 | /* | | 3492 | /* |
3488 | * If the server has an an identity scheme, | | 3493 | * If the server has an an identity scheme, |
3489 | * fetch the identity credentials. If not, the | | 3494 | * fetch the identity credentials. If not, the |
3490 | * identity is verified only by the trusted | | 3495 | * identity is verified only by the trusted |
3491 | * certificate. The next signature will set the | | 3496 | * certificate. The next signature will set the |
3492 | * server proventic. | | 3497 | * server proventic. |
3493 | */ | | 3498 | */ |
3494 | if (peer->crypto & (CRYPTO_FLAG_GQ | | | 3499 | if (peer->crypto & (CRYPTO_FLAG_GQ | |
3495 | CRYPTO_FLAG_IFF | CRYPTO_FLAG_MV)) | | 3500 | CRYPTO_FLAG_IFF | CRYPTO_FLAG_MV)) |
3496 | continue; | | 3501 | continue; |
3497 | | | 3502 | |
3498 | peer->crypto |= CRYPTO_FLAG_VRFY; | | 3503 | peer->crypto |= CRYPTO_FLAG_VRFY; |
3499 | } | | 3504 | } |
3500 | } | | 3505 | } |
3501 | | | 3506 | |
3502 | /* | | 3507 | /* |
3503 | * That was awesome. Now update the timestamps and signatures. | | 3508 | * That was awesome. Now update the timestamps and signatures. |
3504 | */ | | 3509 | */ |
3505 | crypto_update(); | | 3510 | crypto_update(); |
3506 | return (XEVNT_OK); | | 3511 | return (XEVNT_OK); |
3507 | } | | 3512 | } |
3508 | | | 3513 | |
3509 | | | 3514 | |
3510 | /* | | 3515 | /* |
3511 | * cert_free - free certificate information structure | | 3516 | * cert_free - free certificate information structure |
3512 | */ | | 3517 | */ |
3513 | void | | 3518 | void |
3514 | cert_free( | | 3519 | cert_free( |
3515 | struct cert_info *cinf /* certificate info/value structure */ | | 3520 | struct cert_info *cinf /* certificate info/value structure */ |
3516 | ) | | 3521 | ) |
3517 | { | | 3522 | { |
3518 | if (cinf->pkey != NULL) | | 3523 | if (cinf->pkey != NULL) |
3519 | EVP_PKEY_free(cinf->pkey); | | 3524 | EVP_PKEY_free(cinf->pkey); |
3520 | if (cinf->subject != NULL) | | 3525 | if (cinf->subject != NULL) |
3521 | free(cinf->subject); | | 3526 | free(cinf->subject); |
3522 | if (cinf->issuer != NULL) | | 3527 | if (cinf->issuer != NULL) |
3523 | free(cinf->issuer); | | 3528 | free(cinf->issuer); |
3524 | if (cinf->grpkey != NULL) | | 3529 | if (cinf->grpkey != NULL) |
3525 | free(cinf->grpkey); | | 3530 | free(cinf->grpkey); |
3526 | value_free(&cinf->cert); | | 3531 | value_free(&cinf->cert); |
3527 | free(cinf); | | 3532 | free(cinf); |
3528 | } | | 3533 | } |
3529 | | | 3534 | |
3530 | | | 3535 | |
3531 | /* | | 3536 | /* |
3532 | *********************************************************************** | | 3537 | *********************************************************************** |
3533 | * * | | 3538 | * * |
3534 | * The following routines are used only at initialization time * | | 3539 | * The following routines are used only at initialization time * |
3535 | * * | | 3540 | * * |
3536 | *********************************************************************** | | 3541 | *********************************************************************** |
3537 | */ | | 3542 | */ |
3538 | /* | | 3543 | /* |
3539 | * crypto_key - load cryptographic parameters and keys from files | | 3544 | * crypto_key - load cryptographic parameters and keys from files |
3540 | * | | 3545 | * |
3541 | * This routine loads a PEM-encoded public/private key pair and extracts | | 3546 | * This routine loads a PEM-encoded public/private key pair and extracts |
3542 | * the filestamp from the file name. | | 3547 | * the filestamp from the file name. |
3543 | * | | 3548 | * |
3544 | * Returns public key pointer if valid, NULL if not. Side effect updates | | 3549 | * Returns public key pointer if valid, NULL if not. Side effect updates |
3545 | * the filestamp if valid. | | 3550 | * the filestamp if valid. |
3546 | */ | | 3551 | */ |
3547 | static EVP_PKEY * | | 3552 | static EVP_PKEY * |
3548 | crypto_key( | | 3553 | crypto_key( |
3549 | char *cp, /* file name */ | | 3554 | char *cp, /* file name */ |
3550 | tstamp_t *fstamp /* filestamp */ | | 3555 | tstamp_t *fstamp /* filestamp */ |
3551 | ) | | 3556 | ) |
3552 | { | | 3557 | { |
3553 | FILE *str; /* file handle */ | | 3558 | FILE *str; /* file handle */ |
3554 | EVP_PKEY *pkey = NULL; /* public/private key */ | | 3559 | EVP_PKEY *pkey = NULL; /* public/private key */ |
3555 | char filename[MAXFILENAME]; /* name of key file */ | | 3560 | char filename[MAXFILENAME]; /* name of key file */ |
3556 | char linkname[MAXFILENAME]; /* filestamp buffer) */ | | 3561 | char linkname[MAXFILENAME]; /* filestamp buffer) */ |
3557 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 3562 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3558 | char *ptr; | | 3563 | char *ptr; |
3559 | | | 3564 | |
3560 | /* | | 3565 | /* |
3561 | * Open the key file. If the first character of the file name is | | 3566 | * Open the key file. If the first character of the file name is |
3562 | * not '/', prepend the keys directory string. If something goes | | 3567 | * not '/', prepend the keys directory string. If something goes |
3563 | * wrong, abandon ship. | | 3568 | * wrong, abandon ship. |
3564 | */ | | 3569 | */ |
3565 | if (*cp == '/') | | 3570 | if (*cp == '/') |
3566 | strcpy(filename, cp); | | 3571 | strcpy(filename, cp); |
3567 | else | | 3572 | else |
3568 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); | | 3573 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); |
3569 | str = fopen(filename, "r"); | | 3574 | str = fopen(filename, "r"); |
3570 | if (str == NULL) | | 3575 | if (str == NULL) |
3571 | return (NULL); | | 3576 | return (NULL); |
3572 | | | 3577 | |
3573 | /* | | 3578 | /* |
3574 | * Read the filestamp, which is contained in the first line. | | 3579 | * Read the filestamp, which is contained in the first line. |
3575 | */ | | 3580 | */ |
3576 | if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) { | | 3581 | if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) { |
3577 | msyslog(LOG_ERR, "crypto_key: no data %s\n", | | 3582 | msyslog(LOG_ERR, "crypto_key: no data %s\n", |
3578 | filename); | | 3583 | filename); |
3579 | (void)fclose(str); | | 3584 | (void)fclose(str); |
3580 | return (NULL); | | 3585 | return (NULL); |
3581 | } | | 3586 | } |
3582 | if ((ptr = strrchr(ptr, '.')) == NULL) { | | 3587 | if ((ptr = strrchr(ptr, '.')) == NULL) { |
3583 | msyslog(LOG_ERR, "crypto_key: no filestamp %s\n", | | 3588 | msyslog(LOG_ERR, "crypto_key: no filestamp %s\n", |
3584 | filename); | | 3589 | filename); |
3585 | (void)fclose(str); | | 3590 | (void)fclose(str); |
3586 | return (NULL); | | 3591 | return (NULL); |
3587 | } | | 3592 | } |
3588 | if (sscanf(++ptr, "%u", fstamp) != 1) { | | 3593 | if (sscanf(++ptr, "%u", fstamp) != 1) { |
3589 | msyslog(LOG_ERR, "crypto_key: invalid timestamp %s\n", | | 3594 | msyslog(LOG_ERR, "crypto_key: invalid timestamp %s\n", |
3590 | filename); | | 3595 | filename); |
3591 | (void)fclose(str); | | 3596 | (void)fclose(str); |
3592 | return (NULL); | | 3597 | return (NULL); |
3593 | } | | 3598 | } |
3594 | | | 3599 | |
3595 | /* | | 3600 | /* |
3596 | * Read and decrypt PEM-encoded private key. | | 3601 | * Read and decrypt PEM-encoded private key. |
3597 | */ | | 3602 | */ |
3598 | pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd); | | 3603 | pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd); |
3599 | fclose(str); | | 3604 | fclose(str); |
3600 | if (pkey == NULL) { | | 3605 | if (pkey == NULL) { |
3601 | msyslog(LOG_ERR, "crypto_key %s\n", | | 3606 | msyslog(LOG_ERR, "crypto_key %s\n", |
3602 | ERR_error_string(ERR_get_error(), NULL)); | | 3607 | ERR_error_string(ERR_get_error(), NULL)); |
3603 | return (NULL); | | 3608 | return (NULL); |
3604 | } | | 3609 | } |
3605 | | | 3610 | |
3606 | /* | | 3611 | /* |
3607 | * Leave tracks in the cryptostats. | | 3612 | * Leave tracks in the cryptostats. |
3608 | */ | | 3613 | */ |
3609 | if ((ptr = strrchr(linkname, '\n')) != NULL) | | 3614 | if ((ptr = strrchr(linkname, '\n')) != NULL) |
3610 | *ptr = '\0'; | | 3615 | *ptr = '\0'; |
3611 | sprintf(statstr, "%s mod %d", &linkname[2], | | 3616 | snprintf(statstr, NTP_MAXSTRLEN, "%s mod %d", &linkname[2], |
3612 | EVP_PKEY_size(pkey) * 8); | | 3617 | EVP_PKEY_size(pkey) * 8); |
3613 | record_crypto_stats(NULL, statstr); | | 3618 | record_crypto_stats(NULL, statstr); |
3614 | #ifdef DEBUG | | 3619 | #ifdef DEBUG |
3615 | if (debug) | | 3620 | if (debug) |
3616 | printf("crypto_key: %s\n", statstr); | | 3621 | printf("crypto_key: %s\n", statstr); |
3617 | if (debug > 1) { | | 3622 | if (debug > 1) { |
3618 | if (pkey->type == EVP_PKEY_DSA) | | 3623 | if (pkey->type == EVP_PKEY_DSA) |
3619 | DSA_print_fp(stdout, pkey->pkey.dsa, 0); | | 3624 | DSA_print_fp(stdout, pkey->pkey.dsa, 0); |
3620 | else | | 3625 | else |
3621 | RSA_print_fp(stdout, pkey->pkey.rsa, 0); | | 3626 | RSA_print_fp(stdout, pkey->pkey.rsa, 0); |
3622 | } | | 3627 | } |
3623 | #endif | | 3628 | #endif |
3624 | return (pkey); | | 3629 | return (pkey); |
3625 | } | | 3630 | } |
3626 | | | 3631 | |
3627 | | | 3632 | |
3628 | /* | | 3633 | /* |
3629 | * crypto_cert - load certificate from file | | 3634 | * crypto_cert - load certificate from file |
3630 | * | | 3635 | * |
3631 | * This routine loads a X.509 RSA or DSA certificate from a file and | | 3636 | * This routine loads a X.509 RSA or DSA certificate from a file and |
3632 | * constructs a info/cert value structure for this machine. The | | 3637 | * constructs a info/cert value structure for this machine. The |
3633 | * structure includes a filestamp extracted from the file name. Later | | 3638 | * structure includes a filestamp extracted from the file name. Later |
3634 | * the certificate can be sent to another machine by request. | | 3639 | * the certificate can be sent to another machine by request. |
3635 | * | | 3640 | * |
3636 | * Returns certificate info/value pointer if valid, NULL if not. | | 3641 | * Returns certificate info/value pointer if valid, NULL if not. |
3637 | */ | | 3642 | */ |
3638 | static struct cert_info * /* certificate information */ | | 3643 | static struct cert_info * /* certificate information */ |
3639 | crypto_cert( | | 3644 | crypto_cert( |
3640 | char *cp /* file name */ | | 3645 | char *cp /* file name */ |
3641 | ) | | 3646 | ) |
3642 | { | | 3647 | { |
3643 | struct cert_info *ret; /* certificate information */ | | 3648 | struct cert_info *ret; /* certificate information */ |
3644 | FILE *str; /* file handle */ | | 3649 | FILE *str; /* file handle */ |
3645 | char filename[MAXFILENAME]; /* name of certificate file */ | | 3650 | char filename[MAXFILENAME]; /* name of certificate file */ |
3646 | char linkname[MAXFILENAME]; /* filestamp buffer */ | | 3651 | char linkname[MAXFILENAME]; /* filestamp buffer */ |
3647 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 3652 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3648 | tstamp_t fstamp; /* filestamp */ | | 3653 | tstamp_t fstamp; /* filestamp */ |
3649 | long len; | | 3654 | long len; |
3650 | char *ptr; | | 3655 | char *ptr; |
3651 | char *name, *header; | | 3656 | char *name, *header; |
3652 | u_char *data; | | 3657 | u_char *data; |
3653 | | | 3658 | |
3654 | /* | | 3659 | /* |
3655 | * Open the certificate file. If the first character of the file | | 3660 | * Open the certificate file. If the first character of the file |
3656 | * name is not '/', prepend the keys directory string. If | | 3661 | * name is not '/', prepend the keys directory string. If |
3657 | * something goes wrong, abandon ship. | | 3662 | * something goes wrong, abandon ship. |
3658 | */ | | 3663 | */ |
3659 | if (*cp == '/') | | 3664 | if (*cp == '/') |
3660 | strcpy(filename, cp); | | 3665 | strcpy(filename, cp); |
3661 | else | | 3666 | else |
3662 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); | | 3667 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); |
3663 | str = fopen(filename, "r"); | | 3668 | str = fopen(filename, "r"); |
3664 | if (str == NULL) | | 3669 | if (str == NULL) |
3665 | return (NULL); | | 3670 | return (NULL); |
3666 | | | 3671 | |
3667 | /* | | 3672 | /* |
3668 | * Read the filestamp, which is contained in the first line. | | 3673 | * Read the filestamp, which is contained in the first line. |
3669 | */ | | 3674 | */ |
3670 | if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) { | | 3675 | if ((ptr = fgets(linkname, MAXFILENAME, str)) == NULL) { |
3671 | msyslog(LOG_ERR, "crypto_cert: no data %s\n", | | 3676 | msyslog(LOG_ERR, "crypto_cert: no data %s\n", |
3672 | filename); | | 3677 | filename); |
3673 | (void)fclose(str); | | 3678 | (void)fclose(str); |
3674 | return (NULL); | | 3679 | return (NULL); |
3675 | } | | 3680 | } |
3676 | if ((ptr = strrchr(ptr, '.')) == NULL) { | | 3681 | if ((ptr = strrchr(ptr, '.')) == NULL) { |
3677 | msyslog(LOG_ERR, "crypto_cert: no filestamp %s\n", | | 3682 | msyslog(LOG_ERR, "crypto_cert: no filestamp %s\n", |
3678 | filename); | | 3683 | filename); |
3679 | (void)fclose(str); | | 3684 | (void)fclose(str); |
3680 | return (NULL); | | 3685 | return (NULL); |
3681 | } | | 3686 | } |
3682 | if (sscanf(++ptr, "%u", &fstamp) != 1) { | | 3687 | if (sscanf(++ptr, "%u", &fstamp) != 1) { |
3683 | msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s\n", | | 3688 | msyslog(LOG_ERR, "crypto_cert: invalid filestamp %s\n", |
3684 | filename); | | 3689 | filename); |
3685 | (void)fclose(str); | | 3690 | (void)fclose(str); |
3686 | return (NULL); | | 3691 | return (NULL); |
3687 | } | | 3692 | } |
3688 | | | 3693 | |
3689 | /* | | 3694 | /* |
3690 | * Read PEM-encoded certificate and install. | | 3695 | * Read PEM-encoded certificate and install. |
3691 | */ | | 3696 | */ |
3692 | if (!PEM_read(str, &name, &header, &data, &len)) { | | 3697 | if (!PEM_read(str, &name, &header, &data, &len)) { |
3693 | msyslog(LOG_ERR, "crypto_cert %s\n", | | 3698 | msyslog(LOG_ERR, "crypto_cert %s\n", |
3694 | ERR_error_string(ERR_get_error(), NULL)); | | 3699 | ERR_error_string(ERR_get_error(), NULL)); |
3695 | (void)fclose(str); | | 3700 | (void)fclose(str); |
3696 | return (NULL); | | 3701 | return (NULL); |
3697 | } | | 3702 | } |
3698 | free(header); | | 3703 | free(header); |
3699 | if (strcmp(name, "CERTIFICATE") !=0) { | | 3704 | if (strcmp(name, "CERTIFICATE") !=0) { |
3700 | msyslog(LOG_INFO, "crypto_cert: wrong PEM type %s", | | 3705 | msyslog(LOG_INFO, "crypto_cert: wrong PEM type %s", |
3701 | name); | | 3706 | name); |
3702 | free(name); | | 3707 | free(name); |
3703 | free(data); | | 3708 | free(data); |
3704 | (void)fclose(str); | | 3709 | (void)fclose(str); |
3705 | return (NULL); | | 3710 | return (NULL); |
3706 | } | | 3711 | } |
3707 | free(name); | | 3712 | free(name); |
3708 | | | 3713 | |
3709 | /* | | 3714 | /* |
3710 | * Parse certificate and generate info/value structure. | | 3715 | * Parse certificate and generate info/value structure. |
3711 | */ | | 3716 | */ |
3712 | ret = cert_parse(data, len, fstamp); | | 3717 | ret = cert_parse(data, len, fstamp); |
3713 | free(data); | | 3718 | free(data); |
3714 | (void)fclose(str); | | 3719 | (void)fclose(str); |
3715 | if (ret == NULL) | | 3720 | if (ret == NULL) |
3716 | return (NULL); | | 3721 | return (NULL); |
3717 | | | 3722 | |
3718 | if ((ptr = strrchr(linkname, '\n')) != NULL) | | 3723 | if ((ptr = strrchr(linkname, '\n')) != NULL) |
3719 | *ptr = '\0'; | | 3724 | *ptr = '\0'; |
3720 | sprintf(statstr, "%s 0x%x len %lu", &linkname[2], ret->flags, | | 3725 | snprintf(statstr, NTP_MAXSTRLEN, |
3721 | len); | | 3726 | "%s 0x%x len %lu", &linkname[2], ret->flags, len); |
3722 | record_crypto_stats(NULL, statstr); | | 3727 | record_crypto_stats(NULL, statstr); |
3723 | #ifdef DEBUG | | 3728 | #ifdef DEBUG |
3724 | if (debug) | | 3729 | if (debug) |
3725 | printf("crypto_cert: %s\n", statstr); | | 3730 | printf("crypto_cert: %s\n", statstr); |
3726 | #endif | | 3731 | #endif |
3727 | return (ret); | | 3732 | return (ret); |
3728 | } | | 3733 | } |
3729 | | | 3734 | |
3730 | | | 3735 | |
3731 | /* | | 3736 | /* |
3732 | * crypto_tai - load leapseconds table from file | | 3737 | * crypto_tai - load leapseconds table from file |
3733 | * | | 3738 | * |
3734 | * This routine loads the ERTS leapsecond file in NIST text format, | | 3739 | * This routine loads the ERTS leapsecond file in NIST text format, |
3735 | * converts to a value structure and extracts a filestamp from the file | | 3740 | * converts to a value structure and extracts a filestamp from the file |
3736 | * name. The data are used to establish the TAI offset from UTC, which | | 3741 | * name. The data are used to establish the TAI offset from UTC, which |
3737 | * is provided to the kernel if supported. Later the data can be sent to | | 3742 | * is provided to the kernel if supported. Later the data can be sent to |
3738 | * another machine on request. | | 3743 | * another machine on request. |
3739 | */ | | 3744 | */ |
3740 | static void | | 3745 | static void |
3741 | crypto_tai( | | 3746 | crypto_tai( |
3742 | char *cp /* file name */ | | 3747 | char *cp /* file name */ |
3743 | ) | | 3748 | ) |
3744 | { | | 3749 | { |
3745 | FILE *str; /* file handle */ | | 3750 | FILE *str; /* file handle */ |
3746 | char buf[NTP_MAXSTRLEN]; /* file line buffer */ | | 3751 | char buf[NTP_MAXSTRLEN]; /* file line buffer */ |
3747 | u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */ | | 3752 | u_int32 leapsec[MAX_LEAP]; /* NTP time at leaps */ |
3748 | int offset; /* offset at leap (s) */ | | 3753 | int offset; /* offset at leap (s) */ |
3749 | char filename[MAXFILENAME]; /* name of leapseconds file */ | | 3754 | char filename[MAXFILENAME]; /* name of leapseconds file */ |
3750 | char linkname[MAXFILENAME]; /* file link (for filestamp) */ | | 3755 | char linkname[MAXFILENAME]; /* file link (for filestamp) */ |
3751 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ | | 3756 | char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ |
3752 | tstamp_t fstamp; /* filestamp */ | | 3757 | tstamp_t fstamp; /* filestamp */ |
3753 | u_int len; | | 3758 | u_int len; |
3754 | u_int32 *ptr; | | 3759 | u_int32 *ptr; |
3755 | char *dp; | | 3760 | char *dp; |
3756 | int rval, i, j; | | 3761 | int rval, i, j; |
3757 | | | 3762 | |
3758 | /* | | 3763 | /* |
3759 | * Open the file and discard comment lines. If the first | | 3764 | * Open the file and discard comment lines. If the first |
3760 | * character of the file name is not '/', prepend the keys | | 3765 | * character of the file name is not '/', prepend the keys |
3761 | * directory string. If the file is not found, not to worry; it | | 3766 | * directory string. If the file is not found, not to worry; it |
3762 | * can be retrieved over the net. But, if it is found with | | 3767 | * can be retrieved over the net. But, if it is found with |
3763 | * errors, we crash and burn. | | 3768 | * errors, we crash and burn. |
3764 | */ | | 3769 | */ |
3765 | if (*cp == '/') | | 3770 | if (*cp == '/') |
3766 | strcpy(filename, cp); | | 3771 | strcpy(filename, cp); |
3767 | else | | 3772 | else |
3768 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); | | 3773 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, cp); |
3769 | if ((str = fopen(filename, "r")) == NULL) | | 3774 | if ((str = fopen(filename, "r")) == NULL) |
3770 | return; | | 3775 | return; |
3771 | | | 3776 | |
3772 | /* | | 3777 | /* |
3773 | * Extract filestamp if present. | | 3778 | * Extract filestamp if present. |
3774 | */ | | 3779 | */ |
3775 | rval = readlink(filename, linkname, MAXFILENAME - 1); | | 3780 | rval = readlink(filename, linkname, MAXFILENAME - 1); |
3776 | if (rval > 0) { | | 3781 | if (rval > 0) { |
3777 | linkname[rval] = '\0'; | | 3782 | linkname[rval] = '\0'; |
3778 | dp = strrchr(linkname, '.'); | | 3783 | dp = strrchr(linkname, '.'); |
3779 | } else { | | 3784 | } else { |
3780 | dp = strrchr(filename, '.'); | | 3785 | dp = strrchr(filename, '.'); |
3781 | } | | 3786 | } |
3782 | if (dp != NULL) | | 3787 | if (dp != NULL) |
3783 | sscanf(++dp, "%u", &fstamp); | | 3788 | sscanf(++dp, "%u", &fstamp); |
3784 | else | | 3789 | else |
3785 | fstamp = 0; | | 3790 | fstamp = 0; |
3786 | tai_leap.fstamp = htonl(fstamp); | | 3791 | tai_leap.fstamp = htonl(fstamp); |
3787 | | | 3792 | |
3788 | /* | | 3793 | /* |
3789 | * We are rather paranoid here, since an intruder might cause a | | 3794 | * We are rather paranoid here, since an intruder might cause a |
3790 | * coredump by infiltrating naughty values. Empty lines and | | 3795 | * coredump by infiltrating naughty values. Empty lines and |
3791 | * comments are ignored. Other lines must begin with two | | 3796 | * comments are ignored. Other lines must begin with two |
3792 | * integers followed by junk or comments. The first integer is | | 3797 | * integers followed by junk or comments. The first integer is |
3793 | * the NTP seconds of leap insertion, the second is the offset | | 3798 | * the NTP seconds of leap insertion, the second is the offset |
3794 | * of TAI relative to UTC after that insertion. The second word | | 3799 | * of TAI relative to UTC after that insertion. The second word |
3795 | * must equal the initial insertion of ten seconds on 1 January | | 3800 | * must equal the initial insertion of ten seconds on 1 January |
3796 | * 1972 plus one second for each succeeding insertion. | | 3801 | * 1972 plus one second for each succeeding insertion. |
3797 | */ | | 3802 | */ |
3798 | i = 0; | | 3803 | i = 0; |
3799 | while (i < MAX_LEAP) { | | 3804 | while (i < MAX_LEAP) { |
3800 | dp = fgets(buf, NTP_MAXSTRLEN - 1, str); | | 3805 | dp = fgets(buf, NTP_MAXSTRLEN - 1, str); |
3801 | if (dp == NULL) | | 3806 | if (dp == NULL) |
3802 | break; | | 3807 | break; |
3803 | | | 3808 | |
3804 | if (strlen(buf) < 1) | | 3809 | if (strlen(buf) < 1) |
3805 | continue; | | 3810 | continue; |
3806 | | | 3811 | |
3807 | if (*buf == '#') | | 3812 | if (*buf == '#') |
3808 | continue; | | 3813 | continue; |
3809 | | | 3814 | |
3810 | if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2) | | 3815 | if (sscanf(buf, "%u %d", &leapsec[i], &offset) != 2) |
3811 | continue; | | 3816 | continue; |
3812 | | | 3817 | |
3813 | if (i != offset - TAI_1972) | | 3818 | if (i != offset - TAI_1972) |
3814 | break; | | 3819 | break; |
3815 | | | 3820 | |
3816 | i++; | | 3821 | i++; |
3817 | } | | 3822 | } |
3818 | fclose(str); | | 3823 | fclose(str); |
3819 | if (dp != NULL) { | | 3824 | if (dp != NULL) { |
3820 | msyslog(LOG_INFO, | | 3825 | msyslog(LOG_INFO, |
3821 | "crypto_tai: leapseconds file %s error %d", cp, | | 3826 | "crypto_tai: leapseconds file %s error %d", cp, |
3822 | rval); | | 3827 | rval); |
3823 | exit (-1); | | 3828 | exit (-1); |
3824 | } | | 3829 | } |
3825 | | | 3830 | |
3826 | /* | | 3831 | /* |
3827 | * The extension field table entries consists of the NTP seconds | | 3832 | * The extension field table entries consists of the NTP seconds |
3828 | * of leap insertion in network byte order. | | 3833 | * of leap insertion in network byte order. |
3829 | */ | | 3834 | */ |
3830 | len = i * sizeof(u_int32); | | 3835 | len = i * sizeof(u_int32); |
3831 | tai_leap.vallen = htonl(len); | | 3836 | tai_leap.vallen = htonl(len); |
3832 | ptr = emalloc(len); | | 3837 | ptr = emalloc(len); |
3833 | tai_leap.ptr = (u_char *)ptr; | | 3838 | tai_leap.ptr = (u_char *)ptr; |
3834 | for (j = 0; j < i; j++) | | 3839 | for (j = 0; j < i; j++) |
3835 | *ptr++ = htonl(leapsec[j]); | | 3840 | *ptr++ = htonl(leapsec[j]); |
3836 | crypto_flags |= CRYPTO_FLAG_TAI; | | 3841 | crypto_flags |= CRYPTO_FLAG_TAI; |
3837 | sprintf(statstr, "%s fs %u leap %u len %u", cp, fstamp, | | 3842 | snprintf(statstr, NTP_MAXSTRLEN, "%s fs %u leap %u len %u", cp, fstamp, |
3838 | leapsec[--j], len); | | 3843 | leapsec[--j], len); |
3839 | record_crypto_stats(NULL, statstr); | | 3844 | record_crypto_stats(NULL, statstr); |
3840 | #ifdef DEBUG | | 3845 | #ifdef DEBUG |
3841 | if (debug) | | 3846 | if (debug) |
3842 | printf("crypto_tai: %s\n", statstr); | | 3847 | printf("crypto_tai: %s\n", statstr); |
3843 | #endif | | 3848 | #endif |
3844 | } | | 3849 | } |
3845 | | | 3850 | |
3846 | | | 3851 | |
3847 | /* | | 3852 | /* |
3848 | * crypto_setup - load keys, certificate and leapseconds table | | 3853 | * crypto_setup - load keys, certificate and leapseconds table |
3849 | * | | 3854 | * |
3850 | * This routine loads the public/private host key and certificate. If | | 3855 | * This routine loads the public/private host key and certificate. If |
3851 | * available, it loads the public/private sign key, which defaults to | | 3856 | * available, it loads the public/private sign key, which defaults to |
3852 | * the host key, and leapseconds table. The host key must be RSA, but | | 3857 | * the host key, and leapseconds table. The host key must be RSA, but |
3853 | * the sign key can be either RSA or DSA. In either case, the public key | | 3858 | * the sign key can be either RSA or DSA. In either case, the public key |
3854 | * on the certificate must agree with the sign key. | | 3859 | * on the certificate must agree with the sign key. |
3855 | */ | | 3860 | */ |
3856 | void | | 3861 | void |
3857 | crypto_setup(void) | | 3862 | crypto_setup(void) |
3858 | { | | 3863 | { |
3859 | EVP_PKEY *pkey; /* private/public key pair */ | | 3864 | EVP_PKEY *pkey; /* private/public key pair */ |
3860 | char filename[MAXFILENAME]; /* file name buffer */ | | 3865 | char filename[MAXFILENAME]; /* file name buffer */ |
3861 | l_fp seed; /* crypto PRNG seed as NTP timestamp */ | | 3866 | l_fp seed; /* crypto PRNG seed as NTP timestamp */ |
3862 | tstamp_t fstamp; /* filestamp */ | | 3867 | tstamp_t fstamp; /* filestamp */ |
3863 | tstamp_t sstamp; /* sign filestamp */ | | 3868 | tstamp_t sstamp; /* sign filestamp */ |
3864 | u_int len, bytes; | | 3869 | u_int len, bytes; |
3865 | u_char *ptr; | | 3870 | u_char *ptr; |
3866 | | | 3871 | |
3867 | /* | | 3872 | /* |
3868 | * Initialize structures. | | 3873 | * Initialize structures. |
3869 | */ | | 3874 | */ |
3870 | if (!crypto_flags) | | 3875 | if (!crypto_flags) |
3871 | return; | | 3876 | return; |
3872 | | | 3877 | |
3873 | gethostname(filename, MAXFILENAME); | | 3878 | gethostname(filename, MAXFILENAME); |
3874 | bytes = strlen(filename) + 1; | | 3879 | bytes = strlen(filename) + 1; |
3875 | sys_hostname = emalloc(bytes); | | 3880 | sys_hostname = emalloc(bytes); |
3876 | memcpy(sys_hostname, filename, bytes); | | 3881 | memcpy(sys_hostname, filename, bytes); |
3877 | if (passwd == NULL) | | 3882 | if (passwd == NULL) |
3878 | passwd = sys_hostname; | | 3883 | passwd = sys_hostname; |
3879 | memset(&hostval, 0, sizeof(hostval)); | | 3884 | memset(&hostval, 0, sizeof(hostval)); |
3880 | memset(&pubkey, 0, sizeof(pubkey)); | | 3885 | memset(&pubkey, 0, sizeof(pubkey)); |
3881 | memset(&tai_leap, 0, sizeof(tai_leap)); | | 3886 | memset(&tai_leap, 0, sizeof(tai_leap)); |
3882 | | | 3887 | |
3883 | /* | | 3888 | /* |
3884 | * Load required random seed file and seed the random number | | 3889 | * Load required random seed file and seed the random number |
3885 | * generator. Be default, it is found in the user home | | 3890 | * generator. Be default, it is found in the user home |
3886 | * directory. The root home directory may be / or /root, | | 3891 | * directory. The root home directory may be / or /root, |
3887 | * depending on the system. Wiggle the contents a bit and write | | 3892 | * depending on the system. Wiggle the contents a bit and write |
3888 | * it back so the sequence does not repeat when we next restart. | | 3893 | * it back so the sequence does not repeat when we next restart. |
3889 | */ | | 3894 | */ |
3890 | ERR_load_crypto_strings(); | | 3895 | ERR_load_crypto_strings(); |
3891 | if (rand_file == NULL) { | | 3896 | if (rand_file == NULL) { |
3892 | if ((RAND_file_name(filename, MAXFILENAME)) != NULL) { | | 3897 | if ((RAND_file_name(filename, MAXFILENAME)) != NULL) { |
3893 | rand_file = emalloc(strlen(filename) + 1); | | 3898 | rand_file = emalloc(strlen(filename) + 1); |
3894 | strcpy(rand_file, filename); | | 3899 | strcpy(rand_file, filename); |
3895 | } | | 3900 | } |
3896 | } else if (*rand_file != '/') { | | 3901 | } else if (*rand_file != '/') { |
3897 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, | | 3902 | snprintf(filename, MAXFILENAME, "%s/%s", keysdir, |
3898 | rand_file); | | 3903 | rand_file); |
3899 | free(rand_file); | | 3904 | free(rand_file); |
3900 | rand_file = emalloc(strlen(filename) + 1); | | 3905 | rand_file = emalloc(strlen(filename) + 1); |
3901 | strcpy(rand_file, filename); | | 3906 | strcpy(rand_file, filename); |
3902 | } | | 3907 | } |
3903 | if (rand_file == NULL) { | | 3908 | if (rand_file == NULL) { |
3904 | msyslog(LOG_ERR, | | 3909 | msyslog(LOG_ERR, |
3905 | "crypto_setup: random seed file not specified"); | | 3910 | "crypto_setup: random seed file not specified"); |
3906 | exit (-1); | | 3911 | exit (-1); |
3907 | } | | 3912 | } |
3908 | if ((bytes = RAND_load_file(rand_file, -1)) == 0) { | | 3913 | if ((bytes = RAND_load_file(rand_file, -1)) == 0) { |
3909 | msyslog(LOG_ERR, | | 3914 | msyslog(LOG_ERR, |
3910 | "crypto_setup: random seed file %s not found\n", | | 3915 | "crypto_setup: random seed file %s not found\n", |
3911 | rand_file); | | 3916 | rand_file); |
3912 | exit (-1); | | 3917 | exit (-1); |
3913 | } | | 3918 | } |
3914 | get_systime(&seed); | | 3919 | get_systime(&seed); |
3915 | RAND_seed(&seed, sizeof(l_fp)); | | 3920 | RAND_seed(&seed, sizeof(l_fp)); |
3916 | RAND_write_file(rand_file); | | 3921 | RAND_write_file(rand_file); |
3917 | OpenSSL_add_all_algorithms(); | | 3922 | OpenSSL_add_all_algorithms(); |
3918 | #ifdef DEBUG | | 3923 | #ifdef DEBUG |
3919 | if (debug) | | 3924 | if (debug) |
3920 | printf( | | 3925 | printf( |
3921 | "crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n", | | 3926 | "crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n", |
3922 | SSLeay(), rand_file, bytes); | | 3927 | SSLeay(), rand_file, bytes); |
3923 | #endif | | 3928 | #endif |
3924 | | | 3929 | |
3925 | /* | | 3930 | /* |
3926 | * Load required host key from file "ntpkey_host_<hostname>". It | | 3931 | * Load required host key from file "ntpkey_host_<hostname>". It |
3927 | * also becomes the default sign key. | | 3932 | * also becomes the default sign key. |
3928 | */ | | 3933 | */ |
3929 | if (host_file == NULL) { | | 3934 | if (host_file == NULL) { |
3930 | snprintf(filename, MAXFILENAME, "ntpkey_host_%s", | | 3935 | snprintf(filename, MAXFILENAME, "ntpkey_host_%s", |
3931 | sys_hostname); | | 3936 | sys_hostname); |
3932 | host_file = emalloc(strlen(filename) + 1); | | 3937 | host_file = emalloc(strlen(filename) + 1); |
3933 | strcpy(host_file, filename); | | 3938 | strcpy(host_file, filename); |
3934 | } | | 3939 | } |
3935 | pkey = crypto_key(host_file, &fstamp); | | 3940 | pkey = crypto_key(host_file, &fstamp); |
3936 | if (pkey == NULL) { | | 3941 | if (pkey == NULL) { |
3937 | msyslog(LOG_ERR, | | 3942 | msyslog(LOG_ERR, |
3938 | "crypto_setup: host key file %s not found or corrupt", | | 3943 | "crypto_setup: host key file %s not found or corrupt", |
3939 | host_file); | | 3944 | host_file); |
3940 | exit (-1); | | 3945 | exit (-1); |
3941 | } | | 3946 | } |
3942 | host_pkey = pkey; | | 3947 | host_pkey = pkey; |
3943 | sign_pkey = pkey; | | 3948 | sign_pkey = pkey; |
3944 | sstamp = fstamp; | | 3949 | sstamp = fstamp; |
3945 | hostval.fstamp = htonl(fstamp); | | 3950 | hostval.fstamp = htonl(fstamp); |
3946 | if (host_pkey->type != EVP_PKEY_RSA) { | | 3951 | if (host_pkey->type != EVP_PKEY_RSA) { |
3947 | msyslog(LOG_ERR, | | 3952 | msyslog(LOG_ERR, |
3948 | "crypto_setup: host key is not RSA key type"); | | 3953 | "crypto_setup: host key is not RSA key type"); |
3949 | exit (-1); | | 3954 | exit (-1); |
3950 | } | | 3955 | } |
3951 | hostval.vallen = htonl(strlen(sys_hostname)); | | 3956 | hostval.vallen = htonl(strlen(sys_hostname)); |
3952 | hostval.ptr = (u_char *)sys_hostname; | | 3957 | hostval.ptr = (u_char *)sys_hostname; |
3953 | | | 3958 | |
3954 | /* | | 3959 | /* |
3955 | * Construct public key extension field for agreement scheme. | | 3960 | * Construct public key extension field for agreement scheme. |
3956 | */ | | 3961 | */ |
3957 | len = i2d_PublicKey(host_pkey, NULL); | | 3962 | len = i2d_PublicKey(host_pkey, NULL); |
3958 | ptr = emalloc(len); | | 3963 | ptr = emalloc(len); |
3959 | pubkey.ptr = ptr; | | 3964 | pubkey.ptr = ptr; |
3960 | i2d_PublicKey(host_pkey, &ptr); | | 3965 | i2d_PublicKey(host_pkey, &ptr); |
3961 | pubkey.vallen = htonl(len); | | 3966 | pubkey.vallen = htonl(len); |
3962 | pubkey.fstamp = hostval.fstamp; | | 3967 | pubkey.fstamp = hostval.fstamp; |
3963 | | | 3968 | |
3964 | /* | | 3969 | /* |
3965 | * Load optional sign key from file "ntpkey_sign_<hostname>". If | | 3970 | * Load optional sign key from file "ntpkey_sign_<hostname>". If |
3966 | * loaded, it becomes the sign key. | | 3971 | * loaded, it becomes the sign key. |
3967 | */ | | 3972 | */ |
3968 | if (sign_file == NULL) { | | 3973 | if (sign_file == NULL) { |
3969 | snprintf(filename, MAXFILENAME, "ntpkey_sign_%s", | | 3974 | snprintf(filename, MAXFILENAME, "ntpkey_sign_%s", |
3970 | sys_hostname); | | 3975 | sys_hostname); |
3971 | sign_file = emalloc(strlen(filename) + 1); | | 3976 | sign_file = emalloc(strlen(filename) + 1); |
3972 | strcpy(sign_file, filename); | | 3977 | strcpy(sign_file, filename); |
3973 | } | | 3978 | } |
3974 | pkey = crypto_key(sign_file, &fstamp); | | 3979 | pkey = crypto_key(sign_file, &fstamp); |
3975 | if (pkey != NULL) { | | 3980 | if (pkey != NULL) { |
3976 | sign_pkey = pkey; | | 3981 | sign_pkey = pkey; |
3977 | sstamp = fstamp; | | 3982 | sstamp = fstamp; |
3978 | } | | 3983 | } |
3979 | sign_siglen = EVP_PKEY_size(sign_pkey); | | 3984 | sign_siglen = EVP_PKEY_size(sign_pkey); |
3980 | | | 3985 | |
3981 | /* | | 3986 | /* |
3982 | * Load optional IFF parameters from file | | 3987 | * Load optional IFF parameters from file |
3983 | * "ntpkey_iff_<hostname>". | | 3988 | * "ntpkey_iff_<hostname>". |
3984 | */ | | 3989 | */ |
3985 | if (iffpar_file == NULL) { | | 3990 | if (iffpar_file == NULL) { |
3986 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", | | 3991 | snprintf(filename, MAXFILENAME, "ntpkey_iff_%s", |
3987 | sys_hostname); | | 3992 | sys_hostname); |
3988 | iffpar_file = emalloc(strlen(filename) + 1); | | 3993 | iffpar_file = emalloc(strlen(filename) + 1); |
3989 | strcpy(iffpar_file, filename); | | 3994 | strcpy(iffpar_file, filename); |
3990 | } | | 3995 | } |
3991 | iffpar_pkey = crypto_key(iffpar_file, &if_fstamp); | | 3996 | iffpar_pkey = crypto_key(iffpar_file, &if_fstamp); |
3992 | if (iffpar_pkey != NULL) | | 3997 | if (iffpar_pkey != NULL) |
3993 | crypto_flags |= CRYPTO_FLAG_IFF; | | 3998 | crypto_flags |= CRYPTO_FLAG_IFF; |
3994 | | | 3999 | |
3995 | /* | | 4000 | /* |
3996 | * Load optional GQ parameters from file "ntpkey_gq_<hostname>". | | 4001 | * Load optional GQ parameters from file "ntpkey_gq_<hostname>". |
3997 | */ | | 4002 | */ |
3998 | if (gqpar_file == NULL) { | | 4003 | if (gqpar_file == NULL) { |
3999 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", | | 4004 | snprintf(filename, MAXFILENAME, "ntpkey_gq_%s", |
4000 | sys_hostname); | | 4005 | sys_hostname); |
4001 | gqpar_file = emalloc(strlen(filename) + 1); | | 4006 | gqpar_file = emalloc(strlen(filename) + 1); |
4002 | strcpy(gqpar_file, filename); | | 4007 | strcpy(gqpar_file, filename); |
4003 | } | | 4008 | } |
4004 | gqpar_pkey = crypto_key(gqpar_file, &gq_fstamp); | | 4009 | gqpar_pkey = crypto_key(gqpar_file, &gq_fstamp); |
4005 | if (gqpar_pkey != NULL) | | 4010 | if (gqpar_pkey != NULL) |
4006 | crypto_flags |= CRYPTO_FLAG_GQ; | | 4011 | crypto_flags |= CRYPTO_FLAG_GQ; |
4007 | | | 4012 | |
4008 | /* | | 4013 | /* |
4009 | * Load optional MV parameters from file "ntpkey_mv_<hostname>". | | 4014 | * Load optional MV parameters from file "ntpkey_mv_<hostname>". |
4010 | */ | | 4015 | */ |
4011 | if (mvpar_file == NULL) { | | 4016 | if (mvpar_file == NULL) { |
4012 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", | | 4017 | snprintf(filename, MAXFILENAME, "ntpkey_mv_%s", |
4013 | sys_hostname); | | 4018 | sys_hostname); |
4014 | mvpar_file = emalloc(strlen(filename) + 1); | | 4019 | mvpar_file = emalloc(strlen(filename) + 1); |
4015 | strcpy(mvpar_file, filename); | | 4020 | strcpy(mvpar_file, filename); |
4016 | } | | 4021 | } |
4017 | mvpar_pkey = crypto_key(mvpar_file, &mv_fstamp); | | 4022 | mvpar_pkey = crypto_key(mvpar_file, &mv_fstamp); |
4018 | if (mvpar_pkey != NULL) | | 4023 | if (mvpar_pkey != NULL) |
4019 | crypto_flags |= CRYPTO_FLAG_MV; | | 4024 | crypto_flags |= CRYPTO_FLAG_MV; |
4020 | | | 4025 | |
4021 | /* | | 4026 | /* |
4022 | * Load required certificate from file "ntpkey_cert_<hostname>". | | 4027 | * Load required certificate from file "ntpkey_cert_<hostname>". |
4023 | */ | | 4028 | */ |
4024 | if (cert_file == NULL) { | | 4029 | if (cert_file == NULL) { |
4025 | snprintf(filename, MAXFILENAME, "ntpkey_cert_%s", | | 4030 | snprintf(filename, MAXFILENAME, "ntpkey_cert_%s", |
4026 | sys_hostname); | | 4031 | sys_hostname); |
4027 | cert_file = emalloc(strlen(filename) + 1); | | 4032 | cert_file = emalloc(strlen(filename) + 1); |
4028 | strcpy(cert_file, filename); | | 4033 | strcpy(cert_file, filename); |
4029 | } | | 4034 | } |
4030 | if ((cinfo = crypto_cert(cert_file)) == NULL) { | | 4035 | if ((cinfo = crypto_cert(cert_file)) == NULL) { |
4031 | msyslog(LOG_ERR, | | 4036 | msyslog(LOG_ERR, |
4032 | "certificate file %s not found or corrupt", | | 4037 | "certificate file %s not found or corrupt", |
4033 | cert_file); | | 4038 | cert_file); |
4034 | exit (-1); | | 4039 | exit (-1); |
4035 | } | | 4040 | } |
4036 | | | 4041 | |
4037 | /* | | 4042 | /* |
4038 | * The subject name must be the same as the host name, unless | | 4043 | * The subject name must be the same as the host name, unless |
4039 | * the certificate is private, in which case it may have come | | 4044 | * the certificate is private, in which case it may have come |
4040 | * from another host. | | 4045 | * from another host. |
4041 | */ | | 4046 | */ |
4042 | if (!(cinfo->flags & CERT_PRIV) && strcmp(cinfo->subject, | | 4047 | if (!(cinfo->flags & CERT_PRIV) && strcmp(cinfo->subject, |
4043 | sys_hostname) != 0) { | | 4048 | sys_hostname) != 0) { |
4044 | msyslog(LOG_ERR, | | 4049 | msyslog(LOG_ERR, |
4045 | "crypto_setup: certificate %s not for this host", | | 4050 | "crypto_setup: certificate %s not for this host", |
4046 | cert_file); | | 4051 | cert_file); |
4047 | cert_free(cinfo); | | 4052 | cert_free(cinfo); |
4048 | exit (-1); | | 4053 | exit (-1); |
4049 | } | | 4054 | } |
4050 | | | 4055 | |
4051 | /* | | 4056 | /* |
4052 | * It the certificate is trusted, the subject must be the same | | 4057 | * It the certificate is trusted, the subject must be the same |
4053 | * as the issuer, in other words it must be self signed. | | 4058 | * as the issuer, in other words it must be self signed. |
4054 | */ | | 4059 | */ |
4055 | if (cinfo->flags & CERT_TRUST && strcmp(cinfo->subject, | | 4060 | if (cinfo->flags & CERT_TRUST && strcmp(cinfo->subject, |
4056 | cinfo->issuer) != 0) { | | 4061 | cinfo->issuer) != 0) { |
4057 | if (cert_valid(cinfo, sign_pkey) != XEVNT_OK) { | | 4062 | if (cert_valid(cinfo, sign_pkey) != XEVNT_OK) { |
4058 | msyslog(LOG_ERR, | | 4063 | msyslog(LOG_ERR, |
4059 | "crypto_setup: certificate %s is trusted, but not self signed.", | | 4064 | "crypto_setup: certificate %s is trusted, but not self signed.", |
4060 | cert_file); | | 4065 | cert_file); |
4061 | cert_free(cinfo); | | 4066 | cert_free(cinfo); |
4062 | exit (-1); | | 4067 | exit (-1); |
4063 | } | | 4068 | } |
4064 | } | | 4069 | } |
4065 | sign_digest = cinfo->digest; | | 4070 | sign_digest = cinfo->digest; |
4066 | if (cinfo->flags & CERT_PRIV) | | 4071 | if (cinfo->flags & CERT_PRIV) |
4067 | crypto_flags |= CRYPTO_FLAG_PRIV; | | 4072 | crypto_flags |= CRYPTO_FLAG_PRIV; |
4068 | crypto_flags |= cinfo->nid << 16; | | 4073 | crypto_flags |= cinfo->nid << 16; |
4069 | | | 4074 | |
4070 | /* | | 4075 | /* |
4071 | * Load optional leapseconds table from file "ntpkey_leap". If | | 4076 | * Load optional leapseconds table from file "ntpkey_leap". If |
4072 | * the file is missing or defective, the values can later be | | 4077 | * the file is missing or defective, the values can later be |
4073 | * retrieved from a server. | | 4078 | * retrieved from a server. |
4074 | */ | | 4079 | */ |
4075 | if (leap_file == NULL) | | 4080 | if (leap_file == NULL) |
4076 | leap_file = "ntpkey_leap"; | | 4081 | leap_file = "ntpkey_leap"; |
4077 | crypto_tai(leap_file); | | 4082 | crypto_tai(leap_file); |
4078 | #ifdef DEBUG | | 4083 | #ifdef DEBUG |
4079 | if (debug) | | 4084 | if (debug) |
4080 | printf( | | 4085 | printf( |
4081 | "crypto_setup: flags 0x%x host %s signature %s\n", | | 4086 | "crypto_setup: flags 0x%x host %s signature %s\n", |
4082 | crypto_flags, sys_hostname, OBJ_nid2ln(cinfo->nid)); | | 4087 | crypto_flags, sys_hostname, OBJ_nid2ln(cinfo->nid)); |
4083 | #endif | | 4088 | #endif |
4084 | } | | 4089 | } |
4085 | | | 4090 | |
4086 | | | 4091 | |
4087 | /* | | 4092 | /* |
4088 | * crypto_config - configure data from crypto configuration command. | | 4093 | * crypto_config - configure data from crypto configuration command. |
4089 | */ | | 4094 | */ |
4090 | void | | 4095 | void |
4091 | crypto_config( | | 4096 | crypto_config( |
4092 | int item, /* configuration item */ | | 4097 | int item, /* configuration item */ |
4093 | char *cp /* file name */ | | 4098 | char *cp /* file name */ |
4094 | ) | | 4099 | ) |
4095 | { | | 4100 | { |
4096 | switch (item) { | | 4101 | switch (item) { |
4097 | | | 4102 | |
4098 | /* | | 4103 | /* |
4099 | * Set random seed file name. | | 4104 | * Set random seed file name. |
4100 | */ | | 4105 | */ |
4101 | case CRYPTO_CONF_RAND: | | 4106 | case CRYPTO_CONF_RAND: |
4102 | rand_file = emalloc(strlen(cp) + 1); | | 4107 | rand_file = emalloc(strlen(cp) + 1); |
4103 | strcpy(rand_file, cp); | | 4108 | strcpy(rand_file, cp); |
4104 | break; | | 4109 | break; |
4105 | | | 4110 | |
4106 | /* | | 4111 | /* |
4107 | * Set private key password. | | 4112 | * Set private key password. |
4108 | */ | | 4113 | */ |
4109 | case CRYPTO_CONF_PW: | | 4114 | case CRYPTO_CONF_PW: |
4110 | passwd = emalloc(strlen(cp) + 1); | | 4115 | passwd = emalloc(strlen(cp) + 1); |
4111 | strcpy(passwd, cp); | | 4116 | strcpy(passwd, cp); |
4112 | break; | | 4117 | break; |
4113 | | | 4118 | |
4114 | /* | | 4119 | /* |
4115 | * Set host file name. | | 4120 | * Set host file name. |
4116 | */ | | 4121 | */ |
4117 | case CRYPTO_CONF_PRIV: | | 4122 | case CRYPTO_CONF_PRIV: |
4118 | host_file = emalloc(strlen(cp) + 1); | | 4123 | host_file = emalloc(strlen(cp) + 1); |
4119 | strcpy(host_file, cp); | | 4124 | strcpy(host_file, cp); |
4120 | break; | | 4125 | break; |
4121 | | | 4126 | |
4122 | /* | | 4127 | /* |
4123 | * Set sign key file name. | | 4128 | * Set sign key file name. |
4124 | */ | | 4129 | */ |
4125 | case CRYPTO_CONF_SIGN: | | 4130 | case CRYPTO_CONF_SIGN: |
4126 | sign_file = emalloc(strlen(cp) + 1); | | 4131 | sign_file = emalloc(strlen(cp) + 1); |
4127 | strcpy(sign_file, cp); | | 4132 | strcpy(sign_file, cp); |
4128 | break; | | 4133 | break; |
4129 | | | 4134 | |
4130 | /* | | 4135 | /* |
4131 | * Set iff parameters file name. | | 4136 | * Set iff parameters file name. |
4132 | */ | | 4137 | */ |
4133 | case CRYPTO_CONF_IFFPAR: | | 4138 | case CRYPTO_CONF_IFFPAR: |
4134 | iffpar_file = emalloc(strlen(cp) + 1); | | 4139 | iffpar_file = emalloc(strlen(cp) + 1); |
4135 | strcpy(iffpar_file, cp); | | 4140 | strcpy(iffpar_file, cp); |
4136 | break; | | 4141 | break; |
4137 | | | 4142 | |
4138 | /* | | 4143 | /* |
4139 | * Set gq parameters file name. | | 4144 | * Set gq parameters file name. |
4140 | */ | | 4145 | */ |
4141 | case CRYPTO_CONF_GQPAR: | | 4146 | case CRYPTO_CONF_GQPAR: |
4142 | gqpar_file = emalloc(strlen(cp) + 1); | | 4147 | gqpar_file = emalloc(strlen(cp) + 1); |
4143 | strcpy(gqpar_file, cp); | | 4148 | strcpy(gqpar_file, cp); |
4144 | break; | | 4149 | break; |
4145 | | | 4150 | |
4146 | /* | | 4151 | /* |
4147 | * Set mv parameters file name. | | 4152 | * Set mv parameters file name. |
4148 | */ | | 4153 | */ |
4149 | case CRYPTO_CONF_MVPAR: | | 4154 | case CRYPTO_CONF_MVPAR: |
4150 | mvpar_file = emalloc(strlen(cp) + 1); | | 4155 | mvpar_file = emalloc(strlen(cp) + 1); |
4151 | strcpy(mvpar_file, cp); | | 4156 | strcpy(mvpar_file, cp); |
4152 | break; | | 4157 | break; |
4153 | | | 4158 | |
4154 | /* | | 4159 | /* |
4155 | * Set identity scheme. | | 4160 | * Set identity scheme. |
4156 | */ | | 4161 | */ |
4157 | case CRYPTO_CONF_IDENT: | | 4162 | case CRYPTO_CONF_IDENT: |
4158 | if (!strcasecmp(cp, "iff")) | | 4163 | if (!strcasecmp(cp, "iff")) |
4159 | ident_scheme |= CRYPTO_FLAG_IFF; | | 4164 | ident_scheme |= CRYPTO_FLAG_IFF; |
4160 | else if (!strcasecmp(cp, "gq")) | | 4165 | else if (!strcasecmp(cp, "gq")) |
4161 | ident_scheme |= CRYPTO_FLAG_GQ; | | 4166 | ident_scheme |= CRYPTO_FLAG_GQ; |
4162 | else if (!strcasecmp(cp, "mv")) | | 4167 | else if (!strcasecmp(cp, "mv")) |
4163 | ident_scheme |= CRYPTO_FLAG_MV; | | 4168 | ident_scheme |= CRYPTO_FLAG_MV; |
4164 | break; | | 4169 | break; |
4165 | | | 4170 | |
4166 | /* | | 4171 | /* |
4167 | * Set certificate file name. | | 4172 | * Set certificate file name. |
4168 | */ | | 4173 | */ |
4169 | case CRYPTO_CONF_CERT: | | 4174 | case CRYPTO_CONF_CERT: |
4170 | cert_file = emalloc(strlen(cp) + 1); | | 4175 | cert_file = emalloc(strlen(cp) + 1); |
4171 | strcpy(cert_file, cp); | | 4176 | strcpy(cert_file, cp); |
4172 | break; | | 4177 | break; |
4173 | | | 4178 | |
4174 | /* | | 4179 | /* |
4175 | * Set leapseconds file name. | | 4180 | * Set leapseconds file name. |
4176 | */ | | 4181 | */ |
4177 | case CRYPTO_CONF_LEAP: | | 4182 | case CRYPTO_CONF_LEAP: |
4178 | leap_file = emalloc(strlen(cp) + 1); | | 4183 | leap_file = emalloc(strlen(cp) + 1); |
4179 | strcpy(leap_file, cp); | | 4184 | strcpy(leap_file, cp); |
4180 | break; | | 4185 | break; |
4181 | } | | 4186 | } |
4182 | crypto_flags |= CRYPTO_FLAG_ENAB; | | 4187 | crypto_flags |= CRYPTO_FLAG_ENAB; |
4183 | } | | 4188 | } |
4184 | # else | | 4189 | # else |
4185 | int ntp_crypto_bs_pubkey; | | 4190 | int ntp_crypto_bs_pubkey; |
4186 | # endif /* OPENSSL */ | | 4191 | # endif /* OPENSSL */ |