Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: c/sslinfo.c

Issue 2842333002: Updated netty-tcnative to version 2.0.0.Final (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « c/sslcontext.c ('k') | c/sslnetwork.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /** SSL info wrapper
18 *
19 * @author Mladen Turk
20 * @version $Id: sslinfo.c 1658603 2015-02-09 23:26:44Z kkolinko $
21 */
22
23 #include "tcn.h"
24 #include "apr_file_io.h"
25 #include "apr_thread_mutex.h"
26 #include "apr_poll.h"
27
28 #ifdef HAVE_OPENSSL
29 #include "ssl_private.h"
30
31 static const char *hex_basis = "0123456789ABCDEF";
32
33 static char *convert_to_hex(const void *buf, size_t len)
34 {
35 const unsigned char *p = ( const unsigned char *)buf;
36 char *str, *s;
37 size_t i;
38
39 if ((len < 1) || ((str = malloc(len * 2 + 1)) == NULL))
40 return NULL;
41 for (i = 0, s = str; i < len; i++) {
42 unsigned char c = *p++;
43 *s++ = hex_basis[c >> 4];
44 *s++ = hex_basis[c & 0x0F];
45 }
46 *s = '\0';
47 return str;
48 }
49
50 #define DIGIT2NUM(x) (((x)[0] - '0') * 10 + (x)[1] - '0')
51
52 static int get_days_remaining(ASN1_UTCTIME *tm)
53 {
54 apr_time_t then, now = apr_time_now();
55 apr_time_exp_t exp = {0};
56 int diff;
57
58 /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates
59 * that the seconds digits are present even though ASN.1
60 * doesn't. */
61 if (tm->length < 11 || !ASN1_UTCTIME_check(tm))
62 return 0;
63
64 exp.tm_year = DIGIT2NUM(tm->data);
65 exp.tm_mon = DIGIT2NUM(tm->data + 2) - 1;
66 exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1;
67 exp.tm_hour = DIGIT2NUM(tm->data + 6);
68 exp.tm_min = DIGIT2NUM(tm->data + 8);
69 exp.tm_sec = DIGIT2NUM(tm->data + 10);
70
71 if (exp.tm_year <= 50)
72 exp.tm_year += 100;
73 if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS)
74 return 0;
75
76 diff = (int)((apr_time_sec(then) - apr_time_sec(now)) / (60*60*24));
77 return diff > 0 ? diff : 0;
78 }
79
80 static char *get_cert_valid(ASN1_UTCTIME *tm)
81 {
82 char *result;
83 BIO* bio;
84 int n;
85
86 if ((bio = BIO_new(BIO_s_mem())) == NULL)
87 return NULL;
88 ASN1_UTCTIME_print(bio, tm);
89 n = BIO_pending(bio);
90 result = malloc(n+1);
91 n = BIO_read(bio, result, n);
92 result[n] = '\0';
93 BIO_free(bio);
94 return result;
95 }
96
97 static char *get_cert_PEM(X509 *xs)
98 {
99 char *result = NULL;
100 BIO *bio;
101
102 if ((bio = BIO_new(BIO_s_mem())) == NULL)
103 return NULL;
104 if (PEM_write_bio_X509(bio, xs)) {
105 int n = BIO_pending(bio);
106 result = malloc(n+1);
107 n = BIO_read(bio, result, n);
108 result[n] = '\0';
109 }
110 BIO_free(bio);
111 return result;
112 }
113
114 static unsigned char *get_cert_ASN1(X509 *xs, int *len)
115 {
116 unsigned char *result = NULL;
117 BIO *bio;
118
119 *len = 0;
120 if ((bio = BIO_new(BIO_s_mem())) == NULL)
121 return NULL;
122 if (i2d_X509_bio(bio, xs)) {
123 int n = BIO_pending(bio);
124 result = malloc(n);
125 n = BIO_read(bio, result, n);
126 *len = n;
127 }
128 BIO_free(bio);
129 return result;
130 }
131
132
133 static char *get_cert_serial(X509 *xs)
134 {
135 char *result;
136 BIO *bio;
137 int n;
138
139 if ((bio = BIO_new(BIO_s_mem())) == NULL)
140 return NULL;
141 i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs));
142 n = BIO_pending(bio);
143 result = malloc(n+1);
144 n = BIO_read(bio, result, n);
145 result[n] = '\0';
146 BIO_free(bio);
147 return result;
148 }
149
150 static const struct {
151 int fid;
152 int nid;
153 } info_cert_dn_rec[] = {
154 { SSL_INFO_DN_COUNTRYNAME, NID_countryName },
155 { SSL_INFO_DN_STATEORPROVINCENAME, NID_stateOrProvinceName },
156 { SSL_INFO_DN_LOCALITYNAME, NID_localityName },
157 { SSL_INFO_DN_ORGANIZATIONNAME, NID_organizationName },
158 { SSL_INFO_DN_ORGANIZATIONALUNITNAME, NID_organizationalUnitName },
159 { SSL_INFO_DN_COMMONNAME, NID_commonName },
160 { SSL_INFO_DN_TITLE, NID_title },
161 { SSL_INFO_DN_INITIALS, NID_initials },
162 { SSL_INFO_DN_GIVENNAME, NID_givenName },
163 { SSL_INFO_DN_SURNAME, NID_surname },
164 { SSL_INFO_DN_DESCRIPTION, NID_description },
165 { SSL_INFO_DN_UNIQUEIDENTIFIER, NID_x500UniqueIdentifier },
166 { SSL_INFO_DN_EMAILADDRESS, NID_pkcs9_emailAddress },
167 { 0, 0 }
168 };
169
170 static char *lookup_ssl_cert_dn(X509_NAME *xsname, int dnidx)
171 {
172 char *result;
173 X509_NAME_ENTRY *xsne;
174 int i, j, n, idx = 0;
175
176 result = NULL;
177
178 for (i = 0; info_cert_dn_rec[i].fid != 0; i++) {
179 if (info_cert_dn_rec[i].fid == dnidx) {
180 for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
181 (xsname->entries)); j++) {
182 xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
183 (xsname->entries), j);
184
185 n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
186 if (n == info_cert_dn_rec[i].nid && idx-- == 0) {
187 result = malloc(xsne->value->length + 1);
188 memcpy(result, xsne->value->data,
189 xsne->value->length);
190 result[xsne->value->length] = '\0';
191
192 #if APR_CHARSET_EBCDIC
193 ap_xlate_proto_from_ascii(result, xsne->value->length);
194 #endif /* APR_CHARSET_EBCDIC */
195 break;
196 }
197 }
198 break;
199 }
200 }
201 return result;
202 }
203
204 TCN_IMPLEMENT_CALL(jobject, SSLSocket, getInfoB)(TCN_STDARGS, jlong sock,
205 jint what)
206 {
207 tcn_socket_t *a = J2P(sock, tcn_socket_t *);
208 tcn_ssl_conn_t *s;
209 jbyteArray array = NULL;
210 apr_status_t rv = APR_SUCCESS;
211
212 UNREFERENCED(o);
213 TCN_ASSERT(sock != 0);
214
215 s = (tcn_ssl_conn_t *)(a->opaque);
216 switch (what) {
217 case SSL_INFO_SESSION_ID:
218 {
219 SSL_SESSION *session = SSL_get_session(s->ssl);
220 if (session) {
221 unsigned int len;
222 const unsigned char *id = SSL_SESSION_get_id(session, &len);
223 array = tcn_new_arrayb(e, id, len);
224 }
225 }
226 break;
227 default:
228 rv = APR_EINVAL;
229 break;
230 }
231 if (what & SSL_INFO_CLIENT_MASK) {
232 X509 *xs;
233 unsigned char *result;
234 int len;
235 if ((xs = SSL_get_peer_certificate(s->ssl)) != NULL) {
236 switch (what) {
237 case SSL_INFO_CLIENT_CERT:
238 if ((result = get_cert_ASN1(xs, &len))) {
239 array = tcn_new_arrayb(e, result, len);
240 free(result);
241 }
242 break;
243 }
244 X509_free(xs);
245 }
246 rv = APR_SUCCESS;
247 }
248 else if (what & SSL_INFO_SERVER_MASK) {
249 X509 *xs;
250 unsigned char *result;
251 int len;
252 if ((xs = SSL_get_certificate(s->ssl)) != NULL) {
253 switch (what) {
254 case SSL_INFO_SERVER_CERT:
255 if ((result = get_cert_ASN1(xs, &len))) {
256 array = tcn_new_arrayb(e, result, len);
257 free(result);
258 }
259 break;
260 }
261 /* XXX: No need to call the X509_free(xs); */
262 }
263 rv = APR_SUCCESS;
264 }
265 else if (what & SSL_INFO_CLIENT_CERT_CHAIN) {
266 X509 *xs;
267 unsigned char *result;
268 STACK_OF(X509) *sk = SSL_get_peer_cert_chain(s->ssl);
269 int len, n = what & 0x0F;
270 if (n < sk_X509_num(sk)) {
271 xs = sk_X509_value(sk, n);
272 if ((result = get_cert_ASN1(xs, &len))) {
273 array = tcn_new_arrayb(e, result, len);
274 free(result);
275 }
276 }
277 rv = APR_SUCCESS;
278 }
279 if (rv != APR_SUCCESS)
280 tcn_ThrowAPRException(e, rv);
281
282 return array;
283 }
284
285 TCN_IMPLEMENT_CALL(jstring, SSLSocket, getInfoS)(TCN_STDARGS, jlong sock,
286 jint what)
287 {
288 tcn_socket_t *a = J2P(sock, tcn_socket_t *);
289 tcn_ssl_conn_t *s;
290 jstring value = NULL;
291 apr_status_t rv = APR_SUCCESS;
292
293 UNREFERENCED(o);
294 TCN_ASSERT(sock != 0);
295
296 s = (tcn_ssl_conn_t *)(a->opaque);
297 switch (what) {
298 case SSL_INFO_SESSION_ID:
299 {
300 SSL_SESSION *session = SSL_get_session(s->ssl);
301 if (session) {
302 unsigned int len;
303 const unsigned char *id = SSL_SESSION_get_id(session, &len);
304 char *hs = convert_to_hex(id, len);
305 if (hs) {
306 value = tcn_new_string(e, hs);
307 free(hs);
308 }
309 }
310 }
311 break;
312 case SSL_INFO_PROTOCOL:
313 value = tcn_new_string(e, SSL_get_version(s->ssl));
314 break;
315 case SSL_INFO_CIPHER:
316 value = tcn_new_string(e, SSL_get_cipher_name(s->ssl));
317 break;
318 case SSL_INFO_CIPHER_VERSION:
319 value = tcn_new_string(e, SSL_get_cipher_version(s->ssl));
320 break;
321 case SSL_INFO_CIPHER_DESCRIPTION:
322 {
323 SSL_CIPHER *cipher = (SSL_CIPHER *)SSL_get_current_cipher(s->ssl );
324 if (cipher) {
325 char buf[256];
326 const char *desc = SSL_CIPHER_description(cipher, buf, 256);
327 value = tcn_new_string(e, desc);
328 }
329 }
330 break;
331 default:
332 rv = APR_EINVAL;
333 break;
334 }
335 if (what & (SSL_INFO_CLIENT_S_DN | SSL_INFO_CLIENT_I_DN)) {
336 X509 *xs;
337 X509_NAME *xsname;
338 if ((xs = SSL_get_peer_certificate(s->ssl)) != NULL) {
339 char *result;
340 int idx = what & 0x0F;
341 if (what & SSL_INFO_CLIENT_S_DN)
342 xsname = X509_get_subject_name(xs);
343 else
344 xsname = X509_get_issuer_name(xs);
345 if (idx) {
346 result = lookup_ssl_cert_dn(xsname, idx);
347 if (result) {
348 value = tcn_new_string(e, result);
349 free(result);
350 }
351 }
352 else
353 value = tcn_new_string(e, X509_NAME_oneline(xsname, NULL, 0));
354 X509_free(xs);
355 }
356 rv = APR_SUCCESS;
357 }
358 else if (what & (SSL_INFO_SERVER_S_DN | SSL_INFO_SERVER_I_DN)) {
359 X509 *xs;
360 X509_NAME *xsname;
361 if ((xs = SSL_get_certificate(s->ssl)) != NULL) {
362 char *result;
363 int idx = what & 0x0F;
364 if (what & SSL_INFO_SERVER_S_DN)
365 xsname = X509_get_subject_name(xs);
366 else
367 xsname = X509_get_issuer_name(xs);
368 if (idx) {
369 result = lookup_ssl_cert_dn(xsname, what & 0x0F);
370 if (result) {
371 value = tcn_new_string(e, result);
372 free(result);
373 }
374 }
375 else
376 value = tcn_new_string(e, X509_NAME_oneline(xsname, NULL, 0));
377 /* XXX: No need to call the X509_free(xs); */
378 }
379 rv = APR_SUCCESS;
380 }
381 else if (what & SSL_INFO_CLIENT_MASK) {
382 X509 *xs;
383 char *result;
384 int nid;
385 if ((xs = SSL_get_peer_certificate(s->ssl)) != NULL) {
386 switch (what) {
387 case SSL_INFO_CLIENT_V_START:
388 if ((result = get_cert_valid(X509_get_notBefore(xs)))) {
389 value = tcn_new_string(e, result);
390 free(result);
391 }
392 break;
393 case SSL_INFO_CLIENT_V_END:
394 if ((result = get_cert_valid(X509_get_notAfter(xs)))) {
395 value = tcn_new_string(e, result);
396 free(result);
397 }
398 break;
399 case SSL_INFO_CLIENT_A_SIG:
400 nid = OBJ_obj2nid((ASN1_OBJECT *)xs->cert_info->signature->a lgorithm);
401 if (nid == NID_undef)
402 value = tcn_new_string(e, "UNKNOWN");
403 else
404 value = tcn_new_string(e, OBJ_nid2ln(nid));
405 break;
406 case SSL_INFO_CLIENT_A_KEY:
407 nid = OBJ_obj2nid((ASN1_OBJECT *)xs->cert_info->key->algor-> algorithm);
408 if (nid == NID_undef)
409 value = tcn_new_string(e, "UNKNOWN");
410 else
411 value = tcn_new_string(e, OBJ_nid2ln(nid));
412 break;
413 case SSL_INFO_CLIENT_CERT:
414 if ((result = get_cert_PEM(xs))) {
415 value = tcn_new_string(e, result);
416 free(result);
417 }
418 break;
419 case SSL_INFO_CLIENT_M_SERIAL:
420 if ((result = get_cert_serial(xs))) {
421 value = tcn_new_string(e, result);
422 free(result);
423 }
424 break;
425 }
426 X509_free(xs);
427 }
428 rv = APR_SUCCESS;
429 }
430 else if (what & SSL_INFO_SERVER_MASK) {
431 X509 *xs;
432 char *result;
433 int nid;
434 if ((xs = SSL_get_certificate(s->ssl)) != NULL) {
435 switch (what) {
436 case SSL_INFO_SERVER_V_START:
437 if ((result = get_cert_valid(X509_get_notBefore(xs)))) {
438 value = tcn_new_string(e, result);
439 free(result);
440 }
441 break;
442 case SSL_INFO_SERVER_V_END:
443 if ((result = get_cert_valid(X509_get_notAfter(xs)))) {
444 value = tcn_new_string(e, result);
445 free(result);
446 }
447 break;
448 case SSL_INFO_SERVER_A_SIG:
449 nid = OBJ_obj2nid((ASN1_OBJECT *)xs->cert_info->signature->a lgorithm);
450 if (nid == NID_undef)
451 value = tcn_new_string(e, "UNKNOWN");
452 else
453 value = tcn_new_string(e, OBJ_nid2ln(nid));
454 break;
455 case SSL_INFO_SERVER_A_KEY:
456 nid = OBJ_obj2nid((ASN1_OBJECT *)xs->cert_info->key->algor-> algorithm);
457 if (nid == NID_undef)
458 value = tcn_new_string(e, "UNKNOWN");
459 else
460 value = tcn_new_string(e, OBJ_nid2ln(nid));
461 break;
462 case SSL_INFO_SERVER_CERT:
463 if ((result = get_cert_PEM(xs))) {
464 value = tcn_new_string(e, result);
465 free(result);
466 }
467 break;
468 case SSL_INFO_SERVER_M_SERIAL:
469 if ((result = get_cert_serial(xs))) {
470 value = tcn_new_string(e, result);
471 free(result);
472 }
473 break;
474 }
475 /* XXX: No need to call the X509_free(xs); */
476 }
477 rv = APR_SUCCESS;
478 }
479 else if (what & SSL_INFO_CLIENT_CERT_CHAIN) {
480 X509 *xs;
481 char *result;
482 STACK_OF(X509) *sk = SSL_get_peer_cert_chain(s->ssl);
483 int n = what & 0x0F;
484 if (n < sk_X509_num(sk)) {
485 xs = sk_X509_value(sk, n);
486 if ((result = get_cert_PEM(xs))) {
487 value = tcn_new_string(e, result);
488 free(result);
489 }
490 }
491 rv = APR_SUCCESS;
492 }
493 if (rv != APR_SUCCESS)
494 tcn_ThrowAPRException(e, rv);
495
496 return value;
497 }
498
499 TCN_IMPLEMENT_CALL(jint, SSLSocket, getInfoI)(TCN_STDARGS, jlong sock,
500 jint what)
501 {
502 tcn_socket_t *a = J2P(sock, tcn_socket_t *);
503 tcn_ssl_conn_t *s;
504 apr_status_t rv = APR_SUCCESS;
505 jint value = -1;
506
507 UNREFERENCED(o);
508 TCN_ASSERT(sock != 0);
509
510 s = (tcn_ssl_conn_t *)(a->opaque);
511
512 switch (what) {
513 case SSL_INFO_CIPHER_USEKEYSIZE:
514 case SSL_INFO_CIPHER_ALGKEYSIZE:
515 {
516 int usekeysize = 0;
517 int algkeysize = 0;
518 const SSL_CIPHER *cipher = SSL_get_current_cipher(s->ssl);
519 if (cipher) {
520 usekeysize = SSL_CIPHER_get_bits(cipher, &algkeysize);
521 if (what == SSL_INFO_CIPHER_USEKEYSIZE)
522 value = usekeysize;
523 else
524 value = algkeysize;
525 }
526 }
527 break;
528 case SSL_INFO_CLIENT_CERT_CHAIN:
529 {
530 STACK_OF(X509) *sk = SSL_get_peer_cert_chain(s->ssl);
531 value = sk_X509_num(sk);
532 }
533 break;
534 default:
535 rv = APR_EINVAL;
536 break;
537 }
538 if (what & SSL_INFO_CLIENT_MASK) {
539 X509 *xs;
540 if ((xs = SSL_get_peer_certificate(s->ssl)) != NULL) {
541 switch (what) {
542 case SSL_INFO_CLIENT_V_REMAIN:
543 value = get_days_remaining(X509_get_notAfter(xs));
544 rv = APR_SUCCESS;
545 break;
546 default:
547 rv = APR_EINVAL;
548 break;
549 }
550 X509_free(xs);
551 }
552 }
553
554 if (rv != APR_SUCCESS)
555 tcn_ThrowAPRException(e, rv);
556 return value;
557 }
558
559 #else
560 /* OpenSSL is not supported.
561 * Create empty stubs.
562 */
563
564 TCN_IMPLEMENT_CALL(jobject, SSLSocket, getInfoB)(TCN_STDARGS, jlong sock,
565 jint what)
566 {
567 UNREFERENCED_STDARGS;
568 UNREFERENCED(sock);
569 UNREFERENCED(what);
570 return NULL;
571 }
572
573 TCN_IMPLEMENT_CALL(jstring, SSLSocket, getInfoS)(TCN_STDARGS, jlong sock,
574 jint what)
575 {
576 UNREFERENCED_STDARGS;
577 UNREFERENCED(sock);
578 UNREFERENCED(what);
579 return NULL;
580 }
581
582 TCN_IMPLEMENT_CALL(jint, SSLSocket, getInfoI)(TCN_STDARGS, jlong sock,
583 jint what)
584 {
585 UNREFERENCED_STDARGS;
586 UNREFERENCED(sock);
587 UNREFERENCED(what);
588 return 0;
589 }
590
591 #endif
OLDNEW
« no previous file with comments | « c/sslcontext.c ('k') | c/sslnetwork.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698