1 /* zxid/zxcrypto.c  -  Glue for cryptographical functions
2  * Copyright (c) 2015-2016 Synergetics NV (sampo@synergetics.be), All Rights Reserved.
3  * Copyright (c) 2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
4  * Copyright (c) 2006-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
5  * Author: Sampo Kellomaki (sampo@iki.fi)
6  * This is confidential unpublished proprietary source code of the author.
7  * NO WARRANTY, not even implied warranties. Contains trade secrets.
8  * Distribution prohibited unless authorized in writing.
9  * Licensed under Apache License 2.0, see file COPYING.
10  * $Id: zxcrypto.c,v 1.10 2009-11-24 23:53:40 sampo Exp $
11  *
12  * 7.10.2008, added documentation --Sampo
13  * 29.8.2009, added zxid_mk_self_signed_cert() --Sampo
14  * 12.12.2011, added HMAC SHA-256 as needed by JWT/JWS --Sampo
15  * 6.6.2015,   added aes-256-gcm --Sampo
16  * 16.10.2015, upgraded sha256 support, eliminated MD5 from certs --Sampo
17  *
18  * See paper: Tibor Jager, Kenneth G. Paterson, Juraj Somorovsky: "One Bad Apple: Backwards Compatibility Attacks on State-of-the-Art Cryptography", 2013 http://www.nds.ruhr-uni-bochum.de/research/publications/backwards-compatibility/ /t/BackwardsCompatibilityAttacks.pdf
19  *
20  * http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
21  * https://www.openssl.org/docs/crypto/EVP_EncryptInit.html#gcm_and_ocb_modes
22  */
23 
24 #include "platform.h"  /* needed on Win32 for snprintf() et al. */
25 
26 #include <zx/errmac.h>
27 #include <zx/zx.h>
28 #include <zx/zxid.h>
29 #include <zx/zxidutil.h>
30 #include <zx/c/zx-sa-data.h>
31 #include <string.h>
32 #include <sys/stat.h>  /* umask(2) */
33 
34 #ifdef USE_OPENSSL
35 #include <openssl/evp.h>
36 #include <openssl/md5.h>
37 #include <openssl/sha.h>
38 #include <openssl/hmac.h>
39 #include <openssl/rand.h>
40 #include <openssl/x509.h>
41 #include <openssl/x509v3.h>
42 #include <openssl/rsa.h>
43 #include <openssl/pem.h>
44 #endif
45 
46 /* Called by:  zxid_mk_jwt x2 */
47 char* zx_hmac_sha256(struct zx_ctx* c, int key_len, const char* key, int data_len, const char* data, char* md, int* md_len) {
48   return (char*)HMAC(EVP_sha256(), key, key_len, (unsigned char*)data, data_len, (unsigned char*)md, (unsigned int*)md_len);
49 }
50 
51 #if 0
52 /* Called by: */
53 struct zx_str* zx_hmac_sha1(struct zx_ctx* c, struct zx_str* key, struct zx_str* ss) {
54   HMAC(EVP_sha1(), key->s, key->len, ss->s, ss->len, md, mdlen);
55 
56   EVP_CIPHER_CTX *ctx;
57   EVP_CIPHER *type = EVP_des_cbc();
58 
59   int EVP_SealInit(ctx, type, char **ek, int *ekl, char *iv, EVP_PKEY **pubk, int npubk);
60   int EVP_SealUpdate(ctx, unsigned char *out, int *outl, unsigned char *in, int inl);
61   int EVP_SealFinal(ctx, unsigned char *out, int *outl);
62 }
63 
64 /* Following are macros in openssl headers so we need to define wrapper functions. */
65 
66 /* Called by: */
67 int zx_EVP_CIPHER_key_length(const EVP_CIPHER* cipher) { return EVP_CIPHER_key_length(cipher); }
68 int zx_EVP_CIPHER_iv_length(const EVP_CIPHER* cipher)  { return EVP_CIPHER_iv_length(cipher); }
69 int zx_EVP_CIPHER_block_size(const EVP_CIPHER* cipher) { return EVP_CIPHER_block_size(cipher); }
70 #endif
71 
72 /*() Get certificate signature algorithm string. This reads the
73  * signature algorithm from certificate itself.
74  * Returns something like "SHA1" or "SHA256" or "" on error.
75  */
76 
77 /* Called by:  */
78 const char* zxid_get_cert_signature_algo(X509* cert)
79 {
80     if (!cert)
81        return "";
82     return OBJ_nid2ln(OBJ_obj2nid(cert->sig_alg->algorithm));
83 }
84 
85 /*() zx_raw_digest2() computes a message digest over two items. The result
86  * is placed in buffer md, which must already be of length sufficient for
87  * the digest. md will not be nul terminated (and will usually have binary
88  * data). Possible algos: "SHA1", "SHA256", "SHA512", etc.
89  * zx_raw_raw_digest() expects an algorithm object instead of a string.
90  * Returns 0 on failure or length of the digest on success.  */
91 
92 int zx_raw_raw_digest2(struct zx_ctx* c, char* md, const EVP_MD* evp_digest, int len, const char* s, int len2, const char* s2)
93 {
94   char* where = "a";
95   EVP_MD_CTX* mdctx;
96   unsigned int mdlen;
97   mdctx = EVP_MD_CTX_create();
98 
99   if (!EVP_DigestInit_ex(mdctx, evp_digest, 0 /* engine */)) {
100     where = "EVP_DigestInit_ex()";
101     goto sslerr;
102   }
103 
104   if (len && s) {
105     if (!EVP_DigestUpdate(mdctx, s, len)) {
106       where = "EVP_DigestUpdate()";
107       goto sslerr;
108     }
109   }
110 
111   if (len2 && s2) {
112     if (!EVP_DigestUpdate(mdctx, s2, len2)) {
113       where = "EVP_DigestUpdate() 2";
114       goto sslerr;
115     }
116   }
117 
118   if(!EVP_DigestFinal_ex(mdctx, (unsigned char*)md, &mdlen)) {
119     where = "EVP_DigestFinal_ex()";
120     goto sslerr;
121   }
122   EVP_MD_CTX_destroy(mdctx);
123   return mdlen;
124 
125  sslerr:
126   zx_report_openssl_err(where);
127   EVP_MD_CTX_destroy(mdctx);
128   return 0;
129 }
130 
131 int zx_raw_digest2(struct zx_ctx* c, char* md, const char* algo, int len, const char* s, int len2, const char* s2)
132 {
133   const EVP_MD* evp_digest;
134   OpenSSL_add_all_digests();
135   evp_digest = EVP_get_digestbyname(algo);
136   return zx_raw_raw_digest2(c, md, evp_digest, len, s, len2, s2);
137 }
138 
139 /*() zx_EVP_DecryptFinal_ex() is a drop-in replacement for OpenSSL EVP_DecryptFinal_ex.
140  * It performs XML Enc compatible padding check.  See OpenSSL bug 1067
141  * http://rt.openssl.org/Ticket/Display.html?user=guest&;pass=guest&id=1067 */
142 
143 /* Called by:  zx_raw_cipher */
144 int zx_EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) {
145   int i,n;
146   unsigned int b;
147 
148   *outl=0;
149   b=ctx->cipher->block_size;
150   if (b > 1) {
151     if (ctx->buf_len || !ctx->final_used) {
152       //EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_WRONG_FINAL_BLOCK_LENGTH);
153       return(0);
154     }
155     ASSERTOPI(b, <=, sizeof ctx->final);
156     n=ctx->final[b-1];
157     if (n == 0 || n > (int)b) {
158       //EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
159       return(0);
160     }
161 
162     /* The padding used in XML Enc does not follow RFC 1423
163      * and is not supported by OpenSSL. The last padding byte
164      * is checked, but all other padding bytes are ignored
165      * and trimmed.
166      *
167      * [XMLENC] D. Eastlake, ed., XML Encryption Syntax and
168      * Processing, W3C Recommendation 10. Dec. 2002,
169      * www.w3.org/TR/2002/REC-xmlenc-core-20021210">http://www.w3.org/TR/2002/REC-xmlenc-core-20021210 */
170     if (ctx->final[b-1] != n) {
171       //EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
172       return(0);
173     }
174     n=ctx->cipher->block_size-n;
175     for (i=0; i<n; i++)
176       out[i]=ctx->final[i];
177     *outl=n;
178   } else
179     *outl=0;
180   return 1;
181 }
182 
183 //#define ZX_DEFAULT_IV "012345678901234567890123456789012345678901234567890123456789" /* 60 */
184 #define ZX_DEFAULT_IV   "ZX_DEFAULT_IV ZXID.ORG SAML 2.0 and Liberty ID-WSF by Sampo." /* 60 */
185 
186 /*() zx_raw_cipher() can encrypt and decrypt, based on encflag, using symmetic cipher algo.
187  * If encflag (==1) indicates encryption, the initialization vector will be prepended. */
188 
189 /* Called by:  zxenc_symkey_dec x4, zxenc_symkey_enc, zxid_psobj_dec, zxid_psobj_enc */
190 struct zx_str* zx_raw_cipher(struct zx_ctx* c, const char* algo, int encflag, struct zx_str* key, int len, const char* s, int iv_len, const char* iv)
191 {
192   const char* ivv;
193   char* where = "start";
194   struct zx_str* out;
195   int outlen=0, tmplen, alloclen;
196   const EVP_CIPHER* evp_cipher;
197   EVP_CIPHER_CTX ctx;
198   OpenSSL_add_all_algorithms();
199   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) hexdmp("plain  ", s, len, 256);
200   D("len=%d s=%p", len, s);
201   EVP_CIPHER_CTX_init(&ctx);
202   evp_cipher = EVP_get_cipherbyname(algo);
203   if (!evp_cipher) {
204     ERR("Cipher algo name(%s) not recognized by the crypto library (OpenSSL)", algo);
205     return 0;
206   }
207 
208   tmplen = EVP_CIPHER_iv_length(evp_cipher);
209   if (tmplen) {
210     if (iv) {
211       if (iv_len != tmplen) {
212 	ERR("iv len=%d does not match one required by cipher=%d", iv_len, tmplen);
213 	goto clean;
214       }
215       ivv = iv;
216     } else {
217       iv_len = tmplen;
218       ivv = ZX_DEFAULT_IV;
219       ASSERTOPI(EVP_MAX_IV_LENGTH, <=, sizeof(ZX_DEFAULT_IV));
220     }
221     if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) hexdmp("iv     ", ivv, iv_len, 1024);
222   } else
223     ivv = 0;
224   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) hexdmp("symkey ", key->s, key->len, 1024);
225 
226 #if 0
227   alloclen = EVP_CIPHER_block_size(evp_cipher);
228   alloclen = len + alloclen + alloclen;  /* bit pessimistic, but man EVP_CipherInit is ambiguous about the actual size needed. */
229 #else
230   /* 20150606, it appears aes-256-gcm reports too short block size, thus we impose a minimum. */
231   alloclen = EVP_CIPHER_block_size(evp_cipher);
232   D("block_size=%d", alloclen);
233   alloclen = MAX(alloclen, 256);
234   alloclen = len + alloclen + alloclen;  /* bit pessimistic, but man EVP_CipherInit is ambiguous about the actual size needed. */
235 #endif
236   if (encflag)
237     alloclen += iv_len;
238 
239   out = zx_new_len_str(c, alloclen);
240   D("alloclen=%d iv_len=%d encflag=%d out=%p iv=%p", alloclen, iv_len, encflag, out, iv);
241   if (!out) goto clean;
242   if (encflag)
243     memcpy(out->s, ivv, iv_len);
244   else
245     iv_len = 0;  /* When decrypting, the iv has already been stripped. */
246 
247   if (!EVP_CipherInit_ex(&ctx, evp_cipher, 0 /* engine */, (unsigned char*)key->s, (unsigned char*)ivv, encflag)) {
248     where = "EVP_CipherInit_ex()";
249     goto sslerr;
250   }
251 
252   if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->len)) {
253     D("key->len=%d", key->len);
254     where = "wrong key length for algorithm (block ciphers only accept keys of determined length)";
255     goto sslerr;
256   }
257 
258   if (!EVP_CipherUpdate(&ctx, (unsigned char*)out->s + iv_len, &outlen, (unsigned char*)s, len)) { /* Actual crypto happens here */
259     D("len=%d s=%p iv_len=%d outlen=%d out->s=%p", len, s, iv_len, outlen, out->s);
260     where = "EVP_CipherUpdate()";
261     goto sslerr;
262   }
263 
264   ASSERTOPI(outlen + iv_len, <=, alloclen);
265 
266 #if 0
267   if(!EVP_CipherFinal_ex(&ctx, (unsigned char*)out->s + iv_len + outlen, &tmplen)) {  /* Append final block */
268     where = "EVP_CipherFinal_ex()";
269     goto sslerr;
270   }
271 #else
272   /* Patch from Eric Rybski <rybskej@yahoo.com> */
273   if (encflag) {
274     if(!EVP_CipherFinal_ex(&ctx, (unsigned char*)out->s + iv_len + outlen, &tmplen)) { /* Append final block */
275       where = "EVP_CipherFinal_ex()";
276       goto sslerr;
277     }
278   } else {
279     /* Perform our own padding check, as XML Enc is not guaranteed compatible
280      * with OpenSSL & RFC 1423. See OpenSSL bug 1067
281      * http://rt.openssl.org/Ticket/Display.html?user=guest&;pass=guest&id=1067 */
282     EVP_CIPHER_CTX_set_padding(&ctx, 0);
283     if(!zx_EVP_DecryptFinal_ex(&ctx, (unsigned char*)out->s + iv_len + outlen, &tmplen)) { /* Append final block */
284       where = "zx_EVP_DecryptFinal_ex()";
285       goto sslerr;
286     }
287   }
288 #endif
289   EVP_CIPHER_CTX_cleanup(&ctx);
290 
291   outlen += tmplen;
292   ASSERTOPI(outlen + iv_len, <=, alloclen);
293   out->len = outlen + iv_len;
294   out->s[outlen + iv_len] = 0;  /* nul term */
295   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) hexdmp("cipher ", out->s, out->len, 256);
296   return out;
297 
298  sslerr:
299   D("where(%s)", where);
300   zx_report_openssl_err(where);
301  clean:
302   EVP_CIPHER_CTX_cleanup(&ctx);
303   return 0;
304 }
305 
306 /*() RSA public key encryption. See zx_get_rsa_pub_from_cert() for
307  * a way to obtain public key data structure.
308  * N.B. This function +only+ does the public key part. It does not
309  * perform combined enc-session-key-with-pub-key-and-then-data-with-session-key
310  * operation, though this function could be used as a component to implement
311  * such a system.
312  *
313  * This is considered a low level function. See zxenc_pubkey_enc() for a higher level solution. */
314 
315 /* Called by:  zxenc_pubkey_enc x2 */
316 struct zx_str* zx_rsa_pub_enc(struct zx_ctx* c, struct zx_str* plain, RSA* rsa_pkey, int pad)
317 {
318   struct zx_str* ciphered;
319   int ret, siz = RSA_size(rsa_pkey);
320 
321   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) {
322     D("pad=%d, RSA public key follows...", pad);
323     RSA_print_fp(ERRMAC_DEBUG_LOG, rsa_pkey, 0);
324   }
325 
326   switch (pad) {
327   case RSA_PKCS1_PADDING:
328   case RSA_SSLV23_PADDING:
329     if (plain->len > (siz-11))
330       ERR("Too much data for RSA key: can=%d, you have %d bytes.\n", siz-11, plain->len);
331     WARN("RSA_PKCS1_PADDING %d v1.5: WARNING: This padding is vulnearable to attacks. Use OAEP instead.", pad);
332     /* See paper: Tibor Jager, Kenneth G. Paterson, Juraj Somorovsky: "One Bad Apple: Backwards Compatibility Attacks on State-of-the-Art Cryptography", 2013 http://www.nds.ruhr-uni-bochum.de/research/publications/backwards-compatibility/ /t/BackwardsCompatibilityAttacks.pdf */
333     break;
334   case RSA_NO_PADDING:
335     if (plain->len > siz)
336       ERR("Too much data for RSA key: can=%d, you have %d bytes.\n", siz, plain->len);
337     break;
338   case RSA_PKCS1_OAEP_PADDING:
339     if (plain->len > (siz-41))
340       ERR("Too much data for RSA key: can=%d, you have %d bytes.\n", siz-41, plain->len);
341     break;
342   default: D("Illegal padding(%d). See `man 3 rsa'\n",pad);
343   }
344 
345   ciphered = zx_new_len_str(c, siz);
346   if (!ciphered)
347     return 0;
348   ret = RSA_public_encrypt(plain->len, (unsigned char*)plain->s, (unsigned char*)ciphered->s, rsa_pkey, pad);
349   if (siz != ret) {
350     D("RSA pub enc wrong ret=%d siz=%d\n",ret,siz);
351     zx_report_openssl_err("zx_pub_encrypt_rsa fail (${ret})");
352     return 0;
353   }
354   ASSERTOPI(ret, <=, siz);
355   ciphered->len = ret;
356   ciphered->s[ret] = 0;
357   return ciphered;
358 }
359 
360 /*() RSA public key decryption. See zx_get_rsa_pub_from_cert() for
361  * a way to obtain public key data structure. */
362 
363 /* Called by: */
364 struct zx_str* zx_rsa_pub_dec(struct zx_ctx* c, struct zx_str* ciphered, RSA* rsa_pkey, int pad)
365 {
366   struct zx_str* plain;
367   int ret, siz = RSA_size(rsa_pkey);
368   plain = zx_new_len_str(c, siz);
369   if (!plain)
370     return 0;
371   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) {
372     D("pad=%d, RSA public key follows...", pad);
373     RSA_print_fp(ERRMAC_DEBUG_LOG, rsa_pkey, 0);
374   }
375   ret = RSA_public_decrypt(ciphered->len, (unsigned char*)ciphered->s, (unsigned char*)plain->s, rsa_pkey, pad);
376   if (ret == -1) {
377     D("RSA public decrypt failed ret=%d len_cipher_data=%d",ret,ciphered->len);
378     zx_report_openssl_err("zx_public_decrypt_rsa fail");
379     return 0;
380   }
381   ASSERTOPI(ret, <=, siz);
382   plain->len = ret;
383   plain->s[ret] = 0;
384   return plain;
385 }
386 
387 /*() RSA private key decryption. See zxid_read_private_key() and zxid_extract_private_key()
388  * for ways to read in the private key data structure.
389  * N.B. This function +only+ does the private key part. It does not
390  * perform combined dec-session-key-with-priv-key-and-then-data-with-session-key
391  * operation, though this function could be used as a component to implement
392  * such a system.
393  *
394  * This is considered a low level function. See zxenc_privkey_dec() for a higher level solution. */
395 
396 /* Called by:  zxenc_privkey_dec x2 */
397 struct zx_str* zx_rsa_priv_dec(struct zx_ctx* c, struct zx_str* ciphered, RSA* rsa_pkey, int pad)
398 {
399   struct zx_str* plain;
400   int ret, siz = RSA_size(rsa_pkey);
401   plain = zx_new_len_str(c, siz);
402   if (!plain)
403     return 0;
404   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) {
405     D("pad=%d, RSA private key follows...", pad);
406     RSA_print_fp(ERRMAC_DEBUG_LOG, rsa_pkey, 0);
407   }
408   ret = RSA_private_decrypt(ciphered->len, (unsigned char*)ciphered->s, (unsigned char*)plain->s, rsa_pkey, pad);
409   if (ret == -1) {
410     D("RSA private decrypt failed ret=%d len_cipher_data=%d",ret,ciphered->len);
411     zx_report_openssl_err("zx_priv_decrypt_rsa fail");
412     return 0;
413   }
414   ASSERTOPI(ret, <=, siz);
415   plain->len = ret;
416   plain->s[ret] = 0;
417   return plain;
418 }
419 
420 /*() RSA private key encryption. See zxid_read_private_key() and zxid_extract_private_key()
421  * for ways to read in the private key data structure. */
422 
423 /* Called by: */
424 struct zx_str* zx_rsa_priv_enc(struct zx_ctx* c, struct zx_str* plain, RSA* rsa_pkey, int pad)
425 {
426   struct zx_str* ciphered;
427   int ret, siz = RSA_size(rsa_pkey);
428   ciphered = zx_new_len_str(c, siz);
429   if (!ciphered)
430     return 0;
431   if ((errmac_debug&ERRMAC_DEBUG_MASK) > 2) {
432     D("pad=%d, RSA private key follows...", pad);
433     RSA_print_fp(ERRMAC_DEBUG_LOG, rsa_pkey, 0);
434   }
435   ret = RSA_private_encrypt(plain->len, (unsigned char*)plain->s, (unsigned char*)ciphered->s, rsa_pkey, pad);
436   if (ret == -1) {
437     D("RSA private encrypt failed ret=%d len_plain=%d", ret, plain->len);
438     zx_report_openssl_err("zx_priv_encrypt_rsa fail");
439     return 0;
440   }
441   ASSERTOPI(ret, <=, siz);
442   ciphered->len = ret;
443   ciphered->s[ret] = 0;
444   return ciphered;
445 }
446 
447 /*() Obtain RSA public key from X509 certificate. The certificate must have been
448  * previously read into a data structure. See zxid_read_cert() and zxid_extract_cert() */
449 
450 /* Called by:  zxenc_pubkey_enc, zxlog_write_line */
451 RSA* zx_get_rsa_pub_from_cert(X509* cert, char* logkey)
452 {
453   EVP_PKEY* evp_pkey;
454   struct rsa_st* rsa_pkey;
455   evp_pkey = X509_get_pubkey(cert);
456   if (!evp_pkey) {
457     ERR("RSA enc: failed to get public key from certificate (perhaps you have not supplied any certificate, or it is corrupt or of wrong type) %s", logkey);
458     zx_report_openssl_err("zx_get_rsa_pub_from_cert");
459     return 0;
460   }
461   rsa_pkey = EVP_PKEY_get1_RSA(evp_pkey);
462   if (!rsa_pkey) {
463     ERR("RSA enc: failed to extract RSA get public key from certificate (perhaps you have not supplied any certificate, or it is corrupt or of wrong type) %s", logkey);
464     zx_report_openssl_err("zx_get_rsa_pub_from_cert");
465     return 0;
466   }
467   return rsa_pkey;
468 }
469 
470 /*() ZXID centralized hook for obtaning random numbers. This backends to
471  * OpenSSL random number gnerator and seeds from /dev/urandom where
472  * available. If you want to use /dev/random, which may block, you need
473  * to recompile with ZXID_TRUE_RAND set to true. */
474 
475 /* Called by: */
476 void zx_rand(char* buf, int n_bytes)
477 {
478 #ifdef USE_OPENSSL
479 #if ZXID_TRUE_RAND
480   RAND_bytes(buf, n_bytes);
481 #else
482   RAND_pseudo_bytes((unsigned char*)buf, n_bytes);
483 #endif
484 #else
485   ERR("ZXID was compiled without USE_OPENSSL. This means random number generation facilities are unavailable. Recompile ZXID or acknowledge that there is no security. n_rand_bytes=%d", n);
486 #endif
487 }
488 
489 /* Called by:  zxid_mk_at_cert x10, zxid_mk_self_sig_cert x7 */
490 static void zxid_add_name_field(X509_NAME* subj, int typ, int nid, char* val)
491 {
492   X509_NAME_ENTRY* ne;
493   if (!val || !*val)
494     return;
495   ne = X509_NAME_ENTRY_create_by_NID(0, nid, typ, (unsigned char*)val, strlen(val));
496   X509_NAME_add_entry(subj, ne, X509_NAME_entry_count(subj), 0);
497 }
498 
499 /*() Create Self-Signed Certificate-Private Key pair and Certificate Signing Request
500  * This function is invoked when AUTO_CERT is set and a certificate is missing.
501  * As this is not expected to be frequent, we are cavalier about releasing
502  * the memory needed for each intermediate step.
503  *
504  * cf:: zxid configuration object, of which cf->ctx will be used for memory allocation
505  * buflen:: sizeof(buf)
506  * buf:: Buffer used for rendering pem representations of the certificate
507  * log key:: Who and why is calling
508  * name:: Name of the certificate file to be created
509  * returns:: 0 on failure, 1 on success
510  *
511  * See also: keygen() in keygen.c */
512 
513 /* Called by: */
514 int zxid_mk_self_sig_cert(zxid_conf* cf, int buflen, char* buf, const char* lk, const char* name)
515 {
516 #ifdef USE_OPENSSL
517   BIO* wbio_cert;
518   BIO* wbio_pkey;
519   BIO* wbio_csr;
520   int len, lenq, um;
521   long cert_ser;
522   char*     p;
523   char*     q;
524   time_t    ts;
525   X509*     x509ss;
526   X509_REQ* req;
527   X509_REQ_INFO* ri;
528   EVP_PKEY* pkey;
529   EVP_PKEY* tmp_pkey;
530   RSA*      rsa;
531   X509_EXTENSION*  ext;
532   char      cn[256];
533   char      ou[256];
534 
535   X509V3_add_standard_extensions();
536 
537   D("keygen start lk(%s) name(%s)", lk, name);
538 
539   p = strstr(cf->burl, "://");
540   if (p) {
541     p += sizeof("://")-1;
542     len = strcspn(p, ":/");
543     if (len > sizeof(cn)-2)
544       len = sizeof(cn)-2;
545     memcpy(cn, p, len);
546     cn[len] = 0;
547   } else {
548     strcpy(cn, "Unknown server cn. Misconfiguration.");
549   }
550 
551 #if 0
552   /* On some CAs the OU can not exceed 30 chars  2         3
553    *                          123456789012345678901234567890 */
554   snprintf(ou, sizeof(ou)-1, "SSO Dept ZXID Auto-Cert %s", cf->burl);
555 #else
556   snprintf(ou, sizeof(ou)-1, "SSO Dept ZXID Auto-Cert");
557 #endif
558   ou[sizeof(ou)-1] = 0;  /* must terminate manually as on win32 termination is not guaranteed */
559 
560   ts = time(0);
561   RAND_seed(&ts,sizeof(ts));
562 #ifdef WINDOWS
563   RAND_screen(); /* Loading video display memory into random state */
564 #endif
565 
566   /* Here's the beef: Generate keypair */
567 
568   pkey=EVP_PKEY_new();
569   DD("keygen preparing rsa key %s", lk);
570 #if 0
571   rsa = RSA_generate_key(1024 /*bits*/, 0x10001 /*65537*/, 0 /*req_cb*/, 0 /*arg*/);
572 #else
573   /* Crypto analysis (2015) suggests 1024bit key is too weak. */
574   rsa = RSA_generate_key(2048 /*bits*/, 0x10001 /*65537*/, 0 /*req_cb*/, 0 /*arg*/);
575 #endif
576   DD("keygen rsa key generated %s", name);
577   EVP_PKEY_assign_RSA(pkey, rsa);
578 
579 #if 0
580   /* Key generation is a big operation. Write in the new random state. */
581   t = time(0);
582   RAND_seed(&t,sizeof(t));
583   RAND_write_file(randomfile);
584 #endif
585 
586   /* Now handle the public key part, i.e. create self signed and
587    * certificate request. This starts by making a request that
588    * contains all relevant fields.   */
589 
590   req=X509_REQ_new();
591   ri=req->req_info;
592 
593   DD("keygen populate: set version %d (real vers is one higher)", 2);
594   ASN1_INTEGER_set(ri->version, 2L /* version 3 (binary value is one less) */);
595 
596 #if 0 /* See cn code above */
597   /* Parse domain name out of the URL: skip https:// and then scan name without port or path */
598 
599   for (p = cf->burl; !ONE_OF_2(*p, '/', 0); ++p) ;
600   if (*p != '/') goto badurl;
601   ++p;
602   if (*p != '/') {
603 badurl:
604     ERR("Malformed URL: does not start by https:// or http:// -- URL(%s)", cf->burl);
605     return 0;
606   }
607   ++p;
608   for (q = cn; !ONE_OF_3(*p, ':', '/', 0) && q < cn + sizeof(cn)-1; ++q, ++p) *q = *p;
609   *q = 0;
610 
611   D("keygen populate DN: cn(%s) org(%s) c(%s) url=%p cn=%p p=%p q=%p", cn, cf->org_name, cf->country, cf->burl, cn, p, q);
612 #endif
613 
614   /* Note on string types and allowable char sets:
615    * V_ASN1_PRINTABLESTRING  [A-Za-z0-9 '()+,-./:=?]   -- Any domain name, but not query string
616    * V_ASN1_IA5STRING        Any 7bit string
617    * V_ASN1_T61STRING        8bit string   */
618 
619   /* Construct DN part by part. We want cn=www.site.com,o=ZXID Auto-Cert */
620 
621   if (cf->contact_email)
622     zxid_add_name_field(ri->subject, V_ASN1_IA5STRING, NID_pkcs9_emailAddress, cf->contact_email);
623   zxid_add_name_field(ri->subject, V_ASN1_PRINTABLESTRING, NID_commonName, cn);
624   zxid_add_name_field(ri->subject, V_ASN1_T61STRING, NID_organizationalUnitName, ou);
625   zxid_add_name_field(ri->subject, V_ASN1_T61STRING, NID_organizationName, cf->org_name);
626 
627   zxid_add_name_field(ri->subject, V_ASN1_T61STRING, NID_localityName, cf->locality);
628   zxid_add_name_field(ri->subject, V_ASN1_T61STRING, NID_stateOrProvinceName, cf->state);
629   zxid_add_name_field(ri->subject, V_ASN1_T61STRING, NID_countryName, cf->country);
630 
631 #if 0
632   X509_ATTRIBUTE*  xa;
633   ASN1_BIT_STRING* bs;
634   ASN1_TYPE* at;
635 
636   /* It seems this gives indigestion to the default CA */
637   DD("keygen populate attributes %s", lk);  /* Add attributes: we really only need cn */
638 
639   xa = X509_ATTRIBUTE_new();
640   xa->value.set = sk_ASN1_TYPE_new_null();
641   /*xa->single = 1; **** this may also be set on some versions */
642   xa->object=OBJ_nid2obj(NID_commonName);
643 
644   bs = ASN1_BIT_STRING_new();
645   bs->type = V_ASN1_PRINTABLESTRING;
646   ASN1_STRING_set(bs, cn, strlen(cn)+1);  /* *** +1 why? Some archaic bug work-around? */
647 
648   at = ASN1_TYPE_new();
649   ASN1_TYPE_set(at, bs->type, (char*)bs);
650   sk_ASN1_TYPE_push(xa->value.set, at);
651   sk_X509_ATTRIBUTE_push(ri->attributes, xa);
652 #endif
653 
654   DD("keygen request populated %s", lk);
655   X509_REQ_set_pubkey(req, pkey);
656   /*req->req_info->req_kludge=0;    / * no asn1 kludge *** filed deleted as of 0.9.7b?!? */
657 
658   DD("keygen signing request %s", lk);
659 #if 0
660   X509_REQ_sign(req, pkey, EVP_md5());
661 #else
662   /* Due to recent (2013) progress in crypto analysis, MD5 and SHA1 are considered
663    * weak and support is likely to be discontinued in browsers and operating systems. */
664   X509_REQ_sign(req, pkey, EVP_sha256());
665 #endif
666 
667   /* ----- X509 create self signed certificate ----- */
668 
669   DD("keygen making x509ss %s", lk);
670   x509ss = X509_new();
671   X509_set_version(x509ss, 2); /* Set version to V3 and serial number to zero */
672   zx_rand((char*)&cert_ser, 4);
673   ASN1_INTEGER_set(X509_get_serialNumber(x509ss), cert_ser);
674   DD("keygen setting various x509ss fields %s", lk);
675 
676   X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req));
677 #if 1
678   ASN1_TIME_set(X509_get_notBefore(x509ss),0);
679   ASN1_TIME_set(X509_get_notAfter(x509ss), 0x7fffffffL); /* The end of the 32 bit Unix epoch */
680 #else
681   X509_gmtime_adj(X509_get_notBefore(x509ss),0);
682   X509_gmtime_adj(X509_get_notAfter(x509ss), 0x7fffffffL); /* The end of the 32 bit Unix epoch */
683 #endif
684   X509_set_subject_name(x509ss,	X509_REQ_get_subject_name(req));
685 
686   DD("keygen setting x509ss pubkey %s", lk);
687   tmp_pkey =X509_REQ_get_pubkey(req);
688   X509_set_pubkey(x509ss, tmp_pkey);
689   EVP_PKEY_free(tmp_pkey);
690 
691   /* Set up V3 context struct and add certificate extensions. Note
692    * that we need to add (full) suite of CA extensions, otherwise
693    * our cert is not valid for signing itself. */
694 
695   ext = X509V3_EXT_conf_nid(0, 0, NID_basic_constraints, "CA:TRUE,pathlen:3");
696   X509_add_ext(x509ss, ext, -1);
697 
698   ext = X509V3_EXT_conf_nid(0, 0, NID_netscape_cert_type, "client,server,email,objsign,sslCA,emailCA,objCA");
699   X509_add_ext(x509ss, ext, -1);
700 
701   ext = X509V3_EXT_conf_nid(0, 0, NID_key_usage, "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign");
702   X509_add_ext(x509ss, ext, -1);
703 
704   ext = X509V3_EXT_conf_nid(0, 0, NID_netscape_comment, "Auto-Cert, see zxid.org");
705   X509_add_ext(x509ss, ext, -1);
706 
707   DD("keygen signing x509ss %s", lk);
708 #if 0
709   if (!(X509_sign(x509ss, pkey, EVP_md5())))
710 #else
711   if (!(X509_sign(x509ss, pkey, EVP_sha256())))
712 #endif
713   {
714     ERR("Failed to sign x509ss %s", lk);
715     zx_report_openssl_err("X509_sign");
716     return 0;
717   }
718   DD("keygen x509ss ready %s", lk);
719 
720   /* ----- Output phase ----- */
721 
722   um = umask(0077);  /* Key material should be readable only by owner */
723 
724   wbio_csr = BIO_new(BIO_s_mem());
725   DD("write_csr %s", lk);
726   if (!PEM_write_bio_X509_REQ(wbio_csr, req)) {
727     ERR("write_csr %s", lk);
728     zx_report_openssl_err("write_csr");
729     return 0;
730   }
731   len = BIO_get_mem_data(wbio_csr, &p);
732 
733   write_all_path("auto_cert csr", "%s" ZXID_PEM_DIR "csr-%s", cf->cpath, name, len, p);
734   BIO_free_all(wbio_csr);
735 
736   /* Output combined self signed plus private key file. It is important
737    * that this happens after csr so that buf is left with this data
738    * so that the caller can then parse it. */
739 
740   wbio_cert = BIO_new(BIO_s_mem());
741   DD("write_cert %s", lk);
742   if (!PEM_write_bio_X509(wbio_cert, x509ss)) {
743     ERR("write_cert %s", lk);
744     zx_report_openssl_err("write_cert");
745     return 0;
746   }
747   len = BIO_get_mem_data(wbio_cert, &p);
748 
749   wbio_pkey = BIO_new(BIO_s_mem());
750   DD("write_private_key %s", lk);
751   if (!PEM_write_bio_PrivateKey(wbio_pkey, pkey, 0,0,0,0,0)) {
752     ERR("write_private_key %s", lk);
753     zx_report_openssl_err("write_private_key");
754     return 0;
755   }
756   lenq = BIO_get_mem_data(wbio_pkey, &q);
757 
758   write_all_path_fmt("auto_cert ss", buflen, buf,
759 		     "%s" ZXID_PEM_DIR "%s", cf->cpath, name,
760 		     "%.*s%.*s", len, p, lenq, q);
761 
762   BIO_free_all(wbio_cert);
763   BIO_free_all(wbio_pkey);
764 
765   umask(um);
766 
767   EVP_PKEY_free(pkey);
768   X509_REQ_free(req);
769   X509_free(x509ss);
770   X509V3_EXT_cleanup();
771   OBJ_cleanup();
772 
773   zxlog(cf, 0, 0, 0, 0, 0, 0, 0, 0, "K", "KEYGEN", name, 0);
774   D("keygen done. %s", lk);
775   return 1;
776 #else
777   ERR("ZXID was compiled without USE_OPENSSL. This means self signed certificate generation facility is unavailable. Recompile ZXID. %s", lk);
778   return 0;
779 #endif
780 }
781 
782 #if 0
783 /* use PEM_write_X509(fp, cert) instead! */
784 /* Called by: */
785 void zx_print_X509(FILE* fp, X509* cert)
786 {
787   int len;
788   char* p;
789   BIO* wbio_cert = BIO_new(BIO_s_mem());
790   if (!PEM_write_bio_X509(wbio_cert, peer_cert)) {
791     ERR("write_cert %p", peer_cert);
792     zx_report_openssl_err("write_cert");
793     return;
794   }
795   len = BIO_get_mem_data(wbio_cert, &p);
796   fprintf(fp, "%.*s", len, p);
797 }
798 #endif
799 
800 /*
801 
802 A Practical Approach of X.509 Attribute Certificate Framework as Support to Obtain Privilege Delegation
803 Jose A. Montenegro and Fernando Moya
804 Computer Science Department, E.T.S. Ingenieria Informatica, Universidad de Malage, Spain
805 Lecture Notes in Computer Science, 2004, Volume 3093/2004, 624, DOI: 10.1007/978-3-540-25980-0_13
806 
807  Abstract This work introduces a particular implementation of the
808 X.509 Attribute Certificate framework (Xac), presented in the ITU-T
809 Recommendation. The implementation is based on the use of the Openssl
810 library, that we have chosen for its advantages in comparison with
811 other libraries. The paper also describes how the implementation is
812 middleware-oriented, focusing on the delegation model specified by
813 ITU-T proposal, and taking into consideration the ETSI report about
814 Xac.
815 
816 RFC3281
817 http://tools.ietf.org/html/draft-ietf-pkix-3281update-05
818 
819 */
820 
821 /*() Create X509 attribute certificate for one attribute and user specified by nameid (pseudonym)
822  *
823  * cf:: zxid configuration object, of which cf->ctx will be used for memory allocation
824  * buflen:: sizeof(buf)
825  * buf:: Buffer used for rendering pem representation of the certificate
826  * log key:: Who and why is calling
827  * nameid:: Name of the subject
828  * name:: Name of the attribute in certificate
829  * val:: Value of the attribute in certificate
830  * returns:: 0 on failure, 1 on success
831  */
832 
833 /* Called by:  x509_test, zxid_map_val_ss */
834 int zxid_mk_at_cert(zxid_conf* cf, int buflen, char* buf, const char* lk, zxid_nid* nameid, const char* name, struct zx_str* val)
835 {
836 #ifdef USE_OPENSSL
837   BIO*   wbio_cert;
838   int    len;
839   long   cert_ser;
840   char*  p;
841   time_t ts;
842   X509*  x509ss;
843   X509_NAME* issuer;
844   X509_NAME* subject;
845   X509_EXTENSION*  ext;
846   X509*  sign_cert;
847   EVP_PKEY* sign_pkey;
848   char   cn[256];
849   char   ou[256];
850 
851   X509V3_add_standard_extensions();
852 
853   D("keygen start lk(%s) name(%s)", lk, name);
854 
855   p = strstr(cf->burl, "://");
856   if (p) {
857     p += sizeof("://")-1;
858     len = strcspn(p, ":/");
859     if (len > sizeof(cn)-2)
860       len = sizeof(cn)-2;
861     memcpy(cn, p, len);
862     cn[len] = 0;
863   } else {
864     strcpy(cn, "Unknown server cn. Misconfiguration.");
865   }
866 
867   snprintf(ou, sizeof(ou)-1, "SSO Dept ZXID Auto-Cert %s", cf->burl);
868   ou[sizeof(ou)-1] = 0;  /* must terminate manually as on win32 termination is not guaranteed */
869 
870   ts = time(0);
871   RAND_seed(&ts,sizeof(ts));
872 #ifdef WINDOWS
873   RAND_screen(); /* Loading video display memory into random state */
874 #endif
875 
876   //ASN1_INTEGER_set(ri->version, 2L /* version 3 (binary value is one less) */);
877 
878   /* Note on string types and allowable char sets:
879    * V_ASN1_PRINTABLESTRING  [A-Za-z0-9 '()+,-./:=?]   -- Any domain name, but not query string
880    * V_ASN1_IA5STRING        Any 7bit string
881    * V_ASN1_T61STRING        8bit string   */
882 
883   issuer = X509_NAME_new();
884   subject = X509_NAME_new();
885 
886   /* Construct DN part by part. We want cn=www.site.com,o=ZXID Auto-Cert */
887 
888   zxid_add_name_field(issuer, V_ASN1_PRINTABLESTRING, NID_commonName, cn);
889   zxid_add_name_field(issuer, V_ASN1_T61STRING, NID_organizationalUnitName, ou);
890   zxid_add_name_field(issuer, V_ASN1_T61STRING, NID_organizationName, cf->org_name);
891 
892   zxid_add_name_field(issuer, V_ASN1_T61STRING, NID_localityName, cf->locality);
893   zxid_add_name_field(issuer, V_ASN1_T61STRING, NID_stateOrProvinceName, cf->state);
894   zxid_add_name_field(issuer, V_ASN1_T61STRING, NID_countryName, cf->country);
895 
896   /* Construct Subject part by part. */
897 
898   if (nameid) {
899     zxid_add_name_field(subject, V_ASN1_PRINTABLESTRING, NID_commonName,
900 			zx_str_to_c(cf->ctx, ZX_GET_CONTENT(nameid)));
901     zxid_add_name_field(subject, V_ASN1_T61STRING, NID_organizationalUnitName,
902 			zx_str_to_c(cf->ctx, &nameid->SPNameQualifier->g));  /* SP */
903     zxid_add_name_field(subject, V_ASN1_T61STRING, NID_organizationName,
904 			zx_str_to_c(cf->ctx, &nameid->NameQualifier->g));    /* IdP */
905   } else {
906     zxid_add_name_field(subject, V_ASN1_PRINTABLESTRING, NID_commonName, "unspecified-see-zxid_mk_at_cert");
907   }
908 
909   /* ----- Create X509 certificate ----- */
910 
911   x509ss = X509_new();
912   X509_set_version(x509ss, 2); /* Set version to V3 and serial number to zero */
913   zx_rand((char*)&cert_ser, 4);
914   ASN1_INTEGER_set(X509_get_serialNumber(x509ss), cert_ser);
915 
916   X509_set_issuer_name(x509ss, issuer);
917 #if 1
918   ASN1_TIME_set(X509_get_notBefore(x509ss),0);
919   ASN1_TIME_set(X509_get_notAfter(x509ss), 0x7fffffffL); /* The end of the 32 bit Unix epoch */
920 #else
921   X509_gmtime_adj(X509_get_notBefore(x509ss),0);
922   X509_gmtime_adj(X509_get_notAfter(x509ss), 0x7fffffffL); /* The end of the 32 bit Unix epoch */
923 #endif
924   X509_set_subject_name(x509ss,	subject);
925 
926 #if 0 /* *** schedule to remove */
927   /* Set up V3 context struct and add certificate extensions. */
928 
929   ext = X509V3_EXT_conf_nid(0, 0, NID_basic_constraints, "CA:TRUE,pathlen:3");
930   X509_add_ext(x509ss, ext, -1);
931 
932   ext = X509V3_EXT_conf_nid(0, 0, NID_netscape_cert_type, "client,server,email,objsign,sslCA,emailCA,objCA");
933   X509_add_ext(x509ss, ext, -1);
934 
935   ext = X509V3_EXT_conf_nid(0, 0, NID_key_usage, "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign");
936   X509_add_ext(x509ss, ext, -1);
937 #endif
938 
939   ext = X509V3_EXT_conf_nid(0, 0, NID_netscape_comment, "Attribute cert, see zxid.org");
940   X509_add_ext(x509ss, ext, -1);
941 
942 #if 0
943   X509_ATTRIBUTE*  xa;
944   ASN1_BIT_STRING* bs;
945   ASN1_TYPE* at;
946 
947   /* It seems this gives indigestion to the default CA */
948   DD("keygen populate attributes %s", lk);  /* Add attributes: we really only need cn */
949 
950   xa = X509_ATTRIBUTE_new();
951   xa->value.set = sk_ASN1_TYPE_new_null();
952   /*xa->single = 1; **** this may also be set on some versions */
953   xa->object=OBJ_nid2obj(NID_commonName);
954 
955   bs = ASN1_BIT_STRING_new();
956   bs->type = V_ASN1_PRINTABLESTRING;
957   ASN1_STRING_set(bs, cn, strlen(cn)+1);  /* *** +1 why? Some archaic bug work-around? */
958 
959   at = ASN1_TYPE_new();
960   ASN1_TYPE_set(at, bs->type, (char*)bs);
961   sk_ASN1_TYPE_push(xa->value.set, at);
962   sk_X509_ATTRIBUTE_push(ri->attributes, xa);
963   STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, X509_ATTRIBUTE *attr);
964 
965   /* *** Exactly where on x509ss are the attributes supposed to attach?!? */
966 #endif
967 
968   zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "mk_at_cert");
969 
970   DD("keygen signing x509ss %s", lk);
971 #if 0
972   if (!(X509_sign(x509ss, sign_pkey, EVP_md5())))
973 #else
974   if (!(X509_sign(x509ss, sign_pkey, EVP_sha256())))
975 #endif
976   {
977     ERR("Failed to sign x509ss %s", lk);
978     zx_report_openssl_err("X509_sign");
979     return 0;
980   }
981   DD("keygen x509ss ready %s", lk);
982 
983   /* ----- Output phase ----- */
984 
985   wbio_cert = BIO_new(BIO_s_mem());
986   DD("write_cert %s", lk);
987   if (!PEM_write_bio_X509(wbio_cert, x509ss)) {
988     ERR("write_cert %s", lk);
989     zx_report_openssl_err("write_cert");
990     return 0;
991   }
992   len = BIO_get_mem_data(wbio_cert, &p);
993   memcpy(buf, p, MIN(len, buflen-1));
994   buf[MIN(len, buflen-1)] = 0;
995 
996   //***write_all_path("auto_cert ss", "%s" ZXID_PEM_DIR "%s", cf->cpath, name, len, p);
997 
998   BIO_free_all(wbio_cert);
999 
1000   X509_free(x509ss);
1001   X509V3_EXT_cleanup();
1002   OBJ_cleanup();
1003 
1004   zxlog(cf, 0, 0, 0, 0, 0, 0, 0, 0, "K", "X509ATCERT", name, 0);
1005   D("at cert done. %s", lk);
1006   return 1;
1007 #else
1008   ERR("ZXID was compiled without USE_OPENSSL. This means X509 attribute certificate generation facility is unavailable. Recompile ZXID. %s", lk);
1009   return 0;
1010 #endif
1011 }
1012 
1013 /* Adapted by Sampo from FreeBSD md5_crypt.c, which is licensed as follows
1014  * ----------------------------------------------------------------------------
1015  * "THE BEER-WARE LICENSE" (Revision 42):
1016  * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
1017  * can do whatever you want with this stuff. If we meet some day, and you think
1018  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
1019  * ----------------------------------------------------------------------------
1020  */
1021 
1022 extern char pw_basis_64[64];
1023 
1024 /* Called by:  add_password, zx_md5_crypt x6 */
1025 static void to64(char *s, unsigned long v, int n) {
1026   while (--n >= 0) {
1027     *s++ = pw_basis_64[v & 0x3f];
1028     v >>= 6;
1029   }
1030 }
1031 
1032 /*() Compute MD5-Crypt password hash (starts by \$1\$)
1033  *
1034  * pw:: Password in plain
1035  * salt:: 0-8 chars of salt. Preceding \$1\$ is automatically skipped. Salt ends in \$ or nul.
1036  * buf:: must be at least 120 chars
1037  * return:: buf, nul terminated */
1038 
1039 /* Called by:  authn_user, main, zx_pw_chk */
1040 char* zx_md5_crypt(const char* pw, const char* salt, char* buf)
1041 {
1042   const char* magic = "$1$";    /* magic prefix to identify algo */
1043   char* p;
1044   const char *sp, *ep;
1045   unsigned char final[16];
1046   int sl, pl, i, j;
1047   MD5_CTX ctx, ctx1;
1048   unsigned long l;
1049 
1050   /* Refine the Salt first */
1051   sp = salt;
1052 
1053   /* If it starts with the magic string, then skip that */
1054   if (!strncmp(sp, magic, strlen(magic)))
1055     sp += strlen(magic);
1056 
1057   /* It stops at the first '$', max 8 chars */
1058   for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) ;
1059   sl = ep - sp;  /* get the length of the true salt */
1060 
1061   MD5_Init(&ctx);
1062   MD5_Update(&ctx, (unsigned const char *)pw, strlen(pw));       /* pw 1st, as it's most unknown */
1063   MD5_Update(&ctx, (unsigned const char *)magic, strlen(magic)); /* Then our magic string */
1064   MD5_Update(&ctx, (unsigned const char *)sp, sl);               /* Then the raw salt */
1065 
1066   /* Then just as many characters of the MD5(pw,salt,pw) */
1067   MD5_Init(&ctx1);
1068   MD5_Update(&ctx1, (unsigned const char *)pw, strlen(pw));
1069   MD5_Update(&ctx1, (unsigned const char *)sp, sl);
1070   MD5_Update(&ctx1, (unsigned const char *)pw, strlen(pw));
1071   MD5_Final(final, &ctx1);
1072   for (pl = strlen(pw); pl > 0; pl -= 16)
1073     MD5_Update(&ctx, (unsigned const char *)final, pl>16 ? 16 : pl);
1074 
1075   ZERO(final, sizeof(final)); /* Don't leave anything around in vm they could use. */
1076 
1077   /* Then something really weird... */
1078   for (j = 0, i = strlen(pw); i; i >>= 1)
1079     if (i & 1)
1080       MD5_Update(&ctx, (unsigned const char *)final+j, 1);
1081     else
1082       MD5_Update(&ctx, (unsigned const char *)pw+j, 1);
1083 
1084   strcpy(buf, magic);   /* Start the output string */
1085   strncat(buf, sp, sl);
1086   strcat(buf, "$");
1087 
1088   MD5_Final(final, &ctx);
1089 
1090   /* and now, just to make sure things don't run too fast
1091    * On a 60 Mhz Pentium this takes 34 msec, so you would
1092    * need 30 seconds to build a 1000 entry dictionary... */
1093   for (i = 0; i < 1000; i++) {
1094     MD5_Init(&ctx1);
1095     if (i & 1)
1096       MD5_Update(&ctx1, (unsigned const char *)pw, strlen(pw));
1097     else
1098       MD5_Update(&ctx1, (unsigned const char *)final, 16);
1099 
1100     if (i % 3)
1101       MD5_Update(&ctx1, (unsigned const char *)sp, sl);
1102 
1103     if (i % 7)
1104       MD5_Update(&ctx1, (unsigned const char *)pw, strlen(pw));
1105 
1106     if (i & 1)
1107       MD5_Update(&ctx1, (unsigned const char *)final, 16);
1108     else
1109       MD5_Update(&ctx1, (unsigned const char *)pw, strlen(pw));
1110     MD5_Final(final, &ctx1);
1111   }
1112 
1113   p = buf + strlen(buf);
1114 
1115   l = (final[0] << 16) | (final[6] << 8) | final[12];  to64(p, l, 4);  p += 4;
1116   l = (final[1] << 16) | (final[7] << 8) | final[13];  to64(p, l, 4);  p += 4;
1117   l = (final[2] << 16) | (final[8] << 8) | final[14];  to64(p, l, 4);  p += 4;
1118   l = (final[3] << 16) | (final[9] << 8) | final[15];  to64(p, l, 4);  p += 4;
1119   l = (final[4] << 16) | (final[10] << 8) | final[5];  to64(p, l, 4);  p += 4;
1120   l = final[11];                                       to64(p, l, 2);  p += 2;
1121   *p = '\0';
1122 
1123   ZERO(final, sizeof(final)); /* Don't leave anything around in vm they could use. */
1124   return buf;
1125 }
1126 
1127 /* EOF  -  zxcrypto.c */
1128