9 static char strnum[FMT_ULONG];
10 static stralloc ctemp = {0};
11 static stralloc *
envsa = 0;
12 static stralloc btemp = {0};
13 static stralloc etemp = {0};
15 #define set_env_id(n,e,v) \
16 if (!set_env_name_entry((n),(e),(v))) return 0
18 static int env_val(
const char *
env,
const void *val,
int len) {
21 if (!stralloc_cats(
envsa,
env))
return 0;
22 if (!stralloc_catb(
envsa,
"=",1))
return 0;
23 if (!stralloc_catb(
envsa,v,len))
return 0;
24 if (!stralloc_0(
envsa))
return 0;
27 if (!stralloc_copyb(&etemp,v,len))
return 0;
28 if (!stralloc_0(&etemp))
return 0;
29 return pathexec_env(
env,etemp.s);
32 static int env_str(
const char *
env,
const char *val) {
34 return env_val(
env,val,str_len(val));
35 if (!stralloc_cats(envsa,
env))
return 0;
36 if (!stralloc_catb(envsa,
"=",1))
return 0;
37 if (!stralloc_catb(envsa,val,str_len(val) + 1))
return 0;
40 return pathexec_env(
env,val);
43 static int set_env_name_entry(X509_NAME *xname,
const char *
env,
int nid) {
49 #if ((OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER > 0 && LIBRESSL_VERSION_NUMBER < 0x20700000L))
50 for (m = 0; m < sk_X509_NAME_ENTRY_num(xname->entries); m++) {
51 xne = sk_X509_NAME_ENTRY_value(xname->entries,m);
52 n = OBJ_obj2nid(xne->object);
54 if (!env_val(
env,xne->value->data,xne->value->length))
return 0;
56 for (m = 0; m < X509_NAME_entry_count(xname); m++) {
57 xne = X509_NAME_get_entry(xname,m);
58 n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xne));
60 if (!env_val(
env,X509_NAME_ENTRY_get_data(xne)->data,X509_NAME_ENTRY_get_data(xne)->length))
return 0;
68 unsigned const char *x;
72 const SSL_CIPHER *cipher;
76 if (!env_str(
"SSL_PROTOCOL",SSL_get_version(ssl)))
79 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
80 session = SSL_get_session(ssl);
81 x = session->session_id;
82 n = session->session_id_length;
84 session = SSL_get1_session(ssl);
85 x = SSL_SESSION_get_id(session,&n);
88 if (!stralloc_ready(&btemp,2 * n))
return 0;
93 if (c >
'0' + 9) c +=
'a' -
'0' - 10;
94 btemp.s[2 * n + 1] = c;
97 if (c >
'0' + 9) c +=
'a' -
'0' - 10;
100 if (!env_val(
"SSL_SESSION_ID",btemp.s,btemp.len))
return 0;
102 if (!env_str(
"SSL_CIPHER",SSL_get_cipher_name(ssl)))
return 0;
104 cipher = SSL_get_current_cipher(ssl);
105 if (!cipher)
return 0;
106 n = SSL_CIPHER_get_bits(cipher,&m);
107 if (!env_str(
"SSL_CIPHER_EXPORT",n < 56 ?
"true" :
"false"))
return 0;
108 if (!env_val(
"SSL_CIPHER_USEKEYSIZE",strnum,fmt_ulong(strnum,n)))
return 0;
109 if (!env_val(
"SSL_CIPHER_ALGKEYSIZE",strnum,fmt_ulong(strnum,m)))
return 0;
111 if (!env_str(
"SSL_VERSION_INTERFACE",
"ucspi-ssl"))
return 0;
112 if (!env_str(
"SSL_VERSION_LIBRARY",OPENSSL_VERSION_TEXT))
return 0;
117 static int ssl_client_bio_vars(X509 *
cert,STACK_OF(X509) *chain,BIO *bio) {
118 ASN1_STRING *astring;
122 astring = X509_get_notBefore(
cert);
123 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
124 n = BIO_pending(bio);
125 if (!stralloc_ready(&btemp,n))
return 0;
127 n = BIO_read(bio,btemp.s,n);
128 if (n != btemp.len)
return 0;
129 if (!env_val(
"SSL_CLIENT_V_START",btemp.s,btemp.len))
return 0;
131 astring = X509_get_notAfter(
cert);
132 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
133 n = BIO_pending(bio);
134 if (!stralloc_ready(&btemp,n))
return 0;
136 n = BIO_read(bio,btemp.s,n);
137 if (n != btemp.len)
return 0;
138 if (!env_val(
"SSL_CLIENT_V_END",btemp.s,btemp.len))
return 0;
140 if (!PEM_write_bio_X509(bio,
cert))
return 0;
141 n = BIO_pending(bio);
142 if (!stralloc_ready(&btemp,n))
return 0;
144 n = BIO_read(bio,btemp.s,n);
145 if (n != btemp.len)
return 0;
146 if (!env_val(
"SSL_CLIENT_CERT",btemp.s,btemp.len))
return 0;
149 for (m = 0; m < sk_X509_num(chain); m++) {
150 if (!stralloc_copys(&ctemp,
"SSL_CLIENT_CERT_CHAIN_"))
return 0;
151 if (!stralloc_catb(&ctemp,strnum,fmt_ulong(strnum,m)))
return 0;
152 if (!stralloc_0(&ctemp))
return 0;
154 if (m < sk_X509_num(chain)) {
155 if (!PEM_write_bio_X509(bio,sk_X509_value(chain,m)))
return 0;
156 n = BIO_pending(bio);
157 if (!stralloc_ready(&btemp,n))
return 0;
159 n = BIO_read(bio,btemp.s,n);
160 if (n != btemp.len)
return 0;
161 if (!env_val(ctemp.s,btemp.s,btemp.len))
return 0;
169 static int ssl_client_vars(X509 *
cert,STACK_OF(X509) *chain) {
172 const X509_ALGOR *sigalg;
173 const ASN1_OBJECT *calgoid;
182 if (!env_val(
"SSL_CLIENT_M_VERSION",strnum,fmt_ulong(strnum,X509_get_version(
cert) + 1)))
185 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(
cert), 0);
188 if (!env_val(
"SSL_CLIENT_M_SERIAL",x,strlen(x)))
192 xname = X509_get_subject_name(
cert);
193 x = X509_NAME_oneline(xname,0,0);
194 n = env_str(
"SSL_CLIENT_S_DN",x);
198 set_env_id(xname,
"SSL_CLIENT_S_DN_C",NID_countryName);
199 set_env_id(xname,
"SSL_CLIENT_S_DN_ST",NID_stateOrProvinceName);
200 set_env_id(xname,
"SSL_CLIENT_S_DN_L",NID_localityName);
201 set_env_id(xname,
"SSL_CLIENT_S_DN_O",NID_organizationName);
202 set_env_id(xname,
"SSL_CLIENT_S_DN_OU",NID_organizationalUnitName);
203 set_env_id(xname,
"SSL_CLIENT_S_DN_CN",NID_commonName);
204 set_env_id(xname,
"SSL_CLIENT_S_DN_T",NID_title);
205 set_env_id(xname,
"SSL_CLIENT_S_DN_I",NID_initials);
206 set_env_id(xname,
"SSL_CLIENT_S_DN_G",NID_givenName);
207 set_env_id(xname,
"SSL_CLIENT_S_DN_S",NID_surname);
208 set_env_id(xname,
"SSL_CLIENT_S_DN_D",NID_description);
209 set_env_id(xname,
"SSL_CLIENT_S_DN_UID",NID_x500UniqueIdentifier);
210 set_env_id(xname,
"SSL_CLIENT_S_DN_Email",NID_pkcs9_emailAddress);
212 xname = X509_get_issuer_name(
cert);
213 x = X509_NAME_oneline(xname,0,0);
214 n = env_str(
"SSL_CLIENT_I_DN",x);
218 set_env_id(xname,
"SSL_CLIENT_I_DN_C",NID_countryName);
219 set_env_id(xname,
"SSL_CLIENT_I_DN_ST",NID_stateOrProvinceName);
220 set_env_id(xname,
"SSL_CLIENT_I_DN_L",NID_localityName);
221 set_env_id(xname,
"SSL_CLIENT_I_DN_O",NID_organizationName);
222 set_env_id(xname,
"SSL_CLIENT_I_DN_OU",NID_organizationalUnitName);
223 set_env_id(xname,
"SSL_CLIENT_I_DN_CN",NID_commonName);
224 set_env_id(xname,
"SSL_CLIENT_I_DN_T",NID_title);
225 set_env_id(xname,
"SSL_CLIENT_I_DN_I",NID_initials);
226 set_env_id(xname,
"SSL_CLIENT_I_DN_G",NID_givenName);
227 set_env_id(xname,
"SSL_CLIENT_I_DN_S",NID_surname);
228 set_env_id(xname,
"SSL_CLIENT_I_DN_D",NID_description);
229 set_env_id(xname,
"SSL_CLIENT_I_DN_UID",NID_x500UniqueIdentifier);
230 set_env_id(xname,
"SSL_CLIENT_I_DN_Email",NID_pkcs9_emailAddress);
233 #if ((OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER > 0 && LIBRESSL_VERSION_NUMBER < 0x20700000L))
234 n = OBJ_obj2nid(
cert->cert_info->signature->algorithm);
236 sigalg = X509_get0_tbs_sigalg(
cert);
237 X509_ALGOR_get0(&calgoid,0,0,sigalg);
238 n = OBJ_obj2nid(calgoid);
240 if (!env_str(
"SSL_CLIENT_A_SIG",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
244 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
245 n = OBJ_obj2nid(
cert->cert_info->key->algor->algorithm);
247 pubkey = X509_get_X509_PUBKEY(
cert);
248 X509_PUBKEY_get0_param(&algoid,0,0,0,pubkey);
249 n = OBJ_obj2nid(algoid);
251 if (!env_str(
"SSL_CLIENT_A_KEY",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
254 bio = BIO_new(BIO_s_mem());
256 n = ssl_client_bio_vars(
cert,chain,bio);
263 static int ssl_server_bio_vars(X509 *
cert,STACK_OF(X509) *chain,BIO *bio) {
264 ASN1_STRING *astring;
268 astring = X509_get_notBefore(
cert);
269 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
270 n = BIO_pending(bio);
271 if (!stralloc_ready(&btemp,n))
return 0;
273 n = BIO_read(bio,btemp.s,n);
274 if (n != btemp.len)
return 0;
275 if (!env_val(
"SSL_SERVER_V_START",btemp.s,btemp.len))
return 0;
277 astring = X509_get_notAfter(
cert);
278 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
279 n = BIO_pending(bio);
280 if (!stralloc_ready(&btemp,n))
return 0;
282 n = BIO_read(bio,btemp.s,n);
283 if (n != btemp.len)
return 0;
284 if (!env_val(
"SSL_SERVER_V_END",btemp.s,btemp.len))
return 0;
286 if (!PEM_write_bio_X509(bio,
cert))
return 0;
287 n = BIO_pending(bio);
288 if (!stralloc_ready(&btemp,n))
return 0;
290 n = BIO_read(bio,btemp.s,n);
291 if (n != btemp.len)
return 0;
292 if (!env_val(
"SSL_SERVER_CERT",btemp.s,btemp.len))
return 0;
295 for (m = 0; m < sk_X509_num(chain); m++) {
296 if (!stralloc_copys(&ctemp,
"SSL_SERVER_CERT_CHAIN_"))
return 0;
297 if (!stralloc_catb(&ctemp,strnum,fmt_ulong(strnum,m)))
return 0;
298 if (!stralloc_0(&ctemp))
return 0;
300 if (m < sk_X509_num(chain)) {
301 if (!PEM_write_bio_X509(bio,sk_X509_value(chain,m)))
return 0;
302 n = BIO_pending(bio);
303 if (!stralloc_ready(&btemp,n))
return 0;
305 n = BIO_read(bio,btemp.s,n);
306 if (n != btemp.len)
return 0;
307 if (!env_val(ctemp.s,btemp.s,btemp.len))
return 0;
315 static int ssl_server_vars(X509 *
cert,STACK_OF(X509) *chain) {
318 const X509_ALGOR *sigalg;
319 const ASN1_OBJECT *calgoid;
328 if (!env_val(
"SSL_SERVER_M_VERSION",strnum,fmt_ulong(strnum,X509_get_version(
cert) + 1)))
331 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(
cert), 0);
334 if (!env_val(
"SSL_SERVER_M_SERIAL",x,strlen(x)))
return 0;
337 xname = X509_get_subject_name(
cert);
338 x = X509_NAME_oneline(xname,0,0);
339 n = env_str(
"SSL_SERVER_S_DN",x);
343 set_env_id(xname,
"SSL_SERVER_S_DN_C",NID_countryName);
344 set_env_id(xname,
"SSL_SERVER_S_DN_ST",NID_stateOrProvinceName);
345 set_env_id(xname,
"SSL_SERVER_S_DN_L",NID_localityName);
346 set_env_id(xname,
"SSL_SERVER_S_DN_O",NID_organizationName);
347 set_env_id(xname,
"SSL_SERVER_S_DN_OU",NID_organizationalUnitName);
348 set_env_id(xname,
"SSL_SERVER_S_DN_CN",NID_commonName);
349 set_env_id(xname,
"SSL_SERVER_S_DN_T",NID_title);
350 set_env_id(xname,
"SSL_SERVER_S_DN_I",NID_initials);
351 set_env_id(xname,
"SSL_SERVER_S_DN_G",NID_givenName);
352 set_env_id(xname,
"SSL_SERVER_S_DN_S",NID_surname);
353 set_env_id(xname,
"SSL_SERVER_S_DN_D",NID_description);
354 set_env_id(xname,
"SSL_SERVER_S_DN_UID",NID_x500UniqueIdentifier);
355 set_env_id(xname,
"SSL_SERVER_S_DN_Email",NID_pkcs9_emailAddress);
357 xname = X509_get_issuer_name(
cert);
358 x = X509_NAME_oneline(xname,0,0);
359 n = env_str(
"SSL_SERVER_I_DN",x);
363 set_env_id(xname,
"SSL_SERVER_I_DN_C",NID_countryName);
364 set_env_id(xname,
"SSL_SERVER_I_DN_ST",NID_stateOrProvinceName);
365 set_env_id(xname,
"SSL_SERVER_I_DN_L",NID_localityName);
366 set_env_id(xname,
"SSL_SERVER_I_DN_O",NID_organizationName);
367 set_env_id(xname,
"SSL_SERVER_I_DN_OU",NID_organizationalUnitName);
368 set_env_id(xname,
"SSL_SERVER_I_DN_CN",NID_commonName);
369 set_env_id(xname,
"SSL_SERVER_I_DN_T",NID_title);
370 set_env_id(xname,
"SSL_SERVER_I_DN_I",NID_initials);
371 set_env_id(xname,
"SSL_SERVER_I_DN_G",NID_givenName);
372 set_env_id(xname,
"SSL_SERVER_I_DN_S",NID_surname);
373 set_env_id(xname,
"SSL_SERVER_I_DN_D",NID_description);
374 set_env_id(xname,
"SSL_SERVER_I_DN_UID",NID_x500UniqueIdentifier);
375 set_env_id(xname,
"SSL_SERVER_I_DN_Email",NID_pkcs9_emailAddress);
378 #if ((OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER > 0 && LIBRESSL_VERSION_NUMBER < 0x20700000L))
379 n = OBJ_obj2nid(
cert->cert_info->signature->algorithm);
381 sigalg = X509_get0_tbs_sigalg(
cert);
382 X509_ALGOR_get0(&calgoid,0,0,sigalg);
383 n = OBJ_obj2nid(calgoid);
385 if (!env_str(
"SSL_SERVER_A_SIG",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
389 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
390 n = OBJ_obj2nid(
cert->cert_info->key->algor->algorithm);
392 pubkey = X509_get_X509_PUBKEY(
cert);
393 X509_PUBKEY_get0_param(&algoid,0,0,0,pubkey);
394 n = OBJ_obj2nid(algoid);
396 if (!env_str(
"SSL_SERVER_A_KEY",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
399 bio = BIO_new(BIO_s_mem());
401 n = ssl_server_bio_vars(
cert,chain,bio);
412 if (!ssl_client_vars(SSL_get_certificate(ssl),0))
414 #if (OPENSSL_VERSION_NUMBER > 0x30000000L)
415 if (!ssl_server_vars(0,SSL_get_peer_cert_chain(ssl)))
417 if (!ssl_server_vars(SSL_get_peer_certificate(ssl),SSL_get_peer_cert_chain(ssl)))
426 if (!ssl_server_vars(SSL_get_certificate(ssl),0))
428 #if (OPENSSL_VERSION_NUMBER > 0x30000000L)
429 if (!ssl_server_vars(0,SSL_get_peer_cert_chain(ssl)))
431 if (!ssl_client_vars(SSL_get_peer_certificate(ssl),SSL_get_peer_cert_chain(ssl)))
#define set_env_id(n, e, v)
int ssl_server_env(SSL *ssl, stralloc *sa)
int ssl_client_env(SSL *ssl, stralloc *sa)
int ssl_session_vars(SSL *ssl)
void env(const char *s, const char *t)
Header file to be used with sqmail; previously called ssl.h. (name clash)