3 * Copyright (C) 2000 -- DaP <profeta@freemail.c3.hu>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #include <openssl/ssl.h> /* SSL_() */
21 #include <openssl/err.h> /* ERR_() */
22 #include <time.h> /* asctime() */
23 #include <string.h> /* strncpy() */
24 #include "ssl.h" /* struct cert_info */
29 #define MIN(a, b) (a < b ? a : b)
32 /* If openssl was built without ec */
33 #ifndef SSL_OP_SINGLE_ECDH_USE
34 #define SSL_OP_SINGLE_ECDH_USE 0
37 #ifndef HAVE_SSL_CTX_get_ssl_method
38 #define SSL_CTX_get_ssl_method(CTX) CTX->method
42 static struct chiper_info chiper_info
; /* static buffer for _SSL_get_cipher_info() */
43 static char err_buf
[256]; /* generic error buffer */
46 /* +++++ Internal functions +++++ */
49 __SSL_fill_err_buf (char *funcname
)
55 err
= ERR_get_error ();
56 ERR_error_string (err
, buf
);
57 snprintf (err_buf
, sizeof (err_buf
), "%s: %s (%d)\n", funcname
, buf
, err
);
62 __SSL_critical_error (char *funcname
)
64 __SSL_fill_err_buf (funcname
);
65 fprintf (stderr
, "%s\n", err_buf
);
70 /* +++++ SSL functions +++++ */
73 _SSL_context_init (void (*info_cb_func
))
77 SSLeay_add_ssl_algorithms ();
78 SSL_load_error_strings ();
79 ctx
= SSL_CTX_new (SSLv23_client_method ());
81 SSL_CTX_set_session_cache_mode (ctx
, SSL_SESS_CACHE_BOTH
);
82 SSL_CTX_set_timeout (ctx
, 300);
83 SSL_CTX_set_options (ctx
, SSL_OP_NO_SSLv2
|SSL_OP_NO_SSLv3
84 |SSL_OP_NO_COMPRESSION
85 |SSL_OP_SINGLE_DH_USE
|SSL_OP_SINGLE_ECDH_USE
87 |SSL_OP_CIPHER_SERVER_PREFERENCE
);
89 /* used in SSL_connect(), SSL_accept() */
90 SSL_CTX_set_info_callback (ctx
, info_cb_func
);
96 ASN1_TIME_snprintf (char *buf
, int buf_len
, ASN1_TIME
* tm
)
99 BIO
*inMem
= BIO_new (BIO_s_mem ());
101 ASN1_TIME_print (inMem
, tm
);
102 BIO_get_mem_data (inMem
, &expires
);
106 /* expires is not \0 terminated */
107 safe_strcpy (buf
, expires
, MIN(24, buf_len
));
114 broke_oneline (char *oneline
, char *parray
[])
121 ppt
= pt
= oneline
+ 1;
122 while ((pt
= strchr (pt
, '/')))
134 FIXME: Master-Key, Extensions, CA bits
135 (openssl x509 -text -in servcert.pem)
138 _SSL_get_cert_info (struct cert_info
*cert_info
, SSL
* ssl
)
141 X509_PUBKEY
*peer_pub_key
;
142 ASN1_OBJECT
*algorithm
;
144 /* EVP_PKEY *ca_pkey; */
145 /* EVP_PKEY *tmp_pkey; */
152 if (!(peer_cert
= SSL_get_peer_certificate (ssl
)))
153 return (1); /* FATAL? */
155 X509_NAME_oneline (X509_get_subject_name (peer_cert
), cert_info
->subject
,
156 sizeof (cert_info
->subject
));
157 X509_NAME_oneline (X509_get_issuer_name (peer_cert
), cert_info
->issuer
,
158 sizeof (cert_info
->issuer
));
159 broke_oneline (cert_info
->subject
, cert_info
->subject_word
);
160 broke_oneline (cert_info
->issuer
, cert_info
->issuer_word
);
162 peer_pub_key
= X509_get_X509_PUBKEY (peer_cert
);
163 X509_PUBKEY_get0_param (&algorithm
, NULL
, NULL
, NULL
, peer_pub_key
);
164 alg
= OBJ_obj2nid (algorithm
);
165 sign_alg
= X509_get_signature_type (peer_cert
);
166 ASN1_TIME_snprintf (notBefore
, sizeof (notBefore
),
167 X509_get_notBefore (peer_cert
));
168 ASN1_TIME_snprintf (notAfter
, sizeof (notAfter
),
169 X509_get_notAfter (peer_cert
));
171 peer_pkey
= X509_get_pubkey (peer_cert
);
173 safe_strcpy (cert_info
->algorithm
,
174 (alg
== NID_undef
) ? "Unknown" : OBJ_nid2ln (alg
),
175 sizeof (cert_info
->algorithm
));
176 cert_info
->algorithm_bits
= EVP_PKEY_bits (peer_pkey
);
177 safe_strcpy (cert_info
->sign_algorithm
,
178 (sign_alg
== NID_undef
) ? "Unknown" : OBJ_nid2ln (sign_alg
),
179 sizeof (cert_info
->sign_algorithm
));
180 /* EVP_PKEY_bits(ca_pkey)); */
181 cert_info
->sign_algorithm_bits
= 0;
182 safe_strcpy (cert_info
->notbefore
, notBefore
, sizeof (cert_info
->notbefore
));
183 safe_strcpy (cert_info
->notafter
, notAfter
, sizeof (cert_info
->notafter
));
185 EVP_PKEY_free (peer_pkey
);
187 /* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */
189 if (ssl->session->sess_cert->peer_rsa_tmp) {
190 tmp_pkey = EVP_PKEY_new();
191 EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp);
192 cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey);
193 EVP_PKEY_free(tmp_pkey);
195 fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n");
197 cert_info
->rsa_tmp_bits
= 0;
199 X509_free (peer_cert
);
206 _SSL_get_cipher_info (SSL
* ssl
)
211 c
= SSL_get_current_cipher (ssl
);
212 safe_strcpy (chiper_info
.version
, SSL_CIPHER_get_version (c
),
213 sizeof (chiper_info
.version
));
214 safe_strcpy (chiper_info
.chiper
, SSL_CIPHER_get_name (c
),
215 sizeof (chiper_info
.chiper
));
216 SSL_CIPHER_get_bits (c
, &chiper_info
.chiper_bits
);
218 return (&chiper_info
);
223 _SSL_send (SSL
* ssl
, char *buf
, int len
)
228 num
= SSL_write (ssl
, buf
, len
);
230 switch (SSL_get_error (ssl
, num
))
232 case SSL_ERROR_SSL
: /* setup errno! */
234 __SSL_fill_err_buf ("SSL_write");
235 fprintf (stderr
, "%s\n", err_buf
);
237 case SSL_ERROR_SYSCALL
:
239 perror ("SSL_write/write");
241 case SSL_ERROR_ZERO_RETURN
:
242 /* fprintf(stderr, "SSL closed on write\n"); */
251 _SSL_recv (SSL
* ssl
, char *buf
, int len
)
256 num
= SSL_read (ssl
, buf
, len
);
258 switch (SSL_get_error (ssl
, num
))
262 __SSL_fill_err_buf ("SSL_read");
263 fprintf (stderr
, "%s\n", err_buf
);
265 case SSL_ERROR_SYSCALL
:
268 perror ("SSL_read/read");
270 case SSL_ERROR_ZERO_RETURN
:
271 /* fprintf(stdeerr, "SSL closed on read\n"); */
280 _SSL_socket (SSL_CTX
*ctx
, int sd
)
286 if (!(ssl
= SSL_new (ctx
)))
288 __SSL_critical_error ("SSL_new");
290 SSL_set_fd (ssl
, sd
);
292 method
= SSL_CTX_get_ssl_method (ctx
);
293 if (method
== SSLv23_client_method())
294 SSL_set_connect_state (ssl
);
296 SSL_set_accept_state(ssl
);
303 _SSL_set_verify (SSL_CTX
*ctx
, void *verify_callback
, char *cacert
)
305 if (!SSL_CTX_set_default_verify_paths (ctx
))
307 __SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");
313 if (!SSL_CTX_load_verify_locations (ctx, cacert, NULL))
315 __SSL_fill_err_buf ("SSL_CTX_load_verify_locations");
320 SSL_CTX_set_verify (ctx
, SSL_VERIFY_PEER
, verify_callback
);
327 _SSL_close (SSL
* ssl
)
329 SSL_set_shutdown (ssl
, SSL_SENT_SHUTDOWN
| SSL_RECEIVED_SHUTDOWN
);
331 ERR_remove_state (0); /* free state buffer */