From 1c98a87f0daac81245653c227eb2f2508a22a965 Mon Sep 17 00:00:00 2001 From: markus <> Date: Sun, 11 May 2003 21:36:58 +0000 Subject: import 0.9.7b (without idea and rc5) --- src/lib/libcrypto/aes/aes.h | 9 +- src/lib/libcrypto/aes/aes_cbc.c | 58 ++- src/lib/libcrypto/aes/aes_cfb.c | 6 + src/lib/libcrypto/aes/aes_core.c | 12 +- src/lib/libcrypto/aes/aes_ctr.c | 21 +- src/lib/libcrypto/aes/aes_ecb.c | 6 + src/lib/libcrypto/aes/aes_locl.h | 2 +- src/lib/libcrypto/aes/aes_ofb.c | 6 + src/lib/libcrypto/asn1/a_bitstr.c | 4 +- src/lib/libcrypto/asn1/a_bytes.c | 2 +- src/lib/libcrypto/asn1/a_d2i_fp.c | 24 +- src/lib/libcrypto/asn1/a_object.c | 4 +- src/lib/libcrypto/asn1/a_sign.c | 8 +- src/lib/libcrypto/asn1/a_strex.c | 14 +- src/lib/libcrypto/asn1/a_strnid.c | 35 ++ src/lib/libcrypto/asn1/a_time.c | 5 +- src/lib/libcrypto/asn1/a_type.c | 2 +- src/lib/libcrypto/asn1/a_verify.c | 4 +- src/lib/libcrypto/asn1/asn1.h | 5 +- src/lib/libcrypto/asn1/asn1_err.c | 4 +- src/lib/libcrypto/asn1/asn1_par.c | 7 +- src/lib/libcrypto/asn1/f_int.c | 3 +- src/lib/libcrypto/asn1/n_pkey.c | 6 +- src/lib/libcrypto/asn1/p8_pkey.c | 4 +- src/lib/libcrypto/asn1/t_crl.c | 7 +- src/lib/libcrypto/asn1/t_pkey.c | 32 +- src/lib/libcrypto/asn1/t_req.c | 18 +- src/lib/libcrypto/asn1/t_x509.c | 9 +- src/lib/libcrypto/asn1/t_x509a.c | 4 +- src/lib/libcrypto/asn1/tasn_dec.c | 4 +- src/lib/libcrypto/asn1/tasn_fre.c | 5 +- src/lib/libcrypto/asn1/tasn_new.c | 5 +- src/lib/libcrypto/asn1/tasn_prn.c | 2 +- src/lib/libcrypto/bio/b_print.c | 29 +- src/lib/libcrypto/bio/b_sock.c | 16 +- src/lib/libcrypto/bio/bf_buff.c | 2 +- src/lib/libcrypto/bio/bio.h | 7 +- src/lib/libcrypto/bio/bio_lib.c | 15 +- src/lib/libcrypto/bio/bss_bio.c | 3 +- src/lib/libcrypto/bio/bss_conn.c | 4 +- src/lib/libcrypto/bio/bss_file.c | 2 +- src/lib/libcrypto/bio/bss_log.c | 13 +- src/lib/libcrypto/bio/bss_mem.c | 8 +- src/lib/libcrypto/bio/bss_sock.c | 6 + src/lib/libcrypto/bn/asm/ia64.S | 235 ++++++--- src/lib/libcrypto/bn/asm/pa-risc2.s | 36 +- src/lib/libcrypto/bn/asm/x86_64-gcc.c | 575 +++++++++++++++++++++ src/lib/libcrypto/bn/bn.h | 2 + src/lib/libcrypto/bn/bn_div.c | 28 +- src/lib/libcrypto/bn/bn_lcl.h | 26 +- src/lib/libcrypto/bn/bn_lib.c | 4 +- src/lib/libcrypto/bn/bn_mul.c | 529 +++---------------- src/lib/libcrypto/bn/bn_prime.c | 2 +- src/lib/libcrypto/bn/bn_rand.c | 2 +- src/lib/libcrypto/bn/bn_word.c | 5 +- src/lib/libcrypto/buffer/buffer.c | 57 ++ src/lib/libcrypto/buffer/buffer.h | 9 + src/lib/libcrypto/comp/c_zlib.c | 4 +- src/lib/libcrypto/conf/conf_def.c | 18 +- src/lib/libcrypto/conf/conf_mall.c | 4 + src/lib/libcrypto/conf/conf_sap.c | 4 + src/lib/libcrypto/cryptlib.c | 40 +- src/lib/libcrypto/cryptlib.h | 6 +- src/lib/libcrypto/crypto.h | 65 ++- src/lib/libcrypto/des/asm/crypt586.pl | 46 +- src/lib/libcrypto/des/asm/des-586.pl | 50 +- src/lib/libcrypto/des/cbc_cksm.c | 9 + src/lib/libcrypto/des/des.h | 4 +- src/lib/libcrypto/des/des_locl.h | 13 +- src/lib/libcrypto/des/str2key.c | 4 +- src/lib/libcrypto/dh/dh_key.c | 1 - src/lib/libcrypto/dh/dh_lib.c | 10 + src/lib/libcrypto/doc/DH_generate_key.pod | 2 +- src/lib/libcrypto/doc/DH_generate_parameters.pod | 3 +- src/lib/libcrypto/doc/DH_new.pod | 2 +- src/lib/libcrypto/doc/DSA_SIG_new.pod | 3 +- src/lib/libcrypto/doc/DSA_do_sign.pod | 2 +- src/lib/libcrypto/doc/DSA_dup_DH.pod | 2 +- src/lib/libcrypto/doc/DSA_generate_key.pod | 3 +- src/lib/libcrypto/doc/DSA_generate_parameters.pod | 2 +- src/lib/libcrypto/doc/DSA_new.pod | 2 +- src/lib/libcrypto/doc/DSA_sign.pod | 2 +- src/lib/libcrypto/doc/ERR_get_error.pod | 2 +- src/lib/libcrypto/doc/EVP_EncryptInit.pod | 2 +- src/lib/libcrypto/doc/EVP_PKEY_new.pod | 47 ++ src/lib/libcrypto/doc/EVP_PKEY_set1_RSA.pod | 80 +++ src/lib/libcrypto/doc/EVP_SealInit.pod | 26 +- src/lib/libcrypto/doc/OBJ_nid2obj.pod | 149 ++++++ src/lib/libcrypto/doc/PKCS12_create.pod | 57 ++ src/lib/libcrypto/doc/PKCS12_parse.pod | 50 ++ src/lib/libcrypto/doc/PKCS7_decrypt.pod | 53 ++ src/lib/libcrypto/doc/PKCS7_encrypt.pod | 65 +++ src/lib/libcrypto/doc/PKCS7_sign.pod | 85 +++ src/lib/libcrypto/doc/PKCS7_verify.pod | 116 +++++ src/lib/libcrypto/doc/RAND_bytes.pod | 3 +- src/lib/libcrypto/doc/RSA_check_key.pod | 2 +- src/lib/libcrypto/doc/RSA_generate_key.pod | 3 +- src/lib/libcrypto/doc/RSA_new.pod | 3 +- src/lib/libcrypto/doc/RSA_print.pod | 6 +- src/lib/libcrypto/doc/RSA_private_encrypt.pod | 3 +- src/lib/libcrypto/doc/RSA_public_encrypt.pod | 3 +- src/lib/libcrypto/doc/RSA_set_method.pod | 13 +- src/lib/libcrypto/doc/RSA_sign.pod | 4 +- .../libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod | 4 +- src/lib/libcrypto/doc/SMIME_read_PKCS7.pod | 71 +++ src/lib/libcrypto/doc/SMIME_write_PKCS7.pod | 59 +++ .../libcrypto/doc/X509_NAME_ENTRY_get_object.pod | 72 +++ .../libcrypto/doc/X509_NAME_add_entry_by_txt.pod | 110 ++++ .../libcrypto/doc/X509_NAME_get_index_by_NID.pod | 106 ++++ src/lib/libcrypto/doc/X509_NAME_print_ex.pod | 105 ++++ src/lib/libcrypto/doc/X509_new.pod | 37 ++ src/lib/libcrypto/doc/d2i_ASN1_OBJECT.pod | 29 ++ src/lib/libcrypto/doc/d2i_DHparams.pod | 14 +- src/lib/libcrypto/doc/d2i_DSAPublicKey.pod | 82 +++ src/lib/libcrypto/doc/d2i_RSAPublicKey.pod | 39 +- src/lib/libcrypto/doc/d2i_X509.pod | 231 +++++++++ src/lib/libcrypto/doc/d2i_X509_ALGOR.pod | 30 ++ src/lib/libcrypto/doc/d2i_X509_CRL.pod | 37 ++ src/lib/libcrypto/doc/d2i_X509_NAME.pod | 31 ++ src/lib/libcrypto/doc/d2i_X509_REQ.pod | 36 ++ src/lib/libcrypto/doc/d2i_X509_SIG.pod | 30 ++ src/lib/libcrypto/doc/engine.pod | 12 +- src/lib/libcrypto/dsa/dsa_lib.c | 15 +- src/lib/libcrypto/dsa/dsa_ossl.c | 14 +- src/lib/libcrypto/dsa/dsa_sign.c | 1 - src/lib/libcrypto/dsa/dsa_vrf.c | 1 - src/lib/libcrypto/ec/ec.h | 2 - src/lib/libcrypto/ec/ec_err.c | 2 - src/lib/libcrypto/ec/ec_lib.c | 8 +- src/lib/libcrypto/ec/ec_mult.c | 11 + src/lib/libcrypto/engine/eng_all.c | 15 +- src/lib/libcrypto/engine/eng_err.c | 3 +- src/lib/libcrypto/engine/eng_fat.c | 8 +- src/lib/libcrypto/engine/eng_init.c | 2 +- src/lib/libcrypto/engine/eng_list.c | 33 +- src/lib/libcrypto/engine/eng_openssl.c | 18 +- src/lib/libcrypto/engine/engine.h | 10 +- src/lib/libcrypto/engine/tb_cipher.c | 4 +- src/lib/libcrypto/engine/tb_dh.c | 4 +- src/lib/libcrypto/engine/tb_digest.c | 4 +- src/lib/libcrypto/engine/tb_dsa.c | 4 +- src/lib/libcrypto/engine/tb_rand.c | 4 +- src/lib/libcrypto/engine/tb_rsa.c | 4 +- src/lib/libcrypto/err/err.c | 2 + src/lib/libcrypto/err/err_all.c | 4 + src/lib/libcrypto/err/err_prn.c | 1 - src/lib/libcrypto/evp/bio_b64.c | 1 + src/lib/libcrypto/evp/bio_enc.c | 9 +- src/lib/libcrypto/evp/c_all.c | 5 + src/lib/libcrypto/evp/digest.c | 17 +- src/lib/libcrypto/evp/e_aes.c | 1 - src/lib/libcrypto/evp/e_idea.c | 2 +- src/lib/libcrypto/evp/e_rc2.c | 1 + src/lib/libcrypto/evp/e_rc4.c | 5 +- src/lib/libcrypto/evp/encode.c | 2 + src/lib/libcrypto/evp/evp_enc.c | 30 +- src/lib/libcrypto/evp/evp_key.c | 6 +- src/lib/libcrypto/evp/evp_lib.c | 2 + src/lib/libcrypto/evp/evp_pbe.c | 2 +- src/lib/libcrypto/evp/p5_crpt.c | 8 +- src/lib/libcrypto/evp/p5_crpt2.c | 3 +- src/lib/libcrypto/evp/p_open.c | 2 +- src/lib/libcrypto/hmac/hmac.c | 3 + src/lib/libcrypto/lhash/lh_stats.c | 86 ++- src/lib/libcrypto/md32_common.h | 38 +- src/lib/libcrypto/md4/md4_dgst.c | 36 +- src/lib/libcrypto/md4/md4_one.c | 3 +- src/lib/libcrypto/md5/md5.h | 4 +- src/lib/libcrypto/md5/md5_dgst.c | 36 +- src/lib/libcrypto/md5/md5_locl.h | 2 +- src/lib/libcrypto/md5/md5_one.c | 3 +- src/lib/libcrypto/mem_clr.c | 75 +++ src/lib/libcrypto/mem_dbg.c | 24 +- src/lib/libcrypto/o_time.c | 3 + src/lib/libcrypto/objects/obj_dat.c | 7 +- src/lib/libcrypto/objects/obj_mac.num | 2 + src/lib/libcrypto/objects/objects.txt | 6 +- src/lib/libcrypto/ocsp/ocsp_asn.c | 2 +- src/lib/libcrypto/ocsp/ocsp_ht.c | 19 +- src/lib/libcrypto/opensslv.h | 4 +- src/lib/libcrypto/ossl_typ.h | 2 + src/lib/libcrypto/pem/pem.h | 8 +- src/lib/libcrypto/pem/pem_info.c | 5 +- src/lib/libcrypto/pem/pem_lib.c | 26 +- src/lib/libcrypto/pem/pem_pk8.c | 2 +- src/lib/libcrypto/pem/pem_seal.c | 2 +- src/lib/libcrypto/perlasm/cbc.pl | 41 +- src/lib/libcrypto/perlasm/x86asm.pl | 9 +- src/lib/libcrypto/pkcs12/p12_crpt.c | 4 +- src/lib/libcrypto/pkcs12/p12_decr.c | 4 +- src/lib/libcrypto/pkcs12/p12_key.c | 2 +- src/lib/libcrypto/pkcs12/p12_npas.c | 2 +- src/lib/libcrypto/pkcs7/pk7_doit.c | 6 +- src/lib/libcrypto/rand/rand.h | 2 + src/lib/libcrypto/rand/rand_lib.c | 10 + src/lib/libcrypto/rand/randfile.c | 9 +- src/lib/libcrypto/ripemd/rmd_dgst.c | 12 +- src/lib/libcrypto/ripemd/rmd_one.c | 3 +- src/lib/libcrypto/rsa/rsa.h | 9 + src/lib/libcrypto/rsa/rsa_eay.c | 150 +++++- src/lib/libcrypto/rsa/rsa_lib.c | 43 +- src/lib/libcrypto/rsa/rsa_pk1.c | 2 +- src/lib/libcrypto/rsa/rsa_saos.c | 6 +- src/lib/libcrypto/rsa/rsa_sign.c | 25 +- src/lib/libcrypto/sha/sha1_one.c | 3 +- src/lib/libcrypto/sha/sha_locl.h | 12 +- src/lib/libcrypto/txt_db/txt_db.c | 4 +- src/lib/libcrypto/ui/ui_lib.c | 10 +- src/lib/libcrypto/ui/ui_openssl.c | 28 +- src/lib/libcrypto/ui/ui_util.c | 8 +- src/lib/libcrypto/util/mkerr.pl | 16 +- src/lib/libcrypto/x509/by_file.c | 20 +- src/lib/libcrypto/x509/x509.h | 3 +- src/lib/libcrypto/x509/x509_cmp.c | 119 ++++- src/lib/libcrypto/x509/x509_v3.c | 2 +- src/lib/libcrypto/x509/x509_vfy.c | 2 +- src/lib/libcrypto/x509v3/ext_dat.h | 6 + src/lib/libcrypto/x509v3/v3_info.c | 2 +- src/lib/libcrypto/x509v3/v3_ocsp.c | 3 + src/lib/libcrypto/x509v3/v3_prn.c | 2 +- src/lib/libcrypto/x509v3/v3_purp.c | 4 + src/lib/libcrypto/x509v3/v3_utl.c | 2 +- src/lib/libcrypto/x509v3/x509v3.h | 1 + src/lib/libssl/LICENSE | 2 +- src/lib/libssl/bio_ssl.c | 6 + src/lib/libssl/doc/standards.txt | 173 ++++++- src/lib/libssl/s23_clnt.c | 24 +- src/lib/libssl/s23_srvr.c | 19 +- src/lib/libssl/s3_both.c | 25 +- src/lib/libssl/s3_clnt.c | 73 +-- src/lib/libssl/s3_lib.c | 193 +++++-- src/lib/libssl/s3_pkt.c | 47 +- src/lib/libssl/s3_srvr.c | 53 +- src/lib/libssl/ssl.h | 30 +- src/lib/libssl/ssl3.h | 48 +- src/lib/libssl/ssl_asn1.c | 11 +- src/lib/libssl/ssl_cert.c | 30 +- src/lib/libssl/ssl_ciph.c | 14 +- src/lib/libssl/ssl_err.c | 1 + src/lib/libssl/ssl_lib.c | 45 +- src/lib/libssl/ssl_sess.c | 17 +- src/lib/libssl/t1_clnt.c | 17 +- src/lib/libssl/t1_enc.c | 20 +- src/lib/libssl/t1_meth.c | 20 +- src/lib/libssl/t1_srvr.c | 17 +- src/lib/libssl/test/methtest.c | 4 +- src/lib/libssl/test/testgen | 2 + src/lib/libssl/test/testssl | 16 +- 248 files changed, 4861 insertions(+), 1460 deletions(-) create mode 100644 src/lib/libcrypto/bn/asm/x86_64-gcc.c create mode 100644 src/lib/libcrypto/doc/EVP_PKEY_new.pod create mode 100644 src/lib/libcrypto/doc/EVP_PKEY_set1_RSA.pod create mode 100644 src/lib/libcrypto/doc/OBJ_nid2obj.pod create mode 100644 src/lib/libcrypto/doc/PKCS12_create.pod create mode 100644 src/lib/libcrypto/doc/PKCS12_parse.pod create mode 100644 src/lib/libcrypto/doc/PKCS7_decrypt.pod create mode 100644 src/lib/libcrypto/doc/PKCS7_encrypt.pod create mode 100644 src/lib/libcrypto/doc/PKCS7_sign.pod create mode 100644 src/lib/libcrypto/doc/PKCS7_verify.pod create mode 100644 src/lib/libcrypto/doc/SMIME_read_PKCS7.pod create mode 100644 src/lib/libcrypto/doc/SMIME_write_PKCS7.pod create mode 100644 src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod create mode 100644 src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod create mode 100644 src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod create mode 100644 src/lib/libcrypto/doc/X509_NAME_print_ex.pod create mode 100644 src/lib/libcrypto/doc/X509_new.pod create mode 100644 src/lib/libcrypto/doc/d2i_ASN1_OBJECT.pod create mode 100644 src/lib/libcrypto/doc/d2i_DSAPublicKey.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509_ALGOR.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509_CRL.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509_NAME.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509_REQ.pod create mode 100644 src/lib/libcrypto/doc/d2i_X509_SIG.pod create mode 100644 src/lib/libcrypto/mem_clr.c (limited to 'src/lib') diff --git a/src/lib/libcrypto/aes/aes.h b/src/lib/libcrypto/aes/aes.h index e8da921ec5..8294a41a3a 100644 --- a/src/lib/libcrypto/aes/aes.h +++ b/src/lib/libcrypto/aes/aes.h @@ -56,8 +56,9 @@ #error AES is disabled. #endif -static const int AES_DECRYPT = 0; -static const int AES_ENCRYPT = 1; +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + /* Because array size can't be a const in C, the following two are macros. Both sizes are in bytes. */ #define AES_MAXNR 14 @@ -99,7 +100,9 @@ void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, unsigned char *ivec, int *num); void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, - unsigned char *counter, unsigned int *num); + unsigned char counter[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); #ifdef __cplusplus diff --git a/src/lib/libcrypto/aes/aes_cbc.c b/src/lib/libcrypto/aes/aes_cbc.c index 3dfd7aba2a..de438306b1 100644 --- a/src/lib/libcrypto/aes/aes_cbc.c +++ b/src/lib/libcrypto/aes/aes_cbc.c @@ -49,7 +49,13 @@ * */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include "aes_locl.h" @@ -57,33 +63,49 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, unsigned char *ivec, const int enc) { - int n; + unsigned long n; unsigned long len = length; - unsigned char tmp[16]; + unsigned char tmp[AES_BLOCK_SIZE]; assert(in && out && key && ivec); - assert(length % AES_BLOCK_SIZE == 0); assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc)); - if (AES_ENCRYPT == enc) - while (len > 0) { - for(n=0; n < 16; ++n) + if (AES_ENCRYPT == enc) { + while (len >= AES_BLOCK_SIZE) { + for(n=0; n < sizeof tmp; ++n) tmp[n] = in[n] ^ ivec[n]; AES_encrypt(tmp, out, key); - memcpy(ivec, out, 16); - len -= 16; - in += 16; - out += 16; + memcpy(ivec, out, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; } - else - while (len > 0) { - memcpy(tmp, in, 16); + if (len) { + for(n=0; n < len; ++n) + tmp[n] = in[n] ^ ivec[n]; + for(n=len; n < AES_BLOCK_SIZE; ++n) + tmp[n] = ivec[n]; + AES_encrypt(tmp, tmp, key); + memcpy(out, tmp, len); + memcpy(ivec, tmp, sizeof tmp); + } + } else { + while (len >= AES_BLOCK_SIZE) { + memcpy(tmp, in, sizeof tmp); AES_decrypt(in, out, key); - for(n=0; n < 16; ++n) + for(n=0; n < AES_BLOCK_SIZE; ++n) out[n] ^= ivec[n]; - memcpy(ivec, tmp, 16); - len -= 16; - in += 16; - out += 16; + memcpy(ivec, tmp, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; } + if (len) { + memcpy(tmp, in, sizeof tmp); + AES_decrypt(tmp, tmp, key); + for(n=0; n < len; ++n) + out[n] ^= ivec[n]; + memcpy(ivec, tmp, sizeof tmp); + } + } } diff --git a/src/lib/libcrypto/aes/aes_cfb.c b/src/lib/libcrypto/aes/aes_cfb.c index 41c2a5ec3d..9b569dda90 100644 --- a/src/lib/libcrypto/aes/aes_cfb.c +++ b/src/lib/libcrypto/aes/aes_cfb.c @@ -105,7 +105,13 @@ * [including the GNU Public Licence.] */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include "aes_locl.h" diff --git a/src/lib/libcrypto/aes/aes_core.c b/src/lib/libcrypto/aes/aes_core.c index 937988dd8c..2f41a825f8 100644 --- a/src/lib/libcrypto/aes/aes_core.c +++ b/src/lib/libcrypto/aes/aes_core.c @@ -28,7 +28,13 @@ /* Note: rewritten a little bit to provide error control and an OpenSSL- compatible API */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include #include "aes_locl.h" @@ -744,7 +750,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, rk[2] = GETU32(userKey + 8); rk[3] = GETU32(userKey + 12); if (bits == 128) { - for (;;) { + while (1) { temp = rk[3]; rk[4] = rk[0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ @@ -764,7 +770,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, rk[4] = GETU32(userKey + 16); rk[5] = GETU32(userKey + 20); if (bits == 192) { - for (;;) { + while (1) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ @@ -786,7 +792,7 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, rk[6] = GETU32(userKey + 24); rk[7] = GETU32(userKey + 28); if (bits == 256) { - for (;;) { + while (1) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ diff --git a/src/lib/libcrypto/aes/aes_ctr.c b/src/lib/libcrypto/aes/aes_ctr.c index aea3db2092..59088499a0 100644 --- a/src/lib/libcrypto/aes/aes_ctr.c +++ b/src/lib/libcrypto/aes/aes_ctr.c @@ -49,7 +49,13 @@ * */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include "aes_locl.h" @@ -90,26 +96,31 @@ static void AES_ctr128_inc(unsigned char *counter) { /* The input encrypted as though 128bit counter mode is being * used. The extra state information to record how much of the - * 128bit block we have used is contained in *num; + * 128bit block we have used is contained in *num, and the + * encrypted counter is kept in ecount_buf. Both *num and + * ecount_buf must be initialised with zeros before the first + * call to AES_ctr128_encrypt(). */ void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, const unsigned long length, const AES_KEY *key, - unsigned char *counter, unsigned int *num) { + unsigned char counter[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num) { unsigned int n; unsigned long l=length; - unsigned char tmp[AES_BLOCK_SIZE]; assert(in && out && key && counter && num); + assert(*num < AES_BLOCK_SIZE); n = *num; while (l--) { if (n == 0) { - AES_encrypt(counter, tmp, key); + AES_encrypt(counter, ecount_buf, key); AES_ctr128_inc(counter); } - *(out++) = *(in++) ^ tmp[n]; + *(out++) = *(in++) ^ ecount_buf[n]; n = (n+1) % AES_BLOCK_SIZE; } diff --git a/src/lib/libcrypto/aes/aes_ecb.c b/src/lib/libcrypto/aes/aes_ecb.c index 1cb2e07d3d..28aa561c2d 100644 --- a/src/lib/libcrypto/aes/aes_ecb.c +++ b/src/lib/libcrypto/aes/aes_ecb.c @@ -49,7 +49,13 @@ * */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include "aes_locl.h" diff --git a/src/lib/libcrypto/aes/aes_locl.h b/src/lib/libcrypto/aes/aes_locl.h index 18fc2d0747..f290946058 100644 --- a/src/lib/libcrypto/aes/aes_locl.h +++ b/src/lib/libcrypto/aes/aes_locl.h @@ -62,7 +62,7 @@ #include #include -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(OPENSSL_SYS_WINCE) # define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) # define GETU32(p) SWAP(*((u32 *)(p))) # define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } diff --git a/src/lib/libcrypto/aes/aes_ofb.c b/src/lib/libcrypto/aes/aes_ofb.c index e33bdaea28..f358bb39e2 100644 --- a/src/lib/libcrypto/aes/aes_ofb.c +++ b/src/lib/libcrypto/aes/aes_ofb.c @@ -105,7 +105,13 @@ * [including the GNU Public Licence.] */ +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif #include + #include #include "aes_locl.h" diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c index e0265f69d2..f4ea96cd54 100644 --- a/src/lib/libcrypto/asn1/a_bitstr.c +++ b/src/lib/libcrypto/asn1/a_bitstr.c @@ -191,7 +191,9 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) if (a->data == NULL) c=(unsigned char *)OPENSSL_malloc(w+1); else - c=(unsigned char *)OPENSSL_realloc(a->data,w+1); + c=(unsigned char *)OPENSSL_realloc_clean(a->data, + a->length, + w+1); if (c == NULL) return(0); if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length); a->data=c; diff --git a/src/lib/libcrypto/asn1/a_bytes.c b/src/lib/libcrypto/asn1/a_bytes.c index bb88660f58..afd27b80e1 100644 --- a/src/lib/libcrypto/asn1/a_bytes.c +++ b/src/lib/libcrypto/asn1/a_bytes.c @@ -285,7 +285,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_CTX *c) goto err; } - if (!BUF_MEM_grow(&b,num+os->length)) + if (!BUF_MEM_grow_clean(&b,num+os->length)) { c->error=ERR_R_BUF_LIB; goto err; diff --git a/src/lib/libcrypto/asn1/a_d2i_fp.c b/src/lib/libcrypto/asn1/a_d2i_fp.c index a80fbe9ff7..b67b75e7c2 100644 --- a/src/lib/libcrypto/asn1/a_d2i_fp.c +++ b/src/lib/libcrypto/asn1/a_d2i_fp.c @@ -149,7 +149,12 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) ASN1_CTX c; int want=HEADER_SIZE; int eos=0; +#if defined(__GNUC__) && defined(__ia64) + /* pathetic compiler bug in all known versions as of Nov. 2002 */ + long off=0; +#else int off=0; +#endif int len=0; b=BUF_MEM_new(); @@ -166,7 +171,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) { want-=(len-off); - if (!BUF_MEM_grow(b,len+want)) + if (!BUF_MEM_grow_clean(b,len+want)) { ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE); goto err; @@ -221,18 +226,23 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) if (want > (len-off)) { want-=(len-off); - if (!BUF_MEM_grow(b,len+want)) + if (!BUF_MEM_grow_clean(b,len+want)) { ASN1err(ASN1_F_ASN1_D2I_BIO,ERR_R_MALLOC_FAILURE); goto err; } - i=BIO_read(in,&(b->data[len]),want); - if (i <= 0) + while (want > 0) { - ASN1err(ASN1_F_ASN1_D2I_BIO,ASN1_R_NOT_ENOUGH_DATA); - goto err; + i=BIO_read(in,&(b->data[len]),want); + if (i <= 0) + { + ASN1err(ASN1_F_ASN1_D2I_BIO, + ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + len+=i; + want -= i; } - len+=i; } off+=(int)c.slen; if (eos <= 0) diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c index 71ce7c3896..0a8e6c287c 100644 --- a/src/lib/libcrypto/asn1/a_object.c +++ b/src/lib/libcrypto/asn1/a_object.c @@ -183,8 +183,8 @@ int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp,"NULL",4)); - i=i2t_ASN1_OBJECT(buf,80,a); - if (i > 80) i=80; + i=i2t_ASN1_OBJECT(buf,sizeof buf,a); + if (i > sizeof buf) i=sizeof buf; BIO_write(bp,buf,i); return(i); } diff --git a/src/lib/libcrypto/asn1/a_sign.c b/src/lib/libcrypto/asn1/a_sign.c index de53b44144..52ce7e3974 100644 --- a/src/lib/libcrypto/asn1/a_sign.c +++ b/src/lib/libcrypto/asn1/a_sign.c @@ -204,9 +204,9 @@ int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2, err: EVP_MD_CTX_cleanup(&ctx); if (buf_in != NULL) - { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); } + { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) - { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); } + { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } return(outl); } @@ -287,8 +287,8 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, err: EVP_MD_CTX_cleanup(&ctx); if (buf_in != NULL) - { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); } + { OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) - { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); } + { OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); } return(outl); } diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c index 7ddb7662f1..1def6c6549 100644 --- a/src/lib/libcrypto/asn1/a_strex.c +++ b/src/lib/libcrypto/asn1/a_strex.c @@ -63,6 +63,7 @@ #include #include "charmap.h" +#include "cryptlib.h" /* ASN1_STRING_print_ex() and X509_NAME_print_ex(). * Enhanced string and name printing routines handling @@ -114,14 +115,17 @@ typedef int char_io(void *arg, const void *buf, int len); static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, char_io *io_ch, void *arg) { unsigned char chflgs, chtmp; - char tmphex[11]; + char tmphex[HEX_SIZE(long)+3]; + + if(c > 0xffffffffL) + return -1; if(c > 0xffff) { - BIO_snprintf(tmphex, 11, "\\W%08lX", c); + BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c); if(!io_ch(arg, tmphex, 10)) return -1; return 10; } if(c > 0xff) { - BIO_snprintf(tmphex, 11, "\\U%04lX", c); + BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c); if(!io_ch(arg, tmphex, 6)) return -1; return 6; } @@ -195,7 +199,7 @@ static int do_buf(unsigned char *buf, int buflen, if(type & BUF_TYPE_CONVUTF8) { unsigned char utfbuf[6]; int utflen; - utflen = UTF8_putc(utfbuf, 6, c); + utflen = UTF8_putc(utfbuf, sizeof utfbuf, c); for(i = 0; i < utflen; i++) { /* We don't need to worry about setting orflags correctly * because if utflen==1 its value will be correct anyway @@ -461,7 +465,7 @@ static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, if(fn_opt != XN_FLAG_FN_NONE) { int objlen, fld_len; if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) { - OBJ_obj2txt(objtmp, 80, fn, 1); + OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1); fld_len = 0; /* XXX: what should this be? */ objbuf = objtmp; } else { diff --git a/src/lib/libcrypto/asn1/a_strnid.c b/src/lib/libcrypto/asn1/a_strnid.c index 04789d1c63..aa49e9d7d0 100644 --- a/src/lib/libcrypto/asn1/a_strnid.c +++ b/src/lib/libcrypto/asn1/a_strnid.c @@ -173,6 +173,7 @@ static ASN1_STRING_TABLE tbl_standard[] = { {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, +{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK} }; @@ -249,4 +250,38 @@ static void st_free(ASN1_STRING_TABLE *tbl) if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl); } + IMPLEMENT_STACK_OF(ASN1_STRING_TABLE) + +#ifdef STRING_TABLE_TEST + +main() +{ + ASN1_STRING_TABLE *tmp; + int i, last_nid = -1; + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++) + { + if (tmp->nid < last_nid) + { + last_nid = 0; + break; + } + last_nid = tmp->nid; + } + + if (last_nid != 0) + { + printf("Table order OK\n"); + exit(0); + } + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++) + printf("Index %d, NID %d, Name=%s\n", i, tmp->nid, + OBJ_nid2ln(tmp->nid)); + +} + +#endif diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c index 27ddd30899..7348da9457 100644 --- a/src/lib/libcrypto/asn1/a_time.c +++ b/src/lib/libcrypto/asn1/a_time.c @@ -105,7 +105,10 @@ ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) ts=OPENSSL_gmtime(&t,&data); if (ts == NULL) + { + ASN1err(ASN1_F_ASN1_TIME_SET, ASN1_R_ERROR_GETTING_TIME); return NULL; + } if((ts->tm_year >= 50) && (ts->tm_year < 150)) return ASN1_UTCTIME_set(s, t); return ASN1_GENERALIZEDTIME_set(s,t); @@ -152,7 +155,7 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZE if (t->data[0] >= '5') strcpy(str, "19"); else strcpy(str, "20"); - strcat(str, (char *)t->data); + BUF_strlcat(str, (char *)t->data, t->length+3); /* Include space for a '\0' */ return ret; } diff --git a/src/lib/libcrypto/asn1/a_type.c b/src/lib/libcrypto/asn1/a_type.c index 96e111cf23..fe3fcd40b0 100644 --- a/src/lib/libcrypto/asn1/a_type.c +++ b/src/lib/libcrypto/asn1/a_type.c @@ -62,7 +62,7 @@ int ASN1_TYPE_get(ASN1_TYPE *a) { - if (a->value.ptr != NULL) + if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL)) return(a->type); else return(0); diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c index bf41de5146..da2a0a6d69 100644 --- a/src/lib/libcrypto/asn1/a_verify.c +++ b/src/lib/libcrypto/asn1/a_verify.c @@ -103,7 +103,7 @@ int ASN1_verify(int (*i2d)(), X509_ALGOR *a, ASN1_BIT_STRING *signature, EVP_VerifyInit_ex(&ctx,type, NULL); EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl); - memset(buf_in,0,(unsigned int)inl); + OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data, @@ -153,7 +153,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signat EVP_VerifyInit_ex(&ctx,type, NULL); EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl); - memset(buf_in,0,(unsigned int)inl); + OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data, diff --git a/src/lib/libcrypto/asn1/asn1.h b/src/lib/libcrypto/asn1/asn1.h index dbb30f4f22..3414509f1b 100644 --- a/src/lib/libcrypto/asn1/asn1.h +++ b/src/lib/libcrypto/asn1/asn1.h @@ -70,7 +70,6 @@ #include -#include #include #ifdef OPENSSL_BUILD_SHLIBCRYPTO @@ -133,7 +132,7 @@ extern "C" { #define B_ASN1_NUMERICSTRING 0x0001 #define B_ASN1_PRINTABLESTRING 0x0002 #define B_ASN1_T61STRING 0x0004 -#define B_ASN1_TELETEXSTRING 0x0008 +#define B_ASN1_TELETEXSTRING 0x0004 #define B_ASN1_VIDEOTEXSTRING 0x0008 #define B_ASN1_IA5STRING 0x0010 #define B_ASN1_GRAPHICSTRING 0x0020 @@ -981,6 +980,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_F_ASN1_TEMPLATE_D2I 131 #define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 #define ASN1_F_ASN1_TEMPLATE_NEW 133 +#define ASN1_F_ASN1_TIME_SET 175 #define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 #define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 #define ASN1_F_ASN1_UNPACK_STRING 136 @@ -1038,6 +1038,7 @@ void ERR_load_ASN1_strings(void); #define ASN1_R_DECODE_ERROR 110 #define ASN1_R_DECODING_ERROR 111 #define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 173 #define ASN1_R_ERROR_LOADING_SECTION 172 #define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 #define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 diff --git a/src/lib/libcrypto/asn1/asn1_err.c b/src/lib/libcrypto/asn1/asn1_err.c index c4c3d2a91d..094ec06fda 100644 --- a/src/lib/libcrypto/asn1/asn1_err.c +++ b/src/lib/libcrypto/asn1/asn1_err.c @@ -1,6 +1,6 @@ /* crypto/asn1/asn1_err.c */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -100,6 +100,7 @@ static ERR_STRING_DATA ASN1_str_functs[]= {ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_D2I,0), "ASN1_TEMPLATE_D2I"}, {ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_EX_D2I,0), "ASN1_TEMPLATE_EX_D2I"}, {ERR_PACK(0,ASN1_F_ASN1_TEMPLATE_NEW,0), "ASN1_TEMPLATE_NEW"}, +{ERR_PACK(0,ASN1_F_ASN1_TIME_SET,0), "ASN1_TIME_set"}, {ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,0), "ASN1_TYPE_get_int_octetstring"}, {ERR_PACK(0,ASN1_F_ASN1_TYPE_GET_OCTETSTRING,0), "ASN1_TYPE_get_octetstring"}, {ERR_PACK(0,ASN1_F_ASN1_UNPACK_STRING,0), "ASN1_unpack_string"}, @@ -160,6 +161,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]= {ASN1_R_DECODE_ERROR ,"decode error"}, {ASN1_R_DECODING_ERROR ,"decoding error"}, {ASN1_R_ENCODE_ERROR ,"encode error"}, +{ASN1_R_ERROR_GETTING_TIME ,"error getting time"}, {ASN1_R_ERROR_LOADING_SECTION ,"error loading section"}, {ASN1_R_ERROR_PARSING_SET_ELEMENT ,"error parsing set element"}, {ASN1_R_ERROR_SETTING_CIPHER_PARAMS ,"error setting cipher params"}, diff --git a/src/lib/libcrypto/asn1/asn1_par.c b/src/lib/libcrypto/asn1/asn1_par.c index facfdd27fc..e48532a24d 100644 --- a/src/lib/libcrypto/asn1/asn1_par.c +++ b/src/lib/libcrypto/asn1/asn1_par.c @@ -79,12 +79,7 @@ static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, else p="prim: "; if (BIO_write(bp,p,6) < 6) goto err; - if (indent) - { - if (indent > 128) indent=128; - memset(str,' ',indent); - if (BIO_write(bp,str,indent) < indent) goto err; - } + BIO_indent(bp,indent,128); p=str; if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) diff --git a/src/lib/libcrypto/asn1/f_int.c b/src/lib/libcrypto/asn1/f_int.c index 48cc3bfb90..9494e597ab 100644 --- a/src/lib/libcrypto/asn1/f_int.c +++ b/src/lib/libcrypto/asn1/f_int.c @@ -169,8 +169,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) sp=(unsigned char *)OPENSSL_malloc( (unsigned int)num+i*2); else - sp=(unsigned char *)OPENSSL_realloc(s, - (unsigned int)num+i*2); + sp=OPENSSL_realloc_clean(s,slen,num+i*2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE); diff --git a/src/lib/libcrypto/asn1/n_pkey.c b/src/lib/libcrypto/asn1/n_pkey.c index 9146ee02c9..766b51c538 100644 --- a/src/lib/libcrypto/asn1/n_pkey.c +++ b/src/lib/libcrypto/asn1/n_pkey.c @@ -187,7 +187,7 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) i2d_NETSCAPE_PKEY(pkey,&zz); /* Wipe the private key encoding */ - memset(pkey->private_key->data, 0, rsalen); + OPENSSL_cleanse(pkey->private_key->data, rsalen); if (cb == NULL) cb=EVP_read_pw_string; @@ -206,7 +206,7 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey) } EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL); - memset(buf,0,256); + OPENSSL_cleanse(buf,256); /* Encrypt private key in place */ zz = enckey->enckey->digest->data; @@ -294,7 +294,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, } EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL); - memset(buf,0,256); + OPENSSL_cleanse(buf,256); EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL); diff --git a/src/lib/libcrypto/asn1/p8_pkey.c b/src/lib/libcrypto/asn1/p8_pkey.c index b634d5bc85..24b409132f 100644 --- a/src/lib/libcrypto/asn1/p8_pkey.c +++ b/src/lib/libcrypto/asn1/p8_pkey.c @@ -68,8 +68,8 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) if(operation == ASN1_OP_FREE_PRE) { PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; if (key->pkey->value.octet_string) - memset(key->pkey->value.octet_string->data, - 0, key->pkey->value.octet_string->length); + OPENSSL_cleanse(key->pkey->value.octet_string->data, + key->pkey->value.octet_string->length); } return 1; } diff --git a/src/lib/libcrypto/asn1/t_crl.c b/src/lib/libcrypto/asn1/t_crl.c index 60db305756..757c148df8 100644 --- a/src/lib/libcrypto/asn1/t_crl.c +++ b/src/lib/libcrypto/asn1/t_crl.c @@ -84,11 +84,11 @@ int X509_CRL_print_fp(FILE *fp, X509_CRL *x) int X509_CRL_print(BIO *out, X509_CRL *x) { - char buf[256]; STACK_OF(X509_REVOKED) *rev; X509_REVOKED *r; long l; int i, n; + char *p; BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); @@ -96,8 +96,9 @@ int X509_CRL_print(BIO *out, X509_CRL *x) i = OBJ_obj2nid(x->sig_alg->algorithm); BIO_printf(out, "%8sSignature Algorithm: %s\n", "", (i == NID_undef) ? "NONE" : OBJ_nid2ln(i)); - X509_NAME_oneline(X509_CRL_get_issuer(x),buf,256); - BIO_printf(out,"%8sIssuer: %s\n","",buf); + p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0); + BIO_printf(out,"%8sIssuer: %s\n","",p); + OPENSSL_free(p); BIO_printf(out,"%8sLast Update: ",""); ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x)); BIO_printf(out,"\n%8sNext Update: ",""); diff --git a/src/lib/libcrypto/asn1/t_pkey.c b/src/lib/libcrypto/asn1/t_pkey.c index 2d46914cb1..4e09c9e44e 100644 --- a/src/lib/libcrypto/asn1/t_pkey.c +++ b/src/lib/libcrypto/asn1/t_pkey.c @@ -130,14 +130,10 @@ int RSA_print(BIO *bp, const RSA *x, int off) goto err; } - if (off) - { - if (off > 128) off=128; - memset(str,' ',off); - } if (x->d != NULL) { - if (off && (BIO_write(bp,str,off) <= 0)) goto err; + if(!BIO_indent(bp,off,128)) + goto err; if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->n)) <= 0) goto err; } @@ -183,7 +179,6 @@ int DSA_print_fp(FILE *fp, const DSA *x, int off) int DSA_print(BIO *bp, const DSA *x, int off) { - char str[128]; unsigned char *m=NULL; int ret=0; size_t buf_len=0,i; @@ -210,14 +205,10 @@ int DSA_print(BIO *bp, const DSA *x, int off) goto err; } - if (off) - { - if (off > 128) off=128; - memset(str,' ',off); - } if (x->priv_key != NULL) { - if (off && (BIO_write(bp,str,off) <= 0)) goto err; + if(!BIO_indent(bp,off,128)) + goto err; if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p)) <= 0) goto err; } @@ -240,17 +231,12 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf, int off) { int n,i; - char str[128]; const char *neg; if (num == NULL) return(1); neg=(num->neg)?"-":""; - if (off) - { - if (off > 128) off=128; - memset(str,' ',off); - if (BIO_write(bp,str,off) <= 0) return(0); - } + if(!BIO_indent(bp,off,128)) + return 0; if (BN_num_bytes(num) <= BN_BYTES) { @@ -274,9 +260,9 @@ static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf, { if ((i%15) == 0) { - str[0]='\n'; - memset(&(str[1]),' ',off+4); - if (BIO_write(bp,str,off+1+4) <= 0) return(0); + if(BIO_puts(bp,"\n") <= 0 + || !BIO_indent(bp,off+4,128)) + return 0; } if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":") <= 0) return(0); diff --git a/src/lib/libcrypto/asn1/t_req.c b/src/lib/libcrypto/asn1/t_req.c index 739f272ecf..740cee80c0 100644 --- a/src/lib/libcrypto/asn1/t_req.c +++ b/src/lib/libcrypto/asn1/t_req.c @@ -91,7 +91,6 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long EVP_PKEY *pkey; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(X509_EXTENSION) *exts; - char str[128]; char mlch = ' '; int nmindent = 0; @@ -116,8 +115,9 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long l=0; for (i=0; iversion->length; i++) { l<<=8; l+=ri->version->data[i]; } - sprintf(str,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,l); - if (BIO_puts(bp,str) <= 0) goto err; + if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg, + l) <= 0) + goto err; } if(!(cflag & X509_FLAG_NO_SUBJECT)) { @@ -168,14 +168,14 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long if(!(cflag & X509_FLAG_NO_ATTRIBUTES)) { /* may not be */ - sprintf(str,"%8sAttributes:\n",""); - if (BIO_puts(bp,str) <= 0) goto err; + if(BIO_printf(bp,"%8sAttributes:\n","") <= 0) + goto err; sk=x->req_info->attributes; if (sk_X509_ATTRIBUTE_num(sk) == 0) { - sprintf(str,"%12sa0:00\n",""); - if (BIO_puts(bp,str) <= 0) goto err; + if(BIO_printf(bp,"%12sa0:00\n","") <= 0) + goto err; } else { @@ -190,8 +190,8 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long a=sk_X509_ATTRIBUTE_value(sk,i); if(X509_REQ_extension_nid(OBJ_obj2nid(a->object))) continue; - sprintf(str,"%12s",""); - if (BIO_puts(bp,str) <= 0) goto err; + if(BIO_printf(bp,"%12s","") <= 0) + goto err; if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0) { if (a->single) diff --git a/src/lib/libcrypto/asn1/t_x509.c b/src/lib/libcrypto/asn1/t_x509.c index 5de4833ed0..d1034c47f8 100644 --- a/src/lib/libcrypto/asn1/t_x509.c +++ b/src/lib/libcrypto/asn1/t_x509.c @@ -433,15 +433,17 @@ err: int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) { - char *s,*c; + char *s,*c,*b; int ret=0,l,ll,i,first=1; - char buf[256]; ll=80-2-obase; - s=X509_NAME_oneline(name,buf,256); + b=s=X509_NAME_oneline(name,NULL,0); if (!*s) + { + OPENSSL_free(b); return 1; + } s++; /* skip the first slash */ l=ll; @@ -497,6 +499,7 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) err: X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB); } + OPENSSL_free(b); return(ret); } diff --git a/src/lib/libcrypto/asn1/t_x509a.c b/src/lib/libcrypto/asn1/t_x509a.c index 7d4a6e6084..ffbbfb51f4 100644 --- a/src/lib/libcrypto/asn1/t_x509a.c +++ b/src/lib/libcrypto/asn1/t_x509a.c @@ -77,7 +77,7 @@ int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { if(!first) BIO_puts(out, ", "); else first = 0; - OBJ_obj2txt(oidstr, 80, + OBJ_obj2txt(oidstr, sizeof oidstr, sk_ASN1_OBJECT_value(aux->trust, i), 0); BIO_puts(out, oidstr); } @@ -90,7 +90,7 @@ int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { if(!first) BIO_puts(out, ", "); else first = 0; - OBJ_obj2txt(oidstr, 80, + OBJ_obj2txt(oidstr, sizeof oidstr, sk_ASN1_OBJECT_value(aux->reject, i), 0); BIO_puts(out, oidstr); } diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index f87c08793a..76fc023230 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c @@ -664,7 +664,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl if(!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL)) goto err; len = buf.length; /* Append a final null to string */ - if(!BUF_MEM_grow(&buf, len + 1)) { + if(!BUF_MEM_grow_clean(&buf, len + 1)) { ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); return 0; } @@ -857,7 +857,7 @@ static int collect_data(BUF_MEM *buf, unsigned char **p, long plen) int len; if(buf) { len = buf->length; - if(!BUF_MEM_grow(buf, len + plen)) { + if(!BUF_MEM_grow_clean(buf, len + plen)) { ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); return 0; } diff --git a/src/lib/libcrypto/asn1/tasn_fre.c b/src/lib/libcrypto/asn1/tasn_fre.c index c7610776f2..2dd844159e 100644 --- a/src/lib/libcrypto/asn1/tasn_fre.c +++ b/src/lib/libcrypto/asn1/tasn_fre.c @@ -206,7 +206,10 @@ void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) break; case V_ASN1_BOOLEAN: - *(ASN1_BOOLEAN *)pval = it->size; + if (it) + *(ASN1_BOOLEAN *)pval = it->size; + else + *(ASN1_BOOLEAN *)pval = -1; return; case V_ASN1_NULL: diff --git a/src/lib/libcrypto/asn1/tasn_new.c b/src/lib/libcrypto/asn1/tasn_new.c index e33861f864..a0e3db574f 100644 --- a/src/lib/libcrypto/asn1/tasn_new.c +++ b/src/lib/libcrypto/asn1/tasn_new.c @@ -305,7 +305,10 @@ int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) return 1; case V_ASN1_BOOLEAN: - *(ASN1_BOOLEAN *)pval = it->size; + if (it) + *(ASN1_BOOLEAN *)pval = it->size; + else + *(ASN1_BOOLEAN *)pval = -1; return 1; case V_ASN1_NULL: diff --git a/src/lib/libcrypto/asn1/tasn_prn.c b/src/lib/libcrypto/asn1/tasn_prn.c index fab67ae5ac..719639b511 100644 --- a/src/lib/libcrypto/asn1/tasn_prn.c +++ b/src/lib/libcrypto/asn1/tasn_prn.c @@ -186,7 +186,7 @@ if(*bool == -1) printf("BOOL MISSING\n"); char objbuf[80], *ln; ln = OBJ_nid2ln(OBJ_obj2nid(fld)); if(!ln) ln = ""; - OBJ_obj2txt(objbuf, 80, fld, 1); + OBJ_obj2txt(objbuf, sizeof objbuf, fld, 1); BIO_printf(out, "%*s%s:%s (%s)", indent, "", "OBJECT", ln, objbuf); } else { BIO_printf(out, "%*s%s:", indent, "", name); diff --git a/src/lib/libcrypto/bio/b_print.c b/src/lib/libcrypto/bio/b_print.c index 80c9cb69db..a9e552f245 100644 --- a/src/lib/libcrypto/bio/b_print.c +++ b/src/lib/libcrypto/bio/b_print.c @@ -378,7 +378,7 @@ _dopr( case 'p': value = (long)va_arg(args, void *); fmtint(sbuffer, buffer, &currlen, maxlen, - value, 16, min, max, flags); + value, 16, min, max, flags|DP_F_NUM); break; case 'n': /* XXX */ if (cflags == DP_C_SHORT) { @@ -482,8 +482,9 @@ fmtint( int flags) { int signvalue = 0; + char *prefix = ""; unsigned LLONG uvalue; - char convert[20]; + char convert[DECIMAL_SIZE(value)+3]; int place = 0; int spadlen = 0; int zpadlen = 0; @@ -501,6 +502,10 @@ fmtint( else if (flags & DP_F_SPACE) signvalue = ' '; } + if (flags & DP_F_NUM) { + if (base == 8) prefix = "0"; + if (base == 16) prefix = "0x"; + } if (flags & DP_F_UP) caps = 1; do { @@ -508,13 +513,13 @@ fmtint( (caps ? "0123456789ABCDEF" : "0123456789abcdef") [uvalue % (unsigned) base]; uvalue = (uvalue / (unsigned) base); - } while (uvalue && (place < 20)); - if (place == 20) + } while (uvalue && (place < sizeof convert)); + if (place == sizeof convert) place--; convert[place] = 0; zpadlen = max - place; - spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0); + spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); if (zpadlen < 0) zpadlen = 0; if (spadlen < 0) @@ -536,6 +541,12 @@ fmtint( if (signvalue) doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); + /* prefix */ + while (*prefix) { + doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix); + prefix++; + } + /* zeros */ if (zpadlen > 0) { while (zpadlen > 0) { @@ -641,8 +652,8 @@ fmtfp( (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10]; intpart = (intpart / 10); - } while (intpart && (iplace < 20)); - if (iplace == 20) + } while (intpart && (iplace < sizeof iplace)); + if (iplace == sizeof iplace) iplace--; iconvert[iplace] = 0; @@ -653,7 +664,7 @@ fmtfp( : "0123456789abcdef")[fracpart % 10]; fracpart = (fracpart / 10); } while (fplace < max); - if (fplace == 20) + if (fplace == sizeof fplace) fplace--; fconvert[fplace] = 0; @@ -692,7 +703,7 @@ fmtfp( * Decimal point. This should probably use locale to find the correct * char to print out. */ - if (max > 0) { + if (max > 0 || (flags & DP_F_NUM)) { doapr_outch(sbuffer, buffer, currlen, maxlen, '.'); while (fplace > 0) diff --git a/src/lib/libcrypto/bio/b_sock.c b/src/lib/libcrypto/bio/b_sock.c index 45bd7c47e8..601a14f37c 100644 --- a/src/lib/libcrypto/bio/b_sock.c +++ b/src/lib/libcrypto/bio/b_sock.c @@ -83,6 +83,7 @@ static int wsa_init_done=0; #endif +#if 0 static unsigned long BIO_ghbn_hits=0L; static unsigned long BIO_ghbn_miss=0L; @@ -93,6 +94,7 @@ static struct ghbn_cache_st struct hostent *ent; unsigned long order; } ghbn_cache[GHBN_NUM]; +#endif static int get_ip(const char *str,unsigned char *ip); #if 0 @@ -230,6 +232,7 @@ int BIO_sock_error(int sock) return(j); } +#if 0 long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) { int i; @@ -267,6 +270,7 @@ long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) } return(1); } +#endif #if 0 static struct hostent *ghbn_dup(struct hostent *a) @@ -463,6 +467,12 @@ int BIO_sock_init(void) } } #endif /* OPENSSL_SYS_WINDOWS */ +#ifdef WATT32 + extern int _watt_do_exit; + _watt_do_exit = 0; /* don't make sock_init() call exit() */ + if (sock_init()) + return (-1); +#endif return(1); } @@ -472,7 +482,9 @@ void BIO_sock_cleanup(void) if (wsa_init_done) { wsa_init_done=0; +#ifndef OPENSSL_SYS_WINCE WSACancelBlockingCall(); +#endif WSACleanup(); } #endif @@ -480,7 +492,7 @@ void BIO_sock_cleanup(void) #if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 -int BIO_socket_ioctl(int fd, long type, unsigned long *arg) +int BIO_socket_ioctl(int fd, long type, void *arg) { int i; @@ -730,7 +742,7 @@ int BIO_set_tcp_ndelay(int s, int on) int BIO_socket_nbio(int s, int mode) { int ret= -1; - unsigned long l; + int l; l=mode; #ifdef FIONBIO diff --git a/src/lib/libcrypto/bio/bf_buff.c b/src/lib/libcrypto/bio/bf_buff.c index 6ccda06596..1cecd70579 100644 --- a/src/lib/libcrypto/bio/bf_buff.c +++ b/src/lib/libcrypto/bio/bf_buff.c @@ -482,7 +482,7 @@ static int buffer_gets(BIO *b, char *buf, int size) size-=i; ctx->ibuf_len-=i; ctx->ibuf_off+=i; - if ((flag) || (i == size)) + if (flag || size == 0) { *buf='\0'; return(num); diff --git a/src/lib/libcrypto/bio/bio.h b/src/lib/libcrypto/bio/bio.h index c5caf253c9..fbbc16d00c 100644 --- a/src/lib/libcrypto/bio/bio.h +++ b/src/lib/libcrypto/bio/bio.h @@ -244,7 +244,7 @@ typedef struct bio_method_st long (_far *ctrl)(); int (_far *create)(); int (_far *destroy)(); - long (_fat *callback_ctrl)(); + long (_far *callback_ctrl)(); } BIO_METHOD; #endif @@ -522,6 +522,7 @@ int BIO_read(BIO *b, void *data, int len); int BIO_gets(BIO *bp,char *buf, int size); int BIO_write(BIO *b, const void *data, int len); int BIO_puts(BIO *bp,const char *buf); +int BIO_indent(BIO *b,int indent,int max); long BIO_ctrl(BIO *bp,int cmd,long larg,void *parg); long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long)); char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg); @@ -584,7 +585,7 @@ struct hostent *BIO_gethostbyname(const char *name); * and an appropriate error code is set). */ int BIO_sock_error(int sock); -int BIO_socket_ioctl(int fd, long type, unsigned long *arg); +int BIO_socket_ioctl(int fd, long type, void *arg); int BIO_socket_nbio(int fd,int mode); int BIO_get_port(const char *str, unsigned short *port_ptr); int BIO_get_host_ip(const char *str, unsigned char *ip); @@ -608,7 +609,7 @@ int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, void BIO_copy_next_retry(BIO *b); -long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); +/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/ int BIO_printf(BIO *bio, const char *format, ...); int BIO_vprintf(BIO *bio, const char *format, va_list args); diff --git a/src/lib/libcrypto/bio/bio_lib.c b/src/lib/libcrypto/bio/bio_lib.c index 50df2238fa..692c8fb5c6 100644 --- a/src/lib/libcrypto/bio/bio_lib.c +++ b/src/lib/libcrypto/bio/bio_lib.c @@ -272,6 +272,18 @@ int BIO_gets(BIO *b, char *in, int inl) return(i); } +int BIO_indent(BIO *b,int indent,int max) + { + if(indent < 0) + indent=0; + if(indent > max) + indent=max; + while(indent--) + if(BIO_puts(b," ") != 1) + return 0; + return 1; + } + long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { int i; @@ -383,6 +395,8 @@ BIO *BIO_pop(BIO *b) if (b == NULL) return(NULL); ret=b->next_bio; + BIO_ctrl(b,BIO_CTRL_POP,0,NULL); + if (b->prev_bio != NULL) b->prev_bio->next_bio=b->next_bio; if (b->next_bio != NULL) @@ -390,7 +404,6 @@ BIO *BIO_pop(BIO *b) b->next_bio=NULL; b->prev_bio=NULL; - BIO_ctrl(b,BIO_CTRL_POP,0,NULL); return(ret); } diff --git a/src/lib/libcrypto/bio/bss_bio.c b/src/lib/libcrypto/bio/bss_bio.c index 1c485a4479..aa58dab046 100644 --- a/src/lib/libcrypto/bio/bss_bio.c +++ b/src/lib/libcrypto/bio/bss_bio.c @@ -28,13 +28,12 @@ #include #include -#include #include #include "e_os.h" /* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ -#if defined(OPENSSL_SYS_VSWORKS) +#if defined(OPENSSL_SYS_VXWORKS) # undef SSIZE_MAX #endif #ifndef SSIZE_MAX diff --git a/src/lib/libcrypto/bio/bss_conn.c b/src/lib/libcrypto/bio/bss_conn.c index f91ae4c8c6..743db6ff94 100644 --- a/src/lib/libcrypto/bio/bss_conn.c +++ b/src/lib/libcrypto/bio/bss_conn.c @@ -519,7 +519,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) else if (num == 2) { char buf[16]; - char *p = ptr; + unsigned char *p = ptr; sprintf(buf,"%d.%d.%d.%d", p[0],p[1],p[2],p[3]); @@ -530,7 +530,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) } else if (num == 3) { - char buf[16]; + char buf[DECIMAL_SIZE(int)+1]; sprintf(buf,"%d",*(int *)ptr); if (data->param_port != NULL) diff --git a/src/lib/libcrypto/bio/bss_file.c b/src/lib/libcrypto/bio/bss_file.c index 826b361fa2..a66600c1a3 100644 --- a/src/lib/libcrypto/bio/bss_file.c +++ b/src/lib/libcrypto/bio/bss_file.c @@ -247,7 +247,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) ret=0; break; } -#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) +#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) if (!(num & BIO_FP_TEXT)) strcat(p,"b"); else diff --git a/src/lib/libcrypto/bio/bss_log.c b/src/lib/libcrypto/bio/bss_log.c index a39d95297c..1eb678cac0 100644 --- a/src/lib/libcrypto/bio/bss_log.c +++ b/src/lib/libcrypto/bio/bss_log.c @@ -68,7 +68,8 @@ #include "cryptlib.h" -#if defined(OPENSSL_SYS_WIN32) +#if defined(OPENSSL_SYS_WINCE) +#elif defined(OPENSSL_SYS_WIN32) # include #elif defined(OPENSSL_SYS_VMS) # include @@ -77,7 +78,7 @@ # include #elif defined(__ultrix) # include -#elif !defined(MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) /* Unix */ +#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) # include #endif @@ -274,7 +275,7 @@ static void xsyslog(BIO *bp, int priority, const char *string) LPCSTR lpszStrings[2]; WORD evtype= EVENTLOG_ERROR_TYPE; int pid = _getpid(); - char pidbuf[20]; + char pidbuf[DECIMAL_SIZE(pid)+4]; switch (priority) { @@ -373,11 +374,15 @@ static void xcloselog(BIO* bp) { } -#else /* Unix */ +#else /* Unix/Watt32 */ static void xopenlog(BIO* bp, char* name, int level) { +#ifdef WATT32 /* djgpp/DOS */ + openlog(name, LOG_PID|LOG_CONS|LOG_NDELAY, level); +#else openlog(name, LOG_PID|LOG_CONS, level); +#endif } static void xsyslog(BIO *bp, int priority, const char *string) diff --git a/src/lib/libcrypto/bio/bss_mem.c b/src/lib/libcrypto/bio/bss_mem.c index 28ff7582bf..a4edb711ae 100644 --- a/src/lib/libcrypto/bio/bss_mem.c +++ b/src/lib/libcrypto/bio/bss_mem.c @@ -190,7 +190,7 @@ static int mem_write(BIO *b, const char *in, int inl) BIO_clear_retry_flags(b); blen=bm->length; - if (BUF_MEM_grow(bm,blen+inl) != (blen+inl)) + if (BUF_MEM_grow_clean(bm,blen+inl) != (blen+inl)) goto end; memcpy(&(bm->data[blen]),in,inl); ret=inl; @@ -284,7 +284,11 @@ static int mem_gets(BIO *bp, char *buf, int size) BIO_clear_retry_flags(bp); j=bm->length; - if (j <= 0) return(0); + if (j <= 0) + { + *buf='\0'; + return 0; + } p=bm->data; for (i=0; i +#ifdef WATT32 +#define sock_write SockWrite /* Watt-32 uses same names */ +#define sock_read SockRead +#define sock_puts SockPuts +#endif + static int sock_write(BIO *h, const char *buf, int num); static int sock_read(BIO *h, char *buf, int size); static int sock_puts(BIO *h, const char *str); diff --git a/src/lib/libcrypto/bn/asm/ia64.S b/src/lib/libcrypto/bn/asm/ia64.S index ae56066310..7dfda85566 100644 --- a/src/lib/libcrypto/bn/asm/ia64.S +++ b/src/lib/libcrypto/bn/asm/ia64.S @@ -1,6 +1,6 @@ .explicit .text -.ident "ia64.S, Version 1.1" +.ident "ia64.S, Version 2.0" .ident "IA-64 ISA artwork by Andy Polyakov " // @@ -13,6 +13,35 @@ // disclaimed. // ==================================================================== // +// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is +// different from Itanium to this module viewpoint. Most notably, is it +// "wider" than Itanium? Can you experience loop scalability as +// discussed in commentary sections? Not really:-( Itanium2 has 6 +// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to +// spin twice as fast, as I need 8 IALU ports. Amount of floating point +// ports is the same, i.e. 2, while I need 4. In other words, to this +// module Itanium2 remains effectively as "wide" as Itanium. Yet it's +// essentially different in respect to this module, and a re-tune was +// required. Well, because some intruction latencies has changed. Most +// noticeably those intensively used: +// +// Itanium Itanium2 +// ldf8 9 6 L2 hit +// ld8 2 1 L1 hit +// getf 2 5 +// xma[->getf] 7[+1] 4[+0] +// add[->st8] 1[+1] 1[+0] +// +// What does it mean? You might ratiocinate that the original code +// should run just faster... Because sum of latencies is smaller... +// Wrong! Note that getf latency increased. This means that if a loop is +// scheduled for lower latency (and they are), then it will suffer from +// stall condition and the code will therefore turn anti-scalable, e.g. +// original bn_mul_words spun at 5*n or 2.5 times slower than expected +// on Itanium2! What to do? Reschedule loops for Itanium2? But then +// Itanium would exhibit anti-scalability. So I've chosen to reschedule +// for worst latency for every instruction aiming for best *all-round* +// performance. // Q. How much faster does it get? // A. Here is the output from 'openssl speed rsa dsa' for vanilla @@ -149,12 +178,27 @@ bn_add_words: brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16 } .body -{ .mib; mov r14=r32 // rp +{ .mib; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r14=0,r32 // rp +#else + mov r14=r32 // rp +#endif mov r9=pr };; -{ .mii; mov r15=r33 // ap +{ .mii; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r15=0,r33 // ap +#else + mov r15=r33 // ap +#endif mov ar.lc=r10 mov ar.ec=6 } -{ .mib; mov r16=r34 // bp +{ .mib; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r16=0,r34 // bp +#else + mov r16=r34 // bp +#endif mov pr.rot=1<<16 };; .L_bn_add_words_ctop: @@ -174,7 +218,7 @@ bn_add_words: { .mii; (p59) add r8=1,r8 // return value - mov pr=r9,-1 + mov pr=r9,0x1ffff mov ar.lc=r3 } { .mbb; nop.b 0x0 br.ret.sptk.many b0 };; @@ -202,12 +246,27 @@ bn_sub_words: brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16 } .body -{ .mib; mov r14=r32 // rp +{ .mib; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r14=0,r32 // rp +#else + mov r14=r32 // rp +#endif mov r9=pr };; -{ .mii; mov r15=r33 // ap +{ .mii; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r15=0,r33 // ap +#else + mov r15=r33 // ap +#endif mov ar.lc=r10 mov ar.ec=6 } -{ .mib; mov r16=r34 // bp +{ .mib; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r16=0,r34 // bp +#else + mov r16=r34 // bp +#endif mov pr.rot=1<<16 };; .L_bn_sub_words_ctop: @@ -227,7 +286,7 @@ bn_sub_words: { .mii; (p59) add r8=1,r8 // return value - mov pr=r9,-1 + mov pr=r9,0x1ffff mov ar.lc=r3 } { .mbb; nop.b 0x0 br.ret.sptk.many b0 };; @@ -253,7 +312,7 @@ bn_mul_words: #ifdef XMA_TEMPTATION { .mfi; alloc r2=ar.pfs,4,0,0,0 };; #else -{ .mfi; alloc r2=ar.pfs,4,4,0,8 };; +{ .mfi; alloc r2=ar.pfs,4,12,0,16 };; #endif { .mib; mov r8=r0 // return value cmp4.le p6,p0=r34,r0 @@ -266,24 +325,30 @@ bn_mul_words: .body { .mib; setf.sig f8=r35 // w - mov pr.rot=0x400001<<16 - // ------^----- serves as (p48) at first (p26) + mov pr.rot=0x800001<<16 + // ------^----- serves as (p50) at first (p27) brp.loop.imp .L_bn_mul_words_ctop,.L_bn_mul_words_cend-16 } #ifndef XMA_TEMPTATION -{ .mii; mov r14=r32 // rp - mov r15=r33 // ap +{ .mii; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r14=0,r32 // rp + addp4 r15=0,r33 // ap +#else + mov r14=r32 // rp + mov r15=r33 // ap +#endif mov ar.lc=r10 } -{ .mii; mov r39=0 // serves as r33 at first (p26) - mov ar.ec=12 };; +{ .mii; mov r40=0 // serves as r35 at first (p27) + mov ar.ec=13 };; -// This loop spins in 2*(n+11) ticks. It's scheduled for data in L2 -// cache (i.e. 9 ticks away) as floating point load/store instructions +// This loop spins in 2*(n+12) ticks. It's scheduled for data in Itanium +// L2 cache (i.e. 9 ticks away) as floating point load/store instructions // bypass L1 cache and L2 latency is actually best-case scenario for -// ldf8. The loop is not scalable and shall run in 2*(n+11) even on -// "wider" IA-64 implementations. It's a trade-off here. n+22 loop +// ldf8. The loop is not scalable and shall run in 2*(n+12) even on +// "wider" IA-64 implementations. It's a trade-off here. n+24 loop // would give us ~5% in *overall* performance improvement on "wider" // IA-64, but would hurt Itanium for about same because of longer // epilogue. As it's a matter of few percents in either case I've @@ -291,25 +356,25 @@ bn_mul_words: // this very instruction sequence in bn_mul_add_words loop which in // turn is scalable). .L_bn_mul_words_ctop: -{ .mfi; (p25) getf.sig r36=f49 // low - (p21) xmpy.lu f45=f37,f8 - (p27) cmp.ltu p52,p48=r39,r38 } +{ .mfi; (p25) getf.sig r36=f52 // low + (p21) xmpy.lu f48=f37,f8 + (p28) cmp.ltu p54,p50=r41,r39 } { .mfi; (p16) ldf8 f32=[r15],8 - (p21) xmpy.hu f38=f37,f8 + (p21) xmpy.hu f40=f37,f8 (p0) nop.i 0x0 };; -{ .mii; (p26) getf.sig r32=f43 // high - .pred.rel "mutex",p48,p52 - (p48) add r38=r37,r33 // (p26) - (p52) add r38=r37,r33,1 } // (p26) -{ .mfb; (p27) st8 [r14]=r39,8 +{ .mii; (p25) getf.sig r32=f44 // high + .pred.rel "mutex",p50,p54 + (p50) add r40=r38,r35 // (p27) + (p54) add r40=r38,r35,1 } // (p27) +{ .mfb; (p28) st8 [r14]=r41,8 (p0) nop.f 0x0 br.ctop.sptk .L_bn_mul_words_ctop };; .L_bn_mul_words_cend: { .mii; nop.m 0x0 -.pred.rel "mutex",p49,p53 -(p49) add r8=r34,r0 -(p53) add r8=r34,r0,1 } +.pred.rel "mutex",p51,p55 +(p51) add r8=r36,r0 +(p55) add r8=r36,r0,1 } { .mfb; nop.m 0x0 nop.f 0x0 nop.b 0x0 } @@ -344,7 +409,7 @@ bn_mul_words: #endif // XMA_TEMPTATION { .mii; nop.m 0x0 - mov pr=r9,-1 + mov pr=r9,0x1ffff mov ar.lc=r3 } { .mfb; rum 1<<5 // clear um.mfh nop.f 0x0 @@ -376,59 +441,69 @@ bn_mul_add_words: .body { .mib; setf.sig f8=r35 // w - mov pr.rot=0x400001<<16 - // ------^----- serves as (p48) at first (p26) + mov pr.rot=0x800001<<16 + // ------^----- serves as (p50) at first (p27) brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16 } -{ .mii; mov r14=r32 // rp - mov r15=r33 // ap +{ .mii; +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r14=0,r32 // rp + addp4 r15=0,r33 // ap +#else + mov r14=r32 // rp + mov r15=r33 // ap +#endif mov ar.lc=r10 } -{ .mii; mov r39=0 // serves as r33 at first (p26) - mov r18=r32 // rp copy - mov ar.ec=14 };; +{ .mii; mov r40=0 // serves as r35 at first (p27) +#if defined(_HPUX_SOURCE) && defined(_ILP32) + addp4 r18=0,r32 // rp copy +#else + mov r18=r32 // rp copy +#endif + mov ar.ec=15 };; -// This loop spins in 3*(n+13) ticks on Itanium and should spin in -// 2*(n+13) on "wider" IA-64 implementations (to be verified with new +// This loop spins in 3*(n+14) ticks on Itanium and should spin in +// 2*(n+14) on "wider" IA-64 implementations (to be verified with new // µ-architecture manuals as they become available). As usual it's // possible to compress the epilogue, down to 10 in this case, at the // cost of scalability. Compressed (and therefore non-scalable) loop -// running at 3*(n+10) would buy you ~10% on Itanium but take ~35% +// running at 3*(n+11) would buy you ~10% on Itanium but take ~35% // from "wider" IA-64 so let it be scalable! Special attention was // paid for having the loop body split at 64-byte boundary. ld8 is // scheduled for L1 cache as the data is more than likely there. // Indeed, bn_mul_words has put it there a moment ago:-) .L_bn_mul_add_words_ctop: -{ .mfi; (p25) getf.sig r36=f49 // low - (p21) xmpy.lu f45=f37,f8 - (p27) cmp.ltu p52,p48=r39,r38 } +{ .mfi; (p25) getf.sig r36=f52 // low + (p21) xmpy.lu f48=f37,f8 + (p28) cmp.ltu p54,p50=r41,r39 } { .mfi; (p16) ldf8 f32=[r15],8 - (p21) xmpy.hu f38=f37,f8 - (p27) add r43=r43,r39 };; -{ .mii; (p26) getf.sig r32=f43 // high - .pred.rel "mutex",p48,p52 - (p48) add r38=r37,r33 // (p26) - (p52) add r38=r37,r33,1 } // (p26) -{ .mfb; (p27) cmp.ltu.unc p56,p0=r43,r39 + (p21) xmpy.hu f40=f37,f8 + (p28) add r45=r45,r41 };; +{ .mii; (p25) getf.sig r32=f44 // high + .pred.rel "mutex",p50,p54 + (p50) add r40=r38,r35 // (p27) + (p54) add r40=r38,r35,1 } // (p27) +{ .mfb; (p28) cmp.ltu.unc p60,p0=r45,r41 (p0) nop.f 0x0 (p0) nop.b 0x0 } -{ .mii; (p26) ld8 r42=[r18],8 - (p58) cmp.eq.or p57,p0=-1,r44 - (p58) add r44=1,r44 } -{ .mfb; (p29) st8 [r14]=r45,8 +{ .mii; (p27) ld8 r44=[r18],8 + (p62) cmp.eq.or p61,p0=-1,r46 + (p62) add r46=1,r46 } +{ .mfb; (p30) st8 [r14]=r47,8 (p0) nop.f 0x0 br.ctop.sptk .L_bn_mul_add_words_ctop};; .L_bn_mul_add_words_cend: { .mii; nop.m 0x0 -.pred.rel "mutex",p51,p55 -(p51) add r8=r36,r0 -(p55) add r8=r36,r0,1 } +.pred.rel "mutex",p53,p57 +(p53) add r8=r38,r0 +(p57) add r8=r38,r0,1 } { .mfb; nop.m 0x0 nop.f 0x0 nop.b 0x0 };; { .mii; -(p59) add r8=1,r8 - mov pr=r9,-1 +(p63) add r8=1,r8 + mov pr=r9,0x1ffff mov ar.lc=r3 } { .mfb; rum 1<<5 // clear um.mfh nop.f 0x0 @@ -461,6 +536,10 @@ bn_sqr_words: mov r9=pr };; .body +#if defined(_HPUX_SOURCE) && defined(_ILP32) +{ .mii; addp4 r32=0,r32 + addp4 r33=0,r33 };; +#endif { .mib; mov pr.rot=1<<16 brp.loop.imp .L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16 @@ -492,7 +571,7 @@ bn_sqr_words: .L_bn_sqr_words_cend: { .mii; nop.m 0x0 - mov pr=r9,-1 + mov pr=r9,0x1ffff mov ar.lc=r3 } { .mfb; rum 1<<5 // clear um.mfh nop.f 0x0 @@ -526,7 +605,14 @@ bn_sqr_comba8: .prologue .fframe 0 .save ar.pfs,r2 +#if defined(_HPUX_SOURCE) && defined(_ILP32) { .mii; alloc r2=ar.pfs,2,1,0,0 + addp4 r33=0,r33 + addp4 r32=0,r32 };; +{ .mii; +#else +{ .mii; alloc r2=ar.pfs,2,1,0,0 +#endif mov r34=r33 add r14=8,r33 };; .body @@ -587,7 +673,14 @@ bn_mul_comba8: .prologue .fframe 0 .save ar.pfs,r2 +#if defined(_HPUX_SOURCE) && defined(_ILP32) { .mii; alloc r2=ar.pfs,3,0,0,0 + addp4 r33=0,r33 + addp4 r34=0,r34 };; +{ .mii; addp4 r32=0,r32 +#else +{ .mii; alloc r2=ar.pfs,3,0,0,0 +#endif add r14=8,r33 add r17=8,r34 } .body @@ -1138,7 +1231,14 @@ bn_sqr_comba4: .prologue .fframe 0 .save ar.pfs,r2 +#if defined(_HPUX_SOURCE) && defined(_ILP32) +{ .mii; alloc r2=ar.pfs,2,1,0,0 + addp4 r32=0,r32 + addp4 r33=0,r33 };; +{ .mii; +#else { .mii; alloc r2=ar.pfs,2,1,0,0 +#endif mov r34=r33 add r14=8,r33 };; .body @@ -1164,7 +1264,14 @@ bn_mul_comba4: .prologue .fframe 0 .save ar.pfs,r2 +#if defined(_HPUX_SOURCE) && defined(_ILP32) +{ .mii; alloc r2=ar.pfs,3,0,0,0 + addp4 r33=0,r33 + addp4 r34=0,r34 };; +{ .mii; addp4 r32=0,r32 +#else { .mii; alloc r2=ar.pfs,3,0,0,0 +#endif add r14=8,r33 add r17=8,r34 } .body @@ -1464,7 +1571,7 @@ bn_div_words: or r8=r8,r33 mov ar.pfs=r2 };; { .mii; shr.u r9=H,I // remainder if anybody wants it - mov pr=r10,-1 } + mov pr=r10,0x1ffff } { .mfb; br.ret.sptk.many b0 };; // Unsigned 64 by 32 (well, by 64 for the moment) bit integer division diff --git a/src/lib/libcrypto/bn/asm/pa-risc2.s b/src/lib/libcrypto/bn/asm/pa-risc2.s index af9730d062..f3b16290eb 100644 --- a/src/lib/libcrypto/bn/asm/pa-risc2.s +++ b/src/lib/libcrypto/bn/asm/pa-risc2.s @@ -747,8 +747,8 @@ bn_div_words .PROC .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN .IMPORT BN_num_bits_word,CODE - .IMPORT __iob,DATA - .IMPORT fprintf,CODE + ;--- not PIC .IMPORT __iob,DATA + ;--- not PIC .IMPORT fprintf,CODE .IMPORT abort,CODE .IMPORT $$div2U,MILLICODE .CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE @@ -844,12 +844,12 @@ $0006001A MOVIB,TR 2,%r8,$0006001C ;offset 0xa18 EXTRD,U %r3,63,32,%r7 ;offset 0xa1c $D2 - ADDIL LR'__iob-$global$,%r27,%r1 ;offset 0xa20 - LDIL LR'C$7,%r21 ;offset 0xa24 - LDO RR'__iob-$global$+32(%r1),%r26 ;offset 0xa28 - .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR ;in=24,25,26;out=28; - B,L fprintf,%r2 ;offset 0xa2c - LDO RR'C$7(%r21),%r25 ;offset 0xa30 + ;--- not PIC ADDIL LR'__iob-$global$,%r27,%r1 ;offset 0xa20 + ;--- not PIC LDIL LR'C$7,%r21 ;offset 0xa24 + ;--- not PIC LDO RR'__iob-$global$+32(%r1),%r26 ;offset 0xa28 + ;--- not PIC .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR ;in=24,25,26;out=28; + ;--- not PIC B,L fprintf,%r2 ;offset 0xa2c + ;--- not PIC LDO RR'C$7(%r21),%r25 ;offset 0xa30 .CALL ; B,L abort,%r2 ;offset 0xa34 NOP ;offset 0xa38 @@ -1605,14 +1605,14 @@ bn_mul_comba4 .PROCEND - .SPACE $TEXT$ - .SUBSPA $CODE$ - .SPACE $PRIVATE$,SORT=16 - .IMPORT $global$,DATA - .SPACE $TEXT$ - .SUBSPA $CODE$ - .SUBSPA $LIT$,ACCESS=0x2c -C$7 - .ALIGN 8 - .STRINGZ "Division would overflow (%d)\n" +;--- not PIC .SPACE $TEXT$ +;--- not PIC .SUBSPA $CODE$ +;--- not PIC .SPACE $PRIVATE$,SORT=16 +;--- not PIC .IMPORT $global$,DATA +;--- not PIC .SPACE $TEXT$ +;--- not PIC .SUBSPA $CODE$ +;--- not PIC .SUBSPA $LIT$,ACCESS=0x2c +;--- not PIC C$7 +;--- not PIC .ALIGN 8 +;--- not PIC .STRINGZ "Division would overflow (%d)\n" .END diff --git a/src/lib/libcrypto/bn/asm/x86_64-gcc.c b/src/lib/libcrypto/bn/asm/x86_64-gcc.c new file mode 100644 index 0000000000..b97b394661 --- /dev/null +++ b/src/lib/libcrypto/bn/asm/x86_64-gcc.c @@ -0,0 +1,575 @@ +/* + * x86_64 BIGNUM accelerator version 0.1, December 2002. + * + * Implemented by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real + * versions, like 1.0... + * A. Well, that's because this code is basically a quick-n-dirty + * proof-of-concept hack. As you can see it's implemented with + * inline assembler, which means that you're bound to GCC and that + * there must be a room for fine-tuning. + * + * Q. Why inline assembler? + * A. x86_64 features own ABI I'm not familiar with. Which is why + * I decided to let the compiler take care of subroutine + * prologue/epilogue as well as register allocation. + * + * Q. How much faster does it get? + * A. Unfortunately people sitting on x86_64 hardware are prohibited + * to disclose the performance numbers, so they (SuSE labs to be + * specific) wouldn't tell me. However! Very similar coding technique + * (reaching out for 128-bit result from 64x64-bit multiplication) + * results in >3 times performance improvement on MIPS and I see no + * reason why gain on x86_64 would be so much different:-) + */ + +#define BN_ULONG unsigned long + +/* + * "m"(a), "+m"(r) is the way to favor DirectPath µ-code; + * "g"(0) let the compiler to decide where does it + * want to keep the value of zero; + */ +#define mul_add(r,a,word,carry) do { \ + register BN_ULONG high,low; \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(word),"m"(a) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+r"(carry),"+d"(high)\ + : "a"(low),"g"(0) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+m"(r),"+d"(high) \ + : "r"(carry),"g"(0) \ + : "cc"); \ + carry=high; \ + } while (0) + +#define mul(r,a,word,carry) do { \ + register BN_ULONG high,low; \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(word),"g"(a) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+r"(carry),"+d"(high)\ + : "a"(low),"g"(0) \ + : "cc"); \ + (r)=carry, carry=high; \ + } while (0) + +#define sqr(r0,r1,a) \ + asm ("mulq %2" \ + : "=a"(r0),"=d"(r1) \ + : "a"(a) \ + : "cc"); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG c1=0; + + if (num <= 0) return(c1); + + while (num&~3) + { + mul_add(rp[0],ap[0],w,c1); + mul_add(rp[1],ap[1],w,c1); + mul_add(rp[2],ap[2],w,c1); + mul_add(rp[3],ap[3],w,c1); + ap+=4; rp+=4; num-=4; + } + if (num) + { + mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1; + mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1; + mul_add(rp[2],ap[2],w,c1); return c1; + } + + return(c1); + } + +BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) + { + BN_ULONG c1=0; + + if (num <= 0) return(c1); + + while (num&~3) + { + mul(rp[0],ap[0],w,c1); + mul(rp[1],ap[1],w,c1); + mul(rp[2],ap[2],w,c1); + mul(rp[3],ap[3],w,c1); + ap+=4; rp+=4; num-=4; + } + if (num) + { + mul(rp[0],ap[0],w,c1); if (--num == 0) return c1; + mul(rp[1],ap[1],w,c1); if (--num == 0) return c1; + mul(rp[2],ap[2],w,c1); + } + return(c1); + } + +void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n) + { + if (n <= 0) return; + + while (n&~3) + { + sqr(r[0],r[1],a[0]); + sqr(r[2],r[3],a[1]); + sqr(r[4],r[5],a[2]); + sqr(r[6],r[7],a[3]); + a+=4; r+=8; n-=4; + } + if (n) + { + sqr(r[0],r[1],a[0]); if (--n == 0) return; + sqr(r[2],r[3],a[1]); if (--n == 0) return; + sqr(r[4],r[5],a[2]); + } + } + +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ BN_ULONG ret,waste; + + asm ("divq %3" + : "=a"(ret),"=d"(waste) + : "a"(l),"d"(h),"g"(d) + : "cc"); + + return ret; +} + +BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) +{ BN_ULONG ret,i; + + if (n <= 0) return 0; + + asm ( + " subq %2,%2 \n" + ".align 16 \n" + "1: movq (%4,%2,8),%0 \n" + " adcq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " leaq 1(%2),%2 \n" + " loop 1b \n" + " sbbq %0,%0 \n" + : "+a"(ret),"+c"(n),"+r"(i) + : "r"(rp),"r"(ap),"r"(bp) + : "cc" + ); + + return ret&1; +} + +#ifndef SIMICS +BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n) +{ BN_ULONG ret,i; + + if (n <= 0) return 0; + + asm ( + " subq %2,%2 \n" + ".align 16 \n" + "1: movq (%4,%2,8),%0 \n" + " sbbq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " leaq 1(%2),%2 \n" + " loop 1b \n" + " sbbq %0,%0 \n" + : "+a"(ret),"+c"(n),"+r"(i) + : "r"(rp),"r"(ap),"r"(bp) + : "cc" + ); + + return ret&1; +} +#else +/* Simics 1.4<7 has buggy sbbq:-( */ +#define BN_MASK2 0xffffffffffffffffL +BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) + { + BN_ULONG t1,t2; + int c=0; + + if (n <= 0) return((BN_ULONG)0); + + for (;;) + { + t1=a[0]; t2=b[0]; + r[0]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[1]; t2=b[1]; + r[1]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[2]; t2=b[2]; + r[2]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + t1=a[3]; t2=b[3]; + r[3]=(t1-t2-c)&BN_MASK2; + if (t1 != t2) c=(t1 < t2); + if (--n <= 0) break; + + a+=4; + b+=4; + r+=4; + } + return(c); + } +#endif + +/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ +/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ +/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ + +#if 0 +/* original macros are kept for reference purposes */ +#define mul_add_c(a,b,c0,c1,c2) { \ + BN_ULONG ta=(a),tb=(b); \ + t1 = ta * tb; \ + t2 = BN_UMULT_HIGH(ta,tb); \ + c0 += t1; t2 += (c0 + */ +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divq %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "g"(d0) \ + : "cc"); \ + q; \ + }) +# define REMAINDER_IS_ALREADY_CALCULATED # endif /* __ */ # endif /* __GNUC__ */ #endif /* OPENSSL_NO_ASM */ @@ -268,6 +282,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, q=(BN_ULONG)(((((BN_ULLONG)n0)< 0x%08X\n", + n0, n1, d0, q); +#endif #endif #ifndef REMAINDER_IS_ALREADY_CALCULATED @@ -292,11 +311,18 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, BN_ULONG t2l,t2h,ql,qh; q=bn_div_words(n0,n1,d0); +#ifdef BN_DEBUG_LEVITTE + fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ +X) -> 0x%08X\n", + n0, n1, d0, q); +#endif #ifndef REMAINDER_IS_ALREADY_CALCULATED rem=(n1-q*d0)&BN_MASK2; #endif -#ifdef BN_UMULT_HIGH +#if defined(BN_UMULT_LOHI) + BN_UMULT_LOHI(t2l,t2h,d1,q); +#elif defined(BN_UMULT_HIGH) t2l = d1 * q; t2h = BN_UMULT_HIGH(d1,q); #else diff --git a/src/lib/libcrypto/bn/bn_lcl.h b/src/lib/libcrypto/bn/bn_lcl.h index 8a4dba375a..5614bc6164 100644 --- a/src/lib/libcrypto/bn/bn_lcl.h +++ b/src/lib/libcrypto/bn/bn_lcl.h @@ -230,6 +230,21 @@ struct bignum_ctx : "r"(a), "r"(b)); \ ret; }) # endif /* compiler */ +# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) +# if defined(__GNUC__) +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret,discard; \ + asm ("mulq %3" \ + : "=a"(discard),"=d"(ret) \ + : "a"(a), "g"(b) \ + : "cc"); \ + ret; }) +# define BN_UMULT_LOHI(low,high,a,b) \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(a),"g"(b) \ + : "cc"); +# endif # endif /* cpu */ #endif /* OPENSSL_NO_ASM */ @@ -337,7 +352,7 @@ struct bignum_ctx #define LBITS(a) ((a)&BN_MASK2l) #define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) -#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<>BN_BITS2)&BN_MASKl) @@ -353,7 +368,7 @@ struct bignum_ctx lt=(bl)*(lt); \ m1=(bl)*(ht); \ ht =(bh)*(ht); \ - m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \ + m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \ ht+=HBITS(m); \ m1=L2HBITS(m); \ lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \ @@ -418,20 +433,19 @@ void bn_sqr_comba4(BN_ULONG *r,const BN_ULONG *a); int bn_cmp_words(const BN_ULONG *a,const BN_ULONG *b,int n); int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl); +#if 0 +/* bn_mul.c rollback */ void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, int dna,int dnb,BN_ULONG *t); void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n,int tna,int tnb,BN_ULONG *t); +#endif void bn_sqr_recursive(BN_ULONG *r,const BN_ULONG *a, int n2, BN_ULONG *t); void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n); void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2, BN_ULONG *t); void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2, BN_ULONG *t); -BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl); -BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl); #ifdef __cplusplus } diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index 8abe095af2..fa0ff485ad 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c @@ -263,12 +263,12 @@ void BN_clear_free(BIGNUM *a) if (a == NULL) return; if (a->d != NULL) { - memset(a->d,0,a->dmax*sizeof(a->d[0])); + OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0])); if (!(BN_get_flags(a,BN_FLG_STATIC_DATA))) OPENSSL_free(a->d); } i=BN_get_flags(a,BN_FLG_MALLOCED); - memset(a,0,sizeof(BIGNUM)); + OPENSSL_cleanse(a,sizeof(BIGNUM)); if (i) OPENSSL_free(a); } diff --git a/src/lib/libcrypto/bn/bn_mul.c b/src/lib/libcrypto/bn/bn_mul.c index b03458d002..cb93ac3356 100644 --- a/src/lib/libcrypto/bn/bn_mul.c +++ b/src/lib/libcrypto/bn/bn_mul.c @@ -56,325 +56,10 @@ * [including the GNU Public Licence.] */ -#ifndef BN_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - #include -#include #include "cryptlib.h" #include "bn_lcl.h" -#if defined(OPENSSL_NO_ASM) || !(defined(__i386) || defined(__i386__)) || defined(__DJGPP__) /* Assembler implementation exists only for x86 */ -/* Here follows specialised variants of bn_add_words() and - bn_sub_words(). They have the property performing operations on - arrays of different sizes. The sizes of those arrays is expressed through - cl, which is the common length ( basicall, min(len(a),len(b)) ), and dl, - which is the delta between the two lengths, calculated as len(a)-len(b). - All lengths are the number of BN_ULONGs... For the operations that require - a result array as parameter, it must have the length cl+abs(dl). - These functions should probably end up in bn_asm.c as soon as there are - assembler counterparts for the systems that use assembler files. */ - -BN_ULONG bn_sub_part_words(BN_ULONG *r, - const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl) - { - BN_ULONG c, t; - - assert(cl >= 0); - c = bn_sub_words(r, a, b, cl); - - if (dl == 0) - return c; - - r += cl; - a += cl; - b += cl; - - if (dl < 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c); -#endif - for (;;) - { - t = b[0]; - r[0] = (0-t-c)&BN_MASK2; - if (t != 0) c=1; - if (++dl >= 0) break; - - t = b[1]; - r[1] = (0-t-c)&BN_MASK2; - if (t != 0) c=1; - if (++dl >= 0) break; - - t = b[2]; - r[2] = (0-t-c)&BN_MASK2; - if (t != 0) c=1; - if (++dl >= 0) break; - - t = b[3]; - r[3] = (0-t-c)&BN_MASK2; - if (t != 0) c=1; - if (++dl >= 0) break; - - b += 4; - r += 4; - } - } - else - { - int save_dl = dl; -#ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, dl, c); -#endif - while(c) - { - t = a[0]; - r[0] = (t-c)&BN_MASK2; - if (t != 0) c=0; - if (--dl <= 0) break; - - t = a[1]; - r[1] = (t-c)&BN_MASK2; - if (t != 0) c=0; - if (--dl <= 0) break; - - t = a[2]; - r[2] = (t-c)&BN_MASK2; - if (t != 0) c=0; - if (--dl <= 0) break; - - t = a[3]; - r[3] = (t-c)&BN_MASK2; - if (t != 0) c=0; - if (--dl <= 0) break; - - save_dl = dl; - a += 4; - r += 4; - } - if (dl > 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", cl, dl); -#endif - if (save_dl > dl) - { - switch (save_dl - dl) - { - case 1: - r[1] = a[1]; - if (--dl <= 0) break; - case 2: - r[2] = a[2]; - if (--dl <= 0) break; - case 3: - r[3] = a[3]; - if (--dl <= 0) break; - } - a += 4; - r += 4; - } - } - if (dl > 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", cl, dl); -#endif - for(;;) - { - r[0] = a[0]; - if (--dl <= 0) break; - r[1] = a[1]; - if (--dl <= 0) break; - r[2] = a[2]; - if (--dl <= 0) break; - r[3] = a[3]; - if (--dl <= 0) break; - - a += 4; - r += 4; - } - } - } - return c; - } -#endif - -BN_ULONG bn_add_part_words(BN_ULONG *r, - const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl) - { - BN_ULONG c, l, t; - - assert(cl >= 0); - c = bn_add_words(r, a, b, cl); - - if (dl == 0) - return c; - - r += cl; - a += cl; - b += cl; - - if (dl < 0) - { - int save_dl = dl; -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, dl, c); -#endif - while (c) - { - l=(c+b[0])&BN_MASK2; - c=(l < c); - r[0]=l; - if (++dl >= 0) break; - - l=(c+b[1])&BN_MASK2; - c=(l < c); - r[1]=l; - if (++dl >= 0) break; - - l=(c+b[2])&BN_MASK2; - c=(l < c); - r[2]=l; - if (++dl >= 0) break; - - l=(c+b[3])&BN_MASK2; - c=(l < c); - r[3]=l; - if (++dl >= 0) break; - - save_dl = dl; - b+=4; - r+=4; - } - if (dl < 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", cl, dl); -#endif - if (save_dl < dl) - { - switch (dl - save_dl) - { - case 1: - r[1] = b[1]; - if (++dl >= 0) break; - case 2: - r[2] = b[2]; - if (++dl >= 0) break; - case 3: - r[3] = b[3]; - if (++dl >= 0) break; - } - b += 4; - r += 4; - } - } - if (dl < 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", cl, dl); -#endif - for(;;) - { - r[0] = b[0]; - if (++dl >= 0) break; - r[1] = b[1]; - if (++dl >= 0) break; - r[2] = b[2]; - if (++dl >= 0) break; - r[3] = b[3]; - if (++dl >= 0) break; - - b += 4; - r += 4; - } - } - } - else - { - int save_dl = dl; -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl); -#endif - while (c) - { - t=(a[0]+c)&BN_MASK2; - c=(t < c); - r[0]=t; - if (--dl <= 0) break; - - t=(a[1]+c)&BN_MASK2; - c=(t < c); - r[1]=t; - if (--dl <= 0) break; - - t=(a[2]+c)&BN_MASK2; - c=(t < c); - r[2]=t; - if (--dl <= 0) break; - - t=(a[3]+c)&BN_MASK2; - c=(t < c); - r[3]=t; - if (--dl <= 0) break; - - save_dl = dl; - a+=4; - r+=4; - } -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, dl); -#endif - if (dl > 0) - { - if (save_dl > dl) - { - switch (save_dl - dl) - { - case 1: - r[1] = a[1]; - if (--dl <= 0) break; - case 2: - r[2] = a[2]; - if (--dl <= 0) break; - case 3: - r[3] = a[3]; - if (--dl <= 0) break; - } - a += 4; - r += 4; - } - } - if (dl > 0) - { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", cl, dl); -#endif - for(;;) - { - r[0] = a[0]; - if (--dl <= 0) break; - r[1] = a[1]; - if (--dl <= 0) break; - r[2] = a[2]; - if (--dl <= 0) break; - r[3] = a[3]; - if (--dl <= 0) break; - - a += 4; - r += 4; - } - } - } - return c; - } - #ifdef BN_RECURSION /* Karatsuba recursive multiplication algorithm * (cf. Knuth, The Art of Computer Programming, Vol. 2) */ @@ -390,15 +75,14 @@ BN_ULONG bn_add_part_words(BN_ULONG *r, * a[1]*b[1] */ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, - int dna, int dnb, BN_ULONG *t) + BN_ULONG *t) { int n=n2/2,c1,c2; - int tna=n+dna, tnb=n+dnb; unsigned int neg,zero; BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_recursive %d * %d\n",n2,n2); + printf(" bn_mul_recursive %d * %d\n",n2,n2); # endif # ifdef BN_MUL_COMBA # if 0 @@ -408,40 +92,34 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, return; } # endif - /* Only call bn_mul_comba 8 if n2 == 8 and the - * two arrays are complete [steve] - */ - if (n2 == 8 && dna == 0 && dnb == 0) + if (n2 == 8) { bn_mul_comba8(r,a,b); return; } # endif /* BN_MUL_COMBA */ - /* Else do normal multiply */ if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { - bn_mul_normal(r,a,n2+dna,b,n2+dnb); - if ((dna + dnb) < 0) - memset(&r[2*n2 + dna + dnb], 0, - sizeof(BN_ULONG) * -(dna + dnb)); + /* This should not happen */ + bn_mul_normal(r,a,n2,b,n2); return; } /* r=(a[0]-a[1])*(b[1]-b[0]) */ - c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna); - c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n); + c1=bn_cmp_words(a,&(a[n]),n); + c2=bn_cmp_words(&(b[n]),b,n); zero=neg=0; switch (c1*3+c2) { case -4: - bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */ - bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */ + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ break; case -3: zero=1; break; case -2: - bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */ - bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */ + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ neg=1; break; case -1: @@ -450,22 +128,21 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, zero=1; break; case 2: - bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */ - bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */ + bn_sub_words(t, a, &(a[n]),n); /* + */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ neg=1; break; case 3: zero=1; break; case 4: - bn_sub_part_words(t, a, &(a[n]),tna,n-tna); - bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); + bn_sub_words(t, a, &(a[n]),n); + bn_sub_words(&(t[n]),&(b[n]),b, n); break; } # ifdef BN_MUL_COMBA - if (n == 4 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba4 could take - extra args to do this well */ + if (n == 4) { if (!zero) bn_mul_comba4(&(t[n2]),t,&(t[n])); @@ -475,9 +152,7 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, bn_mul_comba4(r,a,b); bn_mul_comba4(&(r[n2]),&(a[n]),&(b[n])); } - else if (n == 8 && dna == 0 && dnb == 0) /* XXX: bn_mul_comba8 could - take extra args to do this - well */ + else if (n == 8) { if (!zero) bn_mul_comba8(&(t[n2]),t,&(t[n])); @@ -492,11 +167,11 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, { p= &(t[n2*2]); if (!zero) - bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p); + bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); else memset(&(t[n2]),0,n2*sizeof(BN_ULONG)); - bn_mul_recursive(r,a,b,n,0,0,p); - bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,dna,dnb,p); + bn_mul_recursive(r,a,b,n,p); + bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),n,p); } /* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign @@ -545,39 +220,39 @@ void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, /* n+tn is the word length * t needs to be n*4 is size, as does r */ -void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, - int tna, int tnb, BN_ULONG *t) +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int tn, + int n, BN_ULONG *t) { int i,j,n2=n*2; unsigned int c1,c2,neg,zero; BN_ULONG ln,lo,*p; # ifdef BN_COUNT - fprintf(stderr," bn_mul_part_recursive (%d+%d) * (%d+%d)\n", - tna, n, tnb, n); + printf(" bn_mul_part_recursive %d * %d\n",tn+n,tn+n); # endif if (n < 8) { - bn_mul_normal(r,a,n+tna,b,n+tnb); + i=tn+n; + bn_mul_normal(r,a,i,b,i); return; } /* r=(a[0]-a[1])*(b[1]-b[0]) */ - c1=bn_cmp_part_words(a,&(a[n]),tna,n-tna); - c2=bn_cmp_part_words(&(b[n]),b,tnb,tnb-n); + c1=bn_cmp_words(a,&(a[n]),n); + c2=bn_cmp_words(&(b[n]),b,n); zero=neg=0; switch (c1*3+c2) { case -4: - bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */ - bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */ + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ break; case -3: zero=1; /* break; */ case -2: - bn_sub_part_words(t, &(a[n]),a, tna,tna-n); /* - */ - bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); /* + */ + bn_sub_words(t, &(a[n]),a, n); /* - */ + bn_sub_words(&(t[n]),&(b[n]),b, n); /* + */ neg=1; break; case -1: @@ -586,16 +261,16 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, zero=1; /* break; */ case 2: - bn_sub_part_words(t, a, &(a[n]),tna,n-tna); /* + */ - bn_sub_part_words(&(t[n]),b, &(b[n]),tnb,n-tnb); /* - */ + bn_sub_words(t, a, &(a[n]),n); /* + */ + bn_sub_words(&(t[n]),b, &(b[n]),n); /* - */ neg=1; break; case 3: zero=1; /* break; */ case 4: - bn_sub_part_words(t, a, &(a[n]),tna,n-tna); - bn_sub_part_words(&(t[n]),&(b[n]),b, tnb,tnb-n); + bn_sub_words(t, a, &(a[n]),n); + bn_sub_words(&(t[n]),&(b[n]),b, n); break; } /* The zero case isn't yet implemented here. The speedup @@ -614,59 +289,54 @@ void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, { bn_mul_comba8(&(t[n2]),t,&(t[n])); bn_mul_comba8(r,a,b); - bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb); - memset(&(r[n2+tna+tnb]),0,sizeof(BN_ULONG)*(n2-tna-tnb)); + bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); + memset(&(r[n2+tn*2]),0,sizeof(BN_ULONG)*(n2-tn*2)); } else { p= &(t[n2*2]); - bn_mul_recursive(&(t[n2]),t,&(t[n]),n,0,0,p); - bn_mul_recursive(r,a,b,n,0,0,p); + bn_mul_recursive(&(t[n2]),t,&(t[n]),n,p); + bn_mul_recursive(r,a,b,n,p); i=n/2; /* If there is only a bottom half to the number, * just do it */ - if (tna > tnb) - j = tna - i; - else - j = tnb - i; + j=tn-i; if (j == 0) { - bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]), - i,tna-i,tnb-i,p); + bn_mul_recursive(&(r[n2]),&(a[n]),&(b[n]),i,p); memset(&(r[n2+i*2]),0,sizeof(BN_ULONG)*(n2-i*2)); } else if (j > 0) /* eg, n == 16, i == 8 and tn == 11 */ { bn_mul_part_recursive(&(r[n2]),&(a[n]),&(b[n]), - i,tna-i,tnb-i,p); - memset(&(r[n2+tna+tnb]),0, - sizeof(BN_ULONG)*(n2-tna-tnb)); + j,i,p); + memset(&(r[n2+tn*2]),0, + sizeof(BN_ULONG)*(n2-tn*2)); } else /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ { memset(&(r[n2]),0,sizeof(BN_ULONG)*n2); - if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL - && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) + if (tn < BN_MUL_RECURSIVE_SIZE_NORMAL) { - bn_mul_normal(&(r[n2]),&(a[n]),tna,&(b[n]),tnb); + bn_mul_normal(&(r[n2]),&(a[n]),tn,&(b[n]),tn); } else { for (;;) { i/=2; - if (i < tna && i < tnb) + if (i < tn) { bn_mul_part_recursive(&(r[n2]), &(a[n]),&(b[n]), - i,tna-i,tnb-i,p); + tn-i,i,p); break; } - else if (i <= tna && i <= tnb) + else if (i == tn) { bn_mul_recursive(&(r[n2]), &(a[n]),&(b[n]), - i,tna-i,tnb-i,p); + i,p); break; } } @@ -727,10 +397,10 @@ void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, int n=n2/2; # ifdef BN_COUNT - fprintf(stderr," bn_mul_low_recursive %d * %d\n",n2,n2); + printf(" bn_mul_low_recursive %d * %d\n",n2,n2); # endif - bn_mul_recursive(r,a,b,n,0,0,&(t[0])); + bn_mul_recursive(r,a,b,n,&(t[0])); if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) { bn_mul_low_recursive(&(t[0]),&(a[0]),&(b[n]),n,&(t[n2])); @@ -761,7 +431,7 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, BN_ULONG ll,lc,*lp,*mp; # ifdef BN_COUNT - fprintf(stderr," bn_mul_high %d * %d\n",n2,n2); + printf(" bn_mul_high %d * %d\n",n2,n2); # endif n=n2/2; @@ -814,8 +484,8 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, else # endif { - bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,0,0,&(t[n2])); - bn_mul_recursive(r,&(a[n]),&(b[n]),n,0,0,&(t[n2])); + bn_mul_recursive(&(t[0]),&(r[0]),&(r[n]),n,&(t[n2])); + bn_mul_recursive(r,&(a[n]),&(b[n]),n,&(t[n2])); } /* s0 == low(al*bl) @@ -940,19 +610,19 @@ void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { - int ret=0; int top,al,bl; BIGNUM *rr; + int ret = 0; #if defined(BN_MUL_COMBA) || defined(BN_RECURSION) int i; #endif #ifdef BN_RECURSION - BIGNUM *t=NULL; - int j=0,k; + BIGNUM *t; + int j,k; #endif #ifdef BN_COUNT - fprintf(stderr,"BN_mul %d * %d\n",a->top,b->top); + printf("BN_mul %d * %d\n",a->top,b->top); #endif bn_check_top(a); @@ -1005,55 +675,21 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) #ifdef BN_RECURSION if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { - if (i >= -1 && i <= 1) + if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA) && bldmax) { - int sav_j =0; - /* Find out the power of two lower or equal - to the longest of the two numbers */ - if (i >= 0) - { - j = BN_num_bits_word((BN_ULONG)al); - } - if (i == -1) - { - j = BN_num_bits_word((BN_ULONG)bl); - } - sav_j = j; - j = 1<<(j-1); - assert(j <= al || j <= bl); - k = j+j; - t = BN_CTX_get(ctx); - if (al > j || bl > j) - { - bn_wexpand(t,k*4); - bn_wexpand(rr,k*4); - bn_mul_part_recursive(rr->d,a->d,b->d, - j,al-j,bl-j,t->d); - } - else /* al <= j || bl <= j */ - { - bn_wexpand(t,k*2); - bn_wexpand(rr,k*2); - bn_mul_recursive(rr->d,a->d,b->d, - j,al-j,bl-j,t->d); - } - rr->top=top; - goto end; - } -#if 0 - if (i == 1 && !BN_get_flags(b,BN_FLG_STATIC_DATA)) - { - BIGNUM *tmp_bn = (BIGNUM *)b; - if (bn_wexpand(tmp_bn,al) == NULL) goto err; - tmp_bn->d[bl]=0; +#if 0 /* tribute to const-ification, bldmax above covers for this */ + if (bn_wexpand(b,al) == NULL) goto err; +#endif + b->d[bl]=0; bl++; i--; } - else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA)) + else if (i == -1 && !BN_get_flags(a,BN_FLG_STATIC_DATA) && aldmax) { - BIGNUM *tmp_bn = (BIGNUM *)a; - if (bn_wexpand(tmp_bn,bl) == NULL) goto err; - tmp_bn->d[al]=0; +#if 0 /* tribute to const-ification, aldmax above covers for this */ + if (bn_wexpand(a,bl) == NULL) goto err; +#endif + a->d[al]=0; al++; i++; } @@ -1070,17 +706,26 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) if (bn_wexpand(t,k*2) == NULL) goto err; if (bn_wexpand(rr,k*2) == NULL) goto err; bn_mul_recursive(rr->d,a->d,b->d,al,t->d); + rr->top=top; + goto end; } +#if 0 /* tribute to const-ification, rsa/dsa performance is not affected */ else { - if (bn_wexpand(t,k*4) == NULL) goto err; - if (bn_wexpand(rr,k*4) == NULL) goto err; + if (bn_wexpand(a,k) == NULL ) goto err; + if (bn_wexpand(b,k) == NULL ) goto err; + if (bn_wexpand(t,k*4) == NULL ) goto err; + if (bn_wexpand(rr,k*4) == NULL ) goto err; + for (i=a->top; id[i]=0; + for (i=b->top; id[i]=0; bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d); } rr->top=top; goto end; - } #endif + } } #endif /* BN_RECURSION */ if (bn_wexpand(rr,top) == NULL) goto err; @@ -1103,7 +748,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) BN_ULONG *rr; #ifdef BN_COUNT - fprintf(stderr," bn_mul_normal %d * %d\n",na,nb); + printf(" bn_mul_normal %d * %d\n",na,nb); #endif if (na < nb) @@ -1116,13 +761,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) } rr= &(r[na]); - if (nb <= 0) - { - (void)bn_mul_words(r,a,na,0); - return; - } - else - rr[0]=bn_mul_words(r,a,na,b[0]); + rr[0]=bn_mul_words(r,a,na,b[0]); for (;;) { @@ -1143,7 +782,7 @@ void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) { #ifdef BN_COUNT - fprintf(stderr," bn_mul_low_normal %d * %d\n",n,n); + printf(" bn_mul_low_normal %d * %d\n",n,n); #endif bn_mul_words(r,a,n,b[0]); diff --git a/src/lib/libcrypto/bn/bn_prime.c b/src/lib/libcrypto/bn/bn_prime.c index 918b9237c6..e072d9255c 100644 --- a/src/lib/libcrypto/bn/bn_prime.c +++ b/src/lib/libcrypto/bn/bn_prime.c @@ -140,6 +140,7 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BN_CTX *ctx; int checks = BN_prime_checks_for_size(bits); + BN_init(&t); ctx=BN_CTX_new(); if (ctx == NULL) goto err; if (ret == NULL) @@ -148,7 +149,6 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, } else rnd=ret; - BN_init(&t); loop: /* make a random number and set the top and bottom bits */ if (add == NULL) diff --git a/src/lib/libcrypto/bn/bn_rand.c b/src/lib/libcrypto/bn/bn_rand.c index 9e08ccd22e..893c9d2af9 100644 --- a/src/lib/libcrypto/bn/bn_rand.c +++ b/src/lib/libcrypto/bn/bn_rand.c @@ -201,7 +201,7 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) err: if (buf != NULL) { - memset(buf,0,bytes); + OPENSSL_cleanse(buf,bytes); OPENSSL_free(buf); } return(ret); diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c index cd59baa2c4..988e0ca7b3 100644 --- a/src/lib/libcrypto/bn/bn_word.c +++ b/src/lib/libcrypto/bn/bn_word.c @@ -123,7 +123,10 @@ int BN_add_word(BIGNUM *a, BN_ULONG w) i=0; for (;;) { - l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; + if (i >= a->top) + l=w; + else + l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; a->d[i]=l; if (w > l) w=1; diff --git a/src/lib/libcrypto/buffer/buffer.c b/src/lib/libcrypto/buffer/buffer.c index 9299baba9e..d96487e7db 100644 --- a/src/lib/libcrypto/buffer/buffer.c +++ b/src/lib/libcrypto/buffer/buffer.c @@ -125,6 +125,43 @@ int BUF_MEM_grow(BUF_MEM *str, int len) return(len); } +int BUF_MEM_grow_clean(BUF_MEM *str, int len) + { + char *ret; + unsigned int n; + + if (str->length >= len) + { + memset(&str->data[len],0,str->length-len); + str->length=len; + return(len); + } + if (str->max >= len) + { + memset(&str->data[str->length],0,len-str->length); + str->length=len; + return(len); + } + n=(len+3)/3*4; + if (str->data == NULL) + ret=OPENSSL_malloc(n); + else + ret=OPENSSL_realloc_clean(str->data,str->max,n); + if (ret == NULL) + { + BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + len=0; + } + else + { + str->data=ret; + str->max=n; + memset(&str->data[str->length],0,len-str->length); + str->length=len; + } + return(len); + } + char *BUF_strdup(const char *str) { char *ret; @@ -143,3 +180,23 @@ char *BUF_strdup(const char *str) return(ret); } +size_t BUF_strlcpy(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 1 && *src; size--) + { + *dst++ = *src++; + l++; + } + if (size) + *dst = '\0'; + return l + strlen(src); + } + +size_t BUF_strlcat(char *dst, const char *src, size_t size) + { + size_t l = 0; + for(; size > 0 && *dst; size--, dst++) + l++; + return l + BUF_strlcpy(dst, src, size); + } diff --git a/src/lib/libcrypto/buffer/buffer.h b/src/lib/libcrypto/buffer/buffer.h index 11e2d0359a..465dc34f3f 100644 --- a/src/lib/libcrypto/buffer/buffer.h +++ b/src/lib/libcrypto/buffer/buffer.h @@ -63,6 +63,9 @@ extern "C" { #endif +#include +#include + typedef struct buf_mem_st { int length; /* current number of bytes */ @@ -73,8 +76,14 @@ typedef struct buf_mem_st BUF_MEM *BUF_MEM_new(void); void BUF_MEM_free(BUF_MEM *a); int BUF_MEM_grow(BUF_MEM *str, int len); +int BUF_MEM_grow_clean(BUF_MEM *str, int len); char * BUF_strdup(const char *str); +/* safe string functions */ +size_t BUF_strlcpy(char *dst,const char *src,size_t siz); +size_t BUF_strlcat(char *dst,const char *src,size_t siz); + + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/src/lib/libcrypto/comp/c_zlib.c b/src/lib/libcrypto/comp/c_zlib.c index cd2f8a491b..8c0876151a 100644 --- a/src/lib/libcrypto/comp/c_zlib.c +++ b/src/lib/libcrypto/comp/c_zlib.c @@ -208,11 +208,11 @@ COMP_METHOD *COMP_zlib(void) = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); zlib_loaded++; - meth = &zlib_method; } } -#elif defined(ZLIB) +#endif +#if defined(ZLIB) || defined(ZLIB_SHARED) meth = &zlib_method; #endif diff --git a/src/lib/libcrypto/conf/conf_def.c b/src/lib/libcrypto/conf/conf_def.c index 5e194de60e..57d2739ae0 100644 --- a/src/lib/libcrypto/conf/conf_def.c +++ b/src/lib/libcrypto/conf/conf_def.c @@ -208,7 +208,8 @@ static int def_load(CONF *conf, const char *name, long *line) static int def_load_bio(CONF *conf, BIO *in, long *line) { -#define BUFSIZE 512 +/* The macro BUFSIZE conflicts with a system macro in VxWorks */ +#define CONFBUFSIZE 512 int bufnum=0,i,ii; BUF_MEM *buff=NULL; char *s,*p,*end; @@ -252,20 +253,21 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) section_sk=(STACK_OF(CONF_VALUE) *)sv->value; bufnum=0; + again=0; for (;;) { - again=0; - if (!BUF_MEM_grow(buff,bufnum+BUFSIZE)) + if (!BUF_MEM_grow(buff,bufnum+CONFBUFSIZE)) { CONFerr(CONF_F_CONF_LOAD_BIO,ERR_R_BUF_LIB); goto err; } p= &(buff->data[bufnum]); *p='\0'; - BIO_gets(in, p, BUFSIZE-1); - p[BUFSIZE-1]='\0'; + BIO_gets(in, p, CONFBUFSIZE-1); + p[CONFBUFSIZE-1]='\0'; ii=i=strlen(p); - if (i == 0) break; + if (i == 0 && !again) break; + again=0; while (i > 0) { if ((p[i-1] != '\r') && (p[i-1] != '\n')) @@ -275,7 +277,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) } /* we removed some trailing stuff so there is a new * line on the end. */ - if (i == ii) + if (ii && i == ii) again=1; /* long line */ else { @@ -627,7 +629,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) CONFerr(CONF_F_STR_COPY,CONF_R_VARIABLE_HAS_NO_VALUE); goto err; } - BUF_MEM_grow(buf,(strlen(p)+len-(e-from))); + BUF_MEM_grow_clean(buf,(strlen(p)+len-(e-from))); while (*p) buf->data[to++]= *(p++); from=e; diff --git a/src/lib/libcrypto/conf/conf_mall.c b/src/lib/libcrypto/conf/conf_mall.c index d702af689b..4ba40cf44c 100644 --- a/src/lib/libcrypto/conf/conf_mall.c +++ b/src/lib/libcrypto/conf/conf_mall.c @@ -63,7 +63,9 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif /* Load all OpenSSL builtin modules */ @@ -71,6 +73,8 @@ void OPENSSL_load_builtin_modules(void) { /* Add builtin modules here */ ASN1_add_oid_module(); +#ifndef OPENSSL_NO_ENGINE ENGINE_add_conf_module(); +#endif } diff --git a/src/lib/libcrypto/conf/conf_sap.c b/src/lib/libcrypto/conf/conf_sap.c index 97fb174303..e15c2e5546 100644 --- a/src/lib/libcrypto/conf/conf_sap.c +++ b/src/lib/libcrypto/conf/conf_sap.c @@ -63,7 +63,9 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif /* This is the automatic configuration loader: it is called automatically by * OpenSSL when any of a number of standard initialisation functions are called, @@ -78,8 +80,10 @@ void OPENSSL_config(const char *config_name) return; OPENSSL_load_builtin_modules(); +#ifndef OPENSSL_NO_ENGINE /* Need to load ENGINEs */ ENGINE_load_builtin_engines(); +#endif /* Add others here? */ diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c index 612b3b93b4..2924def2bb 100644 --- a/src/lib/libcrypto/cryptlib.c +++ b/src/lib/libcrypto/cryptlib.c @@ -89,6 +89,7 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] = "ssl_session", "ssl_sess_cert", "ssl", + "ssl_method", "rand", "rand2", "debug_malloc", @@ -103,7 +104,8 @@ static const char* lock_names[CRYPTO_NUM_LOCKS] = "dynlock", "engine", "ui", -#if CRYPTO_NUM_LOCKS != 31 + "hwcrhk", /* This is a HACK which will disappear in 0.9.8 */ +#if CRYPTO_NUM_LOCKS != 33 # error "Inconsistency between crypto.h and cryptlib.c" #endif }; @@ -206,10 +208,18 @@ int CRYPTO_get_new_dynlockid(void) i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); /* If there was none, push, thereby creating a new one */ if (i == -1) - i=sk_CRYPTO_dynlock_push(dyn_locks,pointer); + /* Since sk_push() returns the number of items on the + stack, not the location of the pushed item, we need + to transform the returned number into a position, + by decreasing it. */ + i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; + else + /* If we found a place with a NULL pointer, put our pointer + in it. */ + sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - if (!i) + if (i == -1) { dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); OPENSSL_free(pointer); @@ -401,15 +411,17 @@ void CRYPTO_lock(int mode, int type, const char *file, int line) #endif if (type < 0) { - struct CRYPTO_dynlock_value *pointer - = CRYPTO_get_dynlock_value(type); - - if (pointer && dynlock_lock_callback) + if (dynlock_lock_callback != NULL) { + struct CRYPTO_dynlock_value *pointer + = CRYPTO_get_dynlock_value(type); + + OPENSSL_assert(pointer != NULL); + dynlock_lock_callback(mode, pointer, file, line); - } - CRYPTO_destroy_dynlockid(type); + CRYPTO_destroy_dynlockid(type); + } } else if (locking_callback != NULL) @@ -460,7 +472,7 @@ const char *CRYPTO_get_lock_name(int type) return("dynamic"); else if (type < CRYPTO_NUM_LOCKS) return(lock_names[type]); - else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) + else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks)) return("ERROR"); else return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); @@ -492,3 +504,11 @@ BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, #endif #endif + +void OpenSSLDie(const char *file,int line,const char *assertion) + { + fprintf(stderr, + "%s(%d): OpenSSL internal error, assertion failed: %s\n", + file,line,assertion); + abort(); + } diff --git a/src/lib/libcrypto/cryptlib.h b/src/lib/libcrypto/cryptlib.h index 88e4ae509f..0d6b9d59f0 100644 --- a/src/lib/libcrypto/cryptlib.h +++ b/src/lib/libcrypto/cryptlib.h @@ -89,9 +89,9 @@ extern "C" { #define X509_CERT_DIR_EVP "SSL_CERT_DIR" #define X509_CERT_FILE_EVP "SSL_CERT_FILE" -/* size of string represenations */ -#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) -#define HEX_SIZE(type) ((sizeof(type)*2) +/* size of string representations */ +#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) +#define HEX_SIZE(type) (sizeof(type)*2) #ifdef __cplusplus } diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h index fc6ff860af..273bc5e3f8 100644 --- a/src/lib/libcrypto/crypto.h +++ b/src/lib/libcrypto/crypto.h @@ -96,37 +96,39 @@ extern "C" { * names in cryptlib.c */ -#define CRYPTO_LOCK_ERR 1 -#define CRYPTO_LOCK_EX_DATA 2 -#define CRYPTO_LOCK_X509 3 -#define CRYPTO_LOCK_X509_INFO 4 -#define CRYPTO_LOCK_X509_PKEY 5 +#define CRYPTO_LOCK_ERR 1 +#define CRYPTO_LOCK_EX_DATA 2 +#define CRYPTO_LOCK_X509 3 +#define CRYPTO_LOCK_X509_INFO 4 +#define CRYPTO_LOCK_X509_PKEY 5 #define CRYPTO_LOCK_X509_CRL 6 #define CRYPTO_LOCK_X509_REQ 7 #define CRYPTO_LOCK_DSA 8 #define CRYPTO_LOCK_RSA 9 #define CRYPTO_LOCK_EVP_PKEY 10 -#define CRYPTO_LOCK_X509_STORE 11 -#define CRYPTO_LOCK_SSL_CTX 12 -#define CRYPTO_LOCK_SSL_CERT 13 -#define CRYPTO_LOCK_SSL_SESSION 14 -#define CRYPTO_LOCK_SSL_SESS_CERT 15 -#define CRYPTO_LOCK_SSL 16 -#define CRYPTO_LOCK_RAND 17 -#define CRYPTO_LOCK_RAND2 18 -#define CRYPTO_LOCK_MALLOC 19 -#define CRYPTO_LOCK_BIO 20 -#define CRYPTO_LOCK_GETHOSTBYNAME 21 -#define CRYPTO_LOCK_GETSERVBYNAME 22 -#define CRYPTO_LOCK_READDIR 23 -#define CRYPTO_LOCK_RSA_BLINDING 24 -#define CRYPTO_LOCK_DH 25 -#define CRYPTO_LOCK_MALLOC2 26 -#define CRYPTO_LOCK_DSO 27 -#define CRYPTO_LOCK_DYNLOCK 28 -#define CRYPTO_LOCK_ENGINE 29 -#define CRYPTO_LOCK_UI 30 -#define CRYPTO_NUM_LOCKS 31 +#define CRYPTO_LOCK_X509_STORE 11 +#define CRYPTO_LOCK_SSL_CTX 12 +#define CRYPTO_LOCK_SSL_CERT 13 +#define CRYPTO_LOCK_SSL_SESSION 14 +#define CRYPTO_LOCK_SSL_SESS_CERT 15 +#define CRYPTO_LOCK_SSL 16 +#define CRYPTO_LOCK_SSL_METHOD 17 +#define CRYPTO_LOCK_RAND 18 +#define CRYPTO_LOCK_RAND2 19 +#define CRYPTO_LOCK_MALLOC 20 +#define CRYPTO_LOCK_BIO 21 +#define CRYPTO_LOCK_GETHOSTBYNAME 22 +#define CRYPTO_LOCK_GETSERVBYNAME 23 +#define CRYPTO_LOCK_READDIR 24 +#define CRYPTO_LOCK_RSA_BLINDING 25 +#define CRYPTO_LOCK_DH 26 +#define CRYPTO_LOCK_MALLOC2 27 +#define CRYPTO_LOCK_DSO 28 +#define CRYPTO_LOCK_DYNLOCK 29 +#define CRYPTO_LOCK_ENGINE 30 +#define CRYPTO_LOCK_UI 31 +#define CRYPTO_LOCK_HWCRHK 32 /* This is a HACK which will disappear in 0.9.8 */ +#define CRYPTO_NUM_LOCKS 33 #define CRYPTO_LOCK 1 #define CRYPTO_UNLOCK 2 @@ -148,7 +150,7 @@ extern "C" { #endif #else #define CRYPTO_w_lock(a) -#define CRYPTO_w_unlock(a) +#define CRYPTO_w_unlock(a) #define CRYPTO_r_lock(a) #define CRYPTO_r_unlock(a) #define CRYPTO_add(a,b,c) ((*(a))+=(b)) @@ -278,6 +280,8 @@ int CRYPTO_is_mem_check_on(void); #define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) #define OPENSSL_realloc(addr,num) \ CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +#define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) #define OPENSSL_remalloc(addr,num) \ CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) #define OPENSSL_freeFunc CRYPTO_free @@ -380,8 +384,12 @@ void CRYPTO_free_locked(void *); void *CRYPTO_malloc(int num, const char *file, int line); void CRYPTO_free(void *); void *CRYPTO_realloc(void *addr,int num, const char *file, int line); +void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file, + int line); void *CRYPTO_remalloc(void *addr,int num, const char *file, int line); +void OPENSSL_cleanse(void *ptr, size_t len); + void CRYPTO_set_mem_debug_options(long bits); long CRYPTO_get_mem_debug_options(void); @@ -422,6 +430,9 @@ void CRYPTO_mem_leaks(struct bio_st *bio); typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *); void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); +/* die if we have to */ +void OpenSSLDie(const char *file,int line,const char *assertion); +#define OPENSSL_assert(e) ((e) ? (void)0 : OpenSSLDie(__FILE__, __LINE__, #e)) /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes diff --git a/src/lib/libcrypto/des/asm/crypt586.pl b/src/lib/libcrypto/des/asm/crypt586.pl index 3d41d82f69..1d04ed6def 100644 --- a/src/lib/libcrypto/des/asm/crypt586.pl +++ b/src/lib/libcrypto/des/asm/crypt586.pl @@ -26,11 +26,18 @@ sub fcrypt_body &comment(""); &comment("Load the 2 words"); - $ks="ebp"; + $trans="ebp"; &xor( $L, $L); &xor( $R, $R); - &mov($ks,&wparam(1)); + + # PIC-ification:-) + &picmeup("edx","DES_SPtrans"); + #if ($cpp) { &picmeup("edx","DES_SPtrans"); } + #else { &lea("edx",&DWP("DES_SPtrans")); } + &push("edx"); # becomes &swtmp(1) + # + &mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT &push(&DWC(25)); # add a variable @@ -39,11 +46,11 @@ sub fcrypt_body { &comment(""); &comment("Round $i"); - &D_ENCRYPT($i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx"); &comment(""); &comment("Round ".sprintf("%d",$i+1)); - &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx"); } &mov("ebx", &swtmp(0)); &mov("eax", $L); @@ -61,14 +68,14 @@ sub fcrypt_body &mov(&DWP(0,"edx","",0),"eax"); &mov(&DWP(4,"edx","",0),$L); - &pop("ecx"); # remove variable + &add("esp",8); # remove variables &function_end($name); } sub D_ENCRYPT { - local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; + local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_; &mov( $u, &wparam(2)); # 2 &mov( $t, $R); @@ -85,9 +92,9 @@ sub D_ENCRYPT &shl( $tmp2, 16); # 1 &xor( $u, $tmp1); # 2 &xor( $t, $tmp2); # 2 - &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2 + &mov( $tmp1, &DWP(&n2a($S*4),$trans,"",0)); # 2 &xor( $u, $tmp1); - &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2 + &mov( $tmp2, &DWP(&n2a(($S+1)*4),$trans,"",0)); # 2 &xor( $u, $R); &xor( $t, $R); &xor( $t, $tmp2); @@ -99,31 +106,28 @@ sub D_ENCRYPT &movb( &LB($tmp1), &LB($u) ); &movb( &LB($tmp2), &HB($u) ); &rotr( $t, 4 ); - &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); + &mov( $trans, &swtmp(1)); + &xor( $L, &DWP(" ",$trans,$tmp1,0)); &movb( &LB($tmp1), &LB($t) ); - &xor( $L, $ks); - &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); - &xor( $L, $ks); + &xor( $L, &DWP("0x200",$trans,$tmp2,0)); &movb( &LB($tmp2), &HB($t) ); &shr( $u, 16); - &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); - &xor( $L, $ks); + &xor( $L, &DWP("0x100",$trans,$tmp1,0)); &movb( &LB($tmp1), &HB($u) ); &shr( $t, 16); - &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); - &xor( $L, $ks); - &mov( $ks, &wparam(1)); + &xor( $L, &DWP("0x300",$trans,$tmp2,0)); &movb( &LB($tmp2), &HB($t) ); &and( $u, "0xff" ); &and( $t, "0xff" ); - &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); + &mov( $tmp1, &DWP("0x600",$trans,$tmp1,0)); &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); + &mov( $tmp1, &DWP("0x700",$trans,$tmp2,0)); &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); + &mov( $tmp1, &DWP("0x400",$trans,$u,0)); &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); + &mov( $tmp1, &DWP("0x500",$trans,$t,0)); &xor( $L, $tmp1); + &mov( $trans, &wparam(1)); } sub n2a diff --git a/src/lib/libcrypto/des/asm/des-586.pl b/src/lib/libcrypto/des/asm/des-586.pl index 0d08e8a3a9..b75d3c6b3a 100644 --- a/src/lib/libcrypto/des/asm/des-586.pl +++ b/src/lib/libcrypto/des/asm/des-586.pl @@ -40,7 +40,7 @@ sub DES_encrypt &comment(""); &comment("Load the 2 words"); - $ks="ebp"; + $trans="ebp"; if ($do_ip) { @@ -72,7 +72,12 @@ sub DES_encrypt &rotl($L,3); } - &mov( $ks, &wparam(1) ); + # PIC-ification:-) + &picmeup($trans,"DES_SPtrans"); + #if ($cpp) { &picmeup($trans,"DES_SPtrans"); } + #else { &lea($trans,&DWP("DES_SPtrans")); } + + &mov( "ecx", &wparam(1) ); &cmp("ebx","0"); &je(&label("start_decrypt")); @@ -80,11 +85,11 @@ sub DES_encrypt { &comment(""); &comment("Round $i"); - &D_ENCRYPT($i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx"); &comment(""); &comment("Round ".sprintf("%d",$i+1)); - &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx"); } &jmp(&label("end")); @@ -94,10 +99,10 @@ sub DES_encrypt { &comment(""); &comment("Round $i"); - &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx"); &comment(""); &comment("Round ".sprintf("%d",$i-1)); - &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"DES_SPtrans","eax","ebx","ecx","edx"); + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx"); } &set_label("end"); @@ -134,43 +139,36 @@ sub DES_encrypt sub D_ENCRYPT { - local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; + local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_; - &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); + &mov( $u, &DWP(&n2a($S*4),$tmp2,"",0)); &xor( $tmp1, $tmp1); - &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); + &mov( $t, &DWP(&n2a(($S+1)*4),$tmp2,"",0)); &xor( $u, $R); + &xor( $tmp2, $tmp2); &xor( $t, $R); &and( $u, "0xfcfcfcfc" ); &and( $t, "0xcfcfcfcf" ); &movb( &LB($tmp1), &LB($u) ); &movb( &LB($tmp2), &HB($u) ); &rotr( $t, 4 ); - &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); + &xor( $L, &DWP(" ",$trans,$tmp1,0)); &movb( &LB($tmp1), &LB($t) ); - &xor( $L, $ks); - &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); - &xor( $L, $ks); ###### + &xor( $L, &DWP("0x200",$trans,$tmp2,0)); &movb( &LB($tmp2), &HB($t) ); &shr( $u, 16); - &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); - &xor( $L, $ks); ###### + &xor( $L, &DWP("0x100",$trans,$tmp1,0)); &movb( &LB($tmp1), &HB($u) ); &shr( $t, 16); - &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); - &xor( $L, $ks); - &mov( $ks, &wparam(1) ); + &xor( $L, &DWP("0x300",$trans,$tmp2,0)); &movb( &LB($tmp2), &HB($t) ); &and( $u, "0xff" ); &and( $t, "0xff" ); - &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); - &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); - &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); - &xor( $L, $tmp1); - &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); - &xor( $L, $tmp1); + &xor( $L, &DWP("0x600",$trans,$tmp1,0)); + &xor( $L, &DWP("0x700",$trans,$tmp2,0)); + &mov( $tmp2, &wparam(1) ); + &xor( $L, &DWP("0x400",$trans,$u,0)); + &xor( $L, &DWP("0x500",$trans,$t,0)); } sub n2a diff --git a/src/lib/libcrypto/des/cbc_cksm.c b/src/lib/libcrypto/des/cbc_cksm.c index 6c5305b99d..09a7ba56aa 100644 --- a/src/lib/libcrypto/des/cbc_cksm.c +++ b/src/lib/libcrypto/des/cbc_cksm.c @@ -93,5 +93,14 @@ DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output, l2c(tout1,out); } tout0=tin0=tin1=tin[0]=tin[1]=0; + /* + Transform the data in tout1 so that it will + match the return value that the MIT Kerberos + mit_des_cbc_cksum API returns. + */ + tout1 = ((tout1 >> 24L) & 0x000000FF) + | ((tout1 >> 8L) & 0x0000FF00) + | ((tout1 << 8L) & 0x00FF0000) + | ((tout1 << 24L) & 0xFF000000); return(tout1); } diff --git a/src/lib/libcrypto/des/des.h b/src/lib/libcrypto/des/des.h index 4cb9d84fdf..daaf239dbe 100644 --- a/src/lib/libcrypto/des/des.h +++ b/src/lib/libcrypto/des/des.h @@ -56,8 +56,8 @@ * [including the GNU Public Licence.] */ -#ifndef HEADER_DES_H -#define HEADER_DES_H +#ifndef HEADER_NEW_DES_H +#define HEADER_NEW_DES_H #ifdef OPENSSL_NO_DES #error DES is disabled. diff --git a/src/lib/libcrypto/des/des_locl.h b/src/lib/libcrypto/des/des_locl.h index 70e833be3f..e44e8e98b2 100644 --- a/src/lib/libcrypto/des/des_locl.h +++ b/src/lib/libcrypto/des/des_locl.h @@ -162,7 +162,18 @@ #if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER) #define ROTATE(a,n) (_lrotr(a,n)) -#else +#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rorl %1,%0" \ + : "=r"(ret) \ + : "I"(n),"0"(a) \ + : "cc"); \ + ret; \ + }) +# endif +#endif +#ifndef ROTATE #define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) #endif diff --git a/src/lib/libcrypto/des/str2key.c b/src/lib/libcrypto/des/str2key.c index 36c3f81d99..0373db469c 100644 --- a/src/lib/libcrypto/des/str2key.c +++ b/src/lib/libcrypto/des/str2key.c @@ -94,7 +94,7 @@ void DES_string_to_key(const char *str, DES_cblock *key) DES_set_key_unchecked(key,&ks); #endif DES_cbc_cksum((const unsigned char*)str,key,length,&ks,key); - memset(&ks,0,sizeof(ks)); + OPENSSL_cleanse(&ks,sizeof(ks)); DES_set_odd_parity(key); } @@ -167,7 +167,7 @@ void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) DES_set_key_unchecked(key2,&ks); #endif DES_cbc_cksum((const unsigned char*)str,key2,length,&ks,key2); - memset(&ks,0,sizeof(ks)); + OPENSSL_cleanse(&ks,sizeof(ks)); DES_set_odd_parity(key1); DES_set_odd_parity(key2); } diff --git a/src/lib/libcrypto/dh/dh_key.c b/src/lib/libcrypto/dh/dh_key.c index 1a0efca2c4..77f2f50b51 100644 --- a/src/lib/libcrypto/dh/dh_key.c +++ b/src/lib/libcrypto/dh/dh_key.c @@ -61,7 +61,6 @@ #include #include #include -#include static int generate_key(DH *dh); static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); diff --git a/src/lib/libcrypto/dh/dh_lib.c b/src/lib/libcrypto/dh/dh_lib.c index ba5fd41057..09965ee2ea 100644 --- a/src/lib/libcrypto/dh/dh_lib.c +++ b/src/lib/libcrypto/dh/dh_lib.c @@ -60,7 +60,9 @@ #include "cryptlib.h" #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif const char *DH_version="Diffie-Hellman" OPENSSL_VERSION_PTEXT; @@ -85,11 +87,13 @@ int DH_set_method(DH *dh, const DH_METHOD *meth) const DH_METHOD *mtmp; mtmp = dh->meth; if (mtmp->finish) mtmp->finish(dh); +#ifndef OPENSSL_NO_ENGINE if (dh->engine) { ENGINE_finish(dh->engine); dh->engine = NULL; } +#endif dh->meth = meth; if (meth->init) meth->init(dh); return 1; @@ -112,6 +116,7 @@ DH *DH_new_method(ENGINE *engine) } ret->meth = DH_get_default_method(); +#ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) @@ -135,6 +140,7 @@ DH *DH_new_method(ENGINE *engine) return NULL; } } +#endif ret->pad=0; ret->version=0; @@ -154,8 +160,10 @@ DH *DH_new_method(ENGINE *engine) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; @@ -182,8 +190,10 @@ void DH_free(DH *r) if (r->meth->finish) r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE if (r->engine) ENGINE_finish(r->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); diff --git a/src/lib/libcrypto/doc/DH_generate_key.pod b/src/lib/libcrypto/doc/DH_generate_key.pod index 920995b2e5..81f09fdf45 100644 --- a/src/lib/libcrypto/doc/DH_generate_key.pod +++ b/src/lib/libcrypto/doc/DH_generate_key.pod @@ -40,7 +40,7 @@ The error codes can be obtained by L. =head1 SEE ALSO -L, L, L, L +L, L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DH_generate_parameters.pod b/src/lib/libcrypto/doc/DH_generate_parameters.pod index a7d0c75f0c..9081e9ea7c 100644 --- a/src/lib/libcrypto/doc/DH_generate_parameters.pod +++ b/src/lib/libcrypto/doc/DH_generate_parameters.pod @@ -59,7 +59,8 @@ a usable generator. =head1 SEE ALSO -L, L, L, L +L, L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DH_new.pod b/src/lib/libcrypto/doc/DH_new.pod index 64624b9d15..60c930093e 100644 --- a/src/lib/libcrypto/doc/DH_new.pod +++ b/src/lib/libcrypto/doc/DH_new.pod @@ -29,7 +29,7 @@ DH_free() returns no value. =head1 SEE ALSO -L, L, +L, L, L, L diff --git a/src/lib/libcrypto/doc/DSA_SIG_new.pod b/src/lib/libcrypto/doc/DSA_SIG_new.pod index 671655554a..3ac6140038 100644 --- a/src/lib/libcrypto/doc/DSA_SIG_new.pod +++ b/src/lib/libcrypto/doc/DSA_SIG_new.pod @@ -30,7 +30,8 @@ DSA_SIG_free() returns no value. =head1 SEE ALSO -L, L, L +L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DSA_do_sign.pod b/src/lib/libcrypto/doc/DSA_do_sign.pod index a24fd5714e..5dfc733b20 100644 --- a/src/lib/libcrypto/doc/DSA_do_sign.pod +++ b/src/lib/libcrypto/doc/DSA_do_sign.pod @@ -36,7 +36,7 @@ L. =head1 SEE ALSO -L, L, L, +L, L, L, L, L diff --git a/src/lib/libcrypto/doc/DSA_dup_DH.pod b/src/lib/libcrypto/doc/DSA_dup_DH.pod index fdfe125ab0..7f6f0d1115 100644 --- a/src/lib/libcrypto/doc/DSA_dup_DH.pod +++ b/src/lib/libcrypto/doc/DSA_dup_DH.pod @@ -27,7 +27,7 @@ Be careful to avoid small subgroup attacks when using this. =head1 SEE ALSO -L, L, L +L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DSA_generate_key.pod b/src/lib/libcrypto/doc/DSA_generate_key.pod index 52890db5be..af83ccfaa1 100644 --- a/src/lib/libcrypto/doc/DSA_generate_key.pod +++ b/src/lib/libcrypto/doc/DSA_generate_key.pod @@ -24,7 +24,8 @@ The error codes can be obtained by L. =head1 SEE ALSO -L, L, L, L +L, L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DSA_generate_parameters.pod b/src/lib/libcrypto/doc/DSA_generate_parameters.pod index 43f60b0eb9..be7c924ff8 100644 --- a/src/lib/libcrypto/doc/DSA_generate_parameters.pod +++ b/src/lib/libcrypto/doc/DSA_generate_parameters.pod @@ -90,7 +90,7 @@ Seed lengths E 20 are not supported. =head1 SEE ALSO -L, L, L, +L, L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/DSA_new.pod b/src/lib/libcrypto/doc/DSA_new.pod index 546146d9de..48e9b82a09 100644 --- a/src/lib/libcrypto/doc/DSA_new.pod +++ b/src/lib/libcrypto/doc/DSA_new.pod @@ -31,7 +31,7 @@ DSA_free() returns no value. =head1 SEE ALSO -L, L, +L, L, L, L diff --git a/src/lib/libcrypto/doc/DSA_sign.pod b/src/lib/libcrypto/doc/DSA_sign.pod index f6e60a8ca3..97389e8ec8 100644 --- a/src/lib/libcrypto/doc/DSA_sign.pod +++ b/src/lib/libcrypto/doc/DSA_sign.pod @@ -55,7 +55,7 @@ Standard, DSS), ANSI X9.30 =head1 SEE ALSO -L, L, L, +L, L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/ERR_get_error.pod b/src/lib/libcrypto/doc/ERR_get_error.pod index 9fdedbcb91..34443045fc 100644 --- a/src/lib/libcrypto/doc/ERR_get_error.pod +++ b/src/lib/libcrypto/doc/ERR_get_error.pod @@ -5,7 +5,7 @@ ERR_get_error, ERR_peek_error, ERR_peek_last_error, ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line, ERR_get_error_line_data, ERR_peek_error_line_data, -ERR_peek_error_line_data - obtain error code and data +ERR_peek_last_error_line_data - obtain error code and data =head1 SYNOPSIS diff --git a/src/lib/libcrypto/doc/EVP_EncryptInit.pod b/src/lib/libcrypto/doc/EVP_EncryptInit.pod index 75cceb1ca2..daf57e5895 100644 --- a/src/lib/libcrypto/doc/EVP_EncryptInit.pod +++ b/src/lib/libcrypto/doc/EVP_EncryptInit.pod @@ -419,7 +419,7 @@ Encrypt a string using blowfish: EVP_CIPHER_CTX ctx; FILE *out; EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, NULL, EVP_bf_cbc(), key, iv); + EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv); if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext))) { diff --git a/src/lib/libcrypto/doc/EVP_PKEY_new.pod b/src/lib/libcrypto/doc/EVP_PKEY_new.pod new file mode 100644 index 0000000000..10687e458d --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_new.pod @@ -0,0 +1,47 @@ +=pod + +=head1 NAME + +EVP_PKEY_new, EVP_PKEY_free - private key allocation functions. + +=head1 SYNOPSIS + + #include + + EVP_PKEY *EVP_PKEY_new(void); + void EVP_PKEY_free(EVP_PKEY *key); + + +=head1 DESCRIPTION + +The EVP_PKEY_new() function allocates an empty B +structure which is used by OpenSSL to store private keys. + +EVP_PKEY_free() frees up the private key B. + +=head1 NOTES + +The B structure is used by various OpenSSL functions +which require a general private key without reference to any +particular algorithm. + +The structure returned by EVP_PKEY_new() is empty. To add a +private key to this empty structure the functions described in +L should be used. + +=head1 RETURN VALUES + +EVP_PKEY_new() returns either the newly allocated B +structure of B if an error occurred. + +EVP_PKEY_free() does not return a value. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/EVP_PKEY_set1_RSA.pod b/src/lib/libcrypto/doc/EVP_PKEY_set1_RSA.pod new file mode 100644 index 0000000000..2db692e271 --- /dev/null +++ b/src/lib/libcrypto/doc/EVP_PKEY_set1_RSA.pod @@ -0,0 +1,80 @@ +=pod + +=head1 NAME + +EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY, +EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY, +EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY, +EVP_PKEY_type - EVP_PKEY assignment functions. + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,RSA *key); + int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,DSA *key); + int EVP_PKEY_set1_DH(EVP_PKEY *pkey,DH *key); + int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,EC_KEY *key); + + RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); + DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); + DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey); + EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); + + int EVP_PKEY_assign_RSA(EVP_PKEY *pkey,RSA *key); + int EVP_PKEY_assign_DSA(EVP_PKEY *pkey,DSA *key); + int EVP_PKEY_assign_DH(EVP_PKEY *pkey,DH *key); + int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey,EC_KEY *key); + + int EVP_PKEY_type(int type); + +=head1 DESCRIPTION + +EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and +EVP_PKEY_set1_EC_KEY() set the key referenced by B to B. + +EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and +EVP_PKEY_get1_EC_KEY() return the referenced key in B or +B if the key is not of the correct type. + +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() +and EVP_PKEY_assign_EC_KEY() also set the referenced key to B +however these use the supplied B internally and so B +will be freed when the parent B is freed. + +EVP_PKEY_type() returns the type of key corresponding to the value +B. The type of a key can be obtained with +EVP_PKEY_type(pkey->type). The return value will be EVP_PKEY_RSA, +EVP_PKEY_DSA, EVP_PKEY_DH or EVP_PKEY_EC for the corresponding +key types or NID_undef if the key type is unassigned. + +=head1 NOTES + +In accordance with the OpenSSL naming convention the key obtained +from or assigned to the B using the B<1> functions must be +freed as well as B. + +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() +EVP_PKEY_assign_EC_KEY() are implemented as macros. + +=head1 RETURN VALUES + +EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and +EVP_PKEY_set1_EC_KEY() return 1 for success or 0 for failure. + +EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and +EVP_PKEY_get1_EC_KEY() return the referenced key or B if +an error occurred. + +EVP_PKEY_assign_RSA() EVP_PKEY_assign_DSA(), EVP_PKEY_assign_DH() +and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/EVP_SealInit.pod b/src/lib/libcrypto/doc/EVP_SealInit.pod index 25ef07f7c7..b5e477e294 100644 --- a/src/lib/libcrypto/doc/EVP_SealInit.pod +++ b/src/lib/libcrypto/doc/EVP_SealInit.pod @@ -18,22 +18,28 @@ EVP_SealInit, EVP_SealUpdate, EVP_SealFinal - EVP envelope encryption =head1 DESCRIPTION The EVP envelope routines are a high level interface to envelope -encryption. They generate a random key and then "envelope" it by -using public key encryption. Data can then be encrypted using this -key. +encryption. They generate a random key and IV (if required) then +"envelope" it by using public key encryption. Data can then be +encrypted using this key. EVP_SealInit() initializes a cipher context B for encryption -with cipher B using a random secret key and IV supplied in -the B parameter. B is normally supplied by a function such -as EVP_des_cbc(). The secret key is encrypted using one or more public -keys, this allows the same encrypted data to be decrypted using any -of the corresponding private keys. B is an array of buffers where -the public key encrypted secret key will be written, each buffer must -contain enough room for the corresponding encrypted key: that is +with cipher B using a random secret key and IV. B is normally +supplied by a function such as EVP_des_cbc(). The secret key is encrypted +using one or more public keys, this allows the same encrypted data to be +decrypted using any of the corresponding private keys. B is an array of +buffers where the public key encrypted secret key will be written, each buffer +must contain enough room for the corresponding encrypted key: that is B must have room for B bytes. The actual size of each encrypted secret key is written to the array B. B is an array of B public keys. +The B parameter is a buffer where the generated IV is written to. It must +contain enough room for the corresponding cipher's IV, as determined by (for +example) EVP_CIPHER_iv_length(type). + +If the cipher does not require an IV then the B parameter is ignored +and can be B. + EVP_SealUpdate() and EVP_SealFinal() have exactly the same properties as the EVP_EncryptUpdate() and EVP_EncryptFinal() routines, as documented on the L manual diff --git a/src/lib/libcrypto/doc/OBJ_nid2obj.pod b/src/lib/libcrypto/doc/OBJ_nid2obj.pod new file mode 100644 index 0000000000..7dcc07923f --- /dev/null +++ b/src/lib/libcrypto/doc/OBJ_nid2obj.pod @@ -0,0 +1,149 @@ +=pod + +=head1 NAME + +OBJ_nid2obj, OBJ_nid2ln, OBJ_nid2sn, OBJ_obj2nid, OBJ_txt2nid, OBJ_ln2nid, OBJ_sn2nid, +OBJ_cmp, OBJ_dup, OBJ_txt2obj, OBJ_obj2txt, OBJ_create, OBJ_cleanup - ASN1 object utility +functions + +=head1 SYNOPSIS + + ASN1_OBJECT * OBJ_nid2obj(int n); + const char * OBJ_nid2ln(int n); + const char * OBJ_nid2sn(int n); + + int OBJ_obj2nid(const ASN1_OBJECT *o); + int OBJ_ln2nid(const char *ln); + int OBJ_sn2nid(const char *sn); + + int OBJ_txt2nid(const char *s); + + ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name); + int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); + + int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b); + ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o); + + int OBJ_create(const char *oid,const char *sn,const char *ln); + void OBJ_cleanup(void); + +=head1 DESCRIPTION + +The ASN1 object utility functions process ASN1_OBJECT structures which are +a representation of the ASN1 OBJECT IDENTIFIER (OID) type. + +OBJ_nid2obj(), OBJ_nid2ln() and OBJ_nid2sn() convert the NID B to +an ASN1_OBJECT structure, its long name and its short name respectively, +or B is an error occurred. + +OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() return the corresponding NID +for the object B, the long name or the short name respectively +or NID_undef if an error occurred. + +OBJ_txt2nid() returns NID corresponding to text string . B can be +a long name, a short name or the numerical respresentation of an object. + +OBJ_txt2obj() converts the text string B into an ASN1_OBJECT structure. +If B is 0 then long names and short names will be interpreted +as well as numerical forms. If B is 1 only the numerical form +is acceptable. + +OBJ_obj2txt() converts the B B into a textual representation. +The representation is written as a null terminated string to B +at most B bytes are written, truncating the result if necessary. +The total amount of space required is returned. If B is 0 then +if the object has a long or short name then that will be used, otherwise +the numerical form will be used. If B is 1 then the numerical +form will always be used. + +OBJ_cmp() compares B to B. If the two are identical 0 is returned. + +OBJ_dup() returns a copy of B. + +OBJ_create() adds a new object to the internal table. B is the +numerical form of the object, B the short name and B the +long name. A new NID is returned for the created object. + +OBJ_cleanup() cleans up OpenSSLs internal object table: this should +be called before an application exits if any new objects were added +using OBJ_create(). + +=head1 NOTES + +Objects in OpenSSL can have a short name, a long name and a numerical +identifier (NID) associated with them. A standard set of objects is +represented in an internal table. The appropriate values are defined +in the header file B. + +For example the OID for commonName has the following definitions: + + #define SN_commonName "CN" + #define LN_commonName "commonName" + #define NID_commonName 13 + +New objects can be added by calling OBJ_create(). + +Table objects have certain advantages over other objects: for example +their NIDs can be used in a C language switch statement. They are +also static constant structures which are shared: that is there +is only a single constant structure for each table object. + +Objects which are not in the table have the NID value NID_undef. + +Objects do not need to be in the internal tables to be processed, +the functions OBJ_txt2obj() and OBJ_obj2txt() can process the numerical +form of an OID. + +=head1 EXAMPLES + +Create an object for B: + + ASN1_OBJECT *o; + o = OBJ_nid2obj(NID_commonName); + +Check if an object is B + + if (OBJ_obj2nid(obj) == NID_commonName) + /* Do something */ + +Create a new NID and initialize an object from it: + + int new_nid; + ASN1_OBJECT *obj; + new_nid = OBJ_create("1.2.3.4", "NewOID", "New Object Identifier"); + + obj = OBJ_nid2obj(new_nid); + +Create a new object directly: + + obj = OBJ_txt2obj("1.2.3.4", 1); + +=head1 BUGS + +OBJ_obj2txt() is awkward and messy to use: it doesn't follow the +convention of other OpenSSL functions where the buffer can be set +to B to determine the amount of data that should be written. +Instead B must point to a valid buffer and B should +be set to a positive value. A buffer length of 80 should be more +than enough to handle any OID encountered in practice. + +=head1 RETURN VALUES + +OBJ_nid2obj() returns an B structure or B is an +error occurred. + +OBJ_nid2ln() and OBJ_nid2sn() returns a valid string or B +on error. + +OBJ_obj2nid(), OBJ_ln2nid(), OBJ_sn2nid() and OBJ_txt2nid() return +a NID or B on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/PKCS12_create.pod b/src/lib/libcrypto/doc/PKCS12_create.pod new file mode 100644 index 0000000000..48f3bb8cb8 --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS12_create.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +PKCS12_create - create a PKCS#12 structure + +=head1 SYNOPSIS + + #include + + PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, STACK_OF(X509) *ca, + int nid_key, int nid_cert, int iter, int mac_iter, int keytype); + +=head1 DESCRIPTION + +PKCS12_create() creates a PKCS#12 structure. + +B is the passphrase to use. B is the B to use for +the supplied certifictate and key. B is the private key to include in +the structure and B its corresponding certificates. B, if not B +is an optional set of certificates to also include in the structure. + +B and B are the encryption algorithms that should be used +for the key and certificate respectively. B is the encryption algorithm +iteration count to use and B is the MAC iteration count to use. +B is the type of key. + +=head1 NOTES + +The parameters B, B, B, B and B +can all be set to zero and sensible defaults will be used. + +These defaults are: 40 bit RC2 encryption for certificates, triple DES +encryption for private keys, a key iteration count of PKCS12_DEFAULT_ITER +(currently 2048) and a MAC iteration count of 1. + +The default MAC iteration count is 1 in order to retain compatibility with +old software which did not interpret MAC iteration counts. If such compatibility +is not required then B should be set to PKCS12_DEFAULT_ITER. + +B adds a flag to the store private key. This is a non standard extension +that is only currently interpreted by MSIE. If set to zero the flag is omitted, +if set to B the key can be used for signing only, if set to B +it can be used for signing and encryption. This option was useful for old +export grade software which could use signing only keys of arbitrary size but +had restrictions on the permissible sizes of keys which could be used for +encryption. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +PKCS12_create was added in OpenSSL 0.9.3 + +=cut diff --git a/src/lib/libcrypto/doc/PKCS12_parse.pod b/src/lib/libcrypto/doc/PKCS12_parse.pod new file mode 100644 index 0000000000..51344f883a --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS12_parse.pod @@ -0,0 +1,50 @@ +=pod + +=head1 NAME + +PKCS12_parse - parse a PKCS#12 structure + +=head1 SYNOPSIS + + #include + +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); + +=head1 DESCRIPTION + +PKCS12_parse() parses a PKCS12 structure. + +B is the B structure to parse. B is the passphrase to use. +If successful the private key will be written to B<*pkey>, the corresponding +certificate to B<*cert> and any additional certificates to B<*ca>. + +=head1 NOTES + +The parameters B and B cannot be B. B can be +in which case additional certificates will be discarded. B<*ca> can also +be a valid STACK in which case additional certificates are appended to +B<*ca>. If B<*ca> is B a new STACK will be allocated. + +The B and B attributes (if present) on each certificate +will be stored in the B and B attributes of the B structure. + +=head1 BUGS + +Only a single private key and corresponding certificate is returned by this function. +More complex PKCS#12 files with multiple private keys will only return the first +match. + +Only B and B attributes are currently stored in certificates. +Other attributes are discarded. + +Attributes currently cannot be store in the private key B structure. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +PKCS12_parse was added in OpenSSL 0.9.3 + +=cut diff --git a/src/lib/libcrypto/doc/PKCS7_decrypt.pod b/src/lib/libcrypto/doc/PKCS7_decrypt.pod new file mode 100644 index 0000000000..b0ca067b89 --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS7_decrypt.pod @@ -0,0 +1,53 @@ +=pod + +=head1 NAME + +PKCS7_decrypt - decrypt content from a PKCS#7 envelopedData structure + +=head1 SYNOPSIS + +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); + +=head1 DESCRIPTION + +PKCS7_decrypt() extracts and decrypts the content from a PKCS#7 envelopedData +structure. B is the private key of the recipient, B is the +recipients certificate, B is a BIO to write the content to and +B is an optional set of flags. + +=head1 NOTES + +OpenSSL_add_all_algorithms() (or equivalent) should be called before using this +function or errors about unknown algorithms will occur. + +Although the recipients certificate is not needed to decrypt the data it is needed +to locate the appropriate (of possible several) recipients in the PKCS#7 structure. + +The following flags can be passed in the B parameter. + +If the B flag is set MIME headers for type B are deleted +from the content. If the content is not of type B then an error is +returned. + +=head1 RETURN VALUES + +PKCS7_decrypt() returns either 1 for success or 0 for failure. +The error can be obtained from ERR_get_error(3) + +=head1 BUGS + +PKCS7_decrypt() must be passed the correct recipient key and certificate. It would +be better if it could look up the correct key and certificate from a database. + +The lack of single pass processing and need to hold all data in memory as +mentioned in PKCS7_sign() also applies to PKCS7_verify(). + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +PKCS7_decrypt() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/PKCS7_encrypt.pod b/src/lib/libcrypto/doc/PKCS7_encrypt.pod new file mode 100644 index 0000000000..1a507b22a2 --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS7_encrypt.pod @@ -0,0 +1,65 @@ +=pod + +=head1 NAME + +PKCS7_encrypt - create a PKCS#7 envelopedData structure + +=head1 SYNOPSIS + +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); + +=head1 DESCRIPTION + +PKCS7_encrypt() creates and returns a PKCS#7 envelopedData structure. B +is a list of recipient certificates. B is the content to be encrypted. +B is the symmetric cipher to use. B is an optional set of flags. + +=head1 NOTES + +Only RSA keys are supported in PKCS#7 and envelopedData so the recipient certificates +supplied to this function must all contain RSA public keys, though they do not have to +be signed using the RSA algorithm. + +EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use because +most clients will support it. + +Some old "export grade" clients may only support weak encryption using 40 or 64 bit +RC2. These can be used by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() respectively. + +The algorithm passed in the B parameter must support ASN1 encoding of its +parameters. + +Many browsers implement a "sign and encrypt" option which is simply an S/MIME +envelopedData containing an S/MIME signed message. This can be readily produced +by storing the S/MIME signed message in a memory BIO and passing it to +PKCS7_encrypt(). + +The following flags can be passed in the B parameter. + +If the B flag is set MIME headers for type B are prepended +to the data. + +Normally the supplied content is translated into MIME canonical format (as required +by the S/MIME specifications) if B is set no translation occurs. This +option should be used if the supplied data is in binary format otherwise the translation +will corrupt it. If B is set then B is ignored. + +=head1 RETURN VALUES + +PKCS7_encrypt() returns either a valid PKCS7 structure or NULL if an error occurred. +The error can be obtained from ERR_get_error(3). + +=head1 BUGS + +The lack of single pass processing and need to hold all data in memory as +mentioned in PKCS7_sign() also applies to PKCS7_verify(). + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +PKCS7_decrypt() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/PKCS7_sign.pod b/src/lib/libcrypto/doc/PKCS7_sign.pod new file mode 100644 index 0000000000..fc7e649b34 --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS7_sign.pod @@ -0,0 +1,85 @@ +=pod + +=head1 NAME + +PKCS7_sign - create a PKCS#7 signedData structure + +=head1 SYNOPSIS + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); + +=head1 DESCRIPTION + +PKCS7_sign() creates and returns a PKCS#7 signedData structure. B +is the certificate to sign with, B is the corresponsding private key. +B is an optional additional set of certificates to include in the +PKCS#7 structure (for example any intermediate CAs in the chain). + +The data to be signed is read from BIO B. + +B is an optional set of flags. + +=head1 NOTES + +Any of the following flags (ored together) can be passed in the B parameter. + +Many S/MIME clients expect the signed content to include valid MIME headers. If +the B flag is set MIME headers for type B are prepended +to the data. + +If B is set the signer's certificate will not be included in the +PKCS7 structure, the signer's certificate must still be supplied in the B +parameter though. This can reduce the size of the signature if the signers certificate +can be obtained by other means: for example a previously signed message. + +The data being signed is included in the PKCS7 structure, unless B +is set in which case it is omitted. This is used for PKCS7 detached signatures +which are used in S/MIME plaintext signed messages for example. + +Normally the supplied content is translated into MIME canonical format (as required +by the S/MIME specifications) if B is set no translation occurs. This +option should be used if the supplied data is in binary format otherwise the translation +will corrupt it. + +The signedData structure includes several PKCS#7 autenticatedAttributes including +the signing time, the PKCS#7 content type and the supported list of ciphers in +an SMIMECapabilities attribute. If B is set then no authenticatedAttributes +will be used. If B is set then just the SMIMECapabilities are +omitted. + +If present the SMIMECapabilities attribute indicates support for the following +algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any +of these algorithms is disabled then it will not be included. + +=head1 BUGS + +PKCS7_sign() is somewhat limited. It does not support multiple signers, some +advanced attributes such as counter signatures are not supported. + +The SHA1 digest algorithm is currently always used. + +When the signed data is not detached it will be stored in memory within the +B structure. This effectively limits the size of messages which can be +signed due to memory restraints. There should be a way to sign data without +having to hold it all in memory, this would however require fairly major +revisions of the OpenSSL ASN1 code. + +Clear text signing does not store the content in memory but the way PKCS7_sign() +operates means that two passes of the data must typically be made: one to compute +the signatures and a second to output the data along with the signature. There +should be a way to process the data with only a single pass. + +=head1 RETURN VALUES + +PKCS7_sign() returns either a valid PKCS7 structure or NULL if an error occurred. +The error can be obtained from ERR_get_error(3). + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +PKCS7_sign() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/PKCS7_verify.pod b/src/lib/libcrypto/doc/PKCS7_verify.pod new file mode 100644 index 0000000000..07c9fdad40 --- /dev/null +++ b/src/lib/libcrypto/doc/PKCS7_verify.pod @@ -0,0 +1,116 @@ +=pod + +=head1 NAME + +PKCS7_verify - verify a PKCS#7 signedData structure + +=head1 SYNOPSIS + +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags); + +int PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); + +=head1 DESCRIPTION + +PKCS7_verify() verifies a PKCS#7 signedData structure. B is the PKCS7 +structure to verify. B is a set of certificates in which to search for +the signer's certificate. B is a trusted certficate store (used for +chain verification). B is the signed data if the content is not +present in B (that is it is detached). The content is written to B +if it is not NULL. + +B is an optional set of flags, which can be used to modify the verify +operation. + +PKCS7_get0_signers() retrieves the signer's certificates from B, it does +B check their validity or whether any signatures are valid. The B +and B parameters have the same meanings as in PKCS7_verify(). + +=head1 VERIFY PROCESS + +Normally the verify process proceeds as follows. + +Initially some sanity checks are performed on B. The type of B must +be signedData. There must be at least one signature on the data and if +the content is detached B cannot be B. + +An attempt is made to locate all the signer's certificates, first looking in +the B parameter (if it is not B) and then looking in any certificates +contained in the B structure itself. If any signer's certificates cannot be +located the operation fails. + +Each signer's certificate is chain verified using the B purpose and +the supplied trusted certificate store. Any internal certificates in the message +are used as untrusted CAs. If any chain verify fails an error code is returned. + +Finally the signed content is read (and written to B is it is not NULL) and +the signature's checked. + +If all signature's verify correctly then the function is successful. + +Any of the following flags (ored together) can be passed in the B parameter +to change the default verify behaviour. Only the flag B is +meaningful to PKCS7_get0_signers(). + +If B is set the certificates in the message itself are not +searched when locating the signer's certificate. This means that all the signers +certificates must be in the B parameter. + +If the B flag is set MIME headers for type B are deleted +from the content. If the content is not of type B then an error is +returned. + +If B is set the signer's certificates are not chain verified. + +If B is set then the certificates contained in the message are +not used as untrusted CAs. This means that the whole verify chain (apart from +the signer's certificate) must be contained in the trusted store. + +If B is set then the signatures on the data are not checked. + +=head1 NOTES + +One application of B is to only accept messages signed by +a small number of certificates. The acceptable certificates would be passed +in the B parameter. In this case if the signer is not one of the +certificates supplied in B then the verify will fail because the +signer cannot be found. + +Care should be taken when modifying the default verify behaviour, for example +setting B will totally disable all verification +and any signed message will be considered valid. This combination is however +useful if one merely wishes to write the content to B and its validity +is not considered important. + +Chain verification should arguably be performed using the signing time rather +than the current time. However since the signing time is supplied by the +signer it cannot be trusted without additional evidence (such as a trusted +timestamp). + +=head1 RETURN VALUES + +PKCS7_verify() returns 1 for a successful verification and zero or a negative +value if an error occurs. + +PKCS7_get0_signers() returns all signers or B if an error occurred. + +The error can be obtained from L + +=head1 BUGS + +The trusted certificate store is not searched for the signers certificate, +this is primarily due to the inadequacies of the current B +functionality. + +The lack of single pass processing and need to hold all data in memory as +mentioned in PKCS7_sign() also applies to PKCS7_verify(). + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +PKCS7_verify() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/RAND_bytes.pod b/src/lib/libcrypto/doc/RAND_bytes.pod index b6ebd50527..ce6329ce54 100644 --- a/src/lib/libcrypto/doc/RAND_bytes.pod +++ b/src/lib/libcrypto/doc/RAND_bytes.pod @@ -35,7 +35,8 @@ method. =head1 SEE ALSO -L, L, L +L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_check_key.pod b/src/lib/libcrypto/doc/RSA_check_key.pod index 3d824a07f5..a5198f3db5 100644 --- a/src/lib/libcrypto/doc/RSA_check_key.pod +++ b/src/lib/libcrypto/doc/RSA_check_key.pod @@ -58,7 +58,7 @@ provide their own verifiers. =head1 SEE ALSO -L, L +L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_generate_key.pod b/src/lib/libcrypto/doc/RSA_generate_key.pod index 8714f7179d..52dbb14a53 100644 --- a/src/lib/libcrypto/doc/RSA_generate_key.pod +++ b/src/lib/libcrypto/doc/RSA_generate_key.pod @@ -59,7 +59,8 @@ RSA_generate_key() goes into an infinite loop for illegal input values. =head1 SEE ALSO -L, L, L, L +L, L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_new.pod b/src/lib/libcrypto/doc/RSA_new.pod index f0d996c40f..3d15b92824 100644 --- a/src/lib/libcrypto/doc/RSA_new.pod +++ b/src/lib/libcrypto/doc/RSA_new.pod @@ -30,7 +30,8 @@ RSA_free() returns no value. =head1 SEE ALSO -L, L, L, +L, L, +L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_print.pod b/src/lib/libcrypto/doc/RSA_print.pod index 67876facc5..e28d107d1c 100644 --- a/src/lib/libcrypto/doc/RSA_print.pod +++ b/src/lib/libcrypto/doc/RSA_print.pod @@ -2,9 +2,9 @@ =head1 NAME -RSA_print, RSA_print_fp, DHparams_print, DHparams_print_fp, DSA_print, -DSA_print_fp, DHparams_print, DHparams_print_fp - print cryptographic -parameters +RSA_print, RSA_print_fp, +DSAparams_print, DSAparams_print_fp, DSA_print, DSA_print_fp, +DHparams_print, DHparams_print_fp - print cryptographic parameters =head1 SYNOPSIS diff --git a/src/lib/libcrypto/doc/RSA_private_encrypt.pod b/src/lib/libcrypto/doc/RSA_private_encrypt.pod index 6861a98a10..746a80c79e 100644 --- a/src/lib/libcrypto/doc/RSA_private_encrypt.pod +++ b/src/lib/libcrypto/doc/RSA_private_encrypt.pod @@ -59,7 +59,8 @@ obtained by L. =head1 SEE ALSO -L, L, L, L +L, L, +L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_public_encrypt.pod b/src/lib/libcrypto/doc/RSA_public_encrypt.pod index e20dfcb551..d53e19d2b7 100644 --- a/src/lib/libcrypto/doc/RSA_public_encrypt.pod +++ b/src/lib/libcrypto/doc/RSA_public_encrypt.pod @@ -72,7 +72,8 @@ SSL, PKCS #1 v2.0 =head1 SEE ALSO -L, L, L, L +L, L, L, +L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_set_method.pod b/src/lib/libcrypto/doc/RSA_set_method.pod index 0687c2242a..0a305f6b14 100644 --- a/src/lib/libcrypto/doc/RSA_set_method.pod +++ b/src/lib/libcrypto/doc/RSA_set_method.pod @@ -3,13 +3,12 @@ =head1 NAME RSA_set_default_method, RSA_get_default_method, RSA_set_method, -RSA_get_method, RSA_PKCS1_SSLeay, -RSA_null_method, RSA_flags, RSA_new_method - select RSA method +RSA_get_method, RSA_PKCS1_SSLeay, RSA_null_method, RSA_flags, +RSA_new_method - select RSA method =head1 SYNOPSIS #include - #include void RSA_set_default_method(const RSA_METHOD *meth); @@ -25,7 +24,7 @@ RSA_null_method, RSA_flags, RSA_new_method - select RSA method int RSA_flags(const RSA *rsa); - RSA *RSA_new_method(ENGINE *engine); + RSA *RSA_new_method(RSA_METHOD *method); =head1 DESCRIPTION @@ -70,6 +69,12 @@ B will be used for the RSA operations. If B is NULL, the default ENGINE for RSA operations is used, and if no default ENGINE is set, the RSA_METHOD controlled by RSA_set_default_method() is used. +RSA_flags() returns the B that are set for B's current method. + +RSA_new_method() allocates and initializes an B structure so that +B will be used for the RSA operations. If B is B, +the default method is used. + =head1 THE RSA_METHOD STRUCTURE typedef struct rsa_meth_st diff --git a/src/lib/libcrypto/doc/RSA_sign.pod b/src/lib/libcrypto/doc/RSA_sign.pod index f0bf6eea1b..71688a665e 100644 --- a/src/lib/libcrypto/doc/RSA_sign.pod +++ b/src/lib/libcrypto/doc/RSA_sign.pod @@ -50,8 +50,8 @@ SSL, PKCS #1 v2.0 =head1 SEE ALSO -L, L, L, -L, +L, L, +L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod b/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod index df9ceb339a..e70380bbfc 100644 --- a/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod +++ b/src/lib/libcrypto/doc/RSA_sign_ASN1_OCTET_STRING.pod @@ -47,8 +47,8 @@ These functions serve no recognizable purpose. =head1 SEE ALSO -L, L, L, -L, L, +L, L, +L, L, L, L =head1 HISTORY diff --git a/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod new file mode 100644 index 0000000000..ffafa37887 --- /dev/null +++ b/src/lib/libcrypto/doc/SMIME_read_PKCS7.pod @@ -0,0 +1,71 @@ +=pod + +=head1 NAME + +SMIME_read_PKCS7 - parse S/MIME message. + +=head1 SYNOPSIS + +PKCS7 *SMIME_read_PKCS7(BIO *in, BIO **bcont); + +=head1 DESCRIPTION + +SMIME_read_PKCS7() parses a message in S/MIME format. + +B is a BIO to read the message from. + +If cleartext signing is used then the content is saved in +a memory bio which is written to B<*bcont>, otherwise +B<*bcont> is set to B. + +The parsed PKCS#7 structure is returned or B if an +error occurred. + +=head1 NOTES + +If B<*bcont> is not B then the message is clear text +signed. B<*bcont> can then be passed to PKCS7_verify() with +the B flag set. + +Otherwise the type of the returned structure can be determined +using PKCS7_type(). + +To support future functionality if B is not B +B<*bcont> should be initialized to B. For example: + + BIO *cont = NULL; + PKCS7 *p7; + + p7 = SMIME_read_PKCS7(in, &cont); + +=head1 BUGS + +The MIME parser used by SMIME_read_PKCS7() is somewhat primitive. +While it will handle most S/MIME messages more complex compound +formats may not work. + +The parser assumes that the PKCS7 structure is always base64 +encoded and will not handle the case where it is in binary format +or uses quoted printable format. + +The use of a memory BIO to hold the signed content limits the size +of message which can be processed due to memory restraints: a +streaming single pass option should be available. + +=head1 RETURN VALUES + +SMIME_read_PKCS7() returns a valid B structure or B +is an error occurred. The error can be obtained from ERR_get_error(3). + +=head1 SEE ALSO + +L, L +L, L, +L, L +L + +=head1 HISTORY + +SMIME_read_PKCS7() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod new file mode 100644 index 0000000000..2cfad2e049 --- /dev/null +++ b/src/lib/libcrypto/doc/SMIME_write_PKCS7.pod @@ -0,0 +1,59 @@ +=pod + +=head1 NAME + +SMIME_write_PKCS7 - convert PKCS#7 structure to S/MIME format. + +=head1 SYNOPSIS + +int SMIME_write_PKCS7(BIO *out, PKCS7 *p7, BIO *data, int flags); + +=head1 DESCRIPTION + +SMIME_write_PKCS7() adds the appropriate MIME headers to a PKCS#7 +structure to produce an S/MIME message. + +B is the BIO to write the data to. B is the appropriate +B structure. If cleartext signing (B) is +being used then the signed data must be supplied in the B +argument. B is an optional set of flags. + +=head1 NOTES + +The following flags can be passed in the B parameter. + +If B is set then cleartext signing will be used, +this option only makes sense for signedData where B +is also set when PKCS7_sign() is also called. + +If the B flag is set MIME headers for type B +are added to the content, this only makes sense if B +is also set. + +If cleartext signing is being used then the data must be read twice: +once to compute the signature in PKCS7_sign() and once to output the +S/MIME message. + +=head1 BUGS + +SMIME_write_PKCS7() always base64 encodes PKCS#7 structures, there +should be an option to disable this. + +There should really be a way to produce cleartext signing using only +a single pass of the data. + +=head1 RETURN VALUES + +SMIME_write_PKCS7() returns 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, +L, L +L + +=head1 HISTORY + +SMIME_write_PKCS7() was added to OpenSSL 0.9.5 + +=cut diff --git a/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod new file mode 100644 index 0000000000..d287c18564 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_NAME_ENTRY_get_object.pod @@ -0,0 +1,72 @@ +=pod + +=head1 NAME + +X509_NAME_ENTRY_get_object, X509_NAME_ENTRY_get_data, +X509_NAME_ENTRY_set_object, X509_NAME_ENTRY_set_data, +X509_NAME_ENTRY_create_by_txt, X509_NAME_ENTRY_create_by_NID, +X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions + +=head1 SYNOPSIS + +ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, unsigned char *bytes, int len); + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, char *field, int type, unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, int type,unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, ASN1_OBJECT *obj, int type,unsigned char *bytes, int len); + +=head1 DESCRIPTION + +X509_NAME_ENTRY_get_object() retrieves the field name of B in +and B structure. + +X509_NAME_ENTRY_get_data() retrieves the field value of B in +and B structure. + +X509_NAME_ENTRY_set_object() sets the field name of B to B. + +X509_NAME_ENTRY_set_data() sets the field value of B to string type +B and value determined by B and B. + +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID() +and X509_NAME_ENTRY_create_by_OBJ() create and return an +B structure. + +=head1 NOTES + +X509_NAME_ENTRY_get_object() and X509_NAME_ENTRY_get_data() can be +used to examine an B function as returned by +X509_NAME_get_entry() for example. + +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_NID(), +and X509_NAME_ENTRY_create_by_OBJ() create and return an + +X509_NAME_ENTRY_create_by_txt(), X509_NAME_ENTRY_create_by_OBJ(), +X509_NAME_ENTRY_create_by_NID() and X509_NAME_ENTRY_set_data() +are seldom used in practice because B structures +are almost always part of B structures and the +corresponding B functions are typically used to +create and add new entries in a single operation. + +The arguments of these functions support similar options to the similarly +named ones of the corresponding B functions such as +X509_NAME_add_entry_by_txt(). So for example B can be set to +B but in the case of X509_set_data() the field name must be +set first so the relevant field information can be looked up internally. + +=head1 RETURN VALUES + +=head1 SEE ALSO + +L, L, +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod new file mode 100644 index 0000000000..4472a1c5cf --- /dev/null +++ b/src/lib/libcrypto/doc/X509_NAME_add_entry_by_txt.pod @@ -0,0 +1,110 @@ +=pod + +=head1 NAME + +X509_NAME_add_entry_by_txt, X509_NAME_add_entry_by_OBJ, X509_NAME_add_entry_by_NID, +X509_NAME_add_entry, X509_NAME_delete_entry - X509_NAME modification functions + +=head1 SYNOPSIS + +int X509_NAME_add_entry_by_txt(X509_NAME *name, char *field, int type, unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, int loc, int set); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); + +=head1 DESCRIPTION + +X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ() and +X509_NAME_add_entry_by_NID() add a field whose name is defined +by a string B, an object B or a NID B respectively. +The field value to be added is in B of length B. If +B is -1 then the field length is calculated internally using +strlen(bytes). + +The type of field is determined by B which can either be a +definition of the type of B (such as B) or a +standard ASN1 type (such as B). The new entry is +added to a position determined by B and B. + +X509_NAME_add_entry() adds a copy of B structure B +to B. The new entry is added to a position determined by B +and B. Since a copy of B is added B must be freed up after +the call. + +X509_NAME_delete_entry() deletes an entry from B at position +B. The deleted entry is returned and must be freed up. + +=head1 NOTES + +The use of string types such as B or B +is strongly recommened for the B parameter. This allows the +internal code to correctly determine the type of the field and to +apply length checks according to the relevant standards. This is +done using ASN1_STRING_set_by_NID(). + +If instead an ASN1 type is used no checks are performed and the +supplied data in B is used directly. + +In X509_NAME_add_entry_by_txt() the B string represents +the field name using OBJ_txt2obj(field, 0). + +The B and B parameters determine where a new entry should +be added. For almost all applications B can be set to -1 and B +to 0. This adds a new entry to the end of B as a single valued +RelativeDistinguishedName (RDN). + +B actually determines the index where the new entry is inserted: +if it is -1 it is appended. + +B determines how the new type is added. If it is zero a +new RDN is created. + +If B is -1 or 1 it is added to the previous or next RDN +structure respectively. This will then be a multivalued RDN: +since multivalues RDNs are very seldom used B is almost +always set to zero. + +=head1 EXAMPLES + +Create an B structure: + +"C=UK, O=Disorganized Organization, CN=Joe Bloggs" + + X509_NAME *nm; + nm = X509_NAME_new(); + if (nm == NULL) + /* Some error */ + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, + "C", "UK", -1, -1, 0)) + /* Error */ + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, + "O", "Disorganized Organization", -1, -1, 0)) + /* Error */ + if (!X509_NAME_add_entry_by_txt(nm, MBSTRING_ASC, + "CN", "Joe Bloggs", -1, -1, 0)) + /* Error */ + +=head1 RETURN VALUES + +X509_NAME_add_entry_by_txt(), X509_NAME_add_entry_by_OBJ(), +X509_NAME_add_entry_by_NID() and X509_NAME_add_entry() return 1 for +success of 0 if an error occurred. + +X509_NAME_delete_entry() returns either the deleted B +structure of B if an error occurred. + +=head1 BUGS + +B can still be set to B to use a +different algorithm to determine field types. Since this form does +not understand multicharacter types, performs no length checks and +can result in invalid field types its use is strongly discouraged. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +=cut diff --git a/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod new file mode 100644 index 0000000000..333323d734 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_NAME_get_index_by_NID.pod @@ -0,0 +1,106 @@ +=pod + +=head1 NAME + +X509_NAME_get_index_by_NID, X509_NAME_get_index_by_OBJ, X509_NAME_get_entry, +X509_NAME_entry_count, X509_NAME_get_text_by_NID, X509_NAME_get_text_by_OBJ - +X509_NAME lookup and enumeration functions + +=head1 SYNOPSIS + +int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, int lastpos); + +int X509_NAME_entry_count(X509_NAME *name); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf,int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,int len); + +=head1 DESCRIPTION + +These functions allow an B structure to be examined. The +B structure is the same as the B type defined in +RFC2459 (and elsewhere) and used for example in certificate subject +and issuer names. + +X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() retrieve +the next index matching B or B after B. B +should initially be set to -1. If there are no more entries -1 is returned. + +X509_NAME_entry_count() returns the total number of entries in B. + +X509_NAME_get_entry() retrieves the B from B +corresponding to index B. Acceptable values for B run from +0 to (X509_NAME_entry_count(name) - 1). The value returned is an +internal pointer which must not be freed. + +X509_NAME_get_text_by_NID(), X509_NAME_get_text_by_OBJ() retrieve +the "text" from the first entry in B which matches B or +B, if no such entry exists -1 is returned. At most B bytes +will be written and the text written to B will be null +terminated. The length of the output string written is returned +excluding the terminating null. If B is then the amount +of space needed in B (excluding the final null) is returned. + +=head1 NOTES + +X509_NAME_get_text_by_NID() and X509_NAME_get_text_by_OBJ() are +legacy functions which have various limitations which make them +of minimal use in practice. They can only find the first matching +entry and will copy the contents of the field verbatim: this can +be highly confusing if the target is a muticharacter string type +like a BMPString or a UTF8String. + +For a more general solution X509_NAME_get_index_by_NID() or +X509_NAME_get_index_by_OBJ() should be used followed by +X509_NAME_get_entry() on any matching indices and then the +various B utility functions on the result. + +=head1 EXAMPLES + +Process all entries: + + int i; + X509_NAME_ENTRY *e; + + for (i = 0; i < X509_NAME_entry_count(nm); i++) + { + e = X509_NAME_get_entry(nm, i); + /* Do something with e */ + } + +Process all commonName entries: + + int loc; + X509_NAME_ENTRY *e; + + loc = -1; + for (;;) + { + lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos); + if (lastpos == -1) + break; + e = X509_NAME_get_entry(nm, lastpos); + /* Do something with e */ + } + +=head1 RETURN VALUES + +X509_NAME_get_index_by_NID() and X509_NAME_get_index_by_OBJ() +return the index of the next matching entry or -1 if not found. + +X509_NAME_entry_count() returns the total number of entries. + +X509_NAME_get_entry() returns an B pointer to the +requested entry or B if the index is invalid. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/X509_NAME_print_ex.pod b/src/lib/libcrypto/doc/X509_NAME_print_ex.pod new file mode 100644 index 0000000000..907c04f684 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_NAME_print_ex.pod @@ -0,0 +1,105 @@ +=pod + +=head1 NAME + +X509_NAME_print_ex, X509_NAME_print_ex_fp, X509_NAME_print, +X509_NAME_oneline - X509_NAME printing routines. + +=head1 SYNOPSIS + + #include + + int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); + int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); + char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); + +=head1 DESCRIPTION + +X509_NAME_print_ex() prints a human readable version of B to BIO B. Each +line (for multiline formats) is indented by B spaces. The output format +can be extensively customised by use of the B parameter. + +X509_NAME_print_ex_fp() is identical to X509_NAME_print_ex() except the output is +written to FILE pointer B. + +X509_NAME_oneline() prints an ASCII version of B to B. At most B +bytes will be written. If B is B then a buffer is dynamically allocated +and returned, otherwise B is returned. + +X509_NAME_print() prints out B to B indenting each line by B +characters. Multiple lines are used if the output (including indent) exceeds +80 characters. + +=head1 NOTES + +The functions X509_NAME_oneline() and X509_NAME_print() are legacy functions which +produce a non standard output form, they don't handle multi character fields and +have various quirks and inconsistencies. Their use is strongly discouraged in new +applications. + +Although there are a large number of possible flags for most purposes +B, B or B will suffice. +As noted on the L manual page +for UTF8 terminals the B should be unset: so for example +B would be used. + +The complete set of the flags supported by X509_NAME_print_ex() is listed below. + +Several options can be ored together. + +The options B, B, +B and B determine the field separators +to use. Two distinct separators are used between distinct RelativeDistinguishedName +components and separate values in the same RDN for a multi-valued RDN. Multi-valued +RDNs are currently very rare so the second separator will hardly ever be used. + +B uses comma and plus as separators. B +uses comma and plus with spaces: this is more readable that plain comma and plus. +B uses spaced semicolon and plus. B uses +spaced newline and plus respectively. + +If B is set the whole DN is printed in reversed order. + +The fields B, B, B, +B determine how a field name is displayed. It will +use the short name (e.g. CN) the long name (e.g. commonName) always +use OID numerical form (normally OIDs are only used if the field name is not +recognised) and no field name respectively. + +If B is set then spaces will be placed around the '=' character +separating field names and values. + +If B is set then the encoding of unknown fields is +printed instead of the values. + +If B is set then field names are padded to 20 characters: this +is only of use for multiline format. + +Additionally all the options supported by ASN1_STRING_print_ex() can be used to +control how each field value is displayed. + +In addition a number options can be set for commonly used formats. + +B sets options which produce an output compatible with RFC2253 it +is equivalent to: + B + + +B is a more readable one line format it is the same as: + B + +B is a multiline format is is the same as: + B + +B uses a format identical to X509_NAME_print(): in fact it calls X509_NAME_print() internally. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/X509_new.pod b/src/lib/libcrypto/doc/X509_new.pod new file mode 100644 index 0000000000..fd5fc65ce1 --- /dev/null +++ b/src/lib/libcrypto/doc/X509_new.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +X509_new, X509_free - X509 certificate ASN1 allocation functions + +=head1 SYNOPSIS + + X509 *X509_new(void); + void X509_free(X509 *a); + +=head1 DESCRIPTION + +The X509 ASN1 allocation routines, allocate and free an +X509 structure, which represents an X509 certificate. + +X509_new() allocates and initializes a X509 structure. + +X509_free() frees up the B structure B. + +=head1 RETURN VALUES + +If the allocation fails, X509_new() returns B and sets an error +code that can be obtained by L. +Otherwise it returns a pointer to the newly allocated structure. + +X509_free() returns no value. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +X509_new() and X509_free() are available in all versions of SSLeay and OpenSSL. + +=cut diff --git a/src/lib/libcrypto/doc/d2i_ASN1_OBJECT.pod b/src/lib/libcrypto/doc/d2i_ASN1_OBJECT.pod new file mode 100644 index 0000000000..45bb18492c --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_ASN1_OBJECT.pod @@ -0,0 +1,29 @@ +=pod + +=head1 NAME + +d2i_ASN1_OBJECT, i2d_ASN1_OBJECT - ASN1 OBJECT IDENTIFIER functions + +=head1 SYNOPSIS + + #include + + ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, long length); + int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); + +=head1 DESCRIPTION + +These functions decode and encode an ASN1 OBJECT IDENTIFIER. + +Othewise these behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_DHparams.pod b/src/lib/libcrypto/doc/d2i_DHparams.pod index a6d1743d39..1e98aebeca 100644 --- a/src/lib/libcrypto/doc/d2i_DHparams.pod +++ b/src/lib/libcrypto/doc/d2i_DHparams.pod @@ -2,7 +2,7 @@ =head1 NAME -d2i_DHparams, i2d_DHparams - ... +d2i_DHparams, i2d_DHparams - PKCS#3 DH parameter functions. =head1 SYNOPSIS @@ -13,18 +13,18 @@ d2i_DHparams, i2d_DHparams - ... =head1 DESCRIPTION -... +These functions decode and encode PKCS#3 DH parameters using the +DHparameter structure described in PKCS#3. -=head1 RETURN VALUES - -... +Othewise these behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. =head1 SEE ALSO -... +L =head1 HISTORY -... +TBA =cut diff --git a/src/lib/libcrypto/doc/d2i_DSAPublicKey.pod b/src/lib/libcrypto/doc/d2i_DSAPublicKey.pod new file mode 100644 index 0000000000..6ebd30427b --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_DSAPublicKey.pod @@ -0,0 +1,82 @@ +=pod + +=head1 NAME + +d2i_DSAPublicKey, i2d_DSAPublicKey, d2i_DSAPrivateKey, i2d_DSAPrivateKey, +d2i_DSA_PUBKEY, i2d_DSA_PUBKEY, d2i_DSA_SIG, i2d_DSA_SIG - DSA key encoding +and parsing functions. + +=head1 SYNOPSIS + + #include + + DSA * d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); + + int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); + + DSA * d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); + + int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp); + + DSA * d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); + + int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); + + DSA * d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + + int i2d_DSAparams(const DSA *a, unsigned char **pp); + + DSA * d2i_DSA_SIG(DSA_SIG **a, const unsigned char **pp, long length); + + int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); + +=head1 DESCRIPTION + +d2i_DSAPublicKey() and i2d_DSAPublicKey() decode and encode the DSA public key +components structure. + +d2i_DSA_PUKEY() and i2d_DSA_PUKEY() decode and encode an DSA public key using a +SubjectPublicKeyInfo (certificate public key) structure. + +d2i_DSAPrivateKey(), i2d_DSAPrivateKey() decode and encode the DSA private key +components. + +d2i_DSAparams(), i2d_DSAparams() decode and encode the DSA parameters using +a B structure as defined in RFC2459. + +d2i_DSA_SIG(), i2d_DSA_SIG() decode and encode a DSA signature using a +B structure as defined in RFC2459. + +The usage of all of these functions is similar to the d2i_X509() and +i2d_X509() described in the L manual page. + +=head1 NOTES + +The B structure passed to the private key encoding functions should have +all the private key components present. + +The data encoded by the private key functions is unencrypted and therefore +offers no private key security. + +The B functions should be used in preference to the B +functions when encoding public keys because they use a standard format. + +The B functions use an non standard format the actual data encoded +depends on the value of the B field of the B key parameter. +If B is zero then only the B field is encoded as an +B. If B is 1 then a B consisting of the +B

, B, B and B respectively fields are encoded. + +The B functions also use a non standard structure consiting +consisting of a SEQUENCE containing the B

, B, B and B and +B fields respectively. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod index ff4d0d57db..7c71bcbf3d 100644 --- a/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod +++ b/src/lib/libcrypto/doc/d2i_RSAPublicKey.pod @@ -2,7 +2,9 @@ =head1 NAME -d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, i2d_Netscape_RSA, d2i_Netscape_RSA - ... +d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, +d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, i2d_Netscape_RSA, +d2i_Netscape_RSA - RSA public and private key encoding functions. =head1 SYNOPSIS @@ -12,6 +14,10 @@ d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, i2d_Ne int i2d_RSAPublicKey(RSA *a, unsigned char **pp); + RSA * d2i_RSA_PUBKEY(RSA **a, unsigned char **pp, long length); + + int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); + RSA * d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length); int i2d_RSAPrivateKey(RSA *a, unsigned char **pp); @@ -22,18 +28,39 @@ d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, i2d_Ne =head1 DESCRIPTION -... +d2i_RSAPublicKey() and i2d_RSAPublicKey() decode and encode a PKCS#1 RSAPublicKey +structure. + +d2i_RSA_PUKEY() and i2d_RSA_PUKEY() decode and encode an RSA public key using a +SubjectPublicKeyInfo (certificate public key) structure. + +d2i_RSAPrivateKey(), i2d_RSAPrivateKey() decode and encode a PKCS#1 RSAPrivateKey +structure. + +d2i_Netscape_RSA(), i2d_Netscape_RSA() decode and encode an RSA private key in +NET format. + +The usage of all of these functions is similar to the d2i_X509() and +i2d_X509() described in the L manual page. + +=head1 NOTES + +The B structure passed to the private key encoding functions should have +all the PKCS#1 private key components present. -=head1 RETURN VALUES +The data encoded by the private key functions is unencrypted and therefore +offers no private key security. -... +The NET format functions are present to provide compatibility with certain very +old software. This format has some severe security weaknesses and should be +avoided if possible. =head1 SEE ALSO -... +L =head1 HISTORY -... +TBA =cut diff --git a/src/lib/libcrypto/doc/d2i_X509.pod b/src/lib/libcrypto/doc/d2i_X509.pod new file mode 100644 index 0000000000..5e3c3d0985 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509.pod @@ -0,0 +1,231 @@ +=pod + +=head1 NAME + +d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio, +i2d_X509_fp - X509 encode and decode functions + +=head1 SYNOPSIS + + #include + + X509 *d2i_X509(X509 **px, unsigned char **in, int len); + int i2d_X509(X509 *x, unsigned char **out); + + X509 *d2i_X509_bio(BIO *bp, X509 **x); + X509 *d2i_X509_fp(FILE *fp, X509 **x); + + int i2d_X509_bio(X509 *x, BIO *bp); + int i2d_X509_fp(X509 *x, FILE *fp); + +=head1 DESCRIPTION + +The X509 encode and decode routines encode and parse an +B structure, which represents an X509 certificate. + +d2i_X509() attempts to decode B bytes at B<*out>. If +successful a pointer to the B structure is returned. If an error +occurred then B is returned. If B is not B then the +returned structure is written to B<*px>. If B<*px> is not B +then it is assumed that B<*px> contains a valid B +structure and an attempt is made to reuse it. If the call is +successful B<*out> is incremented to the byte following the +parsed data. + +i2d_X509() encodes the structure pointed to by B into DER format. +If B is not B is writes the DER encoded data to the buffer +at B<*out>, and increments it to point after the data just written. +If the return value is negative an error occurred, otherwise it +returns the length of the encoded data. + +For OpenSSL 0.9.7 and later if B<*out> is B memory will be +allocated for a buffer and the encoded data written to it. In this +case B<*out> is not incremented and it points to the start of the +data just written. + +d2i_X509_bio() is similar to d2i_X509() except it attempts +to parse data from BIO B. + +d2i_X509_fp() is similar to d2i_X509() except it attempts +to parse data from FILE pointer B. + +i2d_X509_bio() is similar to i2d_X509() except it writes +the encoding of the structure B to BIO B and it +returns 1 for success and 0 for failure. + +i2d_X509_fp() is similar to i2d_X509() except it writes +the encoding of the structure B to BIO B and it +returns 1 for success and 0 for failure. + +=head1 NOTES + +The letters B and B in for example B stand for +"internal" (that is an internal C structure) and "DER". So that +B converts from internal to DER. + +The functions can also understand B forms. + +The actual X509 structure passed to i2d_X509() must be a valid +populated B structure it can B simply be fed with an +empty structure such as that returned by X509_new(). + +The encoded data is in binary form and may contain embedded zeroes. +Therefore any FILE pointers or BIOs should be opened in binary mode. +Functions such as B will B return the correct length +of the encoded structure. + +The ways that B<*in> and B<*out> are incremented after the operation +can trap the unwary. See the B section for some common +errors. + +The reason for the auto increment behaviour is to reflect a typical +usage of ASN1 functions: after one structure is encoded or decoded +another will processed after it. + +=head1 EXAMPLES + +Allocate and encode the DER encoding of an X509 structure: + + int len; + unsigned char *buf, *p; + + len = i2d_X509(x, NULL); + + buf = OPENSSL_malloc(len); + + if (buf == NULL) + /* error */ + + p = buf; + + i2d_X509(x, &p); + +If you are using OpenSSL 0.9.7 or later then this can be +simplified to: + + + int len; + unsigned char *buf; + + buf = NULL; + + len = i2d_X509(x, &buf); + + if (len < 0) + /* error */ + +Attempt to decode a buffer: + + X509 *x; + + unsigned char *buf, *p; + + int len; + + /* Something to setup buf and len */ + + p = buf; + + x = d2i_X509(NULL, &p, len); + + if (x == NULL) + /* Some error */ + +Alternative technique: + + X509 *x; + + unsigned char *buf, *p; + + int len; + + /* Something to setup buf and len */ + + p = buf; + + x = NULL; + + if(!d2i_X509(&x, &p, len)) + /* Some error */ + + +=head1 WARNINGS + +The use of temporary variable is mandatory. A common +mistake is to attempt to use a buffer directly as follows: + + int len; + unsigned char *buf; + + len = i2d_X509(x, NULL); + + buf = OPENSSL_malloc(len); + + if (buf == NULL) + /* error */ + + i2d_X509(x, &buf); + + /* Other stuff ... */ + + OPENSSL_free(buf); + +This code will result in B apparently containing garbage because +it was incremented after the call to point after the data just written. +Also B will no longer contain the pointer allocated by B +and the subsequent call to B may well crash. + +The auto allocation feature (setting buf to NULL) only works on OpenSSL +0.9.7 and later. Attempts to use it on earlier versions will typically +cause a segmentation violation. + +Another trap to avoid is misuse of the B argument to B: + + X509 *x; + + if (!d2i_X509(&x, &p, len)) + /* Some error */ + +This will probably crash somewhere in B. The reason for this +is that the variable B is uninitialized and an attempt will be made to +interpret its (invalid) value as an B structure, typically causing +a segmentation violation. If B is set to NULL first then this will not +happen. + +=head1 BUGS + +In some versions of OpenSSL the "reuse" behaviour of d2i_X509() when +B<*px> is valid is broken and some parts of the reused structure may +persist if they are not present in the new one. As a result the use +of this "reuse" behaviour is strongly discouraged. + +i2d_X509() will not return an error in many versions of OpenSSL, +if mandatory fields are not initialized due to a programming error +then the encoded structure may contain invalid data or omit the +fields entirely and will not be parsed by d2i_X509(). This may be +fixed in future so code should not assume that i2d_X509() will +always succeed. + +=head1 RETURN VALUES + +d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B structure +or B if an error occurs. The error code that can be obtained by +L. + +i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes +successfully encoded or a negative value if an error occurs. The error code +can be obtained by L. + +i2d_X509_bio() and i2d_X509_fp() returns 1 for success and 0 if an error +occurs The error code can be obtained by L. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio and i2d_X509_fp +are available in all versions of SSLeay and OpenSSL. + +=cut diff --git a/src/lib/libcrypto/doc/d2i_X509_ALGOR.pod b/src/lib/libcrypto/doc/d2i_X509_ALGOR.pod new file mode 100644 index 0000000000..9e5cd92ca7 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509_ALGOR.pod @@ -0,0 +1,30 @@ +=pod + +=head1 NAME + +d2i_X509_ALGOR, i2d_X509_ALGOR - AlgorithmIdentifier functions. + +=head1 SYNOPSIS + + #include + + X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **a, unsigned char **pp, long length); + int i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **pp); + +=head1 DESCRIPTION + +These functions decode and encode an B structure which is +equivalent to the B structure. + +Othewise these behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_X509_CRL.pod b/src/lib/libcrypto/doc/d2i_X509_CRL.pod new file mode 100644 index 0000000000..06c5b23c09 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509_CRL.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +d2i_X509_CRL, i2d_X509_CRL, d2i_X509_CRL_bio, d2i_509_CRL_fp, +i2d_X509_CRL_bio, i2d_X509_CRL_fp - PKCS#10 certificate request functions. + +=head1 SYNOPSIS + + #include + + X509_CRL *d2i_X509_CRL(X509_CRL **a, unsigned char **pp, long length); + int i2d_X509_CRL(X509_CRL *a, unsigned char **pp); + + X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **x); + X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **x); + + int i2d_X509_CRL_bio(X509_CRL *x, BIO *bp); + int i2d_X509_CRL_fp(X509_CRL *x, FILE *fp); + +=head1 DESCRIPTION + +These functions decode and encode an X509 CRL (certificate revocation +list). + +Othewise the functions behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_X509_NAME.pod b/src/lib/libcrypto/doc/d2i_X509_NAME.pod new file mode 100644 index 0000000000..343ffe1519 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509_NAME.pod @@ -0,0 +1,31 @@ +=pod + +=head1 NAME + +d2i_X509_NAME, i2d_X509_NAME - X509_NAME encoding functions + +=head1 SYNOPSIS + + #include + + X509_NAME *d2i_X509_NAME(X509_NAME **a, unsigned char **pp, long length); + int i2d_X509_NAME(X509_NAME *a, unsigned char **pp); + +=head1 DESCRIPTION + +These functions decode and encode an B structure which is the +the same as the B type defined in RFC2459 (and elsewhere) and used +for example in certificate subject and issuer names. + +Othewise the functions behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_X509_REQ.pod b/src/lib/libcrypto/doc/d2i_X509_REQ.pod new file mode 100644 index 0000000000..be4ad68257 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509_REQ.pod @@ -0,0 +1,36 @@ +=pod + +=head1 NAME + +d2i_X509_REQ, i2d_X509_REQ, d2i_X509_REQ_bio, d2i_X509_REQ_fp, +i2d_X509_REQ_bio, i2d_X509_REQ_fp - PKCS#10 certificate request functions. + +=head1 SYNOPSIS + + #include + + X509_REQ *d2i_X509_REQ(X509_REQ **a, unsigned char **pp, long length); + int i2d_X509_REQ(X509_REQ *a, unsigned char **pp); + + X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **x); + X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **x); + + int i2d_X509_REQ_bio(X509_REQ *x, BIO *bp); + int i2d_X509_REQ_fp(X509_REQ *x, FILE *fp); + +=head1 DESCRIPTION + +These functions decode and encode a PKCS#10 certificate request. + +Othewise these behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/d2i_X509_SIG.pod b/src/lib/libcrypto/doc/d2i_X509_SIG.pod new file mode 100644 index 0000000000..e48fd79a51 --- /dev/null +++ b/src/lib/libcrypto/doc/d2i_X509_SIG.pod @@ -0,0 +1,30 @@ +=pod + +=head1 NAME + +d2i_X509_SIG, i2d_X509_SIG - DigestInfo functions. + +=head1 SYNOPSIS + + #include + + X509_SIG *d2i_X509_SIG(X509_SIG **a, unsigned char **pp, long length); + int i2d_X509_SIG(X509_SIG *a, unsigned char **pp); + +=head1 DESCRIPTION + +These functions decode and encode an X509_SIG structure which is +equivalent to the B structure defined in PKCS#1 and PKCS#7. + +Othewise these behave in a similar way to d2i_X509() and i2d_X509() +described in the L manual page. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +TBA + +=cut diff --git a/src/lib/libcrypto/doc/engine.pod b/src/lib/libcrypto/doc/engine.pod index 61e0264bb7..c77dad5562 100644 --- a/src/lib/libcrypto/doc/engine.pod +++ b/src/lib/libcrypto/doc/engine.pod @@ -187,7 +187,7 @@ tell which one you are dealing with at any given point in time (after all they are both simply (ENGINE *) pointers, the difference is in the way they are used). -=head3 Structural references +I This basic type of reference is typically used for creating new ENGINEs dynamically, iterating across OpenSSL's internal linked-list of loaded @@ -224,7 +224,7 @@ To clarify a particular function's handling of references, one should always consult that function's documentation "man" page, or failing that the openssl/engine.h header file includes some hints. -=head3 Functional references +I As mentioned, functional references exist when the cryptographic functionality of an ENGINE is required to be available. A functional @@ -386,7 +386,7 @@ things, so we will simply illustrate the consequences as they apply to a couple of simple cases and leave developers to consider these and the source code to openssl's builtin utilities as guides. -=head3 Using a specific ENGINE implementation +I Here we'll assume an application has been configured by its user or admin to want to use the "ACME" ENGINE if it is available in the version of @@ -418,7 +418,7 @@ illustrates how to approach this; /* Release the structural reference from ENGINE_by_id() */ ENGINE_free(e); -=head3 Automatically using builtin ENGINE implementations +I Here we'll assume we want to load and register all ENGINE implementations bundled with OpenSSL, such that for any cryptographic algorithm required by @@ -469,7 +469,7 @@ in same cases both. ENGINE implementations should provide indications of this in the descriptions attached to builtin control commands and/or in external product documentation. -=head3 Issuing control commands to an ENGINE +I Let's illustrate by example; a function for which the caller supplies the name of the ENGINE it wishes to use, a table of string-pairs for use before @@ -526,7 +526,7 @@ return success without doing anything. In this case we assume the user is only supplying commands specific to the given ENGINE so we set this to FALSE. -=head3 Discovering supported control commands +I It is possible to discover at run-time the names, numerical-ids, descriptions and input parameters of the control commands supported from a structural diff --git a/src/lib/libcrypto/dsa/dsa_lib.c b/src/lib/libcrypto/dsa/dsa_lib.c index da2cdfa3d6..4171af24c6 100644 --- a/src/lib/libcrypto/dsa/dsa_lib.c +++ b/src/lib/libcrypto/dsa/dsa_lib.c @@ -63,7 +63,9 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif const char *DSA_version="DSA" OPENSSL_VERSION_PTEXT; @@ -93,11 +95,13 @@ int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) const DSA_METHOD *mtmp; mtmp = dsa->meth; if (mtmp->finish) mtmp->finish(dsa); +#ifndef OPENSSL_NO_ENGINE if (dsa->engine) { ENGINE_finish(dsa->engine); dsa->engine = NULL; } +#endif dsa->meth = meth; if (meth->init) meth->init(dsa); return 1; @@ -114,6 +118,7 @@ DSA *DSA_new_method(ENGINE *engine) return(NULL); } ret->meth = DSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) @@ -138,6 +143,7 @@ DSA *DSA_new_method(ENGINE *engine) return NULL; } } +#endif ret->pad=0; ret->version=0; @@ -158,8 +164,10 @@ DSA *DSA_new_method(ENGINE *engine) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; @@ -189,8 +197,10 @@ void DSA_free(DSA *r) if(r->meth->finish) r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE if(r->engine) ENGINE_finish(r->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); @@ -224,7 +234,10 @@ int DSA_size(const DSA *r) { int ret,i; ASN1_INTEGER bs; - unsigned char buf[4]; + unsigned char buf[4]; /* 4 bytes looks really small. + However, i2d_ASN1_INTEGER() will not look + beyond the first byte, as long as the second + parameter is NULL. */ i=BN_num_bits(r->q); bs.length=(i+7)/8; diff --git a/src/lib/libcrypto/dsa/dsa_ossl.c b/src/lib/libcrypto/dsa/dsa_ossl.c index 37dd5fc994..b9e7f3ea5c 100644 --- a/src/lib/libcrypto/dsa/dsa_ossl.c +++ b/src/lib/libcrypto/dsa/dsa_ossl.c @@ -64,7 +64,6 @@ #include #include #include -#include static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); @@ -106,13 +105,15 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) int i,reason=ERR_R_BN_LIB; DSA_SIG *ret=NULL; + BN_init(&m); + BN_init(&xr); + if (!dsa->p || !dsa->q || !dsa->g) { reason=DSA_R_MISSING_PARAMETERS; goto err; } - BN_init(&m); - BN_init(&xr); + s=BN_new(); if (s == NULL) goto err; @@ -178,6 +179,9 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS); return 0; } + + BN_init(&k); + if (ctx_in == NULL) { if ((ctx=BN_CTX_new()) == NULL) goto err; @@ -185,7 +189,6 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) else ctx=ctx_in; - BN_init(&k); if ((r=BN_new()) == NULL) goto err; kinv=NULL; @@ -241,11 +244,12 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, return -1; } - if ((ctx=BN_CTX_new()) == NULL) goto err; BN_init(&u1); BN_init(&u2); BN_init(&t1); + if ((ctx=BN_CTX_new()) == NULL) goto err; + if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0) { ret = 0; diff --git a/src/lib/libcrypto/dsa/dsa_sign.c b/src/lib/libcrypto/dsa/dsa_sign.c index e9469ca62f..89205026f0 100644 --- a/src/lib/libcrypto/dsa/dsa_sign.c +++ b/src/lib/libcrypto/dsa/dsa_sign.c @@ -64,7 +64,6 @@ #include #include #include -#include DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { diff --git a/src/lib/libcrypto/dsa/dsa_vrf.c b/src/lib/libcrypto/dsa/dsa_vrf.c index 066c6b5b28..c4aeddd056 100644 --- a/src/lib/libcrypto/dsa/dsa_vrf.c +++ b/src/lib/libcrypto/dsa/dsa_vrf.c @@ -65,7 +65,6 @@ #include #include #include -#include int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h index a52d4edf14..6d6a9b7127 100644 --- a/src/lib/libcrypto/ec/ec.h +++ b/src/lib/libcrypto/ec/ec.h @@ -195,7 +195,6 @@ void ERR_load_EC_strings(void); #define EC_F_EC_GROUP_GET0_GENERATOR 139 #define EC_F_EC_GROUP_GET_COFACTOR 140 #define EC_F_EC_GROUP_GET_CURVE_GFP 130 -#define EC_F_EC_GROUP_GET_EXTRA_DATA 107 #define EC_F_EC_GROUP_GET_ORDER 141 #define EC_F_EC_GROUP_NEW 108 #define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 @@ -232,7 +231,6 @@ void ERR_load_EC_strings(void); #define EC_R_INVALID_FIELD 103 #define EC_R_INVALID_FORM 104 #define EC_R_NOT_INITIALIZED 111 -#define EC_R_NO_SUCH_EXTRA_DATA 105 #define EC_R_POINT_AT_INFINITY 106 #define EC_R_POINT_IS_NOT_ON_CURVE 107 #define EC_R_SLOT_FULL 108 diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c index 394cdc021f..d37b6aba87 100644 --- a/src/lib/libcrypto/ec/ec_err.c +++ b/src/lib/libcrypto/ec/ec_err.c @@ -84,7 +84,6 @@ static ERR_STRING_DATA EC_str_functs[]= {ERR_PACK(0,EC_F_EC_GROUP_GET0_GENERATOR,0), "EC_GROUP_get0_generator"}, {ERR_PACK(0,EC_F_EC_GROUP_GET_COFACTOR,0), "EC_GROUP_get_cofactor"}, {ERR_PACK(0,EC_F_EC_GROUP_GET_CURVE_GFP,0), "EC_GROUP_get_curve_GFp"}, -{ERR_PACK(0,EC_F_EC_GROUP_GET_EXTRA_DATA,0), "EC_GROUP_get_extra_data"}, {ERR_PACK(0,EC_F_EC_GROUP_GET_ORDER,0), "EC_GROUP_get_order"}, {ERR_PACK(0,EC_F_EC_GROUP_NEW,0), "EC_GROUP_new"}, {ERR_PACK(0,EC_F_EC_GROUP_PRECOMPUTE_MULT,0), "EC_GROUP_precompute_mult"}, @@ -124,7 +123,6 @@ static ERR_STRING_DATA EC_str_reasons[]= {EC_R_INVALID_FIELD ,"invalid field"}, {EC_R_INVALID_FORM ,"invalid form"}, {EC_R_NOT_INITIALIZED ,"not initialized"}, -{EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"}, {EC_R_POINT_AT_INFINITY ,"point at infinity"}, {EC_R_POINT_IS_NOT_ON_CURVE ,"point is not on curve"}, {EC_R_SLOT_FULL ,"slot full"}, diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c index 0cf485de60..deb522060f 100644 --- a/src/lib/libcrypto/ec/ec_lib.c +++ b/src/lib/libcrypto/ec/ec_lib.c @@ -128,7 +128,7 @@ void EC_GROUP_clear_free(EC_GROUP *group) EC_GROUP_clear_free_extra_data(group); - memset(group, 0, sizeof *group); + OPENSSL_cleanse(group, sizeof *group); OPENSSL_free(group); } @@ -268,7 +268,9 @@ void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func || (group->extra_data_free_func != extra_data_free_func) || (group->extra_data_clear_free_func != extra_data_clear_free_func)) { - ECerr(EC_F_EC_GROUP_GET_EXTRA_DATA, EC_R_NO_SUCH_EXTRA_DATA); +#if 0 /* this was an error in 0.9.7, but that does not make a lot of sense */ + ECerr(..._F_EC_GROUP_GET_EXTRA_DATA, ..._R_NO_SUCH_EXTRA_DATA); +#endif return NULL; } @@ -357,7 +359,7 @@ void EC_POINT_clear_free(EC_POINT *point) point->meth->point_clear_finish(point); else if (point->meth != NULL && point->meth->point_finish != 0) point->meth->point_finish(point); - memset(point, 0, sizeof *point); + OPENSSL_cleanse(point, sizeof *point); OPENSSL_free(point); } diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c index 603ba31b81..4dbc931120 100644 --- a/src/lib/libcrypto/ec/ec_mult.c +++ b/src/lib/libcrypto/ec/ec_mult.c @@ -209,6 +209,17 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */ int ret = 0; + if (group->meth != r->meth) + { + ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if ((scalar == NULL) && (num == 0)) + { + return EC_POINT_set_to_infinity(group, r); + } + if (scalar != NULL) { generator = EC_GROUP_get0_generator(group); diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c index b3030fe505..0f6992a40d 100644 --- a/src/lib/libcrypto/engine/eng_all.c +++ b/src/lib/libcrypto/engine/eng_all.c @@ -95,8 +95,19 @@ void ENGINE_load_builtin_engines(void) #ifndef OPENSSL_NO_HW_4758_CCA ENGINE_load_4758cca(); #endif -#ifdef OPENSSL_OPENBSD_DEV_CRYPTO - ENGINE_load_openbsd_dev_crypto(); +#if defined(__OpenBSD__) || defined(__FreeBSD__) + ENGINE_load_cryptodev(); #endif #endif } + +#if defined(__OpenBSD__) || defined(__FreeBSD__) +void ENGINE_setup_bsd_cryptodev(void) { + static int bsd_cryptodev_default_loaded = 0; + if (!bsd_cryptodev_default_loaded) { + ENGINE_load_cryptodev(); + ENGINE_register_all_complete(); + } + bsd_cryptodev_default_loaded=1; +} +#endif diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c index f6c5630395..814d95ee32 100644 --- a/src/lib/libcrypto/engine/eng_err.c +++ b/src/lib/libcrypto/engine/eng_err.c @@ -1,6 +1,6 @@ /* crypto/engine/eng_err.c */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -96,6 +96,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]= {ERR_PACK(0,ENGINE_F_ENGINE_SET_NAME,0), "ENGINE_set_name"}, {ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"}, {ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0), "ENGINE_UNLOAD_KEY"}, +{ERR_PACK(0,ENGINE_F_ENGINE_UP_REF,0), "ENGINE_up_ref"}, {ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0), "INT_CTRL_HELPER"}, {ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0), "INT_ENGINE_CONFIGURE"}, {ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"}, diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c index f7edb5ad32..0d7dae00b2 100644 --- a/src/lib/libcrypto/engine/eng_fat.c +++ b/src/lib/libcrypto/engine/eng_fat.c @@ -66,18 +66,18 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags) if((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) return 0; #ifndef OPENSSL_NO_RSA - if((flags & ENGINE_METHOD_RSA) & !ENGINE_set_default_RSA(e)) + if((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) return 0; #endif #ifndef OPENSSL_NO_DSA - if((flags & ENGINE_METHOD_DSA) & !ENGINE_set_default_DSA(e)) + if((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) return 0; #endif #ifndef OPENSSL_NO_DH - if((flags & ENGINE_METHOD_DH) & !ENGINE_set_default_DH(e)) + if((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) return 0; #endif - if((flags & ENGINE_METHOD_RAND) & !ENGINE_set_default_RAND(e)) + if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) return 0; return 1; } diff --git a/src/lib/libcrypto/engine/eng_init.c b/src/lib/libcrypto/engine/eng_init.c index 98caa21e32..170c1791b3 100644 --- a/src/lib/libcrypto/engine/eng_init.c +++ b/src/lib/libcrypto/engine/eng_init.c @@ -93,7 +93,7 @@ int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) * there's a chance that both threads will together take the count from * 2 to 0 without either calling finish(). */ e->funct_ref--; - engine_ref_debug(e, 1, -1) + engine_ref_debug(e, 1, -1); if((e->funct_ref == 0) && e->finish) { if(unlock_for_handlers) diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c index 0c220558e7..1cc3217f4c 100644 --- a/src/lib/libcrypto/engine/eng_list.c +++ b/src/lib/libcrypto/engine/eng_list.c @@ -191,14 +191,14 @@ ENGINE *ENGINE_get_first(void) { ENGINE *ret; - CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); ret = engine_list_head; if(ret) { ret->struct_ref++; engine_ref_debug(ret, 0, 1) } - CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return ret; } @@ -206,14 +206,14 @@ ENGINE *ENGINE_get_last(void) { ENGINE *ret; - CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); - ret = engine_list_tail; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_tail; if(ret) { ret->struct_ref++; engine_ref_debug(ret, 0, 1) } - CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return ret; } @@ -227,7 +227,7 @@ ENGINE *ENGINE_get_next(ENGINE *e) ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); ret = e->next; if(ret) { @@ -235,7 +235,7 @@ ENGINE *ENGINE_get_next(ENGINE *e) ret->struct_ref++; engine_ref_debug(ret, 0, 1) } - CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* Release the structural reference to the previous ENGINE */ ENGINE_free(e); return ret; @@ -250,7 +250,7 @@ ENGINE *ENGINE_get_prev(ENGINE *e) ERR_R_PASSED_NULL_PARAMETER); return 0; } - CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); ret = e->prev; if(ret) { @@ -258,7 +258,7 @@ ENGINE *ENGINE_get_prev(ENGINE *e) ret->struct_ref++; engine_ref_debug(ret, 0, 1) } - CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* Release the structural reference to the previous ENGINE */ ENGINE_free(e); return ret; @@ -346,7 +346,7 @@ ENGINE *ENGINE_by_id(const char *id) ERR_R_PASSED_NULL_PARAMETER); return NULL; } - CRYPTO_r_lock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); iterator = engine_list_head; while(iterator && (strcmp(id, iterator->id) != 0)) iterator = iterator->next; @@ -372,7 +372,7 @@ ENGINE *ENGINE_by_id(const char *id) engine_ref_debug(iterator, 0, 1) } } - CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); if(iterator == NULL) { ENGINEerr(ENGINE_F_ENGINE_BY_ID, @@ -381,3 +381,14 @@ ENGINE *ENGINE_by_id(const char *id) } return iterator; } + +int ENGINE_up_ref(ENGINE *e) + { + if (e == NULL) + { + ENGINEerr(ENGINE_F_ENGINE_UP_REF,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_add(&e->struct_ref,1,CRYPTO_LOCK_ENGINE); + return 1; + } diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c index e9d976f46b..54579eea2e 100644 --- a/src/lib/libcrypto/engine/eng_openssl.c +++ b/src/lib/libcrypto/engine/eng_openssl.c @@ -63,6 +63,7 @@ #include #include #include +#include /* This testing gunk is implemented (and explained) lower down. It also assumes * the application explicitly calls "ENGINE_load_openssl()" because this is no @@ -78,6 +79,21 @@ /* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ /* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ +/* Now check what of those algorithms are actually enabled */ +#ifdef OPENSSL_NO_RC4 +#undef TEST_ENG_OPENSSL_RC4 +#undef TEST_ENG_OPENSSL_RC4_OTHERS +#undef TEST_ENG_OPENSSL_RC4_P_INIT +#undef TEST_ENG_OPENSSL_RC4_P_CIPHER +#endif +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1) +#undef TEST_ENG_OPENSSL_SHA +#undef TEST_ENG_OPENSSL_SHA_OTHERS +#undef TEST_ENG_OPENSSL_SHA_P_INIT +#undef TEST_ENG_OPENSSL_SHA_P_UPDATE +#undef TEST_ENG_OPENSSL_SHA_P_FINAL +#endif + #ifdef TEST_ENG_OPENSSL_RC4 static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); @@ -180,7 +196,6 @@ IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) * the "init_key" handler is called. * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. */ -#include #include #define TEST_RC4_KEY_SIZE 16 static int test_cipher_nids[] = {NID_rc4,NID_rc4_40}; @@ -265,7 +280,6 @@ static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, #ifdef TEST_ENG_OPENSSL_SHA /* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ -#include #include static int test_digest_nids[] = {NID_sha1}; static int test_digest_nids_number = 1; diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h index cf06618286..8686879e1a 100644 --- a/src/lib/libcrypto/engine/engine.h +++ b/src/lib/libcrypto/engine/engine.h @@ -59,6 +59,12 @@ #ifndef HEADER_ENGINE_H #define HEADER_ENGINE_H +#include + +#ifdef OPENSSL_NO_ENGINE +#error ENGINE is disabled. +#endif + #include #include #ifndef OPENSSL_NO_RSA @@ -307,7 +313,7 @@ void ENGINE_load_ubsec(void); void ENGINE_load_aep(void); void ENGINE_load_sureware(void); void ENGINE_load_4758cca(void); -void ENGINE_load_openbsd_dev_crypto(void); +void ENGINE_load_cryptodev(void); void ENGINE_load_builtin_engines(void); /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation @@ -406,6 +412,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, * compatibility! */ ENGINE *ENGINE_new(void); int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); int ENGINE_set_id(ENGINE *e, const char *id); int ENGINE_set_name(ENGINE *e, const char *name); int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); @@ -662,6 +669,7 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_F_ENGINE_SET_NAME 130 #define ENGINE_F_ENGINE_TABLE_REGISTER 184 #define ENGINE_F_ENGINE_UNLOAD_KEY 152 +#define ENGINE_F_ENGINE_UP_REF 190 #define ENGINE_F_INT_CTRL_HELPER 172 #define ENGINE_F_INT_ENGINE_CONFIGURE 188 #define ENGINE_F_LOG_MESSAGE 141 diff --git a/src/lib/libcrypto/engine/tb_cipher.c b/src/lib/libcrypto/engine/tb_cipher.c index c5a50fc910..50b3cec1fa 100644 --- a/src/lib/libcrypto/engine/tb_cipher.c +++ b/src/lib/libcrypto/engine/tb_cipher.c @@ -81,7 +81,7 @@ int ENGINE_register_ciphers(ENGINE *e) int num_nids = e->ciphers(e, NULL, &nids, 0); if(num_nids > 0) return engine_table_register(&cipher_table, - &engine_unregister_all_ciphers, e, nids, + engine_unregister_all_ciphers, e, nids, num_nids, 0); } return 1; @@ -103,7 +103,7 @@ int ENGINE_set_default_ciphers(ENGINE *e) int num_nids = e->ciphers(e, NULL, &nids, 0); if(num_nids > 0) return engine_table_register(&cipher_table, - &engine_unregister_all_ciphers, e, nids, + engine_unregister_all_ciphers, e, nids, num_nids, 1); } return 1; diff --git a/src/lib/libcrypto/engine/tb_dh.c b/src/lib/libcrypto/engine/tb_dh.c index c9347235ea..e290e1702b 100644 --- a/src/lib/libcrypto/engine/tb_dh.c +++ b/src/lib/libcrypto/engine/tb_dh.c @@ -78,7 +78,7 @@ int ENGINE_register_DH(ENGINE *e) { if(e->dh_meth) return engine_table_register(&dh_table, - &engine_unregister_all_DH, e, &dummy_nid, 1, 0); + engine_unregister_all_DH, e, &dummy_nid, 1, 0); return 1; } @@ -94,7 +94,7 @@ int ENGINE_set_default_DH(ENGINE *e) { if(e->dh_meth) return engine_table_register(&dh_table, - &engine_unregister_all_DH, e, &dummy_nid, 1, 1); + engine_unregister_all_DH, e, &dummy_nid, 1, 1); return 1; } diff --git a/src/lib/libcrypto/engine/tb_digest.c b/src/lib/libcrypto/engine/tb_digest.c index 2c4dd6f796..e82d2a17c9 100644 --- a/src/lib/libcrypto/engine/tb_digest.c +++ b/src/lib/libcrypto/engine/tb_digest.c @@ -81,7 +81,7 @@ int ENGINE_register_digests(ENGINE *e) int num_nids = e->digests(e, NULL, &nids, 0); if(num_nids > 0) return engine_table_register(&digest_table, - &engine_unregister_all_digests, e, nids, + engine_unregister_all_digests, e, nids, num_nids, 0); } return 1; @@ -103,7 +103,7 @@ int ENGINE_set_default_digests(ENGINE *e) int num_nids = e->digests(e, NULL, &nids, 0); if(num_nids > 0) return engine_table_register(&digest_table, - &engine_unregister_all_digests, e, nids, + engine_unregister_all_digests, e, nids, num_nids, 1); } return 1; diff --git a/src/lib/libcrypto/engine/tb_dsa.c b/src/lib/libcrypto/engine/tb_dsa.c index e9209476b8..80170591f2 100644 --- a/src/lib/libcrypto/engine/tb_dsa.c +++ b/src/lib/libcrypto/engine/tb_dsa.c @@ -78,7 +78,7 @@ int ENGINE_register_DSA(ENGINE *e) { if(e->dsa_meth) return engine_table_register(&dsa_table, - &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); + engine_unregister_all_DSA, e, &dummy_nid, 1, 0); return 1; } @@ -94,7 +94,7 @@ int ENGINE_set_default_DSA(ENGINE *e) { if(e->dsa_meth) return engine_table_register(&dsa_table, - &engine_unregister_all_DSA, e, &dummy_nid, 1, 0); + engine_unregister_all_DSA, e, &dummy_nid, 1, 0); return 1; } diff --git a/src/lib/libcrypto/engine/tb_rand.c b/src/lib/libcrypto/engine/tb_rand.c index 0b1d031f1e..69b67111bc 100644 --- a/src/lib/libcrypto/engine/tb_rand.c +++ b/src/lib/libcrypto/engine/tb_rand.c @@ -78,7 +78,7 @@ int ENGINE_register_RAND(ENGINE *e) { if(e->rand_meth) return engine_table_register(&rand_table, - &engine_unregister_all_RAND, e, &dummy_nid, 1, 0); + engine_unregister_all_RAND, e, &dummy_nid, 1, 0); return 1; } @@ -94,7 +94,7 @@ int ENGINE_set_default_RAND(ENGINE *e) { if(e->rand_meth) return engine_table_register(&rand_table, - &engine_unregister_all_RAND, e, &dummy_nid, 1, 1); + engine_unregister_all_RAND, e, &dummy_nid, 1, 1); return 1; } diff --git a/src/lib/libcrypto/engine/tb_rsa.c b/src/lib/libcrypto/engine/tb_rsa.c index f84fea3968..fee4867f52 100644 --- a/src/lib/libcrypto/engine/tb_rsa.c +++ b/src/lib/libcrypto/engine/tb_rsa.c @@ -78,7 +78,7 @@ int ENGINE_register_RSA(ENGINE *e) { if(e->rsa_meth) return engine_table_register(&rsa_table, - &engine_unregister_all_RSA, e, &dummy_nid, 1, 0); + engine_unregister_all_RSA, e, &dummy_nid, 1, 0); return 1; } @@ -94,7 +94,7 @@ int ENGINE_set_default_RSA(ENGINE *e) { if(e->rsa_meth) return engine_table_register(&rsa_table, - &engine_unregister_all_RSA, e, &dummy_nid, 1, 1); + engine_unregister_all_RSA, e, &dummy_nid, 1, 1); return 1; } diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c index 5abe44e6d5..b873270c04 100644 --- a/src/lib/libcrypto/err/err.c +++ b/src/lib/libcrypto/err/err.c @@ -211,6 +211,7 @@ static ERR_STRING_DATA ERR_str_reasons[]= {0,NULL}, }; +#endif /* Define the predeclared (but externally opaque) "ERR_FNS" type */ @@ -491,6 +492,7 @@ static int int_err_get_next_lib(void) } +#ifndef OPENSSL_NO_ERR #define NUM_SYS_STR_REASONS 127 #define LEN_SYS_STR_REASON 32 diff --git a/src/lib/libcrypto/err/err_all.c b/src/lib/libcrypto/err/err_all.c index 90029fd159..dc505d9d9d 100644 --- a/src/lib/libcrypto/err/err_all.c +++ b/src/lib/libcrypto/err/err_all.c @@ -82,7 +82,9 @@ #include #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif #include #include @@ -122,7 +124,9 @@ void ERR_load_crypto_strings(void) ERR_load_PKCS12_strings(); ERR_load_RAND_strings(); ERR_load_DSO_strings(); +#ifndef OPENSSL_NO_ENGINE ERR_load_ENGINE_strings(); +#endif ERR_load_OCSP_strings(); ERR_load_UI_strings(); #endif diff --git a/src/lib/libcrypto/err/err_prn.c b/src/lib/libcrypto/err/err_prn.c index c156663f0e..81e34bd6ce 100644 --- a/src/lib/libcrypto/err/err_prn.c +++ b/src/lib/libcrypto/err/err_prn.c @@ -62,7 +62,6 @@ #include "cryptlib.h" #include #include -#include void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), void *u) diff --git a/src/lib/libcrypto/evp/bio_b64.c b/src/lib/libcrypto/evp/bio_b64.c index f12eac1b55..6e550f6a43 100644 --- a/src/lib/libcrypto/evp/bio_b64.c +++ b/src/lib/libcrypto/evp/bio_b64.c @@ -165,6 +165,7 @@ static int b64_read(BIO *b, char *out, int outl) { i=ctx->buf_len-ctx->buf_off; if (i > outl) i=outl; + OPENSSL_assert(ctx->buf_off+i < sizeof ctx->buf); memcpy(out,&(ctx->buf[ctx->buf_off]),i); ret=i; out+=i; diff --git a/src/lib/libcrypto/evp/bio_enc.c b/src/lib/libcrypto/evp/bio_enc.c index 64fb2353af..ab81851503 100644 --- a/src/lib/libcrypto/evp/bio_enc.c +++ b/src/lib/libcrypto/evp/bio_enc.c @@ -132,7 +132,7 @@ static int enc_free(BIO *a) if (a == NULL) return(0); b=(BIO_ENC_CTX *)a->ptr; EVP_CIPHER_CTX_cleanup(&(b->cipher)); - memset(a->ptr,0,sizeof(BIO_ENC_CTX)); + OPENSSL_cleanse(a->ptr,sizeof(BIO_ENC_CTX)); OPENSSL_free(a->ptr); a->ptr=NULL; a->init=0; @@ -271,7 +271,7 @@ static int enc_write(BIO *b, const char *in, int inl) if (i <= 0) { BIO_copy_next_retry(b); - return(i); + return (ret == inl) ? i : ret - inl; } n-=i; ctx->buf_off+=i; @@ -325,10 +325,7 @@ again: { i=enc_write(b,NULL,0); if (i < 0) - { - ret=i; - break; - } + return i; } if (!ctx->finished) diff --git a/src/lib/libcrypto/evp/c_all.c b/src/lib/libcrypto/evp/c_all.c index 2d3e57c4fa..1b31a14e37 100644 --- a/src/lib/libcrypto/evp/c_all.c +++ b/src/lib/libcrypto/evp/c_all.c @@ -73,4 +73,9 @@ void OPENSSL_add_all_algorithms_noconf(void) { OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE +# if defined(__OpenBSD__) || defined(__FreeBSD__) + ENGINE_setup_bsd_cryptodev(); +# endif +#endif } diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c index a969ac69ed..b22eed4421 100644 --- a/src/lib/libcrypto/evp/digest.c +++ b/src/lib/libcrypto/evp/digest.c @@ -113,7 +113,9 @@ #include "cryptlib.h" #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { @@ -138,6 +140,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); +#ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing * the previous handle, re-querying for an ENGINE, and having a @@ -183,11 +186,13 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) else ctx->engine = NULL; } - else if(!ctx->digest) + else + if(!ctx->digest) { EVPerr(EVP_F_EVP_DIGESTINIT, EVP_R_NO_DIGEST_SET); return 0; } +#endif if (ctx->digest != type) { if (ctx->digest && ctx->digest->ctx_size) @@ -196,7 +201,9 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) if (type->ctx_size) ctx->md_data=OPENSSL_malloc(type->ctx_size); } +#ifndef OPENSSL_NO_ENGINE skip_to_init: +#endif return ctx->digest->init(ctx); } @@ -219,6 +226,8 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) { int ret; + + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); ret=ctx->digest->final(ctx,md); if (size != NULL) *size=ctx->digest->md_size; @@ -244,12 +253,14 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) EVPerr(EVP_F_EVP_MD_CTX_COPY,EVP_R_INPUT_NOT_INITIALIZED); return 0; } +#ifndef OPENSSL_NO_ENGINE /* Make sure it's safe to copy a digest context using an ENGINE */ if (in->engine && !ENGINE_init(in->engine)) { EVPerr(EVP_F_EVP_MD_CTX_COPY,ERR_R_ENGINE_LIB); return 0; } +#endif EVP_MD_CTX_cleanup(out); memcpy(out,in,sizeof *out); @@ -299,13 +310,15 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) ctx->digest->cleanup(ctx); if (ctx->digest && ctx->digest->ctx_size && ctx->md_data) { - memset(ctx->md_data,0,ctx->digest->ctx_size); + OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); OPENSSL_free(ctx->md_data); } +#ifndef OPENSSL_NO_ENGINE if(ctx->engine) /* The EVP_MD we used belongs to an ENGINE, release the * functional reference we held for this reason. */ ENGINE_finish(ctx->engine); +#endif memset(ctx,'\0',sizeof *ctx); return 1; diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c index c323fa2892..fe8bcda631 100644 --- a/src/lib/libcrypto/evp/e_aes.c +++ b/src/lib/libcrypto/evp/e_aes.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include "evp_locl.h" diff --git a/src/lib/libcrypto/evp/e_idea.c b/src/lib/libcrypto/evp/e_idea.c index ed838d3e62..b9efa75ae7 100644 --- a/src/lib/libcrypto/evp/e_idea.c +++ b/src/lib/libcrypto/evp/e_idea.c @@ -109,7 +109,7 @@ static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, idea_set_encrypt_key(key,&tmp); idea_set_decrypt_key(&tmp,ctx->cipher_data); - memset((unsigned char *)&tmp,0, + OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE)); } return 1; diff --git a/src/lib/libcrypto/evp/e_rc2.c b/src/lib/libcrypto/evp/e_rc2.c index 4685198e2e..d42cbfd17e 100644 --- a/src/lib/libcrypto/evp/e_rc2.c +++ b/src/lib/libcrypto/evp/e_rc2.c @@ -174,6 +174,7 @@ static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (type != NULL) { l=EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof iv); i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l); if (i != l) return(-1); diff --git a/src/lib/libcrypto/evp/e_rc4.c b/src/lib/libcrypto/evp/e_rc4.c index 4064cc5fa0..d58f507837 100644 --- a/src/lib/libcrypto/evp/e_rc4.c +++ b/src/lib/libcrypto/evp/e_rc4.c @@ -69,8 +69,6 @@ typedef struct { - /* FIXME: what is the key for? */ - unsigned char key[EVP_RC4_KEY_SIZE]; RC4_KEY ks; /* working key */ } EVP_RC4_KEY; @@ -121,9 +119,8 @@ const EVP_CIPHER *EVP_rc4_40(void) static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { - memcpy(&data(ctx)->key[0],key,EVP_CIPHER_CTX_key_length(ctx)); RC4_set_key(&data(ctx)->ks,EVP_CIPHER_CTX_key_length(ctx), - data(ctx)->key); + key); return 1; } diff --git a/src/lib/libcrypto/evp/encode.c b/src/lib/libcrypto/evp/encode.c index 12c6379df1..08209357ce 100644 --- a/src/lib/libcrypto/evp/encode.c +++ b/src/lib/libcrypto/evp/encode.c @@ -136,6 +136,7 @@ void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, *outl=0; if (inl == 0) return; + OPENSSL_assert(ctx->length <= sizeof ctx->enc_data); if ((ctx->num+inl) < ctx->length) { memcpy(&(ctx->enc_data[ctx->num]),in,inl); @@ -258,6 +259,7 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, /* only save the good data :-) */ if (!B64_NOT_BASE64(v)) { + OPENSSL_assert(n < sizeof ctx->enc_data); d[n++]=tmp; ln++; } diff --git a/src/lib/libcrypto/evp/evp_enc.c b/src/lib/libcrypto/evp/evp_enc.c index 32a1c7a2e9..be0758a879 100644 --- a/src/lib/libcrypto/evp/evp_enc.c +++ b/src/lib/libcrypto/evp/evp_enc.c @@ -60,11 +60,11 @@ #include "cryptlib.h" #include #include +#ifndef OPENSSL_NO_ENGINE #include +#endif #include "evp_locl.h" -#include - const char *EVP_version="EVP" OPENSSL_VERSION_PTEXT; void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) @@ -93,6 +93,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp enc = 1; ctx->encrypt = enc; } +#ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing * the previous handle, re-querying for an ENGINE, and having a @@ -100,6 +101,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp if (ctx->engine && ctx->cipher && (!cipher || (cipher && (cipher->nid == ctx->cipher->nid)))) goto skip_to_init; +#endif if (cipher) { /* Ensure a context left lying around from last time is cleared @@ -109,6 +111,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp /* Restore encrypt field: it is zeroed by cleanup */ ctx->encrypt = enc; +#ifndef OPENSSL_NO_ENGINE if(impl) { if (!ENGINE_init(impl)) @@ -142,6 +145,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp } else ctx->engine = NULL; +#endif ctx->cipher=cipher; ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size); @@ -161,11 +165,13 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *imp EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_NO_CIPHER_SET); return 0; } +#ifndef OPENSSL_NO_ENGINE skip_to_init: +#endif /* we assume block size is a power of 2 in *cryptUpdate */ - assert(ctx->cipher->block_size == 1 - || ctx->cipher->block_size == 8 - || ctx->cipher->block_size == 16); + OPENSSL_assert(ctx->cipher->block_size == 1 + || ctx->cipher->block_size == 8 + || ctx->cipher->block_size == 16); if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { switch(EVP_CIPHER_CTX_mode(ctx)) { @@ -181,6 +187,7 @@ skip_to_init: case EVP_CIPH_CBC_MODE: + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof ctx->iv); if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); break; @@ -237,7 +244,7 @@ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *imp int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv) { - return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0); + return EVP_CipherInit(ctx, cipher, key, iv, 0); } int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, @@ -251,6 +258,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, { int i,j,bl; + OPENSSL_assert(inl > 0); if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0) { if(ctx->cipher->do_cipher(ctx,out,in,inl)) @@ -266,6 +274,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, } i=ctx->buf_len; bl=ctx->cipher->block_size; + OPENSSL_assert(bl <= sizeof ctx->buf); if (i != 0) { if (i+inl < bl) @@ -314,6 +323,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) int i,n,b,bl,ret; b=ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof ctx->buf); if (b == 1) { *outl=0; @@ -358,6 +368,7 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, return EVP_EncryptUpdate(ctx, out, outl, in, inl); b=ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof ctx->final); if(ctx->final_used) { @@ -420,6 +431,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_WRONG_FINAL_BLOCK_LENGTH); return(0); } + OPENSSL_assert(b <= sizeof ctx->final); n=ctx->final[b-1]; if (n > b) { @@ -450,16 +462,18 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { if(c->cipher->cleanup && !c->cipher->cleanup(c)) return 0; - /* Zero cipher context data */ + /* Cleanse cipher context data */ if (c->cipher_data) - memset(c->cipher_data, 0, c->cipher->ctx_size); + OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); } if (c->cipher_data) OPENSSL_free(c->cipher_data); +#ifndef OPENSSL_NO_ENGINE if (c->engine) /* The EVP_CIPHER we used belongs to an ENGINE, release the * functional reference we held for this reason. */ ENGINE_finish(c->engine); +#endif memset(c,0,sizeof(EVP_CIPHER_CTX)); return 1; } diff --git a/src/lib/libcrypto/evp/evp_key.c b/src/lib/libcrypto/evp/evp_key.c index 4271393069..5f387a94d3 100644 --- a/src/lib/libcrypto/evp/evp_key.c +++ b/src/lib/libcrypto/evp/evp_key.c @@ -103,7 +103,7 @@ int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) buff,0,(len>=BUFSIZ)?BUFSIZ-1:len,buf); ret = UI_process(ui); UI_free(ui); - memset(buff,0,BUFSIZ); + OPENSSL_cleanse(buff,BUFSIZ); return ret; } @@ -118,6 +118,8 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, nkey=type->key_len; niv=type->iv_len; + OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); + OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); if (data == NULL) return(nkey); @@ -166,7 +168,7 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, if ((nkey == 0) && (niv == 0)) break; } EVP_MD_CTX_cleanup(&c); - memset(&(md_buf[0]),0,EVP_MAX_MD_SIZE); + OPENSSL_cleanse(&(md_buf[0]),EVP_MAX_MD_SIZE); return(type->key_len); } diff --git a/src/lib/libcrypto/evp/evp_lib.c b/src/lib/libcrypto/evp/evp_lib.c index a431945ef5..52a3b287be 100644 --- a/src/lib/libcrypto/evp/evp_lib.c +++ b/src/lib/libcrypto/evp/evp_lib.c @@ -90,6 +90,7 @@ int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (type != NULL) { l=EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof c->iv); i=ASN1_TYPE_get_octetstring(type,c->oiv,l); if (i != l) return(-1); @@ -106,6 +107,7 @@ int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (type != NULL) { j=EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(j <= sizeof c->iv); i=ASN1_TYPE_set_octetstring(type,c->oiv,j); } return(i); diff --git a/src/lib/libcrypto/evp/evp_pbe.c b/src/lib/libcrypto/evp/evp_pbe.c index bcd4d29f85..0da88fdcff 100644 --- a/src/lib/libcrypto/evp/evp_pbe.c +++ b/src/lib/libcrypto/evp/evp_pbe.c @@ -88,7 +88,7 @@ int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, char obj_tmp[80]; EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); if (!pbe_obj) strcpy (obj_tmp, "NULL"); - else i2t_ASN1_OBJECT(obj_tmp, 80, pbe_obj); + else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); ERR_add_error_data(2, "TYPE=", obj_tmp); return 0; } diff --git a/src/lib/libcrypto/evp/p5_crpt.c b/src/lib/libcrypto/evp/p5_crpt.c index 27a8286489..a1874e83b2 100644 --- a/src/lib/libcrypto/evp/p5_crpt.c +++ b/src/lib/libcrypto/evp/p5_crpt.c @@ -140,12 +140,14 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, EVP_DigestFinal_ex (&ctx, md_tmp, NULL); } EVP_MD_CTX_cleanup(&ctx); + OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= sizeof md_tmp); memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); + OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), EVP_CIPHER_iv_length(cipher)); EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de); - memset(md_tmp, 0, EVP_MAX_MD_SIZE); - memset(key, 0, EVP_MAX_KEY_LENGTH); - memset(iv, 0, EVP_MAX_IV_LENGTH); + OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); return 1; } diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c index 7485d6a278..1f94e1ef88 100644 --- a/src/lib/libcrypto/evp/p5_crpt2.c +++ b/src/lib/libcrypto/evp/p5_crpt2.c @@ -190,6 +190,7 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, goto err; } keylen = EVP_CIPHER_CTX_key_length(ctx); + OPENSSL_assert(keylen <= sizeof key); /* Now decode key derivation function */ @@ -230,7 +231,7 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, iter = ASN1_INTEGER_get(kdf->iter); PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key); EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); - memset(key, 0, keylen); + OPENSSL_cleanse(key, keylen); PBKDF2PARAM_free(kdf); return 1; diff --git a/src/lib/libcrypto/evp/p_open.c b/src/lib/libcrypto/evp/p_open.c index 6976f2a867..5a933d1cda 100644 --- a/src/lib/libcrypto/evp/p_open.c +++ b/src/lib/libcrypto/evp/p_open.c @@ -101,7 +101,7 @@ int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, unsigned char *ek, ret=1; err: - if (key != NULL) memset(key,0,size); + if (key != NULL) OPENSSL_cleanse(key,size); OPENSSL_free(key); return(ret); } diff --git a/src/lib/libcrypto/hmac/hmac.c b/src/lib/libcrypto/hmac/hmac.c index da363b7950..4c91f919d5 100644 --- a/src/lib/libcrypto/hmac/hmac.c +++ b/src/lib/libcrypto/hmac/hmac.c @@ -59,6 +59,7 @@ #include #include #include +#include "cryptlib.h" void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl) @@ -78,6 +79,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, { reset=1; j=EVP_MD_block_size(md); + OPENSSL_assert(j <= sizeof ctx->key); if (j < len) { EVP_DigestInit_ex(&ctx->md_ctx,md, impl); @@ -87,6 +89,7 @@ void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, } else { + OPENSSL_assert(len <= sizeof ctx->key); memcpy(ctx->key,key,len); ctx->key_length=len; } diff --git a/src/lib/libcrypto/lhash/lh_stats.c b/src/lib/libcrypto/lhash/lh_stats.c index 39ea2885f4..5aa7766aa6 100644 --- a/src/lib/libcrypto/lhash/lh_stats.c +++ b/src/lib/libcrypto/lhash/lh_stats.c @@ -179,49 +179,29 @@ end:; void lh_stats_bio(const LHASH *lh, BIO *out) { - char buf[128]; - - sprintf(buf,"num_items = %lu\n",lh->num_items); - BIO_puts(out,buf); - sprintf(buf,"num_nodes = %u\n",lh->num_nodes); - BIO_puts(out,buf); - sprintf(buf,"num_alloc_nodes = %u\n",lh->num_alloc_nodes); - BIO_puts(out,buf); - sprintf(buf,"num_expands = %lu\n",lh->num_expands); - BIO_puts(out,buf); - sprintf(buf,"num_expand_reallocs = %lu\n",lh->num_expand_reallocs); - BIO_puts(out,buf); - sprintf(buf,"num_contracts = %lu\n",lh->num_contracts); - BIO_puts(out,buf); - sprintf(buf,"num_contract_reallocs = %lu\n",lh->num_contract_reallocs); - BIO_puts(out,buf); - sprintf(buf,"num_hash_calls = %lu\n",lh->num_hash_calls); - BIO_puts(out,buf); - sprintf(buf,"num_comp_calls = %lu\n",lh->num_comp_calls); - BIO_puts(out,buf); - sprintf(buf,"num_insert = %lu\n",lh->num_insert); - BIO_puts(out,buf); - sprintf(buf,"num_replace = %lu\n",lh->num_replace); - BIO_puts(out,buf); - sprintf(buf,"num_delete = %lu\n",lh->num_delete); - BIO_puts(out,buf); - sprintf(buf,"num_no_delete = %lu\n",lh->num_no_delete); - BIO_puts(out,buf); - sprintf(buf,"num_retrieve = %lu\n",lh->num_retrieve); - BIO_puts(out,buf); - sprintf(buf,"num_retrieve_miss = %lu\n",lh->num_retrieve_miss); - BIO_puts(out,buf); - sprintf(buf,"num_hash_comps = %lu\n",lh->num_hash_comps); - BIO_puts(out,buf); + BIO_printf(out,"num_items = %lu\n",lh->num_items); + BIO_printf(out,"num_nodes = %u\n",lh->num_nodes); + BIO_printf(out,"num_alloc_nodes = %u\n",lh->num_alloc_nodes); + BIO_printf(out,"num_expands = %lu\n",lh->num_expands); + BIO_printf(out,"num_expand_reallocs = %lu\n", + lh->num_expand_reallocs); + BIO_printf(out,"num_contracts = %lu\n",lh->num_contracts); + BIO_printf(out,"num_contract_reallocs = %lu\n", + lh->num_contract_reallocs); + BIO_printf(out,"num_hash_calls = %lu\n",lh->num_hash_calls); + BIO_printf(out,"num_comp_calls = %lu\n",lh->num_comp_calls); + BIO_printf(out,"num_insert = %lu\n",lh->num_insert); + BIO_printf(out,"num_replace = %lu\n",lh->num_replace); + BIO_printf(out,"num_delete = %lu\n",lh->num_delete); + BIO_printf(out,"num_no_delete = %lu\n",lh->num_no_delete); + BIO_printf(out,"num_retrieve = %lu\n",lh->num_retrieve); + BIO_printf(out,"num_retrieve_miss = %lu\n",lh->num_retrieve_miss); + BIO_printf(out,"num_hash_comps = %lu\n",lh->num_hash_comps); #if 0 - sprintf(buf,"p = %u\n",lh->p); - BIO_puts(out,buf); - sprintf(buf,"pmax = %u\n",lh->pmax); - BIO_puts(out,buf); - sprintf(buf,"up_load = %lu\n",lh->up_load); - BIO_puts(out,buf); - sprintf(buf,"down_load = %lu\n",lh->down_load); - BIO_puts(out,buf); + BIO_printf(out,"p = %u\n",lh->p); + BIO_printf(out,"pmax = %u\n",lh->pmax); + BIO_printf(out,"up_load = %lu\n",lh->up_load); + BIO_printf(out,"down_load = %lu\n",lh->down_load); #endif } @@ -229,14 +209,12 @@ void lh_node_stats_bio(const LHASH *lh, BIO *out) { LHASH_NODE *n; unsigned int i,num; - char buf[128]; for (i=0; inum_nodes; i++) { for (n=lh->b[i],num=0; n != NULL; n=n->next) num++; - sprintf(buf,"node %6u -> %3u\n",i,num); - BIO_puts(out,buf); + BIO_printf(out,"node %6u -> %3u\n",i,num); } } @@ -246,7 +224,6 @@ void lh_node_usage_stats_bio(const LHASH *lh, BIO *out) unsigned long num; unsigned int i; unsigned long total=0,n_used=0; - char buf[128]; for (i=0; inum_nodes; i++) { @@ -258,17 +235,14 @@ void lh_node_usage_stats_bio(const LHASH *lh, BIO *out) total+=num; } } - sprintf(buf,"%lu nodes used out of %u\n",n_used,lh->num_nodes); - BIO_puts(out,buf); - sprintf(buf,"%lu items\n",total); - BIO_puts(out,buf); + BIO_printf(out,"%lu nodes used out of %u\n",n_used,lh->num_nodes); + BIO_printf(out,"%lu items\n",total); if (n_used == 0) return; - sprintf(buf,"load %d.%02d actual load %d.%02d\n", - (int)(total/lh->num_nodes), - (int)((total%lh->num_nodes)*100/lh->num_nodes), - (int)(total/n_used), - (int)((total%n_used)*100/n_used)); - BIO_puts(out,buf); + BIO_printf(out,"load %d.%02d actual load %d.%02d\n", + (int)(total/lh->num_nodes), + (int)((total%lh->num_nodes)*100/lh->num_nodes), + (int)(total/n_used), + (int)((total%n_used)*100/n_used)); } #endif diff --git a/src/lib/libcrypto/md32_common.h b/src/lib/libcrypto/md32_common.h index 353d2b96ad..573850b122 100644 --- a/src/lib/libcrypto/md32_common.h +++ b/src/lib/libcrypto/md32_common.h @@ -1,6 +1,6 @@ /* crypto/md32_common.h */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -198,7 +198,7 @@ * * */ -# if defined(__i386) || defined(__i386__) +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) # define ROTATE(a,n) ({ register unsigned int ret; \ asm ( \ "roll %1,%0" \ @@ -224,7 +224,7 @@ */ # if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) /* some GNU C inline assembler templates by */ -# if (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) +# if (defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)) && !defined(I386_ONLY) # define BE_FETCH32(a) ({ register unsigned int l=(a);\ asm ( \ "bswapl %0" \ @@ -456,7 +456,10 @@ int HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len) { ew=(c->num>>2); ec=(c->num&0x03); - l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; + if (sc) + l=p[sw]; + HOST_p_c2l(data,l,sc); + p[sw++]=l; for (; sw < ew; sw++) { HOST_c2l(data,l); p[sw]=l; @@ -603,7 +606,32 @@ int HASH_FINAL (unsigned char *md, HASH_CTX *c) c->num=0; /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack * but I'm not worried :-) - memset((void *)c,0,sizeof(HASH_CTX)); + OPENSSL_cleanse((void *)c,sizeof(HASH_CTX)); */ return 1; } + +#ifndef MD32_REG_T +#define MD32_REG_T long +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + * Apparently there're LP64 compilers that generate better + * code if A-D are declared int. Most notably GCC-x86_64 + * generates better code. + * + */ +#endif diff --git a/src/lib/libcrypto/md4/md4_dgst.c b/src/lib/libcrypto/md4/md4_dgst.c index 6446f5f5e7..7afb7185b6 100644 --- a/src/lib/libcrypto/md4/md4_dgst.c +++ b/src/lib/libcrypto/md4/md4_dgst.c @@ -86,21 +86,7 @@ int MD4_Init(MD4_CTX *c) void md4_block_host_order (MD4_CTX *c, const void *data, int num) { const MD4_LONG *X=data; - register unsigned long A,B,C,D; - /* - * In case you wonder why A-D are declared as long and not - * as MD4_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - * - */ + register unsigned MD32_REG_T A,B,C,D; A=c->A; B=c->B; @@ -176,25 +162,11 @@ void md4_block_host_order (MD4_CTX *c, const void *data, int num) void md4_block_data_order (MD4_CTX *c, const void *data_, int num) { const unsigned char *data=data_; - register unsigned long A,B,C,D,l; - /* - * In case you wonder why A-D are declared as long and not - * as MD4_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - * - */ + register unsigned MD32_REG_T A,B,C,D,l; #ifndef MD32_XARRAY /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; # define X(i) XX##i #else MD4_LONG XX[MD4_LBLOCK]; diff --git a/src/lib/libcrypto/md4/md4_one.c b/src/lib/libcrypto/md4/md4_one.c index 87a995d38d..00565507e4 100644 --- a/src/lib/libcrypto/md4/md4_one.c +++ b/src/lib/libcrypto/md4/md4_one.c @@ -59,6 +59,7 @@ #include #include #include +#include #ifdef CHARSET_EBCDIC #include @@ -89,7 +90,7 @@ unsigned char *MD4(const unsigned char *d, unsigned long n, unsigned char *md) } #endif MD4_Final(md,&c); - memset(&c,0,sizeof(c)); /* security consideration */ + OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */ return(md); } diff --git a/src/lib/libcrypto/md5/md5.h b/src/lib/libcrypto/md5/md5.h index 52cb753e6a..a252e02115 100644 --- a/src/lib/libcrypto/md5/md5.h +++ b/src/lib/libcrypto/md5/md5.h @@ -59,6 +59,8 @@ #ifndef HEADER_MD5_H #define HEADER_MD5_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -76,7 +78,7 @@ extern "C" { #if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) #define MD5_LONG unsigned long -#elif defined(OENSSL_SYS_CRAY) || defined(__ILP64__) +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) #define MD5_LONG unsigned long #define MD5_LONG_LOG2 3 /* diff --git a/src/lib/libcrypto/md5/md5_dgst.c b/src/lib/libcrypto/md5/md5_dgst.c index c38a3f021e..9c7abc3697 100644 --- a/src/lib/libcrypto/md5/md5_dgst.c +++ b/src/lib/libcrypto/md5/md5_dgst.c @@ -86,21 +86,7 @@ int MD5_Init(MD5_CTX *c) void md5_block_host_order (MD5_CTX *c, const void *data, int num) { const MD5_LONG *X=data; - register unsigned long A,B,C,D; - /* - * In case you wonder why A-D are declared as long and not - * as MD5_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - * - */ + register unsigned MD32_REG_T A,B,C,D; A=c->A; B=c->B; @@ -193,25 +179,11 @@ void md5_block_host_order (MD5_CTX *c, const void *data, int num) void md5_block_data_order (MD5_CTX *c, const void *data_, int num) { const unsigned char *data=data_; - register unsigned long A,B,C,D,l; - /* - * In case you wonder why A-D are declared as long and not - * as MD5_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - * - */ + register unsigned MD32_REG_T A,B,C,D,l; #ifndef MD32_XARRAY /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; # define X(i) XX##i #else MD5_LONG XX[MD5_LBLOCK]; diff --git a/src/lib/libcrypto/md5/md5_locl.h b/src/lib/libcrypto/md5/md5_locl.h index 34c5257306..9e360da732 100644 --- a/src/lib/libcrypto/md5/md5_locl.h +++ b/src/lib/libcrypto/md5/md5_locl.h @@ -58,7 +58,7 @@ #include #include -#include +#include #include #ifndef MD5_LONG_LOG2 diff --git a/src/lib/libcrypto/md5/md5_one.c b/src/lib/libcrypto/md5/md5_one.c index b89dec850d..c5dd2d81db 100644 --- a/src/lib/libcrypto/md5/md5_one.c +++ b/src/lib/libcrypto/md5/md5_one.c @@ -59,6 +59,7 @@ #include #include #include +#include #ifdef CHARSET_EBCDIC #include @@ -89,7 +90,7 @@ unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md) } #endif MD5_Final(md,&c); - memset(&c,0,sizeof(c)); /* security consideration */ + OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */ return(md); } diff --git a/src/lib/libcrypto/mem_clr.c b/src/lib/libcrypto/mem_clr.c new file mode 100644 index 0000000000..e4b7f540b0 --- /dev/null +++ b/src/lib/libcrypto/mem_clr.c @@ -0,0 +1,75 @@ +/* crypto/mem_clr.c -*- mode:C; c-file-style: "eay" -*- */ +/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL + * project 2002. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +unsigned char cleanse_ctr = 0; + +void OPENSSL_cleanse(void *ptr, size_t len) + { + unsigned char *p = ptr; + size_t loop = len; + while(loop--) + { + *(p++) = cleanse_ctr; + cleanse_ctr += (17 + (unsigned char)((int)p & 0xF)); + } + if(memchr(ptr, cleanse_ctr, len)) + cleanse_ctr += 63; + } diff --git a/src/lib/libcrypto/mem_dbg.c b/src/lib/libcrypto/mem_dbg.c index 1c4e04f51f..57bd08f65d 100644 --- a/src/lib/libcrypto/mem_dbg.c +++ b/src/lib/libcrypto/mem_dbg.c @@ -102,6 +102,8 @@ typedef struct app_mem_info_st int references; } APP_INFO; +static void app_info_free(APP_INFO *); + static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's * that are at the top of their thread's stack * (with `thread' as key); @@ -140,6 +142,18 @@ static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. * thread named in disabling_thread). */ +static void app_info_free(APP_INFO *inf) + { + if (--(inf->references) <= 0) + { + if (inf->next != NULL) + { + app_info_free(inf->next); + } + OPENSSL_free(inf); + } + } + int CRYPTO_mem_ctrl(int mode) { int ret=mh_mode; @@ -502,9 +516,7 @@ void CRYPTO_dbg_free(void *addr, int before_p) mp->order, mp->addr, mp->num); #endif if (mp->app_info != NULL) - { - mp->app_info->references--; - } + app_info_free(mp->app_info); OPENSSL_free(mp); } @@ -666,7 +678,6 @@ static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *) void CRYPTO_mem_leaks(BIO *b) { MEM_LEAK ml; - char buf[80]; if (mh == NULL && amih == NULL) return; @@ -681,9 +692,8 @@ void CRYPTO_mem_leaks(BIO *b) (char *)&ml); if (ml.chunks != 0) { - sprintf(buf,"%ld bytes leaked in %d chunks\n", - ml.bytes,ml.chunks); - BIO_puts(b,buf); + BIO_printf(b,"%ld bytes leaked in %d chunks\n", + ml.bytes,ml.chunks); } else { diff --git a/src/lib/libcrypto/o_time.c b/src/lib/libcrypto/o_time.c index 1bc0297b36..723eb1b5af 100644 --- a/src/lib/libcrypto/o_time.c +++ b/src/lib/libcrypto/o_time.c @@ -80,6 +80,9 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) ts = result; #elif !defined(OPENSSL_SYS_VMS) ts = gmtime(timer); + if (ts == NULL) + return NULL; + memcpy(result, ts, sizeof(struct tm)); ts = result; #endif diff --git a/src/lib/libcrypto/objects/obj_dat.c b/src/lib/libcrypto/objects/obj_dat.c index ce779dc1b5..5d983e3ed4 100644 --- a/src/lib/libcrypto/objects/obj_dat.c +++ b/src/lib/libcrypto/objects/obj_dat.c @@ -464,7 +464,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) sprintf(tbuf,"%d.%lu",i,l); i=strlen(tbuf); - strncpy(buf,tbuf,buf_len); + BUF_strlcpy(buf,tbuf,buf_len); buf_len-=i; buf+=i; n+=i; @@ -476,7 +476,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) sprintf(tbuf,".%lu",l); i=strlen(tbuf); if (buf_len > 0) - strncpy(buf,tbuf,buf_len); + BUF_strlcpy(buf,tbuf,buf_len); buf_len-=i; buf+=i; n+=i; @@ -488,10 +488,9 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) s=OBJ_nid2ln(nid); if (s == NULL) s=OBJ_nid2sn(nid); - strncpy(buf,s,buf_len); + BUF_strlcpy(buf,s,buf_len); n=strlen(s); } - buf[buf_len-1]='\0'; return(n); } diff --git a/src/lib/libcrypto/objects/obj_mac.num b/src/lib/libcrypto/objects/obj_mac.num index 1486199661..9838072b65 100644 --- a/src/lib/libcrypto/objects/obj_mac.num +++ b/src/lib/libcrypto/objects/obj_mac.num @@ -645,3 +645,5 @@ rsaOAEPEncryptionSET 644 itu_t 645 joint_iso_itu_t 646 international_organizations 647 +ms_smartcard_login 648 +ms_upn 649 diff --git a/src/lib/libcrypto/objects/objects.txt b/src/lib/libcrypto/objects/objects.txt index 71a4908485..3ba11f65cc 100644 --- a/src/lib/libcrypto/objects/objects.txt +++ b/src/lib/libcrypto/objects/objects.txt @@ -276,6 +276,10 @@ rsadsi 3 8 : RC5-CBC : rc5-cbc 1 3 6 1 4 1 311 10 3 3 : msSGC : Microsoft Server Gated Crypto !Cname ms-efs 1 3 6 1 4 1 311 10 3 4 : msEFS : Microsoft Encrypted File System +!Cname ms-smartcard-login +1 3 6 1 4 1 311 20 2 2 : msSmartcardLogin : Microsoft Smartcardlogin +!Cname ms-upn +1 3 6 1 4 1 311 20 2 3 : msUPN : Microsoft Universal Principal Name 1 3 6 1 4 1 188 7 1 1 2 : IDEA-CBC : idea-cbc : IDEA-ECB : idea-ecb @@ -537,7 +541,7 @@ X509 11 : OU : organizationalUnitName X509 12 : : title X509 13 : : description X509 41 : name : name -X509 42 : gn : givenName +X509 42 : GN : givenName X509 43 : : initials X509 44 : : generationQualifier X509 45 : : x500UniqueIdentifier diff --git a/src/lib/libcrypto/ocsp/ocsp_asn.c b/src/lib/libcrypto/ocsp/ocsp_asn.c index 8c148cda6a..6a3a360d54 100644 --- a/src/lib/libcrypto/ocsp/ocsp_asn.c +++ b/src/lib/libcrypto/ocsp/ocsp_asn.c @@ -117,7 +117,7 @@ IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE) ASN1_CHOICE(OCSP_RESPID) = { ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1), - ASN1_IMP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) + ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) } ASN1_CHOICE_END(OCSP_RESPID) IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID) diff --git a/src/lib/libcrypto/ocsp/ocsp_ht.c b/src/lib/libcrypto/ocsp/ocsp_ht.c index b78cd37092..9213e58ae4 100644 --- a/src/lib/libcrypto/ocsp/ocsp_ht.c +++ b/src/lib/libcrypto/ocsp/ocsp_ht.c @@ -64,6 +64,9 @@ #include #include #include +#ifdef OPENSSL_SYS_SUNOS +#define strtoul (unsigned long)strtol +#endif /* OPENSSL_SYS_SUNOS */ /* Quick and dirty HTTP OCSP request handler. * Could make this a bit cleverer by adding @@ -94,7 +97,7 @@ Content-Length: %d\r\n\r\n"; } if(!(mem = BIO_new(BIO_s_mem()))) goto err; /* Copy response to a memory BIO: socket bios can't do gets! */ - while ((len = BIO_read(b, tmpbuf, 1024))) { + while ((len = BIO_read(b, tmpbuf, sizeof tmpbuf))) { if(len < 0) { OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_READ_ERROR); goto err; @@ -107,7 +110,7 @@ Content-Length: %d\r\n\r\n"; } /* Parse the HTTP response. This will look like this: * "HTTP/1.0 200 OK". We need to obtain the numeric code and - * informational message. + * (optional) informational message. */ /* Skip to first white space (passed protocol info) */ @@ -135,13 +138,19 @@ Content-Length: %d\r\n\r\n"; if(*r) goto err; /* Skip over any leading white space in message */ while(*q && isspace((unsigned char)*q)) q++; - if(!*q) goto err; + if(*q) { /* Finally zap any trailing white space in message (include CRLF) */ /* We know q has a non white space character so this is OK */ - for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0; + for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0; + } if(retcode != 200) { OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_ERROR); - ERR_add_error_data(4, "Code=", p, ",Reason=", q); + if(!*q) { + ERR_add_error_data(2, "Code=", p); + } + else { + ERR_add_error_data(4, "Code=", p, ",Reason=", q); + } goto err; } /* Find blank line marking beginning of content */ diff --git a/src/lib/libcrypto/opensslv.h b/src/lib/libcrypto/opensslv.h index 9689b49c5b..08cb1d5018 100644 --- a/src/lib/libcrypto/opensslv.h +++ b/src/lib/libcrypto/opensslv.h @@ -25,8 +25,8 @@ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -#define OPENSSL_VERSION_NUMBER 0x00907003L -#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.7-beta3 30 Jul 2002" +#define OPENSSL_VERSION_NUMBER 0x0090702fL +#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.7b 10 Apr 2003" #define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/src/lib/libcrypto/ossl_typ.h b/src/lib/libcrypto/ossl_typ.h index 6bd42aee4d..285fd0b1d9 100644 --- a/src/lib/libcrypto/ossl_typ.h +++ b/src/lib/libcrypto/ossl_typ.h @@ -55,6 +55,8 @@ #ifndef HEADER_OPENSSL_TYPES_H #define HEADER_OPENSSL_TYPES_H +#include + #ifdef NO_ASN1_TYPEDEFS #define ASN1_INTEGER ASN1_STRING #define ASN1_ENUMERATED ASN1_STRING diff --git a/src/lib/libcrypto/pem/pem.h b/src/lib/libcrypto/pem/pem.h index 3785fca77d..d330cbf9a3 100644 --- a/src/lib/libcrypto/pem/pem.h +++ b/src/lib/libcrypto/pem/pem.h @@ -149,7 +149,7 @@ typedef struct pem_recip_st int cipher; int key_enc; - char iv[8]; + /* char iv[8]; unused and wrong size */ } PEM_USER; typedef struct pem_ctx_st @@ -165,7 +165,8 @@ typedef struct pem_ctx_st struct { int cipher; - unsigned char iv[8]; + /* unused, and wrong size + unsigned char iv[8]; */ } DEK_info; PEM_USER *originator; @@ -187,7 +188,8 @@ typedef struct pem_ctx_st EVP_CIPHER *dec; /* date encryption cipher */ int key_len; /* key length */ unsigned char *key; /* key */ - unsigned char iv[8]; /* the iv */ + /* unused, and wrong size + unsigned char iv[8]; */ int data_enc; /* is the data encrypted */ diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c index 9a6dffb45c..9e4af29c95 100644 --- a/src/lib/libcrypto/pem/pem_info.c +++ b/src/lib/libcrypto/pem/pem_info.c @@ -324,6 +324,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, } /* create the right magic header stuff */ + OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); buf[0]='\0'; PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv); @@ -358,7 +359,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, ret=1; err: - memset((char *)&ctx,0,sizeof(ctx)); - memset(buf,0,PEM_BUFSIZE); + OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); + OPENSSL_cleanse(buf,PEM_BUFSIZE); return(ret); } diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c index a8db6ffbf5..70b5446797 100644 --- a/src/lib/libcrypto/pem/pem_lib.c +++ b/src/lib/libcrypto/pem/pem_lib.c @@ -138,7 +138,7 @@ void PEM_proc_type(char *buf, int type) void PEM_dek_info(char *buf, const char *type, int len, char *str) { - static unsigned char map[17]="0123456789ABCDEF"; + static const unsigned char map[17]="0123456789ABCDEF"; long i; int j; @@ -249,7 +249,7 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char ret = 1; err: - if (!pnm) OPENSSL_free(nm); + if (!ret || !pnm) OPENSSL_free(nm); OPENSSL_free(header); if (!ret) OPENSSL_free(data); return ret; @@ -304,6 +304,7 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x, goto err; } /* dzise + 8 bytes are needed */ + /* actually it needs the cipher block size extra... */ data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20); if (data == NULL) { @@ -333,13 +334,16 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x, kstr=(unsigned char *)buf; } RAND_add(data,i,0);/* put in the RSA key. */ + OPENSSL_assert(enc->iv_len <= sizeof iv); if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */ goto err; /* The 'iv' is used as the iv and as a salt. It is * NOT taken from the BytesToKey function */ EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL); - if (kstr == (unsigned char *)buf) memset(buf,0,PEM_BUFSIZE); + if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE); + + OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); buf[0]='\0'; PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); @@ -362,13 +366,13 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x, i=PEM_write_bio(bp,name,buf,data,i); if (i <= 0) ret=0; err: - memset(key,0,sizeof(key)); - memset(iv,0,sizeof(iv)); - memset((char *)&ctx,0,sizeof(ctx)); - memset(buf,0,PEM_BUFSIZE); + OPENSSL_cleanse(key,sizeof(key)); + OPENSSL_cleanse(iv,sizeof(iv)); + OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); + OPENSSL_cleanse(buf,PEM_BUFSIZE); if (data != NULL) { - memset(data,0,(unsigned int)dsize); + OPENSSL_cleanse(data,(unsigned int)dsize); OPENSSL_free(data); } return(ret); @@ -409,8 +413,8 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, EVP_DecryptUpdate(&ctx,data,&i,data,j); o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j); EVP_CIPHER_CTX_cleanup(&ctx); - memset((char *)buf,0,sizeof(buf)); - memset((char *)key,0,sizeof(key)); + OPENSSL_cleanse((char *)buf,sizeof(buf)); + OPENSSL_cleanse((char *)key,sizeof(key)); j+=i; if (!o) { @@ -691,7 +695,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, if (strncmp(buf,"-----END ",9) == 0) break; if (i > 65) break; - if (!BUF_MEM_grow(dataB,i+bl+9)) + if (!BUF_MEM_grow_clean(dataB,i+bl+9)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; diff --git a/src/lib/libcrypto/pem/pem_pk8.c b/src/lib/libcrypto/pem/pem_pk8.c index f44182ffb5..db38a2a79d 100644 --- a/src/lib/libcrypto/pem/pem_pk8.c +++ b/src/lib/libcrypto/pem/pem_pk8.c @@ -136,7 +136,7 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER kstr = buf; } p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if(kstr == buf) memset(buf, 0, klen); + if(kstr == buf) OPENSSL_cleanse(buf, klen); PKCS8_PRIV_KEY_INFO_free(p8inf); if(isder) ret = i2d_PKCS8_bio(bp, p8); else ret = PEM_write_bio_PKCS8(bp, p8); diff --git a/src/lib/libcrypto/pem/pem_seal.c b/src/lib/libcrypto/pem/pem_seal.c index ae463a301d..56e08abd70 100644 --- a/src/lib/libcrypto/pem/pem_seal.c +++ b/src/lib/libcrypto/pem/pem_seal.c @@ -112,7 +112,7 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, ret=npubk; err: if (s != NULL) OPENSSL_free(s); - memset(key,0,EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(key,EVP_MAX_KEY_LENGTH); return(ret); } diff --git a/src/lib/libcrypto/perlasm/cbc.pl b/src/lib/libcrypto/perlasm/cbc.pl index 0145c4f0cc..22149c680e 100644 --- a/src/lib/libcrypto/perlasm/cbc.pl +++ b/src/lib/libcrypto/perlasm/cbc.pl @@ -146,9 +146,15 @@ sub cbc &mov($count, &wparam(2)); # length &and($count, 7); &jz(&label("finish")); + &call(&label("PIC_point")); +&set_label("PIC_point"); + &blindpop("edx"); + &lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx")); + &mov($count,&DWP(0,"ecx",$count,4)) + &add($count,"edx"); &xor("ecx","ecx"); &xor("edx","edx"); - &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); + #&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); &jmp_ptr($count); &set_label("ej7"); @@ -318,22 +324,23 @@ sub cbc &set_label("cbc_enc_jmp_table",1); &data_word("0"); - &data_word(&label("ej1")); - &data_word(&label("ej2")); - &data_word(&label("ej3")); - &data_word(&label("ej4")); - &data_word(&label("ej5")); - &data_word(&label("ej6")); - &data_word(&label("ej7")); - &set_label("cbc_dec_jmp_table",1); - &data_word("0"); - &data_word(&label("dj1")); - &data_word(&label("dj2")); - &data_word(&label("dj3")); - &data_word(&label("dj4")); - &data_word(&label("dj5")); - &data_word(&label("dj6")); - &data_word(&label("dj7")); + &data_word(&label("ej1")."-".&label("PIC_point")); + &data_word(&label("ej2")."-".&label("PIC_point")); + &data_word(&label("ej3")."-".&label("PIC_point")); + &data_word(&label("ej4")."-".&label("PIC_point")); + &data_word(&label("ej5")."-".&label("PIC_point")); + &data_word(&label("ej6")."-".&label("PIC_point")); + &data_word(&label("ej7")."-".&label("PIC_point")); + # not used + #&set_label("cbc_dec_jmp_table",1); + #&data_word("0"); + #&data_word(&label("dj1")."-".&label("PIC_point")); + #&data_word(&label("dj2")."-".&label("PIC_point")); + #&data_word(&label("dj3")."-".&label("PIC_point")); + #&data_word(&label("dj4")."-".&label("PIC_point")); + #&data_word(&label("dj5")."-".&label("PIC_point")); + #&data_word(&label("dj6")."-".&label("PIC_point")); + #&data_word(&label("dj7")."-".&label("PIC_point")); &function_end_B($name); diff --git a/src/lib/libcrypto/perlasm/x86asm.pl b/src/lib/libcrypto/perlasm/x86asm.pl index 9a3d85b098..1cb96e914a 100644 --- a/src/lib/libcrypto/perlasm/x86asm.pl +++ b/src/lib/libcrypto/perlasm/x86asm.pl @@ -18,9 +18,9 @@ sub main'asm_init ($type,$fn,$i386)=@_; $filename=$fn; - $cpp=$sol=$aout=$win32=$gaswin=0; + $elf=$cpp=$sol=$aout=$win32=$gaswin=0; if ( ($type eq "elf")) - { require "x86unix.pl"; } + { $elf=1; require "x86unix.pl"; } elsif ( ($type eq "a.out")) { $aout=1; require "x86unix.pl"; } elsif ( ($type eq "gaswin")) @@ -47,6 +47,9 @@ EOF exit(1); } + $pic=0; + for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); } + &asm_init_output(); &comment("Don't even think of reading this code"); @@ -91,7 +94,7 @@ $tmp #undef SIZE #undef TYPE #define SIZE(a,b) -#define TYPE(a,b) +#define TYPE(a,b) .def a; .scl 2; .type 32; .endef #endif /* __CYGWIN || __DJGPP */ #endif diff --git a/src/lib/libcrypto/pkcs12/p12_crpt.c b/src/lib/libcrypto/pkcs12/p12_crpt.c index 97be6a5fb5..5e8958612b 100644 --- a/src/lib/libcrypto/pkcs12/p12_crpt.c +++ b/src/lib/libcrypto/pkcs12/p12_crpt.c @@ -118,7 +118,7 @@ int PKCS12_PBE_keyivgen (EVP_CIPHER_CTX *ctx, const char *pass, int passlen, } PBEPARAM_free(pbe); EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); - memset(key, 0, EVP_MAX_KEY_LENGTH); - memset(iv, 0, EVP_MAX_IV_LENGTH); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); return 1; } diff --git a/src/lib/libcrypto/pkcs12/p12_decr.c b/src/lib/libcrypto/pkcs12/p12_decr.c index 394af368f4..b5684a83ba 100644 --- a/src/lib/libcrypto/pkcs12/p12_decr.c +++ b/src/lib/libcrypto/pkcs12/p12_decr.c @@ -136,7 +136,7 @@ void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, } #endif ret = ASN1_item_d2i(NULL, &p, outlen, it); - if (zbuf) memset(out, 0, outlen); + if (zbuf) OPENSSL_cleanse(out, outlen); if(!ret) PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_DECODE_ERROR); OPENSSL_free(out); return ret; @@ -168,7 +168,7 @@ ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *i OPENSSL_free(in); return NULL; } - if (zbuf) memset(in, 0, inlen); + if (zbuf) OPENSSL_cleanse(in, inlen); OPENSSL_free(in); return oct; } diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c index 0d39ebde8c..9196a34b4a 100644 --- a/src/lib/libcrypto/pkcs12/p12_key.c +++ b/src/lib/libcrypto/pkcs12/p12_key.c @@ -91,7 +91,7 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); if(unipass) { - memset(unipass, 0, uniplen); /* Clear password from memory */ + OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ OPENSSL_free(unipass); } return ret; diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c index a549433eeb..af708a2743 100644 --- a/src/lib/libcrypto/pkcs12/p12_npas.c +++ b/src/lib/libcrypto/pkcs12/p12_npas.c @@ -107,7 +107,7 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) { STACK_OF(PKCS7) *asafes, *newsafes; STACK_OF(PKCS12_SAFEBAG) *bags; - int i, bagnid, pbe_nid, pbe_iter, pbe_saltlen; + int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; PKCS7 *p7, *p7new; ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; unsigned char mac[EVP_MAX_MD_SIZE]; diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c index 4a4ff340ce..0060a2ea3d 100644 --- a/src/lib/libcrypto/pkcs7/pk7_doit.c +++ b/src/lib/libcrypto/pkcs7/pk7_doit.c @@ -241,7 +241,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj); } OPENSSL_free(tmp); - memset(key, 0, keylen); + OPENSSL_cleanse(key, keylen); if (out == NULL) out=btmp; @@ -448,7 +448,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); - memset(tmp,0,jj); + OPENSSL_cleanse(tmp,jj); if (out == NULL) out=etmp; @@ -578,7 +578,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) /* We now have the EVP_MD_CTX, lets do the * signing. */ EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); - if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey))) + if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) { PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); goto err; diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h index 66e39991ec..606382dd21 100644 --- a/src/lib/libcrypto/rand/rand.h +++ b/src/lib/libcrypto/rand/rand.h @@ -87,7 +87,9 @@ extern int rand_predictable; int RAND_set_rand_method(const RAND_METHOD *meth); const RAND_METHOD *RAND_get_rand_method(void); +#ifndef OPENSSL_NO_ENGINE int RAND_set_rand_engine(ENGINE *engine); +#endif RAND_METHOD *RAND_SSLeay(void); void RAND_cleanup(void ); int RAND_bytes(unsigned char *buf,int num); diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c index 5cf5dc1188..513e338985 100644 --- a/src/lib/libcrypto/rand/rand_lib.c +++ b/src/lib/libcrypto/rand/rand_lib.c @@ -60,19 +60,25 @@ #include #include "cryptlib.h" #include +#ifndef OPENSSL_NO_ENGINE #include +#endif +#ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref =NULL; +#endif static const RAND_METHOD *default_RAND_meth = NULL; int RAND_set_rand_method(const RAND_METHOD *meth) { +#ifndef OPENSSL_NO_ENGINE if(funct_ref) { ENGINE_finish(funct_ref); funct_ref = NULL; } +#endif default_RAND_meth = meth; return 1; } @@ -81,6 +87,7 @@ const RAND_METHOD *RAND_get_rand_method(void) { if (!default_RAND_meth) { +#ifndef OPENSSL_NO_ENGINE ENGINE *e = ENGINE_get_default_RAND(); if(e) { @@ -94,11 +101,13 @@ const RAND_METHOD *RAND_get_rand_method(void) if(e) funct_ref = e; else +#endif default_RAND_meth = RAND_SSLeay(); } return default_RAND_meth; } +#ifndef OPENSSL_NO_ENGINE int RAND_set_rand_engine(ENGINE *engine) { const RAND_METHOD *tmp_meth = NULL; @@ -118,6 +127,7 @@ int RAND_set_rand_engine(ENGINE *engine) funct_ref = engine; return 1; } +#endif void RAND_cleanup(void) { diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c index 982074c465..41574768ab 100644 --- a/src/lib/libcrypto/rand/randfile.c +++ b/src/lib/libcrypto/rand/randfile.c @@ -124,7 +124,7 @@ int RAND_load_file(const char *file, long bytes) } } fclose(in); - memset(buf,0,BUFSIZE); + OPENSSL_cleanse(buf,BUFSIZE); err: return(ret); } @@ -189,7 +189,7 @@ int RAND_write_file(const char *file) #endif /* OPENSSL_SYS_VMS */ fclose(out); - memset(buf,0,BUFSIZE); + OPENSSL_cleanse(buf,BUFSIZE); err: return (rand_err ? -1 : ret); } @@ -203,8 +203,9 @@ const char *RAND_file_name(char *buf, size_t size) s=getenv("RANDFILE"); if (s != NULL) { - strncpy(buf,s,size-1); - buf[size-1]='\0'; + if(strlen(s) >= size) + return NULL; + strcpy(buf,s); ret=buf; } else diff --git a/src/lib/libcrypto/ripemd/rmd_dgst.c b/src/lib/libcrypto/ripemd/rmd_dgst.c index a3170f7c8a..f351f00eea 100644 --- a/src/lib/libcrypto/ripemd/rmd_dgst.c +++ b/src/lib/libcrypto/ripemd/rmd_dgst.c @@ -90,8 +90,8 @@ int RIPEMD160_Init(RIPEMD160_CTX *c) void ripemd160_block_host_order (RIPEMD160_CTX *ctx, const void *p, int num) { const RIPEMD160_LONG *XX=p; - register unsigned long A,B,C,D,E; - register unsigned long a,b,c,d,e; + register unsigned MD32_REG_T A,B,C,D,E; + register unsigned MD32_REG_T a,b,c,d,e; for (;num--;XX+=HASH_LBLOCK) { @@ -290,12 +290,12 @@ void ripemd160_block_host_order (RIPEMD160_CTX *ctx, const void *p, int num) void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, int num) { const unsigned char *data=p; - register unsigned long A,B,C,D,E; - unsigned long a,b,c,d,e,l; + register unsigned MD32_REG_T A,B,C,D,E; + unsigned MD32_REG_T a,b,c,d,e,l; #ifndef MD32_XARRAY /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; # define X(i) XX##i #else RIPEMD160_LONG XX[16]; diff --git a/src/lib/libcrypto/ripemd/rmd_one.c b/src/lib/libcrypto/ripemd/rmd_one.c index efdf2dd6ef..f8b580c33a 100644 --- a/src/lib/libcrypto/ripemd/rmd_one.c +++ b/src/lib/libcrypto/ripemd/rmd_one.c @@ -59,6 +59,7 @@ #include #include #include +#include unsigned char *RIPEMD160(const unsigned char *d, unsigned long n, unsigned char *md) @@ -70,7 +71,7 @@ unsigned char *RIPEMD160(const unsigned char *d, unsigned long n, RIPEMD160_Init(&c); RIPEMD160_Update(&c,d,n); RIPEMD160_Final(md,&c); - memset(&c,0,sizeof(c)); /* security consideration */ + OPENSSL_cleanse(&c,sizeof(c)); /* security consideration */ return(md); } diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h index 98b3bd7cc5..e26a68b482 100644 --- a/src/lib/libcrypto/rsa/rsa.h +++ b/src/lib/libcrypto/rsa/rsa.h @@ -158,6 +158,11 @@ struct rsa_st #define RSA_FLAG_CACHE_PUBLIC 0x02 #define RSA_FLAG_CACHE_PRIVATE 0x04 #define RSA_FLAG_BLINDING 0x08 +#define RSA_FLAG_NO_BLINDING 0x80 /* new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ #define RSA_FLAG_THREAD_SAFE 0x10 /* This flag means the private key operations will be handled by rsa_mod_exp * and that they do not depend on the private key components being present: @@ -170,11 +175,15 @@ struct rsa_st */ #define RSA_FLAG_SIGN_VER 0x40 +#define RSA_FLAG_NO_BLINDING 0x80 + #define RSA_PKCS1_PADDING 1 #define RSA_SSLV23_PADDING 2 #define RSA_NO_PADDING 3 #define RSA_PKCS1_OAEP_PADDING 4 +#define RSA_PKCS1_PADDING_SIZE 11 + #define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) #define RSA_get_app_data(s) RSA_get_ex_data(s,0) diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c index 0eda816081..027b4dc754 100644 --- a/src/lib/libcrypto/rsa/rsa_eay.c +++ b/src/lib/libcrypto/rsa/rsa_eay.c @@ -61,7 +61,6 @@ #include #include #include -#include #ifndef RSA_NULL @@ -187,12 +186,65 @@ err: BN_clear_free(&ret); if (buf != NULL) { - memset(buf,0,num); + OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); } +static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx) + { + int ret = 1; + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + /* Check again inside the lock - the macro's check is racey */ + if(rsa->blinding == NULL) + ret = RSA_blinding_on(rsa, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + return ret; + } + +#define BLINDING_HELPER(rsa, ctx, err_instr) \ + do { \ + if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \ + ((rsa)->blinding == NULL) && \ + !rsa_eay_blinding(rsa, ctx)) \ + err_instr \ + } while(0) + +static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx) + { + BIGNUM *A, *Ai; + BN_BLINDING *ret = NULL; + + /* added in OpenSSL 0.9.6j and 0.9.7b */ + + /* NB: similar code appears in RSA_blinding_on (rsa_lib.c); + * this should be placed in a new function of its own, but for reasons + * of binary compatibility can't */ + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) + { + /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */ + RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0); + if (!BN_pseudo_rand_range(A,rsa->n)) goto err; + } + else + { + if (!BN_rand_range(A,rsa->n)) goto err; + } + if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; + + if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) + goto err; + ret = BN_BLINDING_new(A,Ai,rsa->n); + BN_free(Ai); +err: + BN_CTX_end(ctx); + return ret; + } + /* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) @@ -201,6 +253,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; BN_init(&f); BN_init(&ret); @@ -237,10 +291,39 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, goto err; } - if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) - RSA_blinding_on(rsa,ctx); - if (rsa->flags & RSA_FLAG_BLINDING) - if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; + BLINDING_HELPER(rsa, ctx, goto err;); + blinding = rsa->blinding; + + /* Now unless blinding is disabled, 'blinding' is non-NULL. + * But the BN_BLINDING object may be owned by some other thread + * (we don't want to keep it constant and we don't want to use + * lots of locking to avoid race conditions, so only a single + * thread can use it; other threads have to use local blinding + * factors) */ + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + { + if (blinding->thread_id != CRYPTO_thread_id()) + { + /* we need a local one-time blinding factor */ + + blinding = setup_blinding(rsa, ctx); + if (blinding == NULL) + goto err; + local_blinding = 1; + } + } + + if (blinding) + if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err; if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && @@ -254,8 +337,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; } - if (rsa->flags & RSA_FLAG_BLINDING) - if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; + if (blinding) + if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err; /* put in leading 0 bytes if the number is less than the * length of the modulus */ @@ -269,9 +352,11 @@ err: if (ctx != NULL) BN_CTX_free(ctx); BN_clear_free(&ret); BN_clear_free(&f); + if (local_blinding) + BN_BLINDING_free(blinding); if (buf != NULL) { - memset(buf,0,num); + OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); @@ -285,6 +370,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; + int local_blinding = 0; + BN_BLINDING *blinding = NULL; BN_init(&f); BN_init(&ret); @@ -316,10 +403,39 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, goto err; } - if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) - RSA_blinding_on(rsa,ctx); - if (rsa->flags & RSA_FLAG_BLINDING) - if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; + BLINDING_HELPER(rsa, ctx, goto err;); + blinding = rsa->blinding; + + /* Now unless blinding is disabled, 'blinding' is non-NULL. + * But the BN_BLINDING object may be owned by some other thread + * (we don't want to keep it constant and we don't want to use + * lots of locking to avoid race conditions, so only a single + * thread can use it; other threads have to use local blinding + * factors) */ + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) + { + if (blinding == NULL) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) + { + if (blinding->thread_id != CRYPTO_thread_id()) + { + /* we need a local one-time blinding factor */ + + blinding = setup_blinding(rsa, ctx); + if (blinding == NULL) + goto err; + local_blinding = 1; + } + } + + if (blinding) + if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err; /* do the decrypt */ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || @@ -335,8 +451,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, goto err; } - if (rsa->flags & RSA_FLAG_BLINDING) - if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; + if (blinding) + if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err; p=buf; j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */ @@ -370,7 +486,7 @@ err: BN_clear_free(&ret); if (buf != NULL) { - memset(buf,0,num); + OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); @@ -467,7 +583,7 @@ err: BN_clear_free(&ret); if (buf != NULL) { - memset(buf,0,num); + OPENSSL_cleanse(buf,num); OPENSSL_free(buf); } return(r); diff --git a/src/lib/libcrypto/rsa/rsa_lib.c b/src/lib/libcrypto/rsa/rsa_lib.c index 93235744f7..53c5092014 100644 --- a/src/lib/libcrypto/rsa/rsa_lib.c +++ b/src/lib/libcrypto/rsa/rsa_lib.c @@ -62,7 +62,10 @@ #include #include #include +#include +#ifndef OPENSSL_NO_ENGINE #include +#endif const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT; @@ -70,7 +73,9 @@ static const RSA_METHOD *default_RSA_meth=NULL; RSA *RSA_new(void) { - return(RSA_new_method(NULL)); + RSA *r=RSA_new_method(NULL); + + return r; } void RSA_set_default_method(const RSA_METHOD *meth) @@ -108,11 +113,13 @@ int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) const RSA_METHOD *mtmp; mtmp = rsa->meth; if (mtmp->finish) mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE if (rsa->engine) { ENGINE_finish(rsa->engine); rsa->engine = NULL; } +#endif rsa->meth = meth; if (meth->init) meth->init(rsa); return 1; @@ -130,6 +137,7 @@ RSA *RSA_new_method(ENGINE *engine) } ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE if (engine) { if (!ENGINE_init(engine)) @@ -154,6 +162,7 @@ RSA *RSA_new_method(ENGINE *engine) return NULL; } } +#endif ret->pad=0; ret->version=0; @@ -175,8 +184,10 @@ RSA *RSA_new_method(ENGINE *engine) CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE if (ret->engine) ENGINE_finish(ret->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; @@ -205,8 +216,10 @@ void RSA_free(RSA *r) if (r->meth->finish) r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE if (r->engine) ENGINE_finish(r->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); @@ -297,7 +310,8 @@ void RSA_blinding_off(RSA *rsa) BN_BLINDING_free(rsa->blinding); rsa->blinding=NULL; } - rsa->flags&= ~RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_BLINDING; + rsa->flags |= RSA_FLAG_NO_BLINDING; } int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) @@ -316,15 +330,32 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) if (rsa->blinding != NULL) BN_BLINDING_free(rsa->blinding); + /* NB: similar code appears in setup_blinding (rsa_eay.c); + * this should be placed in a new function of its own, but for reasons + * of binary compatibility can't */ + BN_CTX_start(ctx); A = BN_CTX_get(ctx); - if (!BN_rand_range(A,rsa->n)) goto err; + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) + { + /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */ + RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0); + if (!BN_pseudo_rand_range(A,rsa->n)) goto err; + } + else + { + if (!BN_rand_range(A,rsa->n)) goto err; + } if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) - goto err; - rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n); - rsa->flags|=RSA_FLAG_BLINDING; + goto err; + if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err; + /* to make things thread-safe without excessive locking, + * rsa->blinding will be used just by the current thread: */ + rsa->blinding->thread_id = CRYPTO_thread_id(); + rsa->flags |= RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_NO_BLINDING; BN_free(Ai); ret=1; err: diff --git a/src/lib/libcrypto/rsa/rsa_pk1.c b/src/lib/libcrypto/rsa/rsa_pk1.c index c1edd6764f..8560755f1d 100644 --- a/src/lib/libcrypto/rsa/rsa_pk1.c +++ b/src/lib/libcrypto/rsa/rsa_pk1.c @@ -68,7 +68,7 @@ int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, int j; unsigned char *p; - if (flen > (tlen-11)) + if (flen > (tlen-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); return(0); diff --git a/src/lib/libcrypto/rsa/rsa_saos.c b/src/lib/libcrypto/rsa/rsa_saos.c index 85adacc08f..f462716a57 100644 --- a/src/lib/libcrypto/rsa/rsa_saos.c +++ b/src/lib/libcrypto/rsa/rsa_saos.c @@ -77,7 +77,7 @@ int RSA_sign_ASN1_OCTET_STRING(int type, i=i2d_ASN1_OCTET_STRING(&sig,NULL); j=RSA_size(rsa); - if ((i-RSA_PKCS1_PADDING) > j) + if (i > (j-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return(0); @@ -96,7 +96,7 @@ int RSA_sign_ASN1_OCTET_STRING(int type, else *siglen=i; - memset(s,0,(unsigned int)j+1); + OPENSSL_cleanse(s,(unsigned int)j+1); OPENSSL_free(s); return(ret); } @@ -139,7 +139,7 @@ int RSA_verify_ASN1_OCTET_STRING(int dtype, ret=1; err: if (sig != NULL) M_ASN1_OCTET_STRING_free(sig); - memset(s,0,(unsigned int)siglen); + OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); return(ret); } diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c index 2a440901de..8a1e642183 100644 --- a/src/lib/libcrypto/rsa/rsa_sign.c +++ b/src/lib/libcrypto/rsa/rsa_sign.c @@ -62,7 +62,6 @@ #include #include #include -#include /* Size of an SSL signature: MD5+SHA1 */ #define SSL_SIG_LENGTH 36 @@ -77,10 +76,11 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, const unsigned char *s = NULL; X509_ALGOR algor; ASN1_OCTET_STRING digest; - if((rsa->flags & RSA_FLAG_SIGN_VER) - && ENGINE_get_RSA(rsa->engine)->rsa_sign) - return ENGINE_get_RSA(rsa->engine)->rsa_sign(type, - m, m_len, sigret, siglen, rsa); + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) + { + return rsa->meth->rsa_sign(type, m, m_len, + sigret, siglen, rsa); + } /* Special case: SSL signature, just check the length */ if(type == NID_md5_sha1) { if(m_len != SSL_SIG_LENGTH) { @@ -113,7 +113,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, i=i2d_X509_SIG(&sig,NULL); } j=RSA_size(rsa); - if ((i-RSA_PKCS1_PADDING) > j) + if (i > (j-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return(0); @@ -136,7 +136,7 @@ int RSA_sign(int type, const unsigned char *m, unsigned int m_len, *siglen=i; if(type != NID_md5_sha1) { - memset(tmps,0,(unsigned int)j+1); + OPENSSL_cleanse(tmps,(unsigned int)j+1); OPENSSL_free(tmps); } return(ret); @@ -155,10 +155,11 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, return(0); } - if((rsa->flags & RSA_FLAG_SIGN_VER) - && ENGINE_get_RSA(rsa->engine)->rsa_verify) - return ENGINE_get_RSA(rsa->engine)->rsa_verify(dtype, - m, m_len, sigbuf, siglen, rsa); + if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) + { + return rsa->meth->rsa_verify(dtype, m, m_len, + sigbuf, siglen, rsa); + } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) @@ -221,7 +222,7 @@ int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, } err: if (sig != NULL) X509_SIG_free(sig); - memset(s,0,(unsigned int)siglen); + OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); return(ret); } diff --git a/src/lib/libcrypto/sha/sha1_one.c b/src/lib/libcrypto/sha/sha1_one.c index e6a24888ed..20e660c71d 100644 --- a/src/lib/libcrypto/sha/sha1_one.c +++ b/src/lib/libcrypto/sha/sha1_one.c @@ -59,6 +59,7 @@ #include #include #include +#include #ifndef OPENSSL_NO_SHA1 unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md) @@ -70,7 +71,7 @@ unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md) SHA1_Init(&c); SHA1_Update(&c,d,n); SHA1_Final(md,&c); - memset(&c,0,sizeof(c)); + OPENSSL_cleanse(&c,sizeof(c)); return(md); } #endif diff --git a/src/lib/libcrypto/sha/sha_locl.h b/src/lib/libcrypto/sha/sha_locl.h index 471dfb9f8f..2dd63a62a6 100644 --- a/src/lib/libcrypto/sha/sha_locl.h +++ b/src/lib/libcrypto/sha/sha_locl.h @@ -224,10 +224,10 @@ int HASH_INIT (SHA_CTX *c) void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num) { const SHA_LONG *W=d; - register unsigned long A,B,C,D,E,T; + register unsigned MD32_REG_T A,B,C,D,E,T; #ifndef MD32_XARRAY - unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; #else SHA_LONG XX[16]; #endif @@ -349,10 +349,10 @@ void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num) void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, int num) { const unsigned char *data=p; - register unsigned long A,B,C,D,E,T,l; + register unsigned MD32_REG_T A,B,C,D,E,T,l; #ifndef MD32_XARRAY - unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; #else SHA_LONG XX[16]; #endif diff --git a/src/lib/libcrypto/txt_db/txt_db.c b/src/lib/libcrypto/txt_db/txt_db.c index 9b186f2da5..58b300b00b 100644 --- a/src/lib/libcrypto/txt_db/txt_db.c +++ b/src/lib/libcrypto/txt_db/txt_db.c @@ -108,7 +108,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num) if (offset != 0) { size+=BUFSIZE; - if (!BUF_MEM_grow(buf,size)) goto err; + if (!BUF_MEM_grow_clean(buf,size)) goto err; } buf->data[offset]='\0'; BIO_gets(in,&(buf->data[offset]),size-offset); @@ -268,7 +268,7 @@ long TXT_DB_write(BIO *out, TXT_DB *db) if (pp[j] != NULL) l+=strlen(pp[j]); } - if (!BUF_MEM_grow(buf,(int)(l*2+nn))) goto err; + if (!BUF_MEM_grow_clean(buf,(int)(l*2+nn))) goto err; p=buf->data; for (j=0; j #include #include "ui_locl.h" +#include "cryptlib.h" IMPLEMENT_STACK_OF(UI_STRING_ST) @@ -144,7 +145,8 @@ static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, { UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,ERR_R_PASSED_NULL_PARAMETER); } - else if (result_buf == NULL) + else if ((type == UIT_PROMPT || type == UIT_VERIFY + || type == UIT_BOOLEAN) && result_buf == NULL) { UIerr(UI_F_GENERAL_ALLOCATE_PROMPT,UI_R_NO_RESULT_BUFFER); } @@ -235,7 +237,7 @@ static int general_allocate_boolean(UI *ui, return ret; } -/* Returns the index to the place in the stack or 0 for error. Uses a +/* Returns the index to the place in the stack or -1 for error. Uses a direct reference to the prompt. */ int UI_add_input_string(UI *ui, const char *prompt, int flags, char *result_buf, int minsize, int maxsize) @@ -831,8 +833,8 @@ int UI_set_result(UI *ui, UI_STRING *uis, const char *result) case UIT_PROMPT: case UIT_VERIFY: { - char number1[20]; - char number2[20]; + char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize)+1]; + char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize)+1]; BIO_snprintf(number1, sizeof(number1), "%d", uis->_.string_data.result_minsize); diff --git a/src/lib/libcrypto/ui/ui_openssl.c b/src/lib/libcrypto/ui/ui_openssl.c index 2c2fbc0443..75318d48a1 100644 --- a/src/lib/libcrypto/ui/ui_openssl.c +++ b/src/lib/libcrypto/ui/ui_openssl.c @@ -159,8 +159,10 @@ #ifdef WIN_CONSOLE_BUG # include +#ifndef OPENSSL_SYS_WINCE # include #endif +#endif /* There are 5 types of terminal interface supported, @@ -191,7 +193,7 @@ # define SGTTY #endif -#if defined(OPENSSL_SYS_VSWORKS) +#if defined(OPENSSL_SYS_VXWORKS) #undef TERMIOS #undef TERMIO #undef SGTTY @@ -221,7 +223,7 @@ # define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) #endif -#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) # include #endif @@ -241,6 +243,10 @@ struct IOSB { }; #endif +#ifdef OPENSSL_SYS_SUNOS + typedef int sig_atomic_t; +#endif + #if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) /* * This one needs work. As a matter of fact the code is unoperational @@ -277,10 +283,12 @@ static FILE *tty_in, *tty_out; static int is_a_tty; /* Declare static functions */ +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) static void read_till_nl(FILE *); static void recsig(int); static void pushsig(void); static void popsig(void); +#endif #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) static int noecho_fgets(char *buf, int size, FILE *tty); #endif @@ -367,6 +375,7 @@ static int read_string(UI *ui, UI_STRING *uis) } +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) /* Internal functions to read a string without echoing */ static void read_till_nl(FILE *in) { @@ -378,7 +387,8 @@ static void read_till_nl(FILE *in) } while (strchr(buf,'\n') == NULL); } -static sig_atomic_t intr_signal; +static volatile sig_atomic_t intr_signal; +#endif static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) { @@ -386,9 +396,9 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) int ok; char result[BUFSIZ]; int maxsize = BUFSIZ-1; +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) char *p; -#ifndef OPENSSL_SYS_WIN16 intr_signal=0; ok=0; ps=0; @@ -439,7 +449,7 @@ error: ok=1; #endif - memset(result,0,BUFSIZ); + OPENSSL_cleanse(result,BUFSIZ); return ok; } @@ -450,7 +460,7 @@ static int open_console(UI *ui) CRYPTO_w_lock(CRYPTO_LOCK_UI); is_a_tty = 1; -#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VSWORKS) +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) tty_in=stdin; tty_out=stderr; #else @@ -540,7 +550,7 @@ static int echo_console(UI *ui) static int close_console(UI *ui) { - if (tty_in != stderr) fclose(tty_in); + if (tty_in != stdin) fclose(tty_in); if (tty_out != stderr) fclose(tty_out); #ifdef OPENSSL_SYS_VMS status = sys$dassgn(channel); @@ -551,6 +561,7 @@ static int close_console(UI *ui) } +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) /* Internal functions to handle signals and act on them */ static void pushsig(void) { @@ -614,9 +625,10 @@ static void recsig(int i) { intr_signal=i; } +#endif /* Internal functions specific for Windows */ -#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) static int noecho_fgets(char *buf, int size, FILE *tty) { int i; diff --git a/src/lib/libcrypto/ui/ui_util.c b/src/lib/libcrypto/ui/ui_util.c index f05573df33..46bc8c1a9a 100644 --- a/src/lib/libcrypto/ui/ui_util.c +++ b/src/lib/libcrypto/ui/ui_util.c @@ -62,7 +62,7 @@ int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify) int ret; ret=UI_UTIL_read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify); - memset(buff,0,BUFSIZ); + OPENSSL_cleanse(buff,BUFSIZ); return(ret); } @@ -78,12 +78,14 @@ int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify) if (ui) { ok = UI_add_input_string(ui,prompt,0,buf,0,size-1); - if (ok == 0 && verify) + if (ok >= 0 && verify) ok = UI_add_verify_string(ui,prompt,0,buff,0,size-1, buf); - if (ok == 0) + if (ok >= 0) ok=UI_process(ui); UI_free(ui); } + if (ok > 0) + ok = 0; return(ok); } diff --git a/src/lib/libcrypto/util/mkerr.pl b/src/lib/libcrypto/util/mkerr.pl index 4105047b21..1b2915c767 100644 --- a/src/lib/libcrypto/util/mkerr.pl +++ b/src/lib/libcrypto/util/mkerr.pl @@ -132,16 +132,16 @@ while (($hdr, $lib) = each %libinc) my $name = $1; $name =~ tr/[a-z]/[A-Z]/; $ftrans{$name} = $1; - } elsif (/\w+\W+(\w+)\W*\(\s*\)$/s){ + } elsif (/\w+\W+(\w+)\W*\(\s*\)(\s*__attribute__\(.*\)\s*)?$/s){ # K&R C next ; - } elsif (/\w+\W+\w+\W*\(.*\)$/s) { - while (not /\(\)$/s) { - s/[^\(\)]*\)$/\)/s; - s/\([^\(\)]*\)\)$/\)/s; + } elsif (/\w+\W+\w+\W*\(.*\)(\s*__attribute__\(.*\)\s*)?$/s) { + while (not /\(\)(\s*__attribute__\(.*\)\s*)?$/s) { + s/[^\(\)]*\)(\s*__attribute__\(.*\)\s*)?$/\)/s; + s/\([^\(\)]*\)\)(\s*__attribute__\(.*\)\s*)?$/\)/s; } s/\(void\)//; - /(\w+)\W*\(\)/s; + /(\w+(\{[0-9]+\})?)\W*\(\)/s; my $name = $1; $name =~ tr/[a-z]/[A-Z]/; $ftrans{$name} = $1; @@ -262,7 +262,7 @@ foreach $lib (keys %csrc) } else { push @out, "/* ====================================================================\n", -" * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved.\n", +" * Copyright (c) 2001-2003 The OpenSSL Project. All rights reserved.\n", " *\n", " * Redistribution and use in source and binary forms, with or without\n", " * modification, are permitted provided that the following conditions\n", @@ -404,7 +404,7 @@ EOF print OUT <<"EOF"; /* $cfile */ /* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/lib/libcrypto/x509/by_file.c b/src/lib/libcrypto/x509/by_file.c index 92e00d2d73..b4b04183d0 100644 --- a/src/lib/libcrypto/x509/by_file.c +++ b/src/lib/libcrypto/x509/by_file.c @@ -100,18 +100,19 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, case X509_L_FILE_LOAD: if (argl == X509_FILETYPE_DEFAULT) { - ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(), - X509_FILETYPE_PEM) != 0); + file = (char *)Getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx,file, + X509_FILETYPE_PEM) != 0); + + else + ok = (X509_load_cert_crl_file(ctx,X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + if (!ok) { X509err(X509_F_BY_FILE_CTRL,X509_R_LOADING_DEFAULTS); } - else - { - file=(char *)Getenv(X509_get_default_cert_file_env()); - ok = (X509_load_cert_crl_file(ctx,file, - X509_FILETYPE_PEM) != 0); - } } else { @@ -284,7 +285,8 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) if(itmp->x509) { X509_STORE_add_cert(ctx->store_ctx, itmp->x509); count++; - } else if(itmp->crl) { + } + if(itmp->crl) { X509_STORE_add_crl(ctx->store_ctx, itmp->crl); count++; } diff --git a/src/lib/libcrypto/x509/x509.h b/src/lib/libcrypto/x509/x509.h index 7095440d36..eaad5685a8 100644 --- a/src/lib/libcrypto/x509/x509.h +++ b/src/lib/libcrypto/x509/x509.h @@ -87,7 +87,6 @@ #ifndef OPENSSL_NO_SHA #include #endif -#include #include #include @@ -487,10 +486,12 @@ typedef struct Netscape_certificate_sequence STACK_OF(X509) *certs; } NETSCAPE_CERT_SEQUENCE; +/* Unused (and iv length is wrong) typedef struct CBCParameter_st { unsigned char iv[8]; } CBC_PARAM; +*/ /* Password based encryption structure */ diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c index cd20b6d66f..f460102f49 100644 --- a/src/lib/libcrypto/x509/x509_cmp.c +++ b/src/lib/libcrypto/x509/x509_cmp.c @@ -57,6 +57,7 @@ */ #include +#include #include "cryptlib.h" #include #include @@ -81,13 +82,14 @@ unsigned long X509_issuer_and_serial_hash(X509 *a) unsigned long ret=0; EVP_MD_CTX ctx; unsigned char md[16]; - char str[256]; + char *f; EVP_MD_CTX_init(&ctx); - X509_NAME_oneline(a->cert_info->issuer,str,256); - ret=strlen(str); + f=X509_NAME_oneline(a->cert_info->issuer,NULL,0); + ret=strlen(f); EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); - EVP_DigestUpdate(&ctx,(unsigned char *)str,ret); + EVP_DigestUpdate(&ctx,(unsigned char *)f,ret); + OPENSSL_free(f); EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data, (unsigned long)a->cert_info->serialNumber->length); EVP_DigestFinal_ex(&ctx,&(md[0]),NULL); @@ -159,6 +161,99 @@ int X509_cmp(const X509 *a, const X509 *b) } #endif + +/* Case insensitive string comparision */ +static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + if (a->length != b->length) + return (a->length - b->length); + + for (i=0; ilength; i++) + { + int ca, cb; + + ca = tolower(a->data[i]); + cb = tolower(b->data[i]); + + if (ca != cb) + return(ca-cb); + } + return 0; +} + +/* Case insensitive string comparision with space normalization + * Space normalization - ignore leading, trailing spaces, + * multiple spaces between characters are replaced by single space + */ +static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + unsigned char *pa = NULL, *pb = NULL; + int la, lb; + + la = a->length; + lb = b->length; + pa = a->data; + pb = b->data; + + /* skip leading spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + + /* skip trailing spaces */ + while (la > 0 && isspace(pa[la-1])) + la--; + while (lb > 0 && isspace(pb[lb-1])) + lb--; + + /* compare strings with space normalization */ + while (la > 0 && lb > 0) + { + int ca, cb; + + /* compare character */ + ca = tolower(*pa); + cb = tolower(*pb); + if (ca != cb) + return (ca - cb); + + pa++; pb++; + la--; lb--; + + if (la <= 0 || lb <= 0) + break; + + /* is white space next character ? */ + if (isspace(*pa) && isspace(*pb)) + { + /* skip remaining white spaces */ + while (la > 0 && isspace(*pa)) + { + la--; + pa++; + } + while (lb > 0 && isspace(*pb)) + { + lb--; + pb++; + } + } + } + if (la > 0 || lb > 0) + return la - lb; + + return 0; +} + int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { int i,j; @@ -172,10 +267,20 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) { na=sk_X509_NAME_ENTRY_value(a->entries,i); nb=sk_X509_NAME_ENTRY_value(b->entries,i); - j=na->value->length-nb->value->length; + j=na->value->type-nb->value->type; if (j) return(j); - j=memcmp(na->value->data,nb->value->data, - na->value->length); + if (na->value->type == V_ASN1_PRINTABLESTRING) + j=nocase_spacenorm_cmp(na->value, nb->value); + else if (na->value->type == V_ASN1_IA5STRING + && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress) + j=nocase_cmp(na->value, nb->value); + else + { + j=na->value->length-nb->value->length; + if (j) return(j); + j=memcmp(na->value->data,nb->value->data, + na->value->length); + } if (j) return(j); j=na->set-nb->set; if (j) return(j); diff --git a/src/lib/libcrypto/x509/x509_v3.c b/src/lib/libcrypto/x509/x509_v3.c index b5f7daa2e5..67b1796a92 100644 --- a/src/lib/libcrypto/x509/x509_v3.c +++ b/src/lib/libcrypto/x509/x509_v3.c @@ -116,7 +116,7 @@ int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, { ex=sk_X509_EXTENSION_value(sk,lastpos); if ( ((ex->critical > 0) && crit) || - (!(ex->critical <= 0) && !crit)) + ((ex->critical <= 0) && !crit)) return(lastpos); } return(-1); diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index db12f7bd35..552d1e7251 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c @@ -756,7 +756,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) { char *str; ASN1_TIME atm; - time_t offset; + long offset; char buff1[24],buff2[24],*p; int i,j; diff --git a/src/lib/libcrypto/x509v3/ext_dat.h b/src/lib/libcrypto/x509v3/ext_dat.h index 2fb97d8925..5442480595 100644 --- a/src/lib/libcrypto/x509v3/ext_dat.h +++ b/src/lib/libcrypto/x509v3/ext_dat.h @@ -90,17 +90,23 @@ static X509V3_EXT_METHOD *standard_exts[] = { &v3_crld, &v3_ext_ku, &v3_crl_reason, +#ifndef OPENSSL_NO_OCSP &v3_crl_invdate, +#endif &v3_sxnet, &v3_info, +#ifndef OPENSSL_NO_OCSP &v3_ocsp_nonce, &v3_ocsp_crlid, &v3_ocsp_accresp, &v3_ocsp_nocheck, &v3_ocsp_acutoff, &v3_ocsp_serviceloc, +#endif &v3_sinfo, +#ifndef OPENSSL_NO_OCSP &v3_crl_hold +#endif }; /* Number of standard extensions */ diff --git a/src/lib/libcrypto/x509v3/v3_info.c b/src/lib/libcrypto/x509v3/v3_info.c index e1cf01a9b4..e269df1373 100644 --- a/src/lib/libcrypto/x509v3/v3_info.c +++ b/src/lib/libcrypto/x509v3/v3_info.c @@ -113,7 +113,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method ret = i2v_GENERAL_NAME(method, desc->location, ret); if(!ret) break; vtmp = sk_CONF_VALUE_value(ret, i); - i2t_ASN1_OBJECT(objtmp, 80, desc->method); + i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); ntmp = OPENSSL_malloc(strlen(objtmp) + strlen(vtmp->name) + 5); if(!ntmp) { X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, diff --git a/src/lib/libcrypto/x509v3/v3_ocsp.c b/src/lib/libcrypto/x509v3/v3_ocsp.c index 083112314e..21badc13f9 100644 --- a/src/lib/libcrypto/x509v3/v3_ocsp.c +++ b/src/lib/libcrypto/x509v3/v3_ocsp.c @@ -56,6 +56,8 @@ * */ +#ifndef OPENSSL_NO_OCSP + #include #include "cryptlib.h" #include @@ -270,3 +272,4 @@ static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int err: return 0; } +#endif diff --git a/src/lib/libcrypto/x509v3/v3_prn.c b/src/lib/libcrypto/x509v3/v3_prn.c index aeaf6170fe..754808b625 100644 --- a/src/lib/libcrypto/x509v3/v3_prn.c +++ b/src/lib/libcrypto/x509v3/v3_prn.c @@ -178,7 +178,7 @@ int X509V3_extensions_print(BIO *bp, char *title, STACK_OF(X509_EXTENSION) *exts ASN1_OBJECT *obj; X509_EXTENSION *ex; ex=sk_X509_EXTENSION_value(exts, i); - if (BIO_printf(bp,"%*s",indent, "") <= 0) return 0; + if (indent && BIO_printf(bp,"%*s",indent, "") <= 0) return 0; obj=X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp,obj); j=X509_EXTENSION_get_critical(ex); diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c index b739e4fd83..4d145f71fd 100644 --- a/src/lib/libcrypto/x509v3/v3_purp.c +++ b/src/lib/libcrypto/x509v3/v3_purp.c @@ -378,6 +378,10 @@ static void x509v3_cache_extensions(X509 *x) case NID_time_stamp: x->ex_xkusage |= XKU_TIMESTAMP; break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; } } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); diff --git a/src/lib/libcrypto/x509v3/v3_utl.c b/src/lib/libcrypto/x509v3/v3_utl.c index 283e943e46..34ac2998de 100644 --- a/src/lib/libcrypto/x509v3/v3_utl.c +++ b/src/lib/libcrypto/x509v3/v3_utl.c @@ -491,7 +491,7 @@ static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens) i = -1; /* First supplied X509_NAME */ while((i = X509_NAME_get_index_by_NID(name, - NID_pkcs9_emailAddress, i)) > 0) { + NID_pkcs9_emailAddress, i)) >= 0) { ne = X509_NAME_get_entry(name, i); email = X509_NAME_ENTRY_get_data(ne); if(!append_ia5(&ret, email)) return NULL; diff --git a/src/lib/libcrypto/x509v3/x509v3.h b/src/lib/libcrypto/x509v3/x509v3.h index daecc55271..fb07a19016 100644 --- a/src/lib/libcrypto/x509v3/x509v3.h +++ b/src/lib/libcrypto/x509v3/x509v3.h @@ -352,6 +352,7 @@ DECLARE_ASN1_SET_OF(POLICYINFO) #define XKU_SGC 0x10 #define XKU_OCSP_SIGN 0x20 #define XKU_TIMESTAMP 0x40 +#define XKU_DVCS 0x80 #define X509_PURPOSE_DYNAMIC 0x1 #define X509_PURPOSE_DYNAMIC_NAME 0x2 diff --git a/src/lib/libssl/LICENSE b/src/lib/libssl/LICENSE index 7b93e0dbce..dddb07842b 100644 --- a/src/lib/libssl/LICENSE +++ b/src/lib/libssl/LICENSE @@ -12,7 +12,7 @@ --------------- /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/lib/libssl/bio_ssl.c b/src/lib/libssl/bio_ssl.c index 467e149947..d683ee43e1 100644 --- a/src/lib/libssl/bio_ssl.c +++ b/src/lib/libssl/bio_ssl.c @@ -403,6 +403,10 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO_free_all(ssl->wbio); } + if (b->next_bio != NULL) + { + CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO); + } ssl->wbio=NULL; ssl->rbio=NULL; break; @@ -509,6 +513,7 @@ static int ssl_puts(BIO *bp, const char *str) BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) { +#ifndef OPENSSL_NO_SOCK BIO *ret=NULL,*buf=NULL,*ssl=NULL; if ((buf=BIO_new(BIO_f_buffer())) == NULL) @@ -521,6 +526,7 @@ BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) err: if (buf != NULL) BIO_free(buf); if (ssl != NULL) BIO_free(ssl); +#endif return(NULL); } diff --git a/src/lib/libssl/doc/standards.txt b/src/lib/libssl/doc/standards.txt index 596d9001e6..edbe2f3a57 100644 --- a/src/lib/libssl/doc/standards.txt +++ b/src/lib/libssl/doc/standards.txt @@ -42,20 +42,9 @@ whole or at least great parts) in OpenSSL. 2268 A Description of the RC2(r) Encryption Algorithm. R. Rivest. January 1998. (Format: TXT=19048 bytes) (Status: INFORMATIONAL) -2314 PKCS 10: Certification Request Syntax Version 1.5. B. Kaliski. - March 1998. (Format: TXT=15814 bytes) (Status: INFORMATIONAL) - 2315 PKCS 7: Cryptographic Message Syntax Version 1.5. B. Kaliski. March 1998. (Format: TXT=69679 bytes) (Status: INFORMATIONAL) -2437 PKCS #1: RSA Cryptography Specifications Version 2.0. B. Kaliski, - J. Staddon. October 1998. (Format: TXT=73529 bytes) (Obsoletes - RFC2313) (Status: INFORMATIONAL) - -2459 Internet X.509 Public Key Infrastructure Certificate and CRL - Profile. R. Housley, W. Ford, W. Polk, D. Solo. January 1999. - (Format: TXT=278438 bytes) (Status: PROPOSED STANDARD) - PKCS#8: Private-Key Information Syntax Standard PKCS#12: Personal Information Exchange Syntax Standard, version 1.0. @@ -65,6 +54,40 @@ PKCS#12: Personal Information Exchange Syntax Standard, version 1.0. C. Adams. June 1999. (Format: TXT=43243 bytes) (Status: PROPOSED STANDARD) +2712 Addition of Kerberos Cipher Suites to Transport Layer Security + (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes) + (Status: PROPOSED STANDARD) + +2898 PKCS #5: Password-Based Cryptography Specification Version 2.0. + B. Kaliski. September 2000. (Format: TXT=68692 bytes) (Status: + INFORMATIONAL) + +2986 PKCS #10: Certification Request Syntax Specification Version 1.7. + M. Nystrom, B. Kaliski. November 2000. (Format: TXT=27794 bytes) + (Obsoletes RFC2314) (Status: INFORMATIONAL) + +3174 US Secure Hash Algorithm 1 (SHA1). D. Eastlake 3rd, P. Jones. + September 2001. (Format: TXT=35525 bytes) (Status: INFORMATIONAL) + +3268 Advanced Encryption Standard (AES) Ciphersuites for Transport + Layer Security (TLS). P. Chown. June 2002. (Format: TXT=13530 bytes) + (Status: PROPOSED STANDARD) + +3279 Algorithms and Identifiers for the Internet X.509 Public Key + Infrastructure Certificate and Certificate Revocation List (CRL) + Profile. L. Bassham, W. Polk, R. Housley. April 2002. (Format: + TXT=53833 bytes) (Status: PROPOSED STANDARD) + +3280 Internet X.509 Public Key Infrastructure Certificate and + Certificate Revocation List (CRL) Profile. R. Housley, W. Polk, W. + Ford, D. Solo. April 2002. (Format: TXT=295556 bytes) (Obsoletes + RFC2459) (Status: PROPOSED STANDARD) + +3447 Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography + Specifications Version 2.1. J. Jonsson, B. Kaliski. February 2003. + (Format: TXT=143173 bytes) (Obsoletes RFC2437) (Status: + INFORMATIONAL) + Related: -------- @@ -90,23 +113,60 @@ STARTTLS documents. Certification and Related Services. B. Kaliski. February 1993. (Format: TXT=17537 bytes) (Status: PROPOSED STANDARD) -2256 A Summary of the X.500(96) User Schema for use with LDAPv3. M. - Wahl. December 1997. (Format: TXT=32377 bytes) (Status: PROPOSED - STANDARD) +2025 The Simple Public-Key GSS-API Mechanism (SPKM). C. Adams. October + 1996. (Format: TXT=101692 bytes) (Status: PROPOSED STANDARD) + +2510 Internet X.509 Public Key Infrastructure Certificate Management + Protocols. C. Adams, S. Farrell. March 1999. (Format: TXT=158178 + bytes) (Status: PROPOSED STANDARD) + +2511 Internet X.509 Certificate Request Message Format. M. Myers, C. + Adams, D. Solo, D. Kemp. March 1999. (Format: TXT=48278 bytes) + (Status: PROPOSED STANDARD) + +2527 Internet X.509 Public Key Infrastructure Certificate Policy and + Certification Practices Framework. S. Chokhani, W. Ford. March 1999. + (Format: TXT=91860 bytes) (Status: INFORMATIONAL) -2487 SMTP Service Extension for Secure SMTP over TLS. P. Hoffman. - January 1999. (Format: TXT=15120 bytes) (Status: PROPOSED STANDARD) +2538 Storing Certificates in the Domain Name System (DNS). D. Eastlake + 3rd, O. Gudmundsson. March 1999. (Format: TXT=19857 bytes) (Status: + PROPOSED STANDARD) + +2539 Storage of Diffie-Hellman Keys in the Domain Name System (DNS). + D. Eastlake 3rd. March 1999. (Format: TXT=21049 bytes) (Status: + PROPOSED STANDARD) + +2559 Internet X.509 Public Key Infrastructure Operational Protocols - + LDAPv2. S. Boeyen, T. Howes, P. Richard. April 1999. (Format: + TXT=22889 bytes) (Updates RFC1778) (Status: PROPOSED STANDARD) 2585 Internet X.509 Public Key Infrastructure Operational Protocols: FTP and HTTP. R. Housley, P. Hoffman. May 1999. (Format: TXT=14813 bytes) (Status: PROPOSED STANDARD) +2587 Internet X.509 Public Key Infrastructure LDAPv2 Schema. S. + Boeyen, T. Howes, P. Richard. June 1999. (Format: TXT=15102 bytes) + (Status: PROPOSED STANDARD) + 2595 Using TLS with IMAP, POP3 and ACAP. C. Newman. June 1999. (Format: TXT=32440 bytes) (Status: PROPOSED STANDARD) -2712 Addition of Kerberos Cipher Suites to Transport Layer Security - (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes) - (Status: PROPOSED STANDARD) +2631 Diffie-Hellman Key Agreement Method. E. Rescorla. June 1999. + (Format: TXT=25932 bytes) (Status: PROPOSED STANDARD) + +2632 S/MIME Version 3 Certificate Handling. B. Ramsdell, Ed.. June + 1999. (Format: TXT=27925 bytes) (Status: PROPOSED STANDARD) + +2716 PPP EAP TLS Authentication Protocol. B. Aboba, D. Simon. October + 1999. (Format: TXT=50108 bytes) (Status: EXPERIMENTAL) + +2773 Encryption using KEA and SKIPJACK. R. Housley, P. Yee, W. Nace. + February 2000. (Format: TXT=20008 bytes) (Updates RFC0959) (Status: + EXPERIMENTAL) + +2797 Certificate Management Messages over CMS. M. Myers, X. Liu, J. + Schaad, J. Weinstein. April 2000. (Format: TXT=103357 bytes) (Status: + PROPOSED STANDARD) 2817 Upgrading to TLS Within HTTP/1.1. R. Khare, S. Lawrence. May 2000. (Format: TXT=27598 bytes) (Updates RFC2616) (Status: PROPOSED @@ -115,6 +175,77 @@ STARTTLS documents. 2818 HTTP Over TLS. E. Rescorla. May 2000. (Format: TXT=15170 bytes) (Status: INFORMATIONAL) +2876 Use of the KEA and SKIPJACK Algorithms in CMS. J. Pawling. July + 2000. (Format: TXT=29265 bytes) (Status: INFORMATIONAL) + +2984 Use of the CAST-128 Encryption Algorithm in CMS. C. Adams. + October 2000. (Format: TXT=11591 bytes) (Status: PROPOSED STANDARD) + +2985 PKCS #9: Selected Object Classes and Attribute Types Version 2.0. + M. Nystrom, B. Kaliski. November 2000. (Format: TXT=70703 bytes) + (Status: INFORMATIONAL) + +3029 Internet X.509 Public Key Infrastructure Data Validation and + Certification Server Protocols. C. Adams, P. Sylvester, M. Zolotarev, + R. Zuccherato. February 2001. (Format: TXT=107347 bytes) (Status: + EXPERIMENTAL) + +3039 Internet X.509 Public Key Infrastructure Qualified Certificates + Profile. S. Santesson, W. Polk, P. Barzin, M. Nystrom. January 2001. + (Format: TXT=67619 bytes) (Status: PROPOSED STANDARD) + +3058 Use of the IDEA Encryption Algorithm in CMS. S. Teiwes, P. + Hartmann, D. Kuenzi. February 2001. (Format: TXT=17257 bytes) + (Status: INFORMATIONAL) + +3161 Internet X.509 Public Key Infrastructure Time-Stamp Protocol + (TSP). C. Adams, P. Cain, D. Pinkas, R. Zuccherato. August 2001. + (Format: TXT=54585 bytes) (Status: PROPOSED STANDARD) + +3185 Reuse of CMS Content Encryption Keys. S. Farrell, S. Turner. + October 2001. (Format: TXT=20404 bytes) (Status: PROPOSED STANDARD) + +3207 SMTP Service Extension for Secure SMTP over Transport Layer + Security. P. Hoffman. February 2002. (Format: TXT=18679 bytes) + (Obsoletes RFC2487) (Status: PROPOSED STANDARD) + +3217 Triple-DES and RC2 Key Wrapping. R. Housley. December 2001. + (Format: TXT=19855 bytes) (Status: INFORMATIONAL) + +3274 Compressed Data Content Type for Cryptographic Message Syntax + (CMS). P. Gutmann. June 2002. (Format: TXT=11276 bytes) (Status: + PROPOSED STANDARD) + +3278 Use of Elliptic Curve Cryptography (ECC) Algorithms in + Cryptographic Message Syntax (CMS). S. Blake-Wilson, D. Brown, P. + Lambert. April 2002. (Format: TXT=33779 bytes) (Status: + INFORMATIONAL) + +3281 An Internet Attribute Certificate Profile for Authorization. S. + Farrell, R. Housley. April 2002. (Format: TXT=90580 bytes) (Status: + PROPOSED STANDARD) + +3369 Cryptographic Message Syntax (CMS). R. Housley. August 2002. + (Format: TXT=113975 bytes) (Obsoletes RFC2630, RFC3211) (Status: + PROPOSED STANDARD) + +3370 Cryptographic Message Syntax (CMS) Algorithms. R. Housley. August + 2002. (Format: TXT=51001 bytes) (Obsoletes RFC2630, RFC3211) (Status: + PROPOSED STANDARD) + +3377 Lightweight Directory Access Protocol (v3): Technical + Specification. J. Hodges, R. Morgan. September 2002. (Format: + TXT=9981 bytes) (Updates RFC2251, RFC2252, RFC2253, RFC2254, RFC2255, + RFC2256, RFC2829, RFC2830) (Status: PROPOSED STANDARD) + +3394 Advanced Encryption Standard (AES) Key Wrap Algorithm. J. Schaad, + R. Housley. September 2002. (Format: TXT=73072 bytes) (Status: + INFORMATIONAL) + +3436 Transport Layer Security over Stream Control Transmission + Protocol. A. Jungmaier, E. Rescorla, M. Tuexen. December 2002. + (Format: TXT=16333 bytes) (Status: PROPOSED STANDARD) + "Securing FTP with TLS", 01/27/2000, @@ -124,7 +255,3 @@ To be implemented: These are documents that describe things that are planed to be implemented in the hopefully short future. -2712 Addition of Kerberos Cipher Suites to Transport Layer Security - (TLS). A. Medvinsky, M. Hur. October 1999. (Format: TXT=13763 bytes) - (Status: PROPOSED STANDARD) - diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c index 019e9aecee..64ee4269ec 100644 --- a/src/lib/libssl/s23_clnt.c +++ b/src/lib/libssl/s23_clnt.c @@ -87,18 +87,25 @@ SSL_METHOD *SSLv23_client_method(void) if (init) { - memcpy((char *)&SSLv23_client_data, - (char *)sslv23_base_method(),sizeof(SSL_METHOD)); - SSLv23_client_data.ssl_connect=ssl23_connect; - SSLv23_client_data.get_ssl_method=ssl23_get_client_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv23_client_data, + (char *)sslv23_base_method(),sizeof(SSL_METHOD)); + SSLv23_client_data.ssl_connect=ssl23_connect; + SSLv23_client_data.get_ssl_method=ssl23_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv23_client_data); } int ssl23_connect(SSL *s) { - BUF_MEM *buf; + BUF_MEM *buf=NULL; unsigned long Time=time(NULL); void (*cb)(const SSL *ssl,int type,int val)=NULL; int ret= -1; @@ -152,6 +159,7 @@ int ssl23_connect(SSL *s) goto end; } s->init_buf=buf; + buf=NULL; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } @@ -200,6 +208,8 @@ int ssl23_connect(SSL *s) } end: s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); @@ -363,7 +373,7 @@ static int ssl23_get_server_hello(SSL *s) if (s->s3 != NULL) ssl3_free(s); - if (!BUF_MEM_grow(s->init_buf, + if (!BUF_MEM_grow_clean(s->init_buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,ERR_R_BUF_LIB); diff --git a/src/lib/libssl/s23_srvr.c b/src/lib/libssl/s23_srvr.c index 8743b61cbb..c5404ca0bc 100644 --- a/src/lib/libssl/s23_srvr.c +++ b/src/lib/libssl/s23_srvr.c @@ -139,11 +139,18 @@ SSL_METHOD *SSLv23_server_method(void) if (init) { - memcpy((char *)&SSLv23_server_data, - (char *)sslv23_base_method(),sizeof(SSL_METHOD)); - SSLv23_server_data.ssl_accept=ssl23_accept; - SSLv23_server_data.get_ssl_method=ssl23_get_server_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv23_server_data, + (char *)sslv23_base_method(),sizeof(SSL_METHOD)); + SSLv23_server_data.ssl_accept=ssl23_accept; + SSLv23_server_data.get_ssl_method=ssl23_get_server_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv23_server_data); } @@ -505,7 +512,7 @@ int ssl23_get_client_hello(SSL *s) if (s->s3 != NULL) ssl3_free(s); - if (!BUF_MEM_grow(s->init_buf, + if (!BUF_MEM_grow_clean(s->init_buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { goto err; diff --git a/src/lib/libssl/s3_both.c b/src/lib/libssl/s3_both.c index 8864366f59..64d317b7ac 100644 --- a/src/lib/libssl/s3_both.c +++ b/src/lib/libssl/s3_both.c @@ -268,16 +268,23 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) X509_STORE_CTX xs_ctx; X509_OBJECT obj; + int no_chain; + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) + no_chain = 1; + else + no_chain = 0; + /* TLSv1 sends a chain with nothing in it, instead of an alert */ buf=s->init_buf; - if (!BUF_MEM_grow(buf,(int)(10))) + if (!BUF_MEM_grow_clean(buf,10)) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); return(0); } if (x != NULL) { - if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) + if(!no_chain && !X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL)) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB); return(0); @@ -286,7 +293,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) for (;;) { n=i2d_X509(x,NULL); - if (!BUF_MEM_grow(buf,(int)(n+l+3))) + if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); return(0); @@ -295,6 +302,10 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) l2n3(n,p); i2d_X509(x,&p); l+=n+3; + + if (no_chain) + break; + if (X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)) == 0) break; @@ -306,8 +317,8 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) * ref count */ X509_free(x); } - - X509_STORE_CTX_cleanup(&xs_ctx); + if (!no_chain) + X509_STORE_CTX_cleanup(&xs_ctx); } /* Thawte special :-) */ @@ -316,7 +327,7 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) { x=sk_X509_value(s->ctx->extra_certs,i); n=i2d_X509(x,NULL); - if (!BUF_MEM_grow(buf,(int)(n+l+3))) + if (!BUF_MEM_grow_clean(buf,(int)(n+l+3))) { SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB); return(0); @@ -439,7 +450,7 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l && !BUF_MEM_grow(s->init_buf,(int)l+4)) + if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4)) { SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB); goto err; diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c index 2b58482484..fae8eadada 100644 --- a/src/lib/libssl/s3_clnt.c +++ b/src/lib/libssl/s3_clnt.c @@ -146,18 +146,25 @@ SSL_METHOD *SSLv3_client_method(void) if (init) { - init=0; - memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(), - sizeof(SSL_METHOD)); - SSLv3_client_data.ssl_connect=ssl3_connect; - SSLv3_client_data.get_ssl_method=ssl3_get_client_method; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(), + sizeof(SSL_METHOD)); + SSLv3_client_data.ssl_connect=ssl3_connect; + SSLv3_client_data.get_ssl_method=ssl3_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv3_client_data); } int ssl3_connect(SSL *s) { - BUF_MEM *buf; + BUF_MEM *buf=NULL; unsigned long Time=time(NULL),l; long num1; void (*cb)(const SSL *ssl,int type,int val)=NULL; @@ -218,6 +225,7 @@ int ssl3_connect(SSL *s) goto end; } s->init_buf=buf; + buf=NULL; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } @@ -496,6 +504,8 @@ int ssl3_connect(SSL *s) } end: s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); @@ -632,30 +642,20 @@ static int ssl3_get_server_hello(SSL *s) /* get the session-id */ j= *(p++); - if(j > sizeof s->session->session_id) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_SSL3_SESSION_ID_TOO_LONG); - goto f_err; - } - - if ((j != 0) && (j != SSL3_SESSION_ID_SIZE)) + if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) { - /* SSLref returns 16 :-( */ - if (j < SSL2_SSL_SESSION_ID_LENGTH) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_SHORT); - goto f_err; - } + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto f_err; } + if (j != 0 && j == s->session->session_id_length && memcmp(p,s->session->session_id,j) == 0) { if(s->sid_ctx_length != s->session->sid_ctx_length || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length)) { + /* actually a client application bug */ al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto f_err; @@ -699,7 +699,12 @@ static int ssl3_get_server_hello(SSL *s) goto f_err; } - if (s->hit && (s->session->cipher != c)) + /* Depending on the session caching (internal/external), the cipher + and/or cipher_id values may not be set. Make sure that + cipher_id is set and use it for comparison. */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) { if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) @@ -1457,16 +1462,16 @@ static int ssl3_send_client_key_exchange(SSL *s) tmp_buf[0]=s->client_version>>8; tmp_buf[1]=s->client_version&0xff; - if (RAND_bytes(&(tmp_buf[2]),SSL_MAX_MASTER_KEY_LENGTH-2) <= 0) + if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) goto err; - s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; + s->session->master_key_length=sizeof tmp_buf; q=p; /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) p+=2; - n=RSA_public_encrypt(SSL_MAX_MASTER_KEY_LENGTH, + n=RSA_public_encrypt(sizeof tmp_buf, tmp_buf,p,rsa,RSA_PKCS1_PADDING); #ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; @@ -1488,8 +1493,8 @@ static int ssl3_send_client_key_exchange(SSL *s) s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, - tmp_buf,SSL_MAX_MASTER_KEY_LENGTH); - memset(tmp_buf,0,SSL_MAX_MASTER_KEY_LENGTH); + tmp_buf,sizeof tmp_buf); + OPENSSL_cleanse(tmp_buf,sizeof tmp_buf); } #endif #ifndef OPENSSL_NO_KRB5 @@ -1585,7 +1590,7 @@ static int ssl3_send_client_key_exchange(SSL *s) n+=2; } - if (RAND_bytes(tmp_buf,SSL_MAX_MASTER_KEY_LENGTH) <= 0) + if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0) goto err; /* 20010420 VRS. Tried it this way; failed. @@ -1595,11 +1600,11 @@ static int ssl3_send_client_key_exchange(SSL *s) ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); */ - memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */ + memset(iv, 0, sizeof iv); /* per RFC 1510 */ EVP_EncryptInit_ex(&ciph_ctx,enc, NULL, kssl_ctx->key,iv); EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf, - SSL_MAX_MASTER_KEY_LENGTH); + sizeof tmp_buf); EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); outl += padl; if (outl > sizeof epms) @@ -1618,10 +1623,10 @@ static int ssl3_send_client_key_exchange(SSL *s) s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, - tmp_buf, SSL_MAX_MASTER_KEY_LENGTH); + tmp_buf, sizeof tmp_buf); - memset(tmp_buf, 0, SSL_MAX_MASTER_KEY_LENGTH); - memset(epms, 0, outl); + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); + OPENSSL_cleanse(epms, outl); } #endif #ifndef OPENSSL_NO_DH diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c index 14b2f13ae2..896b12fc4f 100644 --- a/src/lib/libssl/s3_lib.c +++ b/src/lib/libssl/s3_lib.c @@ -512,6 +512,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, +#if 0 /* Cipher 1E */ { 0, @@ -525,55 +526,70 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS, }, +#endif #ifndef OPENSSL_NO_KRB5 /* The Kerberos ciphers ** 20000107 VRS: And the first shall be last, ** in hopes of avoiding the lynx ssl renegotiation problem. */ -/* Cipher 21 VRS */ +/* Cipher 1E VRS */ { 1, - SSL3_TXT_KRB5_DES_40_CBC_SHA, - SSL3_CK_KRB5_DES_40_CBC_SHA, + SSL3_TXT_KRB5_DES_64_CBC_SHA, + SSL3_CK_KRB5_DES_64_CBC_SHA, SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, - SSL_EXPORT|SSL_EXP40, + SSL_NOT_EXP|SSL_LOW, 0, - 40, + 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS, }, -/* Cipher 22 VRS */ +/* Cipher 1F VRS */ { 1, - SSL3_TXT_KRB5_DES_40_CBC_MD5, - SSL3_CK_KRB5_DES_40_CBC_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, - SSL_EXPORT|SSL_EXP40, + SSL3_TXT_KRB5_DES_192_CBC3_SHA, + SSL3_CK_KRB5_DES_192_CBC3_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_SHA1 |SSL_SSLV3, + SSL_NOT_EXP|SSL_HIGH, 0, - 40, - 56, + 112, + 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS, }, -/* Cipher 23 VRS */ +/* Cipher 20 VRS */ { 1, - SSL3_TXT_KRB5_DES_64_CBC_SHA, - SSL3_CK_KRB5_DES_64_CBC_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, - SSL_NOT_EXP|SSL_LOW, + SSL3_TXT_KRB5_RC4_128_SHA, + SSL3_CK_KRB5_RC4_128_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, + SSL_NOT_EXP|SSL_MEDIUM, 0, - 56, - 56, + 128, + 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS, }, -/* Cipher 24 VRS */ +/* Cipher 21 VRS */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_SHA, + SSL3_CK_KRB5_IDEA_128_CBC_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_SHA1 |SSL_SSLV3, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 22 VRS */ { 1, SSL3_TXT_KRB5_DES_64_CBC_MD5, @@ -587,12 +603,12 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, -/* Cipher 25 VRS */ +/* Cipher 23 VRS */ { 1, - SSL3_TXT_KRB5_DES_192_CBC3_SHA, - SSL3_CK_KRB5_DES_192_CBC3_SHA, - SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_SHA1 |SSL_SSLV3, + SSL3_TXT_KRB5_DES_192_CBC3_MD5, + SSL3_CK_KRB5_DES_192_CBC3_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 112, @@ -601,16 +617,114 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ SSL_ALL_STRENGTHS, }, +/* Cipher 24 VRS */ + { + 1, + SSL3_TXT_KRB5_RC4_128_MD5, + SSL3_CK_KRB5_RC4_128_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 25 VRS */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_MD5, + SSL3_CK_KRB5_IDEA_128_CBC_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_MD5 |SSL_SSLV3, + SSL_NOT_EXP|SSL_MEDIUM, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + /* Cipher 26 VRS */ { 1, - SSL3_TXT_KRB5_DES_192_CBC3_MD5, - SSL3_CK_KRB5_DES_192_CBC3_MD5, - SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_MD5 |SSL_SSLV3, - SSL_NOT_EXP|SSL_HIGH, + SSL3_TXT_KRB5_DES_40_CBC_SHA, + SSL3_CK_KRB5_DES_40_CBC_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, 0, - 112, - 168, + 40, + 56, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 27 VRS */ + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_SHA, + SSL3_CK_KRB5_RC2_40_CBC_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_SHA1 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, + 0, + 40, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 28 VRS */ + { + 1, + SSL3_TXT_KRB5_RC4_40_SHA, + SSL3_CK_KRB5_RC4_40_SHA, + SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, + 0, + 128, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 29 VRS */ + { + 1, + SSL3_TXT_KRB5_DES_40_CBC_MD5, + SSL3_CK_KRB5_DES_40_CBC_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, + 0, + 40, + 56, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 2A VRS */ + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_MD5, + SSL3_CK_KRB5_RC2_40_CBC_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_MD5 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, + 0, + 40, + 128, + SSL_ALL_CIPHERS, + SSL_ALL_STRENGTHS, + }, + +/* Cipher 2B VRS */ + { + 1, + SSL3_TXT_KRB5_RC4_40_MD5, + SSL3_CK_KRB5_RC4_40_MD5, + SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, + SSL_EXPORT|SSL_EXP40, + 0, + 128, + 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS, }, @@ -986,7 +1100,7 @@ void ssl3_free(SSL *s) sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free); EVP_MD_CTX_cleanup(&s->s3->finish_dgst1); EVP_MD_CTX_cleanup(&s->s3->finish_dgst2); - memset(s->s3,0,sizeof *s->s3); + OPENSSL_cleanse(s->s3,sizeof *s->s3); OPENSSL_free(s->s3); s->s3=NULL; } @@ -1341,16 +1455,19 @@ SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) { CRYPTO_w_lock(CRYPTO_LOCK_SSL); - for (i=0; is3->rrec); sess=s->session; @@ -353,8 +355,11 @@ again: /* SSLerr() and ssl3_send_alert() have been called */ goto err; - /* otherwise enc_err == -1 */ - goto decryption_failed_or_bad_record_mac; + /* Otherwise enc_err == -1, which indicates bad padding + * (rec->length has not been changed in this case). + * To minimize information leaked via timing, we will perform + * the MAC computation anyway. */ + decryption_failed_or_bad_record_mac = 1; } #ifdef TLS_DEBUG @@ -380,28 +385,46 @@ printf("\n"); SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + decryption_failed_or_bad_record_mac = 1; #endif } /* check the MAC for rr->input (it's in mac_size bytes at the tail) */ - if (rr->length < mac_size) + if (rr->length >= mac_size) { + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + else + { + /* record (minus padding) is too short to contain a MAC */ #if 0 /* OK only for stream ciphers */ al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT); goto f_err; #else - goto decryption_failed_or_bad_record_mac; + decryption_failed_or_bad_record_mac = 1; + rr->length = 0; #endif } - rr->length-=mac_size; i=s->method->ssl3_enc->mac(s,md,0); - if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) + if (mac == NULL || memcmp(md, mac, mac_size) != 0) { - goto decryption_failed_or_bad_record_mac; + decryption_failed_or_bad_record_mac = 1; } } + if (decryption_failed_or_bad_record_mac) + { + /* A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption + * failure is directly visible from the ciphertext anyway, + * we should not reveal which kind of error occured -- this + * might become visible to an attacker (e.g. via a logfile) */ + al=SSL_AD_BAD_RECORD_MAC; + SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto f_err; + } + /* r->length is now just compressed */ if (s->expand != NULL) { @@ -443,14 +466,6 @@ printf("\n"); return(1); -decryption_failed_or_bad_record_mac: - /* Separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, - * we should not reveal which kind of error occured -- this - * might become visible to an attacker (e.g. via logfile) */ - al=SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c index 20d716fb1b..58cf774967 100644 --- a/src/lib/libssl/s3_srvr.c +++ b/src/lib/libssl/s3_srvr.c @@ -152,11 +152,18 @@ SSL_METHOD *SSLv3_server_method(void) if (init) { - memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(), - sizeof(SSL_METHOD)); - SSLv3_server_data.ssl_accept=ssl3_accept; - SSLv3_server_data.get_ssl_method=ssl3_get_server_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(), + sizeof(SSL_METHOD)); + SSLv3_server_data.ssl_accept=ssl3_accept; + SSLv3_server_data.get_ssl_method=ssl3_get_server_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv3_server_data); } @@ -1171,7 +1178,7 @@ static int ssl3_send_server_key_exchange(SSL *s) kn=0; } - if (!BUF_MEM_grow(buf,n+4+kn)) + if (!BUF_MEM_grow_clean(buf,n+4+kn)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF); goto err; @@ -1298,7 +1305,7 @@ static int ssl3_send_certificate_request(SSL *s) { name=sk_X509_NAME_value(sk,i); j=i2d_X509_NAME(name,NULL); - if (!BUF_MEM_grow(buf,4+n+j+2)) + if (!BUF_MEM_grow_clean(buf,4+n+j+2)) { SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB); goto err; @@ -1440,7 +1447,7 @@ static int ssl3_get_client_key_exchange(SSL *s) if (i != SSL_MAX_MASTER_KEY_LENGTH) { al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); + /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */ } if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff)))) @@ -1456,37 +1463,35 @@ static int ssl3_get_client_key_exchange(SSL *s) (p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff)))) { al=SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); - goto f_err; + /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */ + + /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version + * number check as a "bad version oracle" -- an alert would + * reveal that the plaintext corresponding to some ciphertext + * made up by the adversary is properly formatted except + * that the version number is wrong. To avoid such attacks, + * we should treat this just like any other decryption error. */ } } if (al != -1) { -#if 0 - goto f_err; -#else /* Some decryption failure -- use random value instead as countermeasure * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding - * (see RFC 2246, section 7.4.7.1). - * But note that due to length and protocol version checking, the - * attack is impractical anyway (see section 5 in D. Bleichenbacher: - * "Chosen Ciphertext Attacks Against Protocols Based on the RSA - * Encryption Standard PKCS #1", CRYPTO '98, LNCS 1462, pp. 1-12). - */ + * (see RFC 2246, section 7.4.7.1). */ ERR_clear_error(); i = SSL_MAX_MASTER_KEY_LENGTH; p[0] = s->client_version >> 8; p[1] = s->client_version & 0xff; RAND_pseudo_bytes(p+2, i-2); /* should be RAND_bytes, but we cannot work around a failure */ -#endif } s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, p,i); - memset(p,0,i); + OPENSSL_cleanse(p,i); } else #endif @@ -1549,7 +1554,7 @@ static int ssl3_get_client_key_exchange(SSL *s) s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,i); - memset(p,0,i); + OPENSSL_cleanse(p,i); } else #endif @@ -1652,7 +1657,7 @@ static int ssl3_get_client_key_exchange(SSL *s) if (enc == NULL) goto err; - memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */ + memset(iv, 0, sizeof iv); /* per RFC 1510 */ if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv)) { @@ -1740,7 +1745,7 @@ static int ssl3_get_cert_verify(SSL *s) SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, -1, - 512, /* 512? */ + 514, /* 514? */ &ok); if (!ok) return((int)n); diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index e9d1e896d7..4ae8458259 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -204,6 +204,22 @@ extern "C" { /* VRS Additional Kerberos5 entries */ +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +#define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +#define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + #define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA #define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 #define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA @@ -299,9 +315,7 @@ extern "C" { #include #include #include -#include #include -#include #ifdef __cplusplus extern "C" { @@ -507,6 +521,8 @@ typedef struct ssl_session_st /* Never bother the application with retries if the transport * is blocking: */ #define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, @@ -704,10 +720,11 @@ struct ssl_ctx_st #define SSL_SESS_CACHE_SERVER 0x0002 #define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) #define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 -/* This one, when set, makes the server session-id lookup not look - * in the cache. If there is an application get_session callback - * defined, this will still get called. */ +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ #define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx); #define SSL_CTX_sess_number(ctx) \ @@ -1212,14 +1229,12 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM t STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, const char *file); -#ifndef OPENSSL_SYS_WIN32 #ifndef OPENSSL_SYS_VMS #ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, const char *dir); #endif #endif -#endif #endif @@ -1688,6 +1703,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_LENGTH_TOO_SHORT 160 #define SSL_R_LIBRARY_BUG 274 #define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +#define SSL_R_MASTER_KEY_TOO_LONG 1112 #define SSL_R_MESSAGE_TOO_LONG 1111 #define SSL_R_MISSING_DH_DSA_CERT 162 #define SSL_R_MISSING_DH_KEY 163 diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h index 8fd6951d77..1153aeda74 100644 --- a/src/lib/libssl/ssl3.h +++ b/src/lib/libssl/ssl3.h @@ -156,23 +156,29 @@ extern "C" { #define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C #define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D +#if 0 /* Because it clashes with KRB5, is never used any more, and is safe + to remove according to David Hopwood + of the ietf-tls list */ #define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E +#endif /* VRS Additional Kerberos5 entries */ -#define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000021 -#define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000022 -#define SSL3_CK_KRB5_DES_64_CBC_SHA 0x03000023 -#define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000024 -#define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x03000025 -#define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000026 - -#define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" -#define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" -#define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" -#define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" -#define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" -#define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +#define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +#define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +#define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +#define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +#define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +#define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +#define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +#define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +#define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +#define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +#define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +#define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +#define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B #define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" #define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" @@ -209,6 +215,22 @@ extern "C" { #define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" #define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +#define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +#define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +#define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +#define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +#define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +#define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +#define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + #define SSL3_SSL_SESSION_ID_LENGTH 32 #define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 diff --git a/src/lib/libssl/ssl_asn1.c b/src/lib/libssl/ssl_asn1.c index 3723fc2e37..16bc11b559 100644 --- a/src/lib/libssl/ssl_asn1.c +++ b/src/lib/libssl/ssl_asn1.c @@ -299,6 +299,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, unsigned char **pp, os.length = sizeof ret->session_id; ret->session_id_length=os.length; + OPENSSL_assert(os.length <= sizeof ret->session_id); memcpy(ret->session_id,os.data,os.length); M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING); @@ -370,9 +371,15 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, unsigned char **pp, if(os.data != NULL) { if (os.length > SSL_MAX_SID_CTX_LENGTH) + { + ret->sid_ctx_length=os.length; SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_BAD_LENGTH); - ret->sid_ctx_length=os.length; - memcpy(ret->sid_ctx,os.data,os.length); + } + else + { + ret->sid_ctx_length=os.length; + memcpy(ret->sid_ctx,os.data,os.length); + } OPENSSL_free(os.data); os.data=NULL; os.length=0; } else diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c index 3d31bbf05f..da90078a37 100644 --- a/src/lib/libssl/ssl_cert.c +++ b/src/lib/libssl/ssl_cert.c @@ -781,7 +781,7 @@ err: #endif #endif -#else +#else /* OPENSSL_SYS_WIN32 */ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir) @@ -789,10 +789,30 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, WIN32_FIND_DATA FindFileData; HANDLE hFind; int ret = 0; +#ifdef OPENSSL_SYS_WINCE + WCHAR* wdir = NULL; +#endif CRYPTO_w_lock(CRYPTO_LOCK_READDIR); +#ifdef OPENSSL_SYS_WINCE + /* convert strings to UNICODE */ + { + BOOL result = FALSE; + int i; + wdir = malloc((strlen(dir)+1)*2); + if (wdir == NULL) + goto err_noclose; + for (i=0; i<(int)strlen(dir)+1; i++) + wdir[i] = (short)dir[i]; + } +#endif + +#ifdef OPENSSL_SYS_WINCE + hFind = FindFirstFile(wdir, &FindFileData); +#else hFind = FindFirstFile(dir, &FindFileData); +#endif /* Note that a side effect is that the CAs will be sorted by name */ if(hFind == INVALID_HANDLE_VALUE) { @@ -807,7 +827,11 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, char buf[1024]; int r; +#ifdef OPENSSL_SYS_WINCE + if(strlen(dir)+_tcslen(FindFileData.cFileName)+2 > sizeof buf) +#else if(strlen(dir)+strlen(FindFileData.cFileName)+2 > sizeof buf) +#endif { SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,SSL_R_PATH_TOO_LONG); goto err; @@ -825,6 +849,10 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, err: FindClose(hFind); err_noclose: +#ifdef OPENSSL_SYS_WINCE + if (wdir != NULL) + free(wdir); +#endif CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); return ret; } diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c index 37f58886a6..888b667fa1 100644 --- a/src/lib/libssl/ssl_ciph.c +++ b/src/lib/libssl/ssl_ciph.c @@ -668,13 +668,14 @@ static int ssl_cipher_process_rulestr(const char *rule_str, * So additionally check whether the cipher name found * has the correct length. We can save a strlen() call: * just checking for the '\0' at the right place is - * sufficient, we have to strncmp() anyway. + * sufficient, we have to strncmp() anyway. (We cannot + * use strcmp(), because buf is not '\0' terminated.) */ j = found = 0; while (ca_list[j]) { - if ((ca_list[j]->name[buflen] == '\0') && - !strncmp(buf, ca_list[j]->name, buflen)) + if (!strncmp(buf, ca_list[j]->name, buflen) && + (ca_list[j]->name[buflen] == '\0')) { found = 1; break; @@ -751,7 +752,12 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ if (rule_str == NULL) return(NULL); - if (init_ciphers) load_ciphers(); + if (init_ciphers) + { + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + if (init_ciphers) load_ciphers(); + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + } /* * To reduce the work to do we only want to process the compiled diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c index 7067a745f3..d2cb181503 100644 --- a/src/lib/libssl/ssl_err.c +++ b/src/lib/libssl/ssl_err.c @@ -296,6 +296,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_LENGTH_TOO_SHORT ,"length too short"}, {SSL_R_LIBRARY_BUG ,"library bug"}, {SSL_R_LIBRARY_HAS_NO_CIPHERS ,"library has no ciphers"}, +{SSL_R_MASTER_KEY_TOO_LONG ,"master key too long"}, {SSL_R_MESSAGE_TOO_LONG ,"message too long"}, {SSL_R_MISSING_DH_DSA_CERT ,"missing dh dsa cert"}, {SSL_R_MISSING_DH_KEY ,"missing dh key"}, diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 4bc4ce5b3a..ddd8114587 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -121,6 +121,7 @@ #include #include #include +#include "cryptlib.h" const char *SSL_version_str=OPENSSL_VERSION_TEXT; @@ -273,6 +274,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->verify_mode=ctx->verify_mode; s->verify_depth=ctx->verify_depth; s->sid_ctx_length=ctx->sid_ctx_length; + OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx)); s->verify_callback=ctx->default_verify_callback; s->generate_session_id=ctx->generate_session_id; @@ -314,7 +316,7 @@ err: int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx, unsigned int sid_ctx_len) { - if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) + if(sid_ctx_len > sizeof ctx->sid_ctx) { SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); return 0; @@ -364,6 +366,10 @@ int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, * any new session built out of this id/id_len and the ssl_version in * use by this SSL. */ SSL_SESSION r, *p; + + if(id_len > sizeof r.session_id) + return 0; + r.ssl_version = ssl->version; r.session_id_length = id_len; memcpy(r.session_id, id, id_len); @@ -1063,14 +1069,17 @@ int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, * preference */ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(SSL *s) { - if ((s != NULL) && (s->cipher_list != NULL)) - { - return(s->cipher_list); - } - else if ((s->ctx != NULL) && - (s->ctx->cipher_list != NULL)) + if (s != NULL) { - return(s->ctx->cipher_list); + if (s->cipher_list != NULL) + { + return(s->cipher_list); + } + else if ((s->ctx != NULL) && + (s->ctx->cipher_list != NULL)) + { + return(s->ctx->cipher_list); + } } return(NULL); } @@ -1079,14 +1088,17 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(SSL *s) * algorithm id */ STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) { - if ((s != NULL) && (s->cipher_list_by_id != NULL)) - { - return(s->cipher_list_by_id); - } - else if ((s != NULL) && (s->ctx != NULL) && - (s->ctx->cipher_list_by_id != NULL)) + if (s != NULL) { - return(s->ctx->cipher_list_by_id); + if (s->cipher_list_by_id != NULL) + { + return(s->cipher_list_by_id); + } + else if ((s->ctx != NULL) && + (s->ctx->cipher_list_by_id != NULL)) + { + return(s->ctx->cipher_list_by_id); + } } return(NULL); } @@ -1652,7 +1664,7 @@ void ssl_update_cache(SSL *s,int mode) i=s->ctx->session_cache_mode; if ((i & mode) && (!s->hit) - && ((i & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP) + && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) || SSL_CTX_add_session(s->ctx,s->session)) && (s->ctx->new_session_cb != NULL)) { @@ -1884,6 +1896,7 @@ SSL *SSL_dup(SSL *s) * they should not both point to the same object, * and thus we can't use SSL_copy_session_id. */ + ret->method->ssl_free(ret); ret->method = s->method; ret->method->ssl_new(ret); diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c index ca1a7427be..fbc30b94e6 100644 --- a/src/lib/libssl/ssl_sess.c +++ b/src/lib/libssl/ssl_sess.c @@ -309,9 +309,12 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len) if (copy) CRYPTO_add(&ret->references,1,CRYPTO_LOCK_SSL_SESSION); - /* The following should not return 1, otherwise, - * things are very strange */ - SSL_CTX_add_session(s->ctx,ret); + /* Add the externally cached session to the internal + * cache as well if and only if we are supposed to. */ + if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)) + /* The following should not return 1, otherwise, + * things are very strange */ + SSL_CTX_add_session(s->ctx,ret); } if (ret == NULL) goto err; @@ -525,13 +528,13 @@ void SSL_SESSION_free(SSL_SESSION *ss) CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); - memset(ss->key_arg,0,SSL_MAX_KEY_ARG_LENGTH); - memset(ss->master_key,0,SSL_MAX_MASTER_KEY_LENGTH); - memset(ss->session_id,0,SSL_MAX_SSL_SESSION_ID_LENGTH); + OPENSSL_cleanse(ss->key_arg,sizeof ss->key_arg); + OPENSSL_cleanse(ss->master_key,sizeof ss->master_key); + OPENSSL_cleanse(ss->session_id,sizeof ss->session_id); if (ss->sess_cert != NULL) ssl_sess_cert_free(ss->sess_cert); if (ss->peer != NULL) X509_free(ss->peer); if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers); - memset(ss,0,sizeof(*ss)); + OPENSSL_cleanse(ss,sizeof(*ss)); OPENSSL_free(ss); } diff --git a/src/lib/libssl/t1_clnt.c b/src/lib/libssl/t1_clnt.c index 9ad518f9f4..57205fb429 100644 --- a/src/lib/libssl/t1_clnt.c +++ b/src/lib/libssl/t1_clnt.c @@ -79,11 +79,18 @@ SSL_METHOD *TLSv1_client_method(void) if (init) { - memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(), - sizeof(SSL_METHOD)); - TLSv1_client_data.ssl_connect=ssl3_connect; - TLSv1_client_data.get_ssl_method=tls1_get_client_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_client_data.ssl_connect=ssl3_connect; + TLSv1_client_data.get_ssl_method=tls1_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&TLSv1_client_data); } diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 5290bf6665..271e247eea 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c @@ -124,7 +124,7 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, unsigned int j; HMAC_CTX ctx; HMAC_CTX ctx_tmp; - unsigned char A1[HMAC_MAX_MD_CBLOCK]; + unsigned char A1[EVP_MAX_MD_SIZE]; unsigned int A1_len; chunk=EVP_MD_size(md); @@ -161,7 +161,7 @@ static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec, } HMAC_CTX_cleanup(&ctx); HMAC_CTX_cleanup(&ctx_tmp); - memset(A1,0,sizeof(A1)); + OPENSSL_cleanse(A1,sizeof(A1)); } static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1, @@ -418,10 +418,10 @@ printf("\niv="); printf("\n"); #endif - memset(tmp1,0,sizeof(tmp1)); - memset(tmp2,0,sizeof(tmp1)); - memset(iv1,0,sizeof(iv1)); - memset(iv2,0,sizeof(iv2)); + OPENSSL_cleanse(tmp1,sizeof(tmp1)); + OPENSSL_cleanse(tmp2,sizeof(tmp1)); + OPENSSL_cleanse(iv1,sizeof(iv1)); + OPENSSL_cleanse(iv2,sizeof(iv2)); return(1); err: SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); @@ -476,7 +476,7 @@ printf("pre-master\n"); { int z; for (z=0; zsession->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif tls1_generate_key_block(s,p1,p2,num); - memset(p2,0,num); + OPENSSL_cleanse(p2,num); OPENSSL_free(p2); #ifdef TLS_DEBUG printf("\nkey block\n"); @@ -683,10 +683,10 @@ int tls1_final_finish_mac(SSL *s, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx, tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf), s->session->master_key,s->session->master_key_length, - out,buf2,12); + out,buf2,sizeof buf2); EVP_MD_CTX_cleanup(&ctx); - return((int)12); + return sizeof buf2; } int tls1_mac(SSL *ssl, unsigned char *md, int send) @@ -773,7 +773,7 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, s->s3->server_random,SSL3_RANDOM_SIZE); tls1_PRF(s->ctx->md5,s->ctx->sha1, buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len, - s->session->master_key,buff,SSL3_MASTER_SECRET_SIZE); + s->session->master_key,buff,sizeof buff); #ifdef KSSL_DEBUG printf ("tls1_generate_master_secret() complete\n"); #endif /* KSSL_DEBUG */ diff --git a/src/lib/libssl/t1_meth.c b/src/lib/libssl/t1_meth.c index 9bb36a7d1c..fcc243f782 100644 --- a/src/lib/libssl/t1_meth.c +++ b/src/lib/libssl/t1_meth.c @@ -76,13 +76,21 @@ SSL_METHOD *TLSv1_method(void) if (init) { - memcpy((char *)&TLSv1_data,(char *)tlsv1_base_method(), - sizeof(SSL_METHOD)); - TLSv1_data.ssl_connect=ssl3_connect; - TLSv1_data.ssl_accept=ssl3_accept; - TLSv1_data.get_ssl_method=tls1_get_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&TLSv1_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_data.ssl_connect=ssl3_connect; + TLSv1_data.ssl_accept=ssl3_accept; + TLSv1_data.get_ssl_method=tls1_get_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } + return(&TLSv1_data); } diff --git a/src/lib/libssl/t1_srvr.c b/src/lib/libssl/t1_srvr.c index 6e765e587f..1c1149e49f 100644 --- a/src/lib/libssl/t1_srvr.c +++ b/src/lib/libssl/t1_srvr.c @@ -80,11 +80,18 @@ SSL_METHOD *TLSv1_server_method(void) if (init) { - memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(), - sizeof(SSL_METHOD)); - TLSv1_server_data.ssl_accept=ssl3_accept; - TLSv1_server_data.get_ssl_method=tls1_get_server_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(), + sizeof(SSL_METHOD)); + TLSv1_server_data.ssl_accept=ssl3_accept; + TLSv1_server_data.get_ssl_method=tls1_get_server_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&TLSv1_server_data); } diff --git a/src/lib/libssl/test/methtest.c b/src/lib/libssl/test/methtest.c index 06ccb3b310..005c2f4822 100644 --- a/src/lib/libssl/test/methtest.c +++ b/src/lib/libssl/test/methtest.c @@ -96,10 +96,10 @@ char *argv[]; METH_init(top); METH_control(tmp1,METH_CONTROL_DUMP,stdout); METH_control(tmp2,METH_CONTROL_DUMP,stdout); - exit(0); + EXIT(0); err: ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); - exit(1); + EXIT(1); return(0); } diff --git a/src/lib/libssl/test/testgen b/src/lib/libssl/test/testgen index 55c496f4bc..3798543e04 100644 --- a/src/lib/libssl/test/testgen +++ b/src/lib/libssl/test/testgen @@ -27,6 +27,8 @@ fi echo "This could take some time." +rm -f testkey.pem testreq.pem + ../apps/openssl req -config test.cnf $req_new -out testreq.pem if [ $? != 0 ]; then echo problems creating request diff --git a/src/lib/libssl/test/testssl b/src/lib/libssl/test/testssl index ba5e41c861..ca8e718022 100644 --- a/src/lib/libssl/test/testssl +++ b/src/lib/libssl/test/testssl @@ -121,8 +121,12 @@ $ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1 ############################################################################# -echo test tls1 with 1024bit anonymous DH, multiple handshakes -$ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1 +if ../apps/openssl no-dh; then + echo skipping anonymous DH tests +else + echo test tls1 with 1024bit anonymous DH, multiple handshakes + $ssltest -v -bio_pair -tls1 -cipher ADH -dhe1024dsa -num 10 -f -time $extra || exit 1 +fi if ../apps/openssl no-rsa; then echo skipping RSA tests @@ -130,8 +134,12 @@ else echo test tls1 with 1024bit RSA, no DHE, multiple handshakes ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -no_dhe -num 10 -f -time $extra || exit 1 - echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes - ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1 + if ../apps/openssl no-dh; then + echo skipping RSA+DHE tests + else + echo test tls1 with 1024bit RSA, 1024bit DHE, multiple handshakes + ./ssltest -v -bio_pair -tls1 -cert ../apps/server2.pem -dhe1024dsa -num 10 -f -time $extra || exit 1 + fi fi exit 0 -- cgit v1.2.3-55-g6feb