9static char strnum[FMT_ULONG];
10static stralloc ctemp = {0};
11static stralloc *envsa = 0;
12static stralloc btemp = {0};
13static stralloc etemp = {0};
15#define set_env_id(n,e,v) \
16if (!set_env_name_entry((n),(e),(v))) return 0
18static 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);
32static 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);
43static int set_env_name_entry(X509_NAME *xname,
const char *
env,
int nid) {
49 for (m = 0; m < X509_NAME_entry_count(xname); m++) {
50 xne = X509_NAME_get_entry(xname,m);
51 n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xne));
53 if (!env_val(
env,X509_NAME_ENTRY_get_data(xne)->data,X509_NAME_ENTRY_get_data(xne)->length))
return 0;
60 unsigned const char *x;
64 const SSL_CIPHER *cipher;
68 if (!env_str(
"SSL_PROTOCOL",SSL_get_version(ssl)))
71 session = SSL_get1_session(ssl);
72 x = SSL_SESSION_get_id(session,&n);
74 if (!stralloc_ready(&btemp,2 * n))
return 0;
79 if (c >
'0' + 9) c +=
'a' -
'0' - 10;
80 btemp.s[2 * n + 1] = c;
83 if (c >
'0' + 9) c +=
'a' -
'0' - 10;
86 if (!env_val(
"SSL_SESSION_ID",btemp.s,btemp.len))
return 0;
88 if (!env_str(
"SSL_CIPHER",SSL_get_cipher_name(ssl)))
return 0;
90 cipher = SSL_get_current_cipher(ssl);
91 if (!cipher)
return 0;
92 n = SSL_CIPHER_get_bits(cipher,&m);
93 if (!env_str(
"SSL_CIPHER_EXPORT",n < 56 ?
"true" :
"false"))
return 0;
94 if (!env_val(
"SSL_CIPHER_USEKEYSIZE",strnum,fmt_ulong(strnum,n)))
return 0;
95 if (!env_val(
"SSL_CIPHER_ALGKEYSIZE",strnum,fmt_ulong(strnum,m)))
return 0;
97 if (!env_str(
"SSL_VERSION_INTERFACE",
"ucspi-ssl"))
return 0;
98 if (!env_str(
"SSL_VERSION_LIBRARY",OPENSSL_VERSION_TEXT))
return 0;
103static int ssl_client_bio_vars(X509 *
cert,STACK_OF(X509) *chain,BIO *bio) {
104 ASN1_STRING *astring;
108 astring = X509_get_notBefore(
cert);
109 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
110 n = BIO_pending(bio);
111 if (!stralloc_ready(&btemp,n))
return 0;
113 n = BIO_read(bio,btemp.s,n);
114 if (n != btemp.len)
return 0;
115 if (!env_val(
"SSL_CLIENT_V_START",btemp.s,btemp.len))
return 0;
117 astring = X509_get_notAfter(
cert);
118 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
119 n = BIO_pending(bio);
120 if (!stralloc_ready(&btemp,n))
return 0;
122 n = BIO_read(bio,btemp.s,n);
123 if (n != btemp.len)
return 0;
124 if (!env_val(
"SSL_CLIENT_V_END",btemp.s,btemp.len))
return 0;
126 if (!PEM_write_bio_X509(bio,
cert))
return 0;
127 n = BIO_pending(bio);
128 if (!stralloc_ready(&btemp,n))
return 0;
130 n = BIO_read(bio,btemp.s,n);
131 if (n != btemp.len)
return 0;
132 if (!env_val(
"SSL_CLIENT_CERT",btemp.s,btemp.len))
return 0;
135 for (m = 0; m < sk_X509_num(chain); m++) {
136 if (!stralloc_copys(&ctemp,
"SSL_CLIENT_CERT_CHAIN_"))
return 0;
137 if (!stralloc_catb(&ctemp,strnum,fmt_ulong(strnum,m)))
return 0;
138 if (!stralloc_0(&ctemp))
return 0;
140 if (m < sk_X509_num(chain)) {
141 if (!PEM_write_bio_X509(bio,sk_X509_value(chain,m)))
return 0;
142 n = BIO_pending(bio);
143 if (!stralloc_ready(&btemp,n))
return 0;
145 n = BIO_read(bio,btemp.s,n);
146 if (n != btemp.len)
return 0;
147 if (!env_val(ctemp.s,btemp.s,btemp.len))
return 0;
155static int ssl_client_vars(X509 *
cert,STACK_OF(X509) *chain) {
158 const X509_ALGOR *sigalg;
159 const ASN1_OBJECT *calgoid;
168 if (!env_val(
"SSL_CLIENT_M_VERSION",strnum,fmt_ulong(strnum,X509_get_version(
cert) + 1)))
171 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(
cert), 0);
174 if (!env_val(
"SSL_CLIENT_M_SERIAL",x,strlen(x)))
178 xname = X509_get_subject_name(
cert);
179 x = X509_NAME_oneline(xname,0,0);
180 n = env_str(
"SSL_CLIENT_S_DN",x);
184 set_env_id(xname,
"SSL_CLIENT_S_DN_C",NID_countryName);
185 set_env_id(xname,
"SSL_CLIENT_S_DN_ST",NID_stateOrProvinceName);
186 set_env_id(xname,
"SSL_CLIENT_S_DN_L",NID_localityName);
187 set_env_id(xname,
"SSL_CLIENT_S_DN_O",NID_organizationName);
188 set_env_id(xname,
"SSL_CLIENT_S_DN_OU",NID_organizationalUnitName);
189 set_env_id(xname,
"SSL_CLIENT_S_DN_CN",NID_commonName);
190 set_env_id(xname,
"SSL_CLIENT_S_DN_T",NID_title);
191 set_env_id(xname,
"SSL_CLIENT_S_DN_I",NID_initials);
192 set_env_id(xname,
"SSL_CLIENT_S_DN_G",NID_givenName);
193 set_env_id(xname,
"SSL_CLIENT_S_DN_S",NID_surname);
194 set_env_id(xname,
"SSL_CLIENT_S_DN_D",NID_description);
195 set_env_id(xname,
"SSL_CLIENT_S_DN_UID",NID_x500UniqueIdentifier);
196 set_env_id(xname,
"SSL_CLIENT_S_DN_Email",NID_pkcs9_emailAddress);
198 xname = X509_get_issuer_name(
cert);
199 x = X509_NAME_oneline(xname,0,0);
200 n = env_str(
"SSL_CLIENT_I_DN",x);
204 set_env_id(xname,
"SSL_CLIENT_I_DN_C",NID_countryName);
205 set_env_id(xname,
"SSL_CLIENT_I_DN_ST",NID_stateOrProvinceName);
206 set_env_id(xname,
"SSL_CLIENT_I_DN_L",NID_localityName);
207 set_env_id(xname,
"SSL_CLIENT_I_DN_O",NID_organizationName);
208 set_env_id(xname,
"SSL_CLIENT_I_DN_OU",NID_organizationalUnitName);
209 set_env_id(xname,
"SSL_CLIENT_I_DN_CN",NID_commonName);
210 set_env_id(xname,
"SSL_CLIENT_I_DN_T",NID_title);
211 set_env_id(xname,
"SSL_CLIENT_I_DN_I",NID_initials);
212 set_env_id(xname,
"SSL_CLIENT_I_DN_G",NID_givenName);
213 set_env_id(xname,
"SSL_CLIENT_I_DN_S",NID_surname);
214 set_env_id(xname,
"SSL_CLIENT_I_DN_D",NID_description);
215 set_env_id(xname,
"SSL_CLIENT_I_DN_UID",NID_x500UniqueIdentifier);
216 set_env_id(xname,
"SSL_CLIENT_I_DN_Email",NID_pkcs9_emailAddress);
219 sigalg = X509_get0_tbs_sigalg(
cert);
220 X509_ALGOR_get0(&calgoid,0,0,sigalg);
221 n = OBJ_obj2nid(calgoid);
222 if (!env_str(
"SSL_CLIENT_A_SIG",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
226 pubkey = X509_get_X509_PUBKEY(
cert);
227 X509_PUBKEY_get0_param(&algoid,0,0,0,pubkey);
228 n = OBJ_obj2nid(algoid);
229 if (!env_str(
"SSL_CLIENT_A_KEY",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
232 bio = BIO_new(BIO_s_mem());
234 n = ssl_client_bio_vars(
cert,chain,bio);
241static int ssl_server_bio_vars(X509 *
cert,STACK_OF(X509) *chain,BIO *bio) {
242 ASN1_STRING *astring;
246 astring = X509_get_notBefore(
cert);
247 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
248 n = BIO_pending(bio);
249 if (!stralloc_ready(&btemp,n))
return 0;
251 n = BIO_read(bio,btemp.s,n);
252 if (n != btemp.len)
return 0;
253 if (!env_val(
"SSL_SERVER_V_START",btemp.s,btemp.len))
return 0;
255 astring = X509_get_notAfter(
cert);
256 if (!ASN1_UTCTIME_print(bio,astring))
return 0;
257 n = BIO_pending(bio);
258 if (!stralloc_ready(&btemp,n))
return 0;
260 n = BIO_read(bio,btemp.s,n);
261 if (n != btemp.len)
return 0;
262 if (!env_val(
"SSL_SERVER_V_END",btemp.s,btemp.len))
return 0;
264 if (!PEM_write_bio_X509(bio,
cert))
return 0;
265 n = BIO_pending(bio);
266 if (!stralloc_ready(&btemp,n))
return 0;
268 n = BIO_read(bio,btemp.s,n);
269 if (n != btemp.len)
return 0;
270 if (!env_val(
"SSL_SERVER_CERT",btemp.s,btemp.len))
return 0;
273 for (m = 0; m < sk_X509_num(chain); m++) {
274 if (!stralloc_copys(&ctemp,
"SSL_SERVER_CERT_CHAIN_"))
return 0;
275 if (!stralloc_catb(&ctemp,strnum,fmt_ulong(strnum,m)))
return 0;
276 if (!stralloc_0(&ctemp))
return 0;
278 if (m < sk_X509_num(chain)) {
279 if (!PEM_write_bio_X509(bio,sk_X509_value(chain,m)))
return 0;
280 n = BIO_pending(bio);
281 if (!stralloc_ready(&btemp,n))
return 0;
283 n = BIO_read(bio,btemp.s,n);
284 if (n != btemp.len)
return 0;
285 if (!env_val(ctemp.s,btemp.s,btemp.len))
return 0;
293static int ssl_server_vars(X509 *
cert,STACK_OF(X509) *chain) {
296 const X509_ALGOR *sigalg;
297 const ASN1_OBJECT *calgoid;
306 if (!env_val(
"SSL_SERVER_M_VERSION",strnum,fmt_ulong(strnum,X509_get_version(
cert) + 1)))
309 bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(
cert), 0);
312 if (!env_val(
"SSL_SERVER_M_SERIAL",x,strlen(x)))
return 0;
315 xname = X509_get_subject_name(
cert);
316 x = X509_NAME_oneline(xname,0,0);
317 n = env_str(
"SSL_SERVER_S_DN",x);
321 set_env_id(xname,
"SSL_SERVER_S_DN_C",NID_countryName);
322 set_env_id(xname,
"SSL_SERVER_S_DN_ST",NID_stateOrProvinceName);
323 set_env_id(xname,
"SSL_SERVER_S_DN_L",NID_localityName);
324 set_env_id(xname,
"SSL_SERVER_S_DN_O",NID_organizationName);
325 set_env_id(xname,
"SSL_SERVER_S_DN_OU",NID_organizationalUnitName);
326 set_env_id(xname,
"SSL_SERVER_S_DN_CN",NID_commonName);
327 set_env_id(xname,
"SSL_SERVER_S_DN_T",NID_title);
328 set_env_id(xname,
"SSL_SERVER_S_DN_I",NID_initials);
329 set_env_id(xname,
"SSL_SERVER_S_DN_G",NID_givenName);
330 set_env_id(xname,
"SSL_SERVER_S_DN_S",NID_surname);
331 set_env_id(xname,
"SSL_SERVER_S_DN_D",NID_description);
332 set_env_id(xname,
"SSL_SERVER_S_DN_UID",NID_x500UniqueIdentifier);
333 set_env_id(xname,
"SSL_SERVER_S_DN_Email",NID_pkcs9_emailAddress);
335 xname = X509_get_issuer_name(
cert);
336 x = X509_NAME_oneline(xname,0,0);
337 n = env_str(
"SSL_SERVER_I_DN",x);
341 set_env_id(xname,
"SSL_SERVER_I_DN_C",NID_countryName);
342 set_env_id(xname,
"SSL_SERVER_I_DN_ST",NID_stateOrProvinceName);
343 set_env_id(xname,
"SSL_SERVER_I_DN_L",NID_localityName);
344 set_env_id(xname,
"SSL_SERVER_I_DN_O",NID_organizationName);
345 set_env_id(xname,
"SSL_SERVER_I_DN_OU",NID_organizationalUnitName);
346 set_env_id(xname,
"SSL_SERVER_I_DN_CN",NID_commonName);
347 set_env_id(xname,
"SSL_SERVER_I_DN_T",NID_title);
348 set_env_id(xname,
"SSL_SERVER_I_DN_I",NID_initials);
349 set_env_id(xname,
"SSL_SERVER_I_DN_G",NID_givenName);
350 set_env_id(xname,
"SSL_SERVER_I_DN_S",NID_surname);
351 set_env_id(xname,
"SSL_SERVER_I_DN_D",NID_description);
352 set_env_id(xname,
"SSL_SERVER_I_DN_UID",NID_x500UniqueIdentifier);
353 set_env_id(xname,
"SSL_SERVER_I_DN_Email",NID_pkcs9_emailAddress);
356 sigalg = X509_get0_tbs_sigalg(
cert);
357 X509_ALGOR_get0(&calgoid,0,0,sigalg);
358 n = OBJ_obj2nid(calgoid);
359 if (!env_str(
"SSL_SERVER_A_SIG",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
363 pubkey = X509_get_X509_PUBKEY(
cert);
364 X509_PUBKEY_get0_param(&algoid,0,0,0,pubkey);
365 n = OBJ_obj2nid(algoid);
366 if (!env_str(
"SSL_SERVER_A_KEY",(n == NID_undef) ?
"UNKNOWN" : OBJ_nid2ln(n)))
369 bio = BIO_new(BIO_s_mem());
371 n = ssl_server_bio_vars(
cert,chain,bio);
382 if (!ssl_client_vars(SSL_get_certificate(ssl),0))
384 if (!ssl_server_vars(0,SSL_get_peer_cert_chain(ssl)))
392 if (!ssl_server_vars(SSL_get_certificate(ssl),0))
394 if (!ssl_server_vars(0,SSL_get_peer_cert_chain(ssl)))
Header file to be used with sqmail; previously called ssl.h. (name clash)
#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)