aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore18
-rw-r--r--.travis.yml57
-rw-r--r--botan_version.py2
-rw-r--r--circle.yml20
-rwxr-xr-xconfigure.py237
-rw-r--r--doc/dev/build_log.rst252
-rw-r--r--doc/manual/bigint.rst10
-rw-r--r--doc/manual/building.rst50
-rw-r--r--doc/manual/ffi.rst23
-rw-r--r--doc/manual/filters.rst30
-rw-r--r--doc/manual/firststep.rst53
-rw-r--r--doc/manual/index.rst30
-rw-r--r--doc/manual/lowlevel.rst19
-rw-r--r--doc/manual/pbkdf.rst8
-rw-r--r--doc/manual/pubkey.rst10
-rw-r--r--doc/manual/python.rst4
-rw-r--r--doc/manual/secmem.rst2
-rw-r--r--doc/manual/tls.rst2
-rw-r--r--doc/manual/x509.rst2
-rw-r--r--doc/news.rst3272
-rw-r--r--doc/os.rst54
-rw-r--r--doc/pgpkey.txt37
-rw-r--r--doc/release_process.rst (renamed from doc/dev/release_process.rst)48
-rw-r--r--doc/relnotes/0_7_0.rst5
-rw-r--r--doc/relnotes/0_7_1.rst14
-rw-r--r--doc/relnotes/0_7_10.rst17
-rw-r--r--doc/relnotes/0_7_2.rst11
-rw-r--r--doc/relnotes/0_7_3.rst9
-rw-r--r--doc/relnotes/0_7_4.rst14
-rw-r--r--doc/relnotes/0_7_5.rst19
-rw-r--r--doc/relnotes/0_7_6.rst11
-rw-r--r--doc/relnotes/0_7_7.rst15
-rw-r--r--doc/relnotes/0_7_8.rst16
-rw-r--r--doc/relnotes/0_7_9.rst16
-rw-r--r--doc/relnotes/0_8_0.rst21
-rw-r--r--doc/relnotes/0_8_1.rst11
-rw-r--r--doc/relnotes/0_8_2.rst16
-rw-r--r--doc/relnotes/0_8_3.rst19
-rw-r--r--doc/relnotes/0_8_4.rst17
-rw-r--r--doc/relnotes/0_8_5.rst19
-rw-r--r--doc/relnotes/0_8_6.rst23
-rw-r--r--doc/relnotes/0_8_7.rst11
-rw-r--r--doc/relnotes/0_9_0.rst8
-rw-r--r--doc/relnotes/0_9_1.rst17
-rw-r--r--doc/relnotes/0_9_2.rst10
-rw-r--r--doc/relnotes/1_0_0.rst10
-rw-r--r--doc/relnotes/1_0_1.rst8
-rw-r--r--doc/relnotes/1_0_2.rst6
-rw-r--r--doc/relnotes/1_10_0.rst10
-rw-r--r--doc/relnotes/1_10_1.rst21
-rw-r--r--doc/relnotes/1_10_2.rst68
-rw-r--r--doc/relnotes/1_10_3.rst11
-rw-r--r--doc/relnotes/1_10_4.rst17
-rw-r--r--doc/relnotes/1_10_5.rst13
-rw-r--r--doc/relnotes/1_10_6.rst47
-rw-r--r--doc/relnotes/1_10_7.rst6
-rw-r--r--doc/relnotes/1_10_8.rst12
-rw-r--r--doc/relnotes/1_10_9.rst20
-rw-r--r--doc/relnotes/1_11_0.rst65
-rw-r--r--doc/relnotes/1_11_1.rst91
-rw-r--r--doc/relnotes/1_11_10.rst81
-rw-r--r--doc/relnotes/1_11_11.rst28
-rw-r--r--doc/relnotes/1_11_12.rst21
-rw-r--r--doc/relnotes/1_11_13.rst43
-rw-r--r--doc/relnotes/1_11_14.rst83
-rw-r--r--doc/relnotes/1_11_15.rst19
-rw-r--r--doc/relnotes/1_11_16.rst38
-rw-r--r--doc/relnotes/1_11_17.rst16
-rw-r--r--doc/relnotes/1_11_2.rst47
-rw-r--r--doc/relnotes/1_11_3.rst30
-rw-r--r--doc/relnotes/1_11_4.rst37
-rw-r--r--doc/relnotes/1_11_5.rst53
-rw-r--r--doc/relnotes/1_11_6.rst27
-rw-r--r--doc/relnotes/1_11_7.rst23
-rw-r--r--doc/relnotes/1_11_8.rst56
-rw-r--r--doc/relnotes/1_11_9.rst37
-rw-r--r--doc/relnotes/1_1_0.rst20
-rw-r--r--doc/relnotes/1_1_1.rst15
-rw-r--r--doc/relnotes/1_1_10.rst13
-rw-r--r--doc/relnotes/1_1_11.rst11
-rw-r--r--doc/relnotes/1_1_12.rst12
-rw-r--r--doc/relnotes/1_1_13.rst16
-rw-r--r--doc/relnotes/1_1_2.rst17
-rw-r--r--doc/relnotes/1_1_3.rst15
-rw-r--r--doc/relnotes/1_1_4.rst14
-rw-r--r--doc/relnotes/1_1_5.rst8
-rw-r--r--doc/relnotes/1_1_6.rst10
-rw-r--r--doc/relnotes/1_1_7.rst8
-rw-r--r--doc/relnotes/1_1_8.rst13
-rw-r--r--doc/relnotes/1_1_9.rst10
-rw-r--r--doc/relnotes/1_2_0.rst9
-rw-r--r--doc/relnotes/1_2_1.rst10
-rw-r--r--doc/relnotes/1_2_2.rst13
-rw-r--r--doc/relnotes/1_2_3.rst14
-rw-r--r--doc/relnotes/1_2_4.rst8
-rw-r--r--doc/relnotes/1_2_5.rst23
-rw-r--r--doc/relnotes/1_2_6.rst10
-rw-r--r--doc/relnotes/1_2_7.rst15
-rw-r--r--doc/relnotes/1_2_8.rst5
-rw-r--r--doc/relnotes/1_3_0.rst11
-rw-r--r--doc/relnotes/1_3_1.rst7
-rw-r--r--doc/relnotes/1_3_10.rst10
-rw-r--r--doc/relnotes/1_3_11.rst12
-rw-r--r--doc/relnotes/1_3_12.rst15
-rw-r--r--doc/relnotes/1_3_13.rst9
-rw-r--r--doc/relnotes/1_3_14.rst26
-rw-r--r--doc/relnotes/1_3_2.rst21
-rw-r--r--doc/relnotes/1_3_3.rst18
-rw-r--r--doc/relnotes/1_3_4.rst11
-rw-r--r--doc/relnotes/1_3_5.rst21
-rw-r--r--doc/relnotes/1_3_6.rst8
-rw-r--r--doc/relnotes/1_3_7.rst13
-rw-r--r--doc/relnotes/1_3_8.rst26
-rw-r--r--doc/relnotes/1_3_9.rst10
-rw-r--r--doc/relnotes/1_4_0.rst12
-rw-r--r--doc/relnotes/1_4_1.rst11
-rw-r--r--doc/relnotes/1_4_10.rst20
-rw-r--r--doc/relnotes/1_4_11.rst12
-rw-r--r--doc/relnotes/1_4_12.rst8
-rw-r--r--doc/relnotes/1_4_2.rst14
-rw-r--r--doc/relnotes/1_4_3.rst10
-rw-r--r--doc/relnotes/1_4_4.rst9
-rw-r--r--doc/relnotes/1_4_5.rst15
-rw-r--r--doc/relnotes/1_4_6.rst10
-rw-r--r--doc/relnotes/1_4_7.rst17
-rw-r--r--doc/relnotes/1_4_8.rst9
-rw-r--r--doc/relnotes/1_4_9.rst17
-rw-r--r--doc/relnotes/1_5_0.rst13
-rw-r--r--doc/relnotes/1_5_1.rst15
-rw-r--r--doc/relnotes/1_5_10.rst14
-rw-r--r--doc/relnotes/1_5_11.rst11
-rw-r--r--doc/relnotes/1_5_12.rst10
-rw-r--r--doc/relnotes/1_5_13.rst6
-rw-r--r--doc/relnotes/1_5_2.rst18
-rw-r--r--doc/relnotes/1_5_3.rst14
-rw-r--r--doc/relnotes/1_5_4.rst19
-rw-r--r--doc/relnotes/1_5_5.rst13
-rw-r--r--doc/relnotes/1_5_6.rst10
-rw-r--r--doc/relnotes/1_5_7.rst8
-rw-r--r--doc/relnotes/1_5_8.rst13
-rw-r--r--doc/relnotes/1_5_9.rst13
-rw-r--r--doc/relnotes/1_6_0.rst6
-rw-r--r--doc/relnotes/1_6_1.rst8
-rw-r--r--doc/relnotes/1_6_2.rst7
-rw-r--r--doc/relnotes/1_6_3.rst6
-rw-r--r--doc/relnotes/1_6_4.rst5
-rw-r--r--doc/relnotes/1_6_5.rst6
-rw-r--r--doc/relnotes/1_7_0.rst11
-rw-r--r--doc/relnotes/1_7_1.rst10
-rw-r--r--doc/relnotes/1_7_10.rst12
-rw-r--r--doc/relnotes/1_7_11.rst13
-rw-r--r--doc/relnotes/1_7_12.rst19
-rw-r--r--doc/relnotes/1_7_13.rst9
-rw-r--r--doc/relnotes/1_7_14.rst11
-rw-r--r--doc/relnotes/1_7_15.rst11
-rw-r--r--doc/relnotes/1_7_16.rst12
-rw-r--r--doc/relnotes/1_7_17.rst10
-rw-r--r--doc/relnotes/1_7_18.rst11
-rw-r--r--doc/relnotes/1_7_19.rst10
-rw-r--r--doc/relnotes/1_7_2.rst11
-rw-r--r--doc/relnotes/1_7_20.rst8
-rw-r--r--doc/relnotes/1_7_21.rst9
-rw-r--r--doc/relnotes/1_7_22.rst10
-rw-r--r--doc/relnotes/1_7_23.rst15
-rw-r--r--doc/relnotes/1_7_24.rst15
-rw-r--r--doc/relnotes/1_7_3.rst12
-rw-r--r--doc/relnotes/1_7_4.rst11
-rw-r--r--doc/relnotes/1_7_5.rst14
-rw-r--r--doc/relnotes/1_7_6.rst12
-rw-r--r--doc/relnotes/1_7_7.rst14
-rw-r--r--doc/relnotes/1_7_8.rst12
-rw-r--r--doc/relnotes/1_7_9.rst9
-rw-r--r--doc/relnotes/1_8_0.rst6
-rw-r--r--doc/relnotes/1_8_1.rst8
-rw-r--r--doc/relnotes/1_8_10.rst11
-rw-r--r--doc/relnotes/1_8_11.rst10
-rw-r--r--doc/relnotes/1_8_12.rst14
-rw-r--r--doc/relnotes/1_8_13.rst7
-rw-r--r--doc/relnotes/1_8_14.rst17
-rw-r--r--doc/relnotes/1_8_2.rst8
-rw-r--r--doc/relnotes/1_8_3.rst14
-rw-r--r--doc/relnotes/1_8_4.rst5
-rw-r--r--doc/relnotes/1_8_5.rst8
-rw-r--r--doc/relnotes/1_8_6.rst13
-rw-r--r--doc/relnotes/1_8_7.rst6
-rw-r--r--doc/relnotes/1_8_8.rst8
-rw-r--r--doc/relnotes/1_8_9.rst27
-rw-r--r--doc/relnotes/1_9_0.rst12
-rw-r--r--doc/relnotes/1_9_1.rst16
-rw-r--r--doc/relnotes/1_9_10.rst26
-rw-r--r--doc/relnotes/1_9_11.rst44
-rw-r--r--doc/relnotes/1_9_12.rst7
-rw-r--r--doc/relnotes/1_9_13.rst30
-rw-r--r--doc/relnotes/1_9_14.rst10
-rw-r--r--doc/relnotes/1_9_15.rst25
-rw-r--r--doc/relnotes/1_9_16.rst52
-rw-r--r--doc/relnotes/1_9_17.rst45
-rw-r--r--doc/relnotes/1_9_18.rst81
-rw-r--r--doc/relnotes/1_9_2.rst9
-rw-r--r--doc/relnotes/1_9_3.rst11
-rw-r--r--doc/relnotes/1_9_4.rst57
-rw-r--r--doc/relnotes/1_9_5.rst14
-rw-r--r--doc/relnotes/1_9_6.rst9
-rw-r--r--doc/relnotes/1_9_7.rst11
-rw-r--r--doc/relnotes/1_9_8.rst13
-rw-r--r--doc/relnotes/1_9_9.rst26
-rw-r--r--doc/relnotes/contents.rst8
-rw-r--r--doc/relnotes/index.rst277
-rw-r--r--doc/roadmap.rst (renamed from doc/dev/roadmap.rst)19
-rw-r--r--doc/todo.rst (renamed from doc/dev/todo.rst)27
-rw-r--r--doc/website/algos.rst104
-rw-r--r--doc/website/contents.rst17
-rw-r--r--doc/website/download.rst48
-rw-r--r--doc/website/index.rst29
-rw-r--r--doc/website/license.rst8
-rw-r--r--doc/website/manual.rst11
-rw-r--r--doc/website/pgpkey.rst43
-rw-r--r--doc/website/users.rst118
-rw-r--r--doc/website/vcs.rst41
-rw-r--r--readme.rst207
-rw-r--r--src/build-data/buildh.in3
-rw-r--r--src/build-data/cc/clang.txt29
-rw-r--r--src/build-data/cc/ekopath.txt15
-rw-r--r--src/build-data/cc/gcc.txt33
-rw-r--r--src/build-data/cc/hpcc.txt16
-rw-r--r--src/build-data/cc/icc.txt16
-rw-r--r--src/build-data/cc/msvc.txt22
-rw-r--r--src/build-data/cc/pgi.txt15
-rw-r--r--src/build-data/cc/sunstudio.txt16
-rw-r--r--src/build-data/cc/xlc.txt14
-rw-r--r--src/build-data/makefile/gmake.in19
-rw-r--r--src/build-data/makefile/gmake_dso.in12
-rw-r--r--src/build-data/makefile/header.in3
-rw-r--r--src/build-data/makefile/nmake.in29
-rw-r--r--src/build-data/makefile/python.in26
-rw-r--r--src/build-data/os/aix.txt1
-rw-r--r--src/build-data/os/android.txt14
-rw-r--r--src/build-data/os/cygwin.txt2
-rw-r--r--src/build-data/os/darwin.txt6
-rw-r--r--src/build-data/os/freebsd.txt2
-rw-r--r--src/build-data/os/haiku.txt1
-rw-r--r--src/build-data/os/hpux.txt3
-rw-r--r--src/build-data/os/irix.txt1
-rw-r--r--src/build-data/os/linux.txt6
-rw-r--r--src/build-data/os/mingw.txt6
-rw-r--r--src/build-data/os/netbsd.txt2
-rw-r--r--src/build-data/os/openbsd.txt1
-rw-r--r--src/build-data/os/qnx.txt1
-rw-r--r--src/build-data/os/solaris.txt1
-rw-r--r--src/build-data/os/windows.txt5
-rw-r--r--src/build-data/sphinx/conf.py5
-rw-r--r--src/cmd/apps.h1
-rw-r--r--src/cmd/asn1.cpp4
-rw-r--r--src/cmd/base64.cpp4
-rw-r--r--src/cmd/bcrypt.cpp1
-rw-r--r--src/cmd/ca.cpp2
-rw-r--r--src/cmd/cert_verify.cpp6
-rw-r--r--src/cmd/compress.cpp4
-rw-r--r--src/cmd/credentials.h9
-rw-r--r--src/cmd/dsa_sign.cpp1
-rw-r--r--src/cmd/factor.cpp4
-rw-r--r--src/cmd/fpe.cpp5
-rw-r--r--src/cmd/fuzzer.cpp141
-rw-r--r--src/cmd/hash.cpp5
-rw-r--r--src/cmd/implementation/speed.h28
-rw-r--r--src/cmd/implementation/speed_prime.cpp96
-rw-r--r--src/cmd/implementation/speed_public_key.cpp (renamed from src/cmd/speed_pk.cpp)30
-rw-r--r--src/cmd/implementation/speed_transform.cpp67
-rw-r--r--src/cmd/implementation/timer.cpp (renamed from src/cmd/timer.cpp)0
-rw-r--r--src/cmd/implementation/timer.h (renamed from src/cmd/timer.h)0
-rw-r--r--src/cmd/is_prime.cpp5
-rw-r--r--src/cmd/keygen.cpp7
-rw-r--r--src/cmd/pkcs10.cpp11
-rw-r--r--src/cmd/self_sig.cpp12
-rw-r--r--src/cmd/speed.cpp106
-rw-r--r--src/cmd/speed.h16
-rw-r--r--src/cmd/tls_client.cpp7
-rw-r--r--src/cmd/tls_server.cpp5
-rw-r--r--src/lib/alloc/locking_allocator/info.txt1
-rw-r--r--src/lib/alloc/locking_allocator/locking_allocator.cpp5
-rw-r--r--src/lib/asn1/alg_id.h4
-rw-r--r--src/lib/asn1/asn1_alt_name.h4
-rw-r--r--src/lib/asn1/asn1_attribute.h4
-rw-r--r--src/lib/asn1/asn1_obj.cpp4
-rw-r--r--src/lib/asn1/asn1_obj.h12
-rw-r--r--src/lib/asn1/asn1_oid.h4
-rw-r--r--src/lib/asn1/asn1_str.h4
-rw-r--r--src/lib/asn1/asn1_time.cpp349
-rw-r--r--src/lib/asn1/asn1_time.h41
-rw-r--r--src/lib/asn1/ber_dec.cpp12
-rw-r--r--src/lib/asn1/x509_dn.h4
-rw-r--r--src/lib/base/algo_registry.h10
-rw-r--r--src/lib/base/init.h2
-rw-r--r--src/lib/base/transform.h2
-rw-r--r--src/lib/block/aes/aes.h36
-rw-r--r--src/lib/block/aes_ni/aes_ni.h42
-rw-r--r--src/lib/block/aes_ssse3/aes_ssse3.h36
-rw-r--r--src/lib/block/block_cipher.h4
-rw-r--r--src/lib/block/block_utils.h5
-rw-r--r--src/lib/block/blowfish/blowfish.cpp8
-rw-r--r--src/lib/block/blowfish/blowfish.h12
-rw-r--r--src/lib/block/camellia/camellia.h36
-rw-r--r--src/lib/block/cascade/cascade.h16
-rw-r--r--src/lib/block/cast/cast128.h12
-rw-r--r--src/lib/block/cast/cast256.h12
-rw-r--r--src/lib/block/des/des.h24
-rw-r--r--src/lib/block/des/desx.h12
-rw-r--r--src/lib/block/gost_28147/gost_28147.h12
-rw-r--r--src/lib/block/idea/idea.h12
-rw-r--r--src/lib/block/idea_sse2/idea_sse2.h8
-rw-r--r--src/lib/block/kasumi/kasumi.h12
-rw-r--r--src/lib/block/lion/lion.h2
-rw-r--r--src/lib/block/mars/mars.h12
-rw-r--r--src/lib/block/misty1/misty1.h12
-rw-r--r--src/lib/block/noekeon/noekeon.h12
-rw-r--r--src/lib/block/noekeon_simd/noekeon_simd.h8
-rw-r--r--src/lib/block/rc2/rc2.h12
-rw-r--r--src/lib/block/rc5/rc5.h12
-rw-r--r--src/lib/block/rc6/rc6.h12
-rw-r--r--src/lib/block/safer/safer_sk.h12
-rw-r--r--src/lib/block/seed/seed.h12
-rw-r--r--src/lib/block/serpent/serpent.h12
-rw-r--r--src/lib/block/serpent_simd/serp_simd.h8
-rw-r--r--src/lib/block/serpent_x86_32/info.txt12
-rw-r--r--src/lib/block/serpent_x86_32/serp_x86_32.cpp90
-rw-r--r--src/lib/block/serpent_x86_32/serp_x86_32.h31
-rw-r--r--src/lib/block/serpent_x86_32/serp_x86_32_imp.S669
-rw-r--r--src/lib/block/tea/tea.h12
-rw-r--r--src/lib/block/threefish_avx2/info.txt4
-rw-r--r--src/lib/block/twofish/twofish.h12
-rw-r--r--src/lib/block/xtea/xtea.h12
-rw-r--r--src/lib/block/xtea_simd/xtea_simd.h8
-rw-r--r--src/lib/cert/cvc/cvc_self.h1
-rw-r--r--src/lib/cert/cvc/signed_obj.h1
-rw-r--r--src/lib/cert/x509/certstor.cpp4
-rw-r--r--src/lib/cert/x509/crl_ent.h4
-rw-r--r--src/lib/cert/x509/pkcs10.h3
-rw-r--r--src/lib/cert/x509/x509_ca.h1
-rw-r--r--src/lib/cert/x509/x509_crl.cpp8
-rw-r--r--src/lib/cert/x509/x509_crl.h2
-rw-r--r--src/lib/cert/x509/x509_ext.cpp4
-rw-r--r--src/lib/cert/x509/x509_ext.h153
-rw-r--r--src/lib/cert/x509/x509cert.cpp4
-rw-r--r--src/lib/cert/x509/x509cert.h6
-rw-r--r--src/lib/cert/x509/x509opt.cpp4
-rw-r--r--src/lib/cert/x509/x509path.cpp4
-rw-r--r--src/lib/cert/x509/x509path.h2
-rw-r--r--src/lib/cert/x509/x509self.h1
-rw-r--r--src/lib/codec/base64/base64.cpp10
-rw-r--r--src/lib/compression/compress_utils.h2
-rw-r--r--src/lib/credentials/credentials_manager.h22
-rw-r--r--src/lib/entropy/beos_stats/es_beos.h4
-rw-r--r--src/lib/entropy/cryptoapi_rng/es_capi.h4
-rw-r--r--src/lib/entropy/dev_random/dev_random.h4
-rw-r--r--src/lib/entropy/dev_random/info.txt2
-rw-r--r--src/lib/entropy/egd/es_egd.h4
-rw-r--r--src/lib/entropy/egd/info.txt2
-rw-r--r--src/lib/entropy/hres_timer/hres_timer.h4
-rw-r--r--src/lib/entropy/proc_walk/info.txt2
-rw-r--r--src/lib/entropy/proc_walk/proc_walk.cpp2
-rw-r--r--src/lib/entropy/proc_walk/proc_walk.h4
-rw-r--r--src/lib/entropy/rdrand/rdrand.cpp2
-rw-r--r--src/lib/entropy/rdrand/rdrand.h4
-rw-r--r--src/lib/entropy/unix_procs/info.txt2
-rw-r--r--src/lib/entropy/unix_procs/unix_procs.cpp2
-rw-r--r--src/lib/entropy/unix_procs/unix_procs.h6
-rw-r--r--src/lib/entropy/win32_stats/es_win32.h4
-rw-r--r--src/lib/ffi/ffi.cpp13
-rw-r--r--src/lib/filters/basefilt.h16
-rw-r--r--src/lib/filters/codec_filt/b64_filt.cpp5
-rw-r--r--src/lib/filters/codec_filt/b64_filt.h12
-rw-r--r--src/lib/filters/codec_filt/hex_filt.h12
-rw-r--r--src/lib/filters/data_snk.h6
-rw-r--r--src/lib/filters/data_src.cpp28
-rw-r--r--src/lib/filters/data_src.h22
-rw-r--r--src/lib/filters/fd_unix/info.txt2
-rw-r--r--src/lib/filters/filters.h24
-rw-r--r--src/lib/filters/pipe.cpp4
-rw-r--r--src/lib/filters/pipe.h15
-rw-r--r--src/lib/filters/pipe_rw.cpp10
-rw-r--r--src/lib/filters/secqueue.cpp48
-rw-r--r--src/lib/filters/secqueue.h23
-rw-r--r--src/lib/hash/checksum/adler32/adler32.h12
-rw-r--r--src/lib/hash/checksum/crc24/crc24.h12
-rw-r--r--src/lib/hash/checksum/crc32/crc32.h12
-rw-r--r--src/lib/hash/comb4p/comb4p.h14
-rw-r--r--src/lib/hash/gost_3411/gost_3411.h14
-rw-r--r--src/lib/hash/has160/has160.h14
-rw-r--r--src/lib/hash/keccak/keccak.h14
-rw-r--r--src/lib/hash/md2/md2.h14
-rw-r--r--src/lib/hash/md4/md4.h12
-rw-r--r--src/lib/hash/md4_x86_32/info.txt12
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32.cpp37
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32.h28
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32_imp.S137
-rw-r--r--src/lib/hash/md5/md5.h12
-rw-r--r--src/lib/hash/md5_x86_32/info.txt12
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32.cpp34
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32.h28
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32_imp.S166
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.h8
-rw-r--r--src/lib/hash/par_hash/par_hash.h12
-rw-r--r--src/lib/hash/rmd128/rmd128.h12
-rw-r--r--src/lib/hash/rmd160/rmd160.h12
-rw-r--r--src/lib/hash/sha1/sha160.h12
-rw-r--r--src/lib/hash/sha1_sse2/sha1_sse2.h4
-rw-r--r--src/lib/hash/sha1_x86_32/info.txt12
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32.cpp34
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32.h31
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S244
-rw-r--r--src/lib/hash/sha1_x86_64/info.txt12
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64.cpp34
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64.h28
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S266
-rw-r--r--src/lib/hash/sha2_32/sha2_32.h24
-rw-r--r--src/lib/hash/sha2_64/sha2_64.h36
-rw-r--r--src/lib/hash/skein/skein_512.h16
-rw-r--r--src/lib/hash/tiger/tiger.h12
-rw-r--r--src/lib/hash/whirlpool/whrlpool.h12
-rw-r--r--src/lib/kdf/hkdf/hkdf.h4
-rw-r--r--src/lib/kdf/prf_tls/prf_tls.h8
-rw-r--r--src/lib/kdf/prf_x942/prf_x942.h4
-rw-r--r--src/lib/mac/cbc_mac/cbc_mac.h16
-rw-r--r--src/lib/mac/cmac/cmac.h16
-rw-r--r--src/lib/mac/hmac/hmac.h16
-rw-r--r--src/lib/mac/info.txt2
-rw-r--r--src/lib/mac/mac.h6
-rw-r--r--src/lib/mac/poly1305/poly1305.cpp2
-rw-r--r--src/lib/mac/poly1305/poly1305.h14
-rw-r--r--src/lib/mac/siphash/siphash.h16
-rw-r--r--src/lib/mac/x919_mac/x919_mac.h16
-rw-r--r--src/lib/math/bigint/big_rand.cpp29
-rw-r--r--src/lib/math/bigint/bigint.cpp21
-rw-r--r--src/lib/math/bigint/bigint.h28
-rw-r--r--src/lib/math/ec_gfp/curve_gfp.cpp172
-rw-r--r--src/lib/math/ec_gfp/curve_gfp.h14
-rw-r--r--src/lib/math/ec_gfp/curve_nistp.cpp137
-rw-r--r--src/lib/math/ec_gfp/curve_nistp.h152
-rw-r--r--src/lib/math/ec_gfp/info.txt9
-rw-r--r--src/lib/math/ec_gfp/point_gfp.cpp328
-rw-r--r--src/lib/math/ec_gfp/point_gfp.h51
-rw-r--r--src/lib/math/mp/mp_asm.cpp4
-rw-r--r--src/lib/math/mp/mp_comba.cpp4
-rw-r--r--src/lib/math/mp/mp_core.h4
-rw-r--r--src/lib/math/mp/mp_generic/mp_asmi.h4
-rw-r--r--src/lib/math/mp/mp_generic/mp_madd.h4
-rw-r--r--src/lib/math/mp/mp_karat.cpp4
-rw-r--r--src/lib/math/mp/mp_misc.cpp4
-rw-r--r--src/lib/math/mp/mp_monty.cpp4
-rw-r--r--src/lib/math/mp/mp_mulop.cpp4
-rw-r--r--src/lib/math/mp/mp_shift.cpp4
-rw-r--r--src/lib/math/mp/mp_x86_32/mp_asmi.h4
-rw-r--r--src/lib/math/mp/mp_x86_32/mp_madd.h4
-rw-r--r--src/lib/math/mp/mp_x86_32_msvc/mp_asmi.h4
-rw-r--r--src/lib/math/mp/mp_x86_64/mp_asmi.h4
-rw-r--r--src/lib/math/mp/mp_x86_64/mp_madd.h4
-rw-r--r--src/lib/math/numbertheory/def_powm.h16
-rw-r--r--src/lib/math/numbertheory/info.txt16
-rw-r--r--src/lib/math/numbertheory/mp_numth.cpp2
-rw-r--r--src/lib/math/numbertheory/pow_mod.cpp44
-rw-r--r--src/lib/math/numbertheory/pow_mod.h2
-rw-r--r--src/lib/misc/benchmark/benchmark.cpp18
-rw-r--r--src/lib/misc/openpgp/info.txt1
-rw-r--r--src/lib/misc/tss/info.txt2
-rw-r--r--src/lib/modes/aead/ccm/ccm.h4
-rw-r--r--src/lib/modes/aead/gcm/gcm.h7
-rw-r--r--src/lib/modes/aead/siv/info.txt5
-rw-r--r--src/lib/modes/cbc/cbc.cpp5
-rw-r--r--src/lib/modes/cbc/cbc.h4
-rw-r--r--src/lib/modes/cfb/cfb.h1
-rw-r--r--src/lib/modes/ecb/ecb.cpp5
-rw-r--r--src/lib/modes/info.txt2
-rw-r--r--src/lib/modes/mode_pad/mode_pad.h24
-rw-r--r--src/lib/modes/mode_utils.h6
-rw-r--r--src/lib/modes/stream_mode.h2
-rw-r--r--src/lib/modes/xts/xts.cpp3
-rw-r--r--src/lib/passhash/bcrypt/bcrypt.cpp4
-rw-r--r--src/lib/pbkdf/info.txt2
-rw-r--r--src/lib/pbkdf/pbkdf1/pbkdf1.cpp2
-rw-r--r--src/lib/pbkdf/pbkdf1/pbkdf1.h6
-rw-r--r--src/lib/pk_pad/eme_oaep/oaep.h7
-rw-r--r--src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp8
-rw-r--r--src/lib/pk_pad/eme_pkcs1/eme_pkcs.h6
-rw-r--r--src/lib/pk_pad/eme_raw/eme_raw.h8
-rw-r--r--src/lib/pk_pad/emsa1/emsa1.h8
-rw-r--r--src/lib/pk_pad/emsa1_bsi/emsa1_bsi.h2
-rw-r--r--src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp1
-rw-r--r--src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h16
-rw-r--r--src/lib/pk_pad/emsa_pssr/pssr.h8
-rw-r--r--src/lib/pk_pad/emsa_raw/emsa_raw.h8
-rw-r--r--src/lib/pk_pad/emsa_x931/emsa_x931.cpp1
-rw-r--r--src/lib/pk_pad/emsa_x931/emsa_x931.h8
-rw-r--r--src/lib/pk_pad/mgf1/mgf1.h1
-rw-r--r--src/lib/pk_pad/pad_utils.h1
-rw-r--r--src/lib/pubkey/curve25519/curve25519.cpp2
-rw-r--r--src/lib/pubkey/curve25519/curve25519.h2
-rw-r--r--src/lib/pubkey/dh/dh.cpp2
-rw-r--r--src/lib/pubkey/dh/dh.h8
-rw-r--r--src/lib/pubkey/dl_algo/dl_algo.h11
-rw-r--r--src/lib/pubkey/dlies/dlies.h6
-rw-r--r--src/lib/pubkey/dsa/dsa.cpp6
-rw-r--r--src/lib/pubkey/dsa/dsa.h12
-rw-r--r--src/lib/pubkey/ec_group/ec_group.h2
-rw-r--r--src/lib/pubkey/ecc_key/ecc_key.h9
-rw-r--r--src/lib/pubkey/ecdh/ecdh.cpp2
-rw-r--r--src/lib/pubkey/ecdh/ecdh.h7
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.cpp34
-rw-r--r--src/lib/pubkey/ecdsa/ecdsa.h11
-rw-r--r--src/lib/pubkey/ecdsa/info.txt1
-rw-r--r--src/lib/pubkey/elgamal/elgamal.cpp3
-rw-r--r--src/lib/pubkey/elgamal/elgamal.h8
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp40
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.h14
-rw-r--r--src/lib/pubkey/if_algo/if_algo.h13
-rw-r--r--src/lib/pubkey/mce/code_based_key_gen.cpp2
-rw-r--r--src/lib/pubkey/mce/mceliece.h8
-rw-r--r--src/lib/pubkey/mce/mceliece_key.cpp2
-rw-r--r--src/lib/pubkey/mce/mceliece_key.h18
-rw-r--r--src/lib/pubkey/mce/polyn_gf2m.cpp4
-rw-r--r--src/lib/pubkey/mceies/info.txt2
-rw-r--r--src/lib/pubkey/mceies/mceies.cpp11
-rw-r--r--src/lib/pubkey/nr/nr.h12
-rw-r--r--src/lib/pubkey/pk_keys.h2
-rw-r--r--src/lib/pubkey/pk_utils.h1
-rw-r--r--src/lib/pubkey/pubkey.h6
-rw-r--r--src/lib/pubkey/rsa/rsa.cpp12
-rw-r--r--src/lib/pubkey/rsa/rsa.h4
-rw-r--r--src/lib/pubkey/rw/rw.cpp6
-rw-r--r--src/lib/pubkey/rw/rw.h4
-rw-r--r--src/lib/rng/auto_rng/auto_rng.h12
-rw-r--r--src/lib/rng/hmac_drbg/hmac_drbg.h12
-rw-r--r--src/lib/rng/rng.h42
-rw-r--r--src/lib/rng/system_rng/info.txt2
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp12
-rw-r--r--src/lib/rng/x931_rng/x931_rng.h12
-rw-r--r--src/lib/stream/chacha/chacha.h16
-rw-r--r--src/lib/stream/ctr/ctr.h16
-rw-r--r--src/lib/stream/ofb/ofb.h16
-rw-r--r--src/lib/stream/rc4/rc4.h12
-rw-r--r--src/lib/stream/salsa20/salsa20.h16
-rw-r--r--src/lib/tls/msg_server_hello.cpp2
-rw-r--r--src/lib/tls/tls_client.cpp2
-rw-r--r--src/lib/tls/tls_extensions.h60
-rw-r--r--src/lib/tls/tls_messages.h1
-rw-r--r--src/lib/utils/asm_x86_32/asm_x86_32.h128
-rw-r--r--src/lib/utils/asm_x86_32/info.txt25
-rw-r--r--src/lib/utils/asm_x86_64/asm_x86_64.h127
-rw-r--r--src/lib/utils/asm_x86_64/info.txt23
-rw-r--r--src/lib/utils/calendar.cpp142
-rw-r--r--src/lib/utils/calendar.h28
-rw-r--r--src/lib/utils/cpuid.cpp2
-rw-r--r--src/lib/utils/dyn_load/info.txt2
-rw-r--r--src/lib/utils/exceptn.h31
-rw-r--r--src/lib/utils/filesystem.cpp129
-rw-r--r--src/lib/utils/filesystem.h (renamed from src/lib/utils/fs.h)8
-rw-r--r--src/lib/utils/fs.cpp86
-rw-r--r--src/lib/utils/info.txt24
-rw-r--r--src/lib/utils/parsing.cpp29
-rw-r--r--src/lib/utils/rounding.h11
-rw-r--r--src/lib/utils/stl_util.h7
-rw-r--r--src/lib/utils/types.h36
-rw-r--r--src/lib/vendor/boost/info.txt1
-rw-r--r--src/lib/vendor/openssl/openssl_rsa.cpp6
-rwxr-xr-xsrc/ocaml/build.sh3
-rwxr-xr-xsrc/scripts/ci/after_success.sh13
-rw-r--r--src/scripts/ci/appveyor.yml10
-rwxr-xr-xsrc/scripts/ci/build.sh41
-rwxr-xr-xsrc/scripts/ci/circle/clang-shared-debug.sh10
-rwxr-xr-xsrc/scripts/ci/circle/clang-static-debug.sh10
-rwxr-xr-xsrc/scripts/ci/circle/gcc-shared-debug.sh10
-rwxr-xr-xsrc/scripts/ci/circle/gcc-static-debug.sh10
-rwxr-xr-xsrc/scripts/ci/install.sh11
-rwxr-xr-xsrc/scripts/ci/setup.sh23
-rwxr-xr-xsrc/scripts/comba.py4
-rwxr-xr-xsrc/scripts/combine_relnotes.py89
-rwxr-xr-xsrc/scripts/dist.py132
-rwxr-xr-xsrc/scripts/install.py52
-rwxr-xr-xsrc/scripts/show_dependencies.py62
-rwxr-xr-xsrc/scripts/update_docs.py100
-rwxr-xr-xsrc/scripts/website.sh27
-rw-r--r--src/tests/catchy/catch.hpp9416
-rw-r--r--src/tests/catchy/catchy_tests.h128
-rw-r--r--src/tests/catchy/test_base.cpp25
-rw-r--r--src/tests/catchy/test_base64.cpp232
-rw-r--r--src/tests/catchy/test_bigint.cpp169
-rw-r--r--src/tests/catchy/test_cvc.cpp40
-rw-r--r--src/tests/catchy/test_stl_util.cpp21
-rw-r--r--src/tests/catchy/test_utils.cpp195
-rw-r--r--src/tests/catchy/test_x509.cpp142
-rw-r--r--src/tests/data/fuzz/x509/afl_000.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_001.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_002.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_003.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_004.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_005.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_006.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_007.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_008.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_009.pem14
-rw-r--r--src/tests/data/fuzz/x509/afl_010.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_011.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_012.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_013.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_014.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_015.pem5
-rw-r--r--src/tests/data/fuzz/x509/afl_016.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_017.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_018.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_019.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_020.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_021.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_022.pem12
-rw-r--r--src/tests/data/fuzz/x509/afl_023.pem13
-rw-r--r--src/tests/data/fuzz/x509/afl_024.pem3
-rw-r--r--src/tests/data/fuzz/x509/afl_025.pem3
-rw-r--r--src/tests/data/fuzz/x509/afl_026.pembin0 -> 35 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_027.pembin0 -> 10 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_028.pembin0 -> 22 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_029.pembin0 -> 60 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_030.pem1
-rw-r--r--src/tests/data/fuzz/x509/afl_031.pem1
-rw-r--r--src/tests/data/fuzz/x509/afl_032.pembin0 -> 134 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_033.pembin0 -> 134 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_034.pem4
-rw-r--r--src/tests/data/fuzz/x509/afl_035.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_036.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_037.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_038.pembin0 -> 634 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_039.pembin0 -> 631 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_040.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_041.pembin0 -> 637 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_042.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_043.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_044.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_045.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_046.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_047.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_048.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_049.pembin0 -> 639 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_050.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_051.pembin0 -> 624 bytes
-rw-r--r--src/tests/data/fuzz/x509/afl_052.pembin0 -> 624 bytes
-rw-r--r--src/tests/nist_x509.cpp34
-rw-r--r--src/tests/outdata/.gitkeep0
-rw-r--r--src/tests/test_aead.cpp12
-rw-r--r--src/tests/test_bigint.cpp152
-rw-r--r--src/tests/test_block.cpp2
-rw-r--r--src/tests/test_c25519.cpp78
-rw-r--r--src/tests/test_compression.cpp9
-rw-r--r--src/tests/test_cvc.cpp16
-rw-r--r--src/tests/test_dh.cpp13
-rw-r--r--src/tests/test_dlies.cpp35
-rw-r--r--src/tests/test_dsa.cpp12
-rw-r--r--src/tests/test_ecc_pointmul.cpp83
-rw-r--r--src/tests/test_ecdsa.cpp65
-rw-r--r--src/tests/test_elg.cpp26
-rw-r--r--src/tests/test_ffi.cpp397
-rw-r--r--src/tests/test_fuzzer.cpp68
-rw-r--r--src/tests/test_gost_3410.cpp13
-rw-r--r--src/tests/test_hash.cpp2
-rw-r--r--src/tests/test_kdf.cpp10
-rw-r--r--src/tests/test_mac.cpp10
-rw-r--r--src/tests/test_mceliece.cpp38
-rw-r--r--src/tests/test_modes.cpp18
-rw-r--r--src/tests/test_nr.cpp22
-rw-r--r--src/tests/test_ocb.cpp21
-rw-r--r--src/tests/test_pbkdf.cpp10
-rw-r--r--src/tests/test_pubkey.cpp19
-rw-r--r--src/tests/test_rng.cpp2
-rw-r--r--src/tests/test_rng.h12
-rw-r--r--src/tests/test_rsa.cpp14
-rw-r--r--src/tests/test_rw.cpp24
-rw-r--r--src/tests/test_srp6.cpp9
-rw-r--r--src/tests/test_stream.cpp8
-rw-r--r--src/tests/test_tss.cpp16
-rw-r--r--src/tests/tests.cpp57
-rw-r--r--src/tests/tests.h111
-rw-r--r--src/tests/unit_ecc.cpp67
-rw-r--r--src/tests/unit_ecdsa.cpp48
-rw-r--r--src/tests/unit_tls.cpp34
-rw-r--r--src/tests/unit_x509.cpp46
681 files changed, 19186 insertions, 9439 deletions
diff --git a/.gitignore b/.gitignore
index 5275cc126..16046cd27 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,9 +14,27 @@ botan-test
# Text file backups (e.g. gedit, joe)
*~
+\#*\#
+.\#*
+
+# Patch files
+*.patch
+*.diff
+*.orig
+*.rej
+
+# Python cache
+*.pyc
# Amalgamation code
botan_all.h
botan_all_internal.h
botan_all.cpp
botan_all_*.cpp
+
+# Coverage output
+coverage.info
+coverage/
+
+# Test output
+src/tests/outdata/*.pem
diff --git a/.travis.yml b/.travis.yml
index 35f374658..3044c8dfd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,19 @@
language: cpp
+# BEGIN BUILD MATRIX
+#
+# Build matrix must be smaller on branch coverity_scan because quota allows
+# only 5 Coverity Scan jobs at once. Thus we have different versions of this
+# file on branch master and coverity_scan.
+#
+# Please keep this file as much in sync as possible to allow easy merging
+# from master into coverity_scan and only have differences in the build
+# matrix block.
+#
+# Check the difference as follows:
+# $ git checkout master
+# $ git checkout coverity_scan
+# $ git difftool master coverity_scan .travis.yml
os:
- linux
- osx
@@ -10,36 +24,59 @@ compiler:
env:
matrix:
- - BUILD_MODE="shared"
- - BUILD_MODE="static"
- - BUILD_MODE="coverage"
+ - MODULES="all" BUILD_MODE="shared"
+ - MODULES="all" BUILD_MODE="static"
+ - MODULES="all" BUILD_MODE="coverage"
+ - MODULES="all" BUILD_MODE="sanitizer"
+
+ - MODULES="min" BUILD_MODE="shared"
+ - MODULES="min" BUILD_MODE="static"
matrix:
exclude:
- os: osx
compiler: gcc
- compiler: clang
- env: BUILD_MODE="coverage"
+ env: MODULES="all" BUILD_MODE="coverage"
+ - compiler: clang
+ env: MODULES="all" BUILD_MODE="sanitizer"
+ - compiler: clang
+ env: MODULES="min" BUILD_MODE="shared"
+ - compiler: clang
+ env: MODULES="min" BUILD_MODE="static"
+# END BUILD MATRIX
-sudo: required
+cache:
+ directories:
+ - $HOME/.ccache
install:
- - ./src/scripts/ci/setup.sh
+ - ./src/scripts/ci/install.sh
script:
- - ./src/scripts/ci/build.sh
+ - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./src/scripts/ci/build.sh ; fi
after_success:
- ./src/scripts/ci/after_success.sh
notifications:
addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - ccache
+ - g++-4.8
+ - libssl-dev
+ - libsqlite3-dev
+ - zlib1g-dev
+
coverity_scan:
project:
name: "randombit/botan"
notification_email: [email protected]
- build_command_prepend: "./configure.py"
- build_command: "make -j4"
+ build_command_prepend: "./configure.py --cc-bin=/usr/bin/g++-4.8"
+ build_command: "make -j2"
branch_pattern: coverity_scan
diff --git a/botan_version.py b/botan_version.py
index b6d3e56a5..130f26c9b 100644
--- a/botan_version.py
+++ b/botan_version.py
@@ -1,7 +1,7 @@
release_major = 1
release_minor = 11
-release_patch = 17
+release_patch = 20
release_so_abi_rev = release_patch
# These are set by the distribution script
diff --git a/circle.yml b/circle.yml
new file mode 100644
index 000000000..5355df733
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,20 @@
+dependencies:
+ pre:
+ - sudo add-apt-repository -y 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.6 main'
+ - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+ - wget -q -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
+ - sudo apt-get update -qq
+ override:
+ - sudo apt-get install g++-4.8 clang-3.6
+ post:
+ - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 99
+ - sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 99
+ - g++ --version
+ - clang++ --version
+
+test:
+ override:
+ - runall() { for f in "$@"; do bash $f; done }; runall:
+ parallel: true
+ files:
+ - src/scripts/ci/circle/*.sh
diff --git a/configure.py b/configure.py
index b04793877..7622a8991 100755
--- a/configure.py
+++ b/configure.py
@@ -4,14 +4,12 @@
Configuration program for botan
(C) 2009,2010,2011,2012,2013,2014,2015 Jack Lloyd
+(C) 2015 Simon Warta (Kullo GmbH)
Botan is released under the Simplified BSD License (see license.txt)
-Tested with CPython 2.6, 2.7, and 3.3
-
-CPython 2.5 and earlier are not supported
-
-Jython - Target detection does not work (use --os and --cpu)
+Tested with CPython 2.7 and 3.4. CPython 2.6 and earlier are not supported.
+On Jython target detection does not work (use --os and --cpu).
"""
import sys
@@ -42,19 +40,6 @@ def chunks(l, n):
for i in range(0, len(l), n):
yield l[i:i+n]
-def is_official_release():
- # Assume a release date implies official release
- return (botan_version.release_datestamp > 20130000)
-
-def default_build_mode():
- if os.getenv('CONTINUOUS_INTEGRATION') == 'true' or \
- os.getenv('GO_ENVIRONMENT_NAME') == 'Botan':
- return 'maintainer'
-
- if is_official_release():
- return 'release'
- return 'debug'
-
def get_vc_revision():
def get_vc_revision(cmdlist):
@@ -84,15 +69,12 @@ def get_vc_revision():
logging.debug('Error getting rev from %s - %s' % (cmdname, e))
return None
- vc_commands = [['mtn', 'automate', 'heads'],
- ['git', 'rev-parse', 'HEAD']]
-
- for vc_cmd in vc_commands:
- rev = get_vc_revision(vc_cmd)
- if rev is not None:
- return rev
-
- return 'unknown'
+ vc_command = ['git', 'rev-parse', 'HEAD']
+ rev = get_vc_revision(vc_command)
+ if rev is not None:
+ return rev
+ else:
+ return 'unknown'
class BuildConfigurationInformation(object):
@@ -138,10 +120,8 @@ class BuildConfigurationInformation(object):
if options.via_amalgamation:
self.build_sources = ['botan_all.cpp']
- self.build_internal_headers = []
else:
self.build_sources = self.sources
- self.build_internal_headers = self.internal_headers
self.public_headers = sorted(flatten([m.public_headers() for m in modules]))
@@ -280,10 +260,10 @@ def process_command_line(args):
build_group = optparse.OptionGroup(parser, 'Build options')
- modes = ['release', 'debug', 'coverage']
+ build_modes = ['release', 'debug', 'coverage', 'sanitizer']
build_group.add_option('--build-mode', default='release', metavar='MODE',
- choices=modes,
- help="Build mode (one of %s; default %%default)" % (', '.join(modes)))
+ choices=build_modes,
+ help="Build mode (one of %s; default %%default)" % (', '.join(build_modes)))
build_group.add_option('--debug-mode', action='store_const',
const='debug', dest='build_mode',
@@ -296,13 +276,6 @@ def process_command_line(args):
action='store_false',
help='disable building shared library')
- build_group.add_option('--enable-asm', dest='asm_ok',
- action='store_true', default=True,
- help=optparse.SUPPRESS_HELP)
- build_group.add_option('--disable-asm', dest='asm_ok',
- action='store_false',
- help='disallow use of assembler')
-
build_group.add_option('--no-optimizations', dest='no_optimizations',
action='store_true', default=False,
help=optparse.SUPPRESS_HELP)
@@ -322,8 +295,10 @@ def process_command_line(args):
build_group.add_option('--with-build-dir', metavar='DIR', default='',
help='setup the build in DIR')
+ link_methods = ['symlink', 'hardlink', 'copy']
build_group.add_option('--link-method', default=None, metavar='METHOD',
- help='choose how links are created')
+ choices=link_methods,
+ help='choose how links to include headers are created (%s)' % ', '.join(link_methods))
makefile_styles = ['gmake', 'nmake']
build_group.add_option('--makefile-style', metavar='STYLE', default=None,
@@ -428,7 +403,7 @@ def process_command_line(args):
parser.add_option_group(wrapper_group)
parser.add_option_group(install_group)
- # These exist only for autoconf compatability (requested by zw for mtn)
+ # These exist only for autoconf compatibility (requested by zw for mtn)
compat_with_autoconf_options = [
'datadir',
'datarootdir',
@@ -597,7 +572,7 @@ class ModuleInfo(object):
self.need_isa = self.need_isa.split(',')
if self.source == []:
- self.source = list(extract_files_matching(self.lives_in, ['.cpp', '.S']))
+ self.source = list(extract_files_matching(self.lives_in, ['.cpp']))
if self.header_internal == [] and self.header_public == []:
self.header_public = list(extract_files_matching(self.lives_in, ['.h']))
@@ -789,19 +764,22 @@ class ArchInfo(object):
class CompilerInfo(object):
def __init__(self, infofile):
lex_me_harder(infofile, self,
- ['so_link_flags', 'mach_opt', 'mach_abi_linking', 'isa_flags'],
+ ['so_link_commands', 'binary_link_commands', 'mach_opt', 'mach_abi_linking', 'isa_flags'],
{ 'binary_name': None,
+ 'linker_name': None,
'macro_name': None,
- 'compile_option': '-c ',
'output_to_option': '-o ',
'add_include_dir_option': '-I',
'add_lib_dir_option': '-L',
'add_lib_option': '-l',
- 'lib_opt_flags': '',
- 'app_opt_flags': '',
- 'debug_flags': '',
- 'no_debug_flags': '',
+ 'compile_flags_release': '',
+ 'compile_flags_debug': '',
+ 'lib_opt_flags_release': '',
+ 'lib_opt_flags_debug': '',
+ 'app_opt_flags_release': '',
+ 'app_opt_flags_debug': '',
'coverage_flags': '',
+ 'sanitizer_flags': '',
'shared_flags': '',
'lang_flags': '',
'warning_flags': '',
@@ -812,10 +790,12 @@ class CompilerInfo(object):
'makefile_style': ''
})
- self.so_link_flags = force_to_dict(self.so_link_flags)
- self.mach_abi_linking = force_to_dict(self.mach_abi_linking)
- self.isa_flags = force_to_dict(self.isa_flags)
+ self.so_link_commands = force_to_dict(self.so_link_commands)
+ self.binary_link_commands = force_to_dict(self.binary_link_commands)
+ self.mach_abi_linking = force_to_dict(self.mach_abi_linking)
+ self.isa_flags = force_to_dict(self.isa_flags)
+ self.infofile = infofile
self.mach_opt_flags = {}
while self.mach_opt != []:
@@ -886,6 +866,10 @@ class CompilerInfo(object):
if self.coverage_flags == '':
raise Exception('No coverage handling for %s' % (self.basename))
return ' ' + self.coverage_flags + ' ' + abi_flags
+ elif options.build_mode == 'sanitizer':
+ if self.sanitizer_flags == '':
+ raise Exception('No sanitizer handling for %s' % (self.basename))
+ return ' ' + self.sanitizer_flags + ' ' + abi_flags
return ' ' + abi_flags
@@ -895,18 +879,27 @@ class CompilerInfo(object):
def opt_flags(self, who, options):
def gen_flags():
if options.build_mode in ['debug', 'coverage']:
- yield self.debug_flags
+ yield self.compile_flags_debug
else:
- yield self.no_debug_flags
+ yield self.compile_flags_release
if options.no_optimizations or options.build_mode == 'coverage':
return
- if who != 'lib':
- yield self.app_opt_flags
+ if who == 'app':
+ if options.build_mode == 'release':
+ yield self.app_opt_flags_release
+ else:
+ yield self.app_opt_flags_debug
return
-
- yield self.lib_opt_flags
+ elif who == 'lib':
+ if options.build_mode == 'release':
+ yield self.lib_opt_flags_release
+ else:
+ yield self.lib_opt_flags_debug
+ return
+ else:
+ raise Exception("Invalid value of parameter 'who'.")
def submodel_fixup(flags, tup):
return tup[0].replace('SUBMODEL', flags.replace(tup[1], ''))
@@ -927,12 +920,34 @@ class CompilerInfo(object):
"""
Return the command needed to link a shared object
"""
- def so_link_command_for(self, osname):
- if osname in self.so_link_flags:
- return self.so_link_flags[osname]
- if 'default' in self.so_link_flags:
- return self.so_link_flags['default']
- return ''
+ def so_link_command_for(self, osname, options):
+ if options.build_mode == 'debug':
+ search_for = [osname + "-debug", 'default-debug']
+ else:
+ search_for = [osname, 'default']
+
+ for s in search_for:
+ if s in self.so_link_commands:
+ return self.so_link_commands[s]
+
+ raise Exception("No shared library link command found for target '%s' in compiler settings '%s'. Searched for: %s" %
+ (osname, self.infofile, ", ".join(search_for)))
+
+ """
+ Return the command needed to link an app/test object
+ """
+ def binary_link_command_for(self, osname, options):
+ if options.build_mode == 'debug':
+ search_for = [osname + "-debug", 'default-debug']
+ else:
+ search_for = [osname, 'default']
+
+ for s in search_for:
+ if s in self.binary_link_commands:
+ return self.binary_link_commands[s]
+
+ raise Exception("No binary link command found for target '%s' in compiler settings '%s'. Searched for: %s" %
+ (osname, self.infofile, ", ".join(search_for)))
"""
Return defines for build.h
@@ -947,7 +962,9 @@ class OsInfo(object):
{ 'os_type': None,
'program_suffix': '',
'obj_suffix': 'o',
- 'so_suffix': 'so',
+ 'soname_pattern_patch': '',
+ 'soname_pattern_abi': '',
+ 'soname_pattern_base': '',
'static_suffix': 'a',
'ar_command': 'ar crs',
'ar_needs_ranlib': False,
@@ -1130,13 +1147,12 @@ def gen_makefile_lists(var, build_config, options, modules, cc, arch, osinfo):
"""
def build_commands(sources, obj_dir, flags):
for (obj_file,src) in zip(objectfile_list(sources, obj_dir), sources):
- yield '%s: %s\n\t$(CXX)%s $(%s_FLAGS) %s%s %s%s %s$@\n' % (
+ yield '%s: %s\n\t$(CXX)%s $(%s_FLAGS) %s%s %s %s$@\n' % (
obj_file, src,
isa_specific_flags(cc, src),
flags,
cc.add_include_dir_option,
build_config.include_dir,
- cc.compile_option,
src,
cc.output_to_option)
@@ -1250,7 +1266,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'scripts_dir': os.path.join(build_config.src_dir, 'scripts'),
- 'with_shared_lib': options.build_shared_lib,
+ 'build_shared_lib': options.build_shared_lib,
'appobj_dir': build_config.appobj_dir,
'libobj_dir': build_config.libobj_dir,
@@ -1271,7 +1287,8 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'mp_bits': choose_mp_bits(),
- 'cc': (options.compiler_binary or cc.binary_name) + cc.mach_abi_link_flags(options),
+ 'cxx': (options.compiler_binary or cc.binary_name) + cc.mach_abi_link_flags(options),
+ 'linker': cc.linker_name or '$(CXX)',
'lib_opt': cc.opt_flags('lib', options),
'app_opt': cc.opt_flags('app', options),
@@ -1287,9 +1304,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
# This can be made constistent over all platforms in the future
'libname': 'botan' if options.os == 'windows' else 'botan-%d.%d' % (build_config.version_major, build_config.version_minor),
- 'lib_link_cmd': cc.so_link_command_for(osinfo.basename),
- 'app_link_cmd': '$(CXX) -Wl,-rpath=\$$ORIGIN' if options.os == 'linux' else '$(CXX)',
- 'test_link_cmd': '$(CXX) -Wl,-rpath=\$$ORIGIN' if options.os == 'linux' else '$(CXX)',
+ 'lib_link_cmd': cc.so_link_command_for(osinfo.basename, options),
+ 'app_link_cmd': cc.binary_link_command_for(osinfo.basename, options),
+ 'test_link_cmd': cc.binary_link_command_for(osinfo.basename, options),
'link_to': ' '.join([cc.add_lib_option + lib for lib in link_to()]),
@@ -1313,7 +1330,22 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'lib_prefix': 'lib' if options.os != 'windows' else '',
'static_suffix': osinfo.static_suffix,
- 'so_suffix': osinfo.so_suffix,
+
+ 'soname_base': osinfo.soname_pattern_base.format(
+ version_major = build_config.version_major,
+ version_minor = build_config.version_minor,
+ version_patch = build_config.version_patch,
+ abi_rev = build_config.version_so_rev),
+ 'soname_abi': osinfo.soname_pattern_abi.format(
+ version_major = build_config.version_major,
+ version_minor = build_config.version_minor,
+ version_patch = build_config.version_patch,
+ abi_rev = build_config.version_so_rev),
+ 'soname_patch': osinfo.soname_pattern_patch.format(
+ version_major = build_config.version_major,
+ version_minor = build_config.version_minor,
+ version_patch = build_config.version_patch,
+ abi_rev = build_config.version_so_rev),
'mod_list': '\n'.join(sorted([m.basename for m in modules])),
@@ -1322,8 +1354,8 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
}
if options.os == 'darwin' and options.build_shared_lib:
- vars['app_post_link_cmd'] = 'install_name_tool -change "/$(SONAME)" "@executable_path/$(SONAME)" $(APP)'
- vars['test_post_link_cmd'] = 'install_name_tool -change "/$(SONAME)" "@executable_path/$(SONAME)" $(TEST)'
+ vars['app_post_link_cmd'] = 'install_name_tool -change "/$(SONAME_ABI)" "@executable_path/$(SONAME_ABI)" $(APP)'
+ vars['test_post_link_cmd'] = 'install_name_tool -change "/$(SONAME_ABI)" "@executable_path/$(SONAME_ABI)" $(TEST)'
else:
vars['app_post_link_cmd'] = ''
vars['test_post_link_cmd'] = ''
@@ -1362,11 +1394,11 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options):
for modname in options.enabled_modules:
if modname not in modules:
- logging.warning("Unknown enabled module %s" % (modname))
+ logging.error("Module not found: %s" % (modname))
for modname in options.disabled_modules:
if modname not in modules:
- logging.warning("Unknown disabled module %s" % (modname))
+ logging.warning("Disabled module not found: %s" % (modname))
for (modname, module) in modules.items():
if modname in options.disabled_modules:
@@ -1400,15 +1432,6 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options):
elif module.load_on == 'always':
to_load.append(modname)
- elif module.load_on == 'asm_ok':
- if options.asm_ok:
- if options.no_autoload:
- maybe_dep.append(modname)
- else:
- to_load.append(modname)
- else:
- cannot_use_because(modname,
- 'uses assembly and --disable-asm set')
elif module.load_on == 'auto':
if options.no_autoload:
maybe_dep.append(modname)
@@ -1677,9 +1700,7 @@ def generate_amalgamation(build_config, options):
botan_h.write(pub_header_amalag.contents)
botan_h.write("\n#endif\n")
- internal_headers = Amalgamation_Generator(
- [s for s in build_config.internal_headers
- if s.find('asm_macr_') == -1])
+ internal_headers = Amalgamation_Generator([s for s in build_config.internal_headers])
botan_int_h.write("""
#ifndef BOTAN_AMALGAMATION_INTERNAL_H__
@@ -1712,10 +1733,14 @@ def generate_amalgamation(build_config, options):
for mod in build_config.modules:
tgt = ''
- if not options.single_amalgamation_file and mod.need_isa != []:
- tgt = '_'.join(sorted(mod.need_isa))
- if tgt == 'sse2' and options.arch == 'x86_64':
- tgt = '' # SSE2 is always available on x86-64
+ if not options.single_amalgamation_file:
+ if mod.need_isa != []:
+ tgt = '_'.join(sorted(mod.need_isa))
+ if tgt == 'sse2' and options.arch == 'x86_64':
+ tgt = '' # SSE2 is always available on x86-64
+
+ if options.arch == 'x86_32' and 'simd' in mod.requires:
+ tgt = 'sse2'
if tgt not in botan_amalg_files:
botan_amalg_files[tgt] = open_amalg_file(tgt)
@@ -1772,8 +1797,17 @@ def main(argv = None):
if argv is None:
argv = sys.argv
- logging.basicConfig(stream = sys.stdout,
- format = '%(levelname) 7s: %(message)s')
+ class BotanConfigureLogHandler(logging.StreamHandler):
+ def emit(self, record):
+ # Do the default stuff first
+ super(BotanConfigureLogHandler, self).emit(record)
+ # Exit script if and ERROR or worse occurred
+ if record.levelno >= logging.ERROR:
+ sys.exit(1)
+
+ lh = BotanConfigureLogHandler(stream = sys.stdout)
+ lh.setFormatter(logging.Formatter('%(levelname) 7s: %(message)s'))
+ logging.getLogger().addHandler(lh)
options = process_command_line(argv[1:])
@@ -1890,10 +1924,9 @@ def main(argv = None):
if options.via_amalgamation:
options.gen_amalgamation = True
- if options.gen_amalgamation:
- if options.asm_ok:
- logging.info('Disabling assembly code, cannot use in amalgamation')
- options.asm_ok = False
+ if not options.build_shared_lib and not options.via_amalgamation:
+ raise Exception('Static build is only supported using amalgamation. '
+ 'Add --via-amalgamation.')
loaded_mods = choose_modules_to_use(modules, arch, cc, options)
@@ -1965,9 +1998,10 @@ def main(argv = None):
if e.errno != errno.EEXIST:
raise Exception('Error linking %s into %s: %s' % (header_file, dir, e))
- link_headers(build_config.public_headers, 'public', build_config.botan_include_dir)
+ link_headers(build_config.public_headers, 'public',
+ build_config.botan_include_dir)
- link_headers(build_config.build_internal_headers, 'internal',
+ link_headers(build_config.internal_headers, 'internal',
build_config.internal_include_dir)
with open(os.path.join(build_config.build_dir, 'build_config.py'), 'w') as f:
@@ -1995,8 +2029,7 @@ if __name__ == '__main__':
try:
main()
except Exception as e:
- logging.error(e)
import traceback
logging.debug(traceback.format_exc())
- sys.exit(1)
+ logging.error(e)
sys.exit(0)
diff --git a/doc/dev/build_log.rst b/doc/dev/build_log.rst
deleted file mode 100644
index dd2fd7180..000000000
--- a/doc/dev/build_log.rst
+++ /dev/null
@@ -1,252 +0,0 @@
-
-Build Log
-========================================
-
-To report build results (successful or not), email the `development
-list <http://lists.randombit.net/mailman/listinfo/botan-devel/>`_ your
-results and relevant system information (OS versions, compiler name
-and version, CPU architecture and other hardware information,
-configuration settings).
-
-Debian reports the build results on a number of platforms for both
-`1.8 <https://buildd.debian.org/status/logs.php?pkg=botan1.8>`_ and
-`1.10 <https://buildd.debian.org/status/logs.php?pkg=botan1.10>`_.
-
-=========== ======= =================== ======================== ============================ ========
-Date Version OS CPU Compiler Results
-=========== ======= =================== ======================== ============================ ========
-2012-07-09 1.11.0 Gentoo Intel Core i7-860 GCC 4.7.0 OK
-2012-07-09 1.11.0 Gentoo Intel Core i7-860 Clang 3.1 OK
-
-2012-09-17 1.10.3 Gentoo Intel Core i7-860 Intel C++ 11.1 OK
-
-2011-07-24 1.10.3 Ubuntu 9.04 ARM926EJ-S GCC 4.3.3 OK
-
-2011-07-13 1.10.3 QNX 6.4.1 x86 GCC 4.3.3 OK
-2012-07-11 1.10.3 Windows 7 x64 x86 Visual C++ 16.00.30319.01 OK
-2012-07-11 1.10.3 Windows 7 x64 x86-64 Visual C++ 16.00.30319.01 OK
-
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.7.0 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.6.3 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.5.3 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.4.7 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.3.6 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 4.1.2 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 GCC 3.4.6 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 Clang 3.1 OK
-2012-07-09 1.10.2 Gentoo Intel Core i7-860 Intel C++ 12.1 OK
-
-2011-05-09 1.9.17 Gentoo 10.0 PowerPC G5 GCC 4.4.5 OK
-2011-05-02 1.9.17 FreeBSD 8.2 x86-64 GCC 4.2.1 OK
-2011-04-25 1.9.16 Gentoo 10.0 Intel Core i7-860 Clang 2.9 Miscompiles SSE2 IDEA
-2011-04-23 1.9.16 Gentoo 10.0 Intel Core i7-860 Sun C++ 5.10 OK
-2011-04-22 1.9.16 Gentoo 10.0 Intel Core i7-860 Intel C++ 11.1 OK
-2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 4.3.3 OK
-2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 2.95.3 Can't compile
-2011-04-15 1.9.16 Windows 7 x86-64 Visual C++ 16.00.30319.01 OK
-2011-04-15 1.9.16 QNX 6.4.1 i386 GCC 4.3.3 OK
-2011-03-29 1.9.15 Gentoo 10.0 Intel Core i5-520M GCC 4.5.2 OK
-2011-03-21 1.9.15 Ark Linux x86-64 GCC 4.6.0-pre OK
-2011-03-21 1.9.15 Ark Linux x86-32 GCC 4.6.0-pre OK
-2011-03-21 1.9.15 Ark Linux ARM GCC 4.6.0-pre OK
-2011-03-18 1.9.14 Debian 6.0 Intel Atom D510 GCC 4.4.5 OK
-2011-03-01 1.9.14 OpenBSD 4.6 UltraSPARC IIIi GCC 4.2.4 OK
-2011-03-01 1.9.14 OpenBSD 4.7 i386 GCC 4.2.4 OK
-2011-03-01 1.9.14 Debian 6.0 Intel Madison IA-64 GCC 4.4.5 OK
-2011-03-01 1.9.14 Ubuntu 9.10 ARM Cortex-A8 GCC 4.4.1 OK
-2011-03-01 1.9.14 Debian 5.0 PowerPC G5/970 GCC 4.3.2 OK
-2011-03-01 1.9.14 Windows 7 x64 Intel Core i5-520M Visual C++ 15.00.30729.01 OK (32/64)
-2011-03-01 1.9.14 Gentoo 10.0 Intel Core i7-860 Open64 4.2.1 OK
-2011-03-01 1.9.14 Gentoo 10.0 Intel Core i7-860 Sun C++ 5.10 OK
-2011-03-01 1.9.14 Gentoo 10.0 Intel Core i7-860 Intel C++ 11.1 OK
-2011-03-01 1.9.14 Gentoo 10.0 Intel Core i7-860 GCC 4.5.2 OK
-2011-02-14 1.9.13 NetBSD 5.1 Intel Xeon P4 GNU GCC 4.1.3 OK
-2011-01-14 1.9.12 FreeBSD 8.1 x86-64 Clang 2.9 OK
-2010-11-29 1.9.11 Windows 7 x64 Intel Core i5-520M Visual C++ 15.00.30729.01 OK (32/64)
-2010-11-29 1.9.11 Gentoo 10.0 Intel Core i7-860 GNU GCC 4.1.2, 4.4.5, 4.5.1 OK
-2010-11-29 1.9.11 Debian 5.0 PowerPC G5/970 GCC 4.3.2 OK
-2010-11-29 1.9.11 Gentoo 10.0 Intel Core i7-860 Intel C++ 11.1 OK
-2010-11-29 1.9.11 Gentoo 10.0 Intel Core i7-860 Clang 2.8 Miscompiles SSE2 IDEA
-2010-11-29 1.9.11 Debian 5.0 (32 bit) UltraSPARC T1 Niagra GCC 4.3.2 OK
-2010-09-07 1.9.11 Gentoo 10.0 Intel Core i7-860 Sun C++ 5.10 OK
-2010-08-12 1.9.10 Debian 5.0 Xeon X5450 Harpertown GCC 4.3.2 OK
-2010-08-12 1.9.10 Ubuntu 9.04 Intel Atom N270 GCC 4.3.3 OK
-2010-08-12 1.9.10 Debian 5.0 Intel Prescott GCC 4.3.2 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 GCC 3.4.6 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 GCC 4.1.2 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 GCC 4.3.5 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 GCC 4.4.4 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 GCC 4.5.1 OK
-2010-08-08 1.9.10 Gentoo 10.0 Intel Core i7-860 Clang SVN Miscompiles Turing
-2010-07-27 1.9.9 Debian 5.0 AMD Magny-Cours GCC 4.3.2, 4.5.0 OK
-2010-06-16 1.9.8 Gentoo 10.0 Intel Core2 Q6600 Intel C++ 11.1 OK
-2010-06-16 1.9.8 Debian 5.0 (32 bit) UltraSPARC T1 Niagra GCC 4.3.2 OK
-2010-06-16 1.9.8 Debian 5.0 Intel Madison IA-64 GCC 4.3.2 OK
-2010-06-16 1.9.8 Gentoo 10.0 IBM POWER5+ GCC 4.1.2, 4.2.4, 4.3.2 OK
-2010-06-16 1.9.8 OpenBSD 4.6 UltraSPARC IIIi GCC 3.3.5, 4.2.4 OK
-2010-06-16 1.9.8 FreeBSD 8.0 AMD Opteron 252 GCC 4.2.1 OK
-2010-06-16 1.9.8 gNewSense MIPS Loongson-2 (64) GCC 4.3.2 OK
-2010-06-16 1.9.8 Ubuntu 9.10 ARM Cortex-A8 GCC 4.4.1 OK
-2010-06-11 1.9.8 Gentoo 10.0 Intel Core2 Q6600 GCC 3.4.6, 4.1.2 OK
-2010-06-11 1.9.8 Windows 7 x64 Intel Core i5-520M Visual C++ 15.00.30729.01 OK (32 and 64 bit)
-2010-06-11 1.9.8 Gentoo 10.0 Intel Core i5-520M GCC 4.5.0 OK
-2010-06-01 1.9.8 OpenBSD 4.7 i386 GCC 3.3.5 OK
-2010-05-03 1.9.7 Windows 7 x64 Intel Core i5-520M Visual C++ 15.00.30729.01 OK
-2010-04-27 1.9.7 Gentoo 10.0 PPC 970FX (G5) GCC 4.3.4 OK
-2010-04-27 1.9.7 Gentoo 10.0 Intel Core2 Q6600 GCC 4.4.3, 4.5.0 OK
-2010-03-18 1.9.4 Gentoo 10.0 Intel Core2 Q6600 GCC 4.4.3 OK
-2010-03-18 1.9.4 Debian 5.0 UltraSPARC II (64) GCC 4.3.2 OK
-2010-03-18 1.9.4 Gentoo 10.0 PowerPC G5 GCC 4.3.4 OK
-2010-03-18 1.9.4 Gentoo 10.0 IBM POWER5+ GCC 4.3.2 OK
-2010-03-15 1.9.4 Windows XP x86 Visual C++ 15.00.30729.01 OK
-2010-03-10 1.9.4 FreeBSD 8.0 AMD Opteron 252 GCC 4.2.1 OK, but missing includes
-2009-12-29 1.9.4 Debian 4.0 PowerPC G4 7455 GCC 4.1.2 OK
-2009-12-23 1.9.4 Debian 5.0 Xeon X5450 Harpertown GCC 4.3.2 OK
-2009-11-13 1.9.3 Debian 5.0 UltraSPARC II GCC 4.3.2 OK
-2009-11-10 1.9.2 Debian 4.0 PowerPC G4 GCC 4.1.2 OK
-2009-11-03 1.9.2 Debian Linux 4.0 AMD Opteron 8354 GCC 4.4.1 OK
-2009-10-27 1.9.2 Debian Linux 5.0 Xeon X5450 Harpertown GCC 4.3.2 OK
-2009-10-23 1.9.1 Gentoo Linux Intel Core2 Q6600 GCC 4.4.1, Intel C++ 11.1 OK
-2009-10-23 1.9.1 Gentoo Linux AMD Opteron 2212 GCC 4.3.4 OK
-2009-09-24 1.9.0 Debian 4.0 AMD Opteron 8354 GCC 4.1.2, 4.4.1 OK
-2010-07-01 1.8.9 OpenSUSE 10.3 Intel Core2 GCC 4.2.1 OK
-2010-06-22 1.8.9 Slackware 13.1 Intel E5400 (64) GCC 4.4.4 OK
-2010-06-22 1.8.9 Slackware 13.1 Pentium-M (32) GCC 4.4.4 OK
-2010-06-16 1.8.9 Debian 5.0 (32 bit) UltraSPARC T1 Niagra GCC 4.3.2 (GCC TR1) Crashes in GF(p) tests
-2010-03-18 1.8.8 Debian 5.0 UltraSPARC II (64) GCC 4.3.2 OK
-2008-10-23 1.8.7 Gentoo 2008.0 PPC 970FX (G5) GCC 4.3.4 OK
-2009-10-07 1.8.7 Debian GNU/Hurd 0.3 i686 GCC 4.3.4 OK
-2009-09-08 1.8.7 Gentoo 2008.0 Intel Core2 Q6600 GCC 4.4.1 OK
-2009-09-04 1.8.6 Gentoo 2008.0 PPC 970FX (G5) GCC 4.3.4 OK
-2009-08-13 1.8.6 Gentoo 2008.0 Intel Core2 Q6600 GCC 4.3.3 OK
-2009-08-13 1.8.6 Windows XP x86 Visual C++ 15.00.30729.01 OK (no TR1)
-2009-08-03 1.8.5 openSuSE 10.3 x86 GCC 4.2.1 OK
-2009-08-03 1.8.5 Gentoo 2008.0 Intel Core2 Q6600 Open64 4.2.1 BAD: Miscompiles several ciphers
-2009-07-31 1.8.5 Solaris 11 x86 Sun C++ 5.9 OK, but minor build problems
-2009-07-30 1.8.5 Gentoo 2006.1 UltraSPARC IIe (32) GCC 3.4.6 OK (no TR1)
-2009-07-25 1.8.5 Debian 4.0 AMD Opteron 2212 GCC 4.1.2 OK
-2009-07-23 1.8.5 Gentoo 2008.0 Marvel Feroceon 88FR131 GCC 4.1.2 OK
-2009-07-23 1.8.5 Debian 5.0 Intel Xscale 80219 GCC 4.3.2 OK
-2009-07-23 1.8.5 Debian 5.0 UltraSPARC II (64) GCC 4.3.2 OK
-2009-07-23 1.8.5 Debian 5.0 UltraSPARC II (32) GCC 4.3.2 BAD: bus error in GF(p)
-2009-07-23 1.8.5 Debian 5.0 UltraSPARC II (32) GCC 4.1.3 BAD: miscompiles BigInt code
-2009-07-23 1.8.5 Debian 4.0 PowerPC G4 GCC 4.1.2 OK
-2009-07-23 1.8.5 Debian 4.0 PowerPC G5 GCC 4.1.2 OK
-2009-07-23 1.8.5 Debian 5.0 Intel Madison IA-64 GCC 4.1.3, 4.3.2 OK
-2009-07-23 1.8.5 Debian 5.0 HP-PA PA8600 GCC 4.3.2 OK
-2009-07-23 1.8.5 Mandriva 2008.1 MIPS Loongson-2 (32) GCC 4.2.3 OK
-2009-07-23 1.8.5 gNewSense MIPS Loongson-2 (64) GCC 4.3.2 OK
-2009-07-21 1.8.5 Windows XP x86 Visual C++ 15.00.30729.01 OK (no TR1)
-2009-07-21 1.8.5 Gentoo 2008.0 Intel Core2 Q6600 GCC 4.1.2, 4.3.3 OK
-2009-07-21 1.8.5 Gentoo 2008.0 Intel Core2 Q6600 Intel C++ 10.1 20080801 OK
-2009-07-21 1.8.5 Gentoo 2008.0 AMD Opteron 2212 GCC 4.3.3 OK
-2009-07-21 1.8.5 Ubuntu 8.04 Intel Xeon X5492 GCC 4.2.4 OK
-2009-07-21 1.8.5 MacOS X 10.5.6 Intel Core 2 Duo T5600 GCC 4.0.1 OK
-2009-07-21 1.8.5 Solaris 10 AMD Opteron GCC 3.4.3 OK (no TR1)
-2008-07-11 1.8.3 Fedora 11 Intel Pentium E5200 GCC 4.4.0 OK
-2008-07-10 1.8.3 Gentoo 2008.0 PPC 970FX (G5) GCC 4.3.1 OK
-2008-07-10 1.8.3 Gentoo 2008.0 IBM POWER5+ GCC 4.2.2 OK
-2009-07-10 1.8.3 Gentoo 2008.0 AMD Opteron 2212 GCC 4.3.3 OK
-2009-07-10 1.8.3 Ubuntu 8.04 Intel Xeon X5492 GCC 4.2.4 OK
-2009-07-10 1.8.3 MacOS X 10.5.6 Intel Core 2 Duo T5600 GCC 4.0.1 OK
-2009-07-10 1.8.3 Debian 5.0.1 Intel Core 2 Duo T5600 GCC 4.3.2 OK
-2009-07-10 1.8.3 Fedora 10 Intel Core 2 Duo T5600 GCC 4.3.2 OK
-2009-07-10 1.8.3 Solaris 10 AMD Opteron GCC 3.4.3 OK (no TR1)
-2009-07-09 1.8.3 Gentoo 2008.0 Intel Core2 Q6600 Intel C++ 10.1 20080801 OK
-2009-07-02 1.8.3 Gentoo 2008.0 Intel Core2 Q6600 GCC 4.3.3 OK
-2009-07-02 1.8.3 FreeBSD 7.0 x86-64 GCC 4.2.1 OK
-2009-07-02 1.8.3 Windows XP x86 Visual C++ 15.00.30729.01 OK (no TR1)
-2008-12-27 1.8.0 Ubuntu 8.04 Pentium 4-M GCC 4.2.3 OK
-2008-12-14 1.8.0 FreeBSD 7.0 x86-64 GCC 4.2.1 OK
-2008-12-10 1.8.0 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.1.2, 4.2.4, 4.3.2 OK
-2008-12-05 1.7.24 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.1.2, 4.2.4, 4.3.2 OK
-2008-12-04 1.7.24 Gentoo 2007.0 Intel Core2 Q6600 Intel 10.1-20080801 OK
-2008-12-03 1.7.24 Solaris 10 x86 GCC 3.4.3 OK (small patch needed, fixed in 1.8.0)
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.1.2 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.2.4 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.3.2 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.4-20081017 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 (32) GCC 4.1.2, 4.2.4 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 (32) GCC 4.3.2 OK (with Boost 1.35 TR1)
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 (32) GCC 4.3.2 Crashes (with libstdc++ TR1)
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 9.1-20061101 OK
-2008-11-24 1.7.23 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1-20080801 OK
-2008-11-24 1.7.23 Fedora 8 STI Cell PPU GCC 4.1.2 OK
-2008-11-24 1.7.23 Fedora 8 STI Cell PPU IBM XLC for Cell 0.9 45 minute link. Miscompiles DES
-2008-11-24 1.7.23 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2, 4.2.2, 4.3.1 OK
-2008-11-24 1.7.23 Gentoo 2007.0 AMD Opteron 2212 GCC 3.3.6, 4.1.2, 4.3.2 OK (no TR1 with 3.3.6)
-2008-11-24 1.7.23 Windows XP x86 Visual C++ 15.00.30729.01 OK (no TR1)
-2008-11-09 1.7.20 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-11-09 1.7.20 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.3.2 OK
-2008-11-09 1.7.20 Windows XP x86 Visual C++ 15.00.30729.01 OK
-2008-11-06 1.7.19 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-11-06 1.7.19 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.1.2, 4.3.1 OK
-2008-11-06 1.7.19 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 9.1-20061101 OK
-2008-11-06 1.7.19 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1-20080801 OK
-2008-11-06 1.7.19 Windows XP x86 Visual C++ 15.00.30729.01 OK
-2008-11-03 1.7.19 FreeBSD 7.0 x86-64 GCC 4.2.1 OK
-2008-10-24 1.7.18 Gentoo 2007.0 IBM POWER5+ GCC 4.2.2, 4.3.1 OK
-2008-10-24 1.7.18 Fedora 8 STI Cell PPU GCC 4.1.2 OK
-2008-10-22 1.7.18 Windows XP Pentium 4-M GCC 3.4.5 (MinGW) OK
-2008-10-22 1.7.18 Windows XP Pentium 4-M Visual C++ 15.00.30729.01 OK
-2008-10-22 1.7.18 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-10-22 1.7.18 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.1.2, 4.2.4, 4.3.2 OK
-2008-10-22 1.7.18 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 9.1-20061101 OK
-2008-10-22 1.7.18 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1-20080801 OK
-2008-10-07 1.7.15 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-10-07 1.7.15 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.3.1 OK
-2008-09-30 1.7.14 Gentoo 2007.0 PPC 970FX (G5) GCC 4.3.1 OK
-2008-09-30 1.7.14 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-09-30 1.7.14 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.3.1 OK
-2008-09-30 1.7.14 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1.018 OK
-2008-09-30 1.7.14 Windows XP Pentium 4-M Visual C++ 15.00.30729.01 OK
-2008-09-30 1.7.14 Windows XP Pentium 4-M GCC 3.4.5 (MinGW) OK
-2008-09-18 1.7.12 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2, 4.2.2 OK
-2008-09-18 1.7.12 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.2.4, 4.3.1 OK
-2008-09-18 1.7.12 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1.018 OK
-2008-09-18 1.7.12 Windows XP Pentium 4-M Visual C++ 15.00.30729.01 OK
-2008-09-18 1.7.12 Windows XP Pentium 4-M GCC 3.4.5 (MinGW) OK
-2008-09-16 1.7.12 Fedora 7 STI Cell PPU GCC 4.1.2 OK
-2008-09-16 1.7.11 MacOS X 10.4 (32) Intel Core2 GCC 4.0.1 OK
-2008-09-11 1.7.11 Gentoo 2007.0 Intel Core2 Q6600 GCC 4.3.1 OK
-2008-09-11 1.7.11 Windows XP Pentium 4-M Visual C++ 15.00.30729.01 OK
-2008-09-08 1.7.9 Gentoo 2007.0 Intel Core2 Q6600 Intel C++ 10.1.018 OK
-2008-08-28 1.7.9 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2 OK
-2008-08-28 1.7.9 Gentoo 2007.0 IBM POWER5+ GCC 4.2.2 OK
-2008-08-28 1.7.9 Gentoo 2007.0 IBM POWER5+ GCC 4.3.1 OK
-2008-08-28 1.7.9 Gentoo STI Cell PPU GCC 4.1.2 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 GCC 4.1.2 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 GCC 4.2.4 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 GCC 4.3.1 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 GCC 4.4-20080822 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 Intel C++ 9.1-20061101 OK
-2008-08-27 1.7.9 Gentoo Intel Core2 Q6600 Intel C++ 10.1-20080602 OK
-2008-08-27 1.7.9 Windows XP Pentium 4-M Visual C++ 2008 OK
-2008-08-27 1.7.9 Windows XP Pentium 4-M GCC 3.4.5 (MinGW) OK
-2008-08-18 1.7.8 Ubuntu 8.04 Pentium 4-M GCC 4.2.3 OK
-2008-08-18 1.7.8 Windows XP Pentium 4-M Visual C++ 2008 OK
-2008-08-18 1.7.8 Windows XP Pentium 4-M GCC 3.4.5 (MinGW) OK
-2008-07-18 1.7.8 Gentoo IBM POWER5+ GCC 4.1.2 OK
-2008-07-15 1.7.8 Gentoo Intel Core2 Q6600 GCC 4.3.1 OK
-2008-07-06 1.7.7 Gentoo Intel Core2 Q6600 PGI 7.2 Miscompiles TEA, Turing, BigInt
-2008-06-28 1.7.7 Gentoo Pentium 4-M GCC 4.1.2 OK
-2008-06-28 1.7.7 Gentoo Intel Core2 Q6600 GCC 4.1.2, 4.2.4, 4.3.1 OK
-2008-06-28 1.7.7 Gentoo Intel Core2 Q6600 Intel C++ 10.1 OK
-2008-06-28 1.7.7 Gentoo IBM POWER5+ GCC 4.1.2, 4.2.2 OK
-2008-06-25 1.7.6 Gentoo IBM POWER5+ GCC 4.1.2, 4.2.2 OK
-2008-06-09 1.7.6 Gentoo PPC 970FX (G5) GCC 4.1.2 OK
-2008-05-14 1.7.6 Gentoo Intel Core2 Q6600 Intel C++ 9.1 Builds, but link problems
-2008-05-14 1.7.6 Gentoo Intel Core2 Q6600 GCC 4.2.3 OK
-2008-04-21 1.7.5 Gentoo STI Cell PPU GCC 4.1.2 OK
-2008-04-14 1.7.5 Debian Pentium 4 GCC 4.1.2 OK
-2008-04-13 1.7.5 Gentoo 2006.1 UltraSPARC II (32) GCC 3.4.6 OK
-2008-04-12 1.7.5 RHEL3 Pentium 4 Xeon GCC 3.2.3 OK
-2008-04-12 1.7.5 Gentoo Intel Core2 Q6600 Intel C++ 10.1 OK
-2008-04-12 1.7.5 Gentoo AMD Opteron 2212 GCC 4.1.2 OK
-2008-04-12 1.7.5 Gentoo Intel Core2 Q6600 GCC 4.2.3 OK
-2008-09-16 1.6.5 MacOS X 10.4 Intel Core2 (32) GCC 4.0.1 OK
-2008-08-28 1.6.5 Gentoo 2007.0 IBM POWER5+ GCC 4.1.2, 4.2.2, 4.3.1 OK
-2008-08-27 1.6.5 Gentoo Intel Core2 Q6600 GCC 4.3.1, 4.4-20080822 OK
-2008-08-18 1.6.4 Windows XP Pentium 4-M Visual C++ 2008 OK
-2008-07-02 1.6.4 Solaris 10 x86-64 Sun Forte 12 OK
-=========== ======= =================== ======================== ============================ ========
diff --git a/doc/manual/bigint.rst b/doc/manual/bigint.rst
index c2036fcfd..04af0c6db 100644
--- a/doc/manual/bigint.rst
+++ b/doc/manual/bigint.rst
@@ -95,11 +95,11 @@ Number theoretic functions available include:
Three variations on *is_prime*, with probabilities set to 32, 56, and 80
respectively.
- .. cpp:function:: BigInt random_prime(RandomNumberGenerator& rng, \
- size_t bits, \
- BigInt coprime = 1, \
- size_t equiv = 1, \
- size_t equiv_mod = 2)
+.. cpp:function:: BigInt random_prime(RandomNumberGenerator& rng, \
+ size_t bits, \
+ BigInt coprime = 1, \
+ size_t equiv = 1, \
+ size_t equiv_mod = 2)
Return a random prime number of ``bits`` bits long that is
relatively prime to ``coprime``, and equivalent to ``equiv`` modulo
diff --git a/doc/manual/building.rst b/doc/manual/building.rst
index cb450974b..2333a9069 100644
--- a/doc/manual/building.rst
+++ b/doc/manual/building.rst
@@ -1,10 +1,9 @@
-
Building The Library
=================================
-This document describes how to build Botan on Unix/POSIX and MS
-Windows systems. The POSIX oriented descriptions should apply to most
-common Unix systems (including MacOS X), along with POSIX-ish systems
+This document describes how to build Botan on Unix/POSIX and Windows
+systems. The POSIX oriented descriptions should apply to most
+common Unix systems (including OS X), along with POSIX-ish systems
like BeOS, QNX, and Plan 9. Currently, systems other than Windows and
POSIX (such as VMS, MacOS 9, OS/390, OS/400, ...) are not supported by
the build system, primarily due to lack of access. Please contact the
@@ -101,14 +100,14 @@ The basic build procedure on Unix and Unix-like systems is::
$ ./configure.py [--enable-modules=<list>] [--cc=CC]
$ make
- $ ./botan test
+ $ ./botan-test
If that fails with an error about not being able to find libbotan.so,
-you may need to set ``LD_LIBRARY_PATH``:
+you may need to set ``LD_LIBRARY_PATH``::
- $ LD_LIBRARY_PATH=. ./botan test
+ $ LD_LIBRARY_PATH=. ./botan-test
-If the tests look OK, install:
+If the tests look OK, install::
$ make install
@@ -118,9 +117,9 @@ and ``--cc=clang`` for Clang.
The ``make install`` target has a default directory in which it will
install Botan (typically ``/usr/local``). You can override this by
-using the ``--prefix`` argument to ``configure.py``, like so:
+using the ``--prefix`` argument to ``configure.py``, like so::
-``./configure.py --prefix=/opt <other arguments>``
+ $ ./configure.py --prefix=/opt <other arguments>
On some systems shared libraries might not be immediately visible to
the runtime linker. For example, on Linux you may have to edit
@@ -129,7 +128,7 @@ shared libraries to be picked up by the linker. An alternative is to
set your ``LD_LIBRARY_PATH`` shell variable to include the directory
that the Botan libraries were installed into.
-On Mac OS X
+On OS X
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In general the Unix instructions above should apply, however OS X does
@@ -149,21 +148,20 @@ build flags. Do this with the --cc-abi-flags option::
$ ./configure.py [other arguments] --cc-abi-flags="-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc"
-On MS Windows
+On Windows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-If you don't want to deal with building botan on Windows, check the
-website; commonly prebuilt Windows binaries with installers are
-available, especially for stable versions.
-
You need to have a copy of Python installed, and have both Python and
your chosen compiler in your path. Open a command shell (or the SDK
shell), and run::
- > python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU]
- > nmake
- > botan.exe test
- > nmake install
+ $ python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU]
+ $ nmake
+ $ botan-test.exe
+ $ nmake install
+
+Botan supports the nmake replacement `Jom <https://wiki.qt.io/Jom>`_
+which enables you to run multiple build jobs in parallel.
For Win95 pre OSR2, the ``cryptoapi_rng`` module will not work,
because CryptoAPI didn't exist. And all versions of NT4 lack the
@@ -187,26 +185,26 @@ For iOS using XCode
To cross compile for iOS, configure with::
- $ ./configure.py --cpu=armv7 --cc=clang --cc-abi-flags="-arch armv7 -arch armv7s --sysroot=$(IOS_SYSROOT)"
+ $ ./configure.py --cpu=armv7 --cc=clang --cc-abi-flags="-arch armv7 -arch armv7s --sysroot=$(IOS_SYSROOT)"
Along with any additional configuration arguments. Using ``--no-autoload``
might be helpful as can substantially reduce code size.
Edit the makefile and change AR (around line 30) to::
- AR = libtool -static -o
+ AR = libtool -static -o
You may also want to edit LIB_OPT to use -Os to optimize for size.
Now build as normal with ``make``. Confirm the binaries are compiled
for both architectures with::
- $ xcrun -sdk iphoneos lipo -info botan
- Architectures in the fat file: botan are: armv7 armv7s
+ $ xcrun -sdk iphoneos lipo -info botan
+ Architectures in the fat file: botan are: armv7 armv7s
Now sign the test application with::
- $ codesign -fs "Your Name" botan-test
+ $ codesign -fs "Your Name" botan-test
which should allow you to run the library self tests on a jailbroken
device.
@@ -383,7 +381,7 @@ Your ``Makefile`` can run ``botan config`` and get the options
necessary for getting your application to compile and link, regardless
of whatever crazy libraries Botan might be linked against.
-MS Windows
+Windows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
No special help exists for building applications on Windows. However,
diff --git a/doc/manual/ffi.rst b/doc/manual/ffi.rst
index a951c63f3..7a01dc8ae 100644
--- a/doc/manual/ffi.rst
+++ b/doc/manual/ffi.rst
@@ -39,7 +39,7 @@ Versioning
Hash Functions
----------------------------------------
-.. cpp:type:: typedef struct botan_hash_struct* botan_hash_t
+.. cpp:type:: opaque* botan_hash_t
An opaque data type for a hash. Don't mess with it.
@@ -72,7 +72,7 @@ Hash Functions
Authentication Codes
----------------------------------------
-.. cpp:type:: typedef struct botan_mac_struct* botan_mac_t
+.. cpp:type:: opaque* botan_mac_t
An opaque data type for a MAC. Don't mess with it, but do remember
to set a random key first.
@@ -87,15 +87,14 @@ Authentication Codes
.. cpp:function:: int botan_mac_update(botan_mac_t mac, uint8_t buf[], size_t len)
-.. cpp:function:: int botan_mac_final(botan_mac_t mac, uint8_t out[], size_t* ou
-t_len)
+.. cpp:function:: int botan_mac_final(botan_mac_t mac, uint8_t out[], size_t* out_len)
.. cpp:function:: size_t botan_mac_output_length(botan_mac_t mac)
Ciphers
----------------------------------------
-.. cpp:type:: typedef struct botan_cipher_struct* botan_cipher_t
+.. cpp:type:: opaque* botan_cipher_t
An opaque data type for a MAC. Don't mess with it, but do remember
to set a random key first. And please use an AEAD.
@@ -111,22 +110,20 @@ Ciphers
.. cpp:function:: int botan_cipher_clear(botan_cipher_t hash)
-.. cpp:function:: int botan_cipher_set_key(botan_cipher_t cipher,
- const uint8_t* key, size_t key_len)
+.. cpp:function:: int botan_cipher_set_key(botan_cipher_t cipher, \
+ const uint8_t* key, size_t key_len)
-.. cpp:function:: int botan_cipher_set_associated_data(botan_cipher_t cipher,
- const uint8_t* ad,
- size_t ad_len)
+.. cpp:function:: int botan_cipher_set_associated_data(botan_cipher_t cipher, \
+ const uint8_t* ad, size_t ad_len)
-.. cpp:function:: int botan_cipher_start(botan_cipher_t cipher,
+.. cpp:function:: int botan_cipher_start(botan_cipher_t cipher, \
const uint8_t* nonce, size_t nonce_len)
.. cpp:function:: int botan_cipher_is_authenticated(botan_cipher_t cipher)
.. cpp:function:: size_t botan_cipher_tag_size(botan_cipher_t cipher)
-.. cpp:function:: int botan_cipher_valid_nonce_length(botan_cipher_t cipher, siz
-e_t nl)
+.. cpp:function:: int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl)
.. cpp:function:: size_t botan_cipher_default_nonce_length(botan_cipher_t cipher)
diff --git a/doc/manual/filters.rst b/doc/manual/filters.rst
index bd73739af..69a7517d7 100644
--- a/doc/manual/filters.rst
+++ b/doc/manual/filters.rst
@@ -630,36 +630,6 @@ reason you name something that doesn't exist, an exception will be thrown.
"CMAC(AES-128)", along with a key to use. The optional ``outlen``
works the same as in ``Hash_Filter``.
-PK Filters
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-There are four classes in this category, ``PK_Encryptor_Filter``,
-``PK_Decryptor_Filter``, ``PK_Signer_Filter``, and
-``PK_Verifier_Filter``. Each takes a pointer to an object of the
-appropriate type (``PK_Encryptor``, ``PK_Decryptor``, etc) that is
-deleted by the destructor. These classes are found in ``pk_filts.h``.
-
-Three of these, for encryption, decryption, and signing are much the
-same in terms of dataflow - ach of them buffers its input until the
-end of the message is marked with a call to the ``end_msg``
-function. Then they encrypt, decrypt, or sign the entire input as a
-single blob and send the output (the ciphertext, the plaintext, or the
-signature) into the next filter.
-
-Signature verification works a little differently, because it needs to
-know what the signature is in order to check it. You can either pass
-this in along with the constructor, or call the function
-``set_signature`` -- with this second method, you need to keep
-a pointer to the filter around so you can send it this command. In
-either case, after ``end_msg`` is called, it will try to
-verify the signature (if the signature has not been set by either
-method, an exception will be thrown here). It will then send a single
-byte onto the next filter -- a 1 or a 0, which specifies whether the
-signature verified or not (respectively).
-
-For more information about PK algorithms (including creating the
-appropriate objects to pass to the constructors), see :doc:`pubkey`.
-
Encoders
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/manual/firststep.rst b/doc/manual/firststep.rst
index 8010789d6..2f998687d 100644
--- a/doc/manual/firststep.rst
+++ b/doc/manual/firststep.rst
@@ -11,62 +11,9 @@ All library headers are included like so::
#include <botan/auto_rng.h>
-Initializing the Library
-----------------------------------------
-
-There is a set of core services that the library needs access to while
-it is performing requests. To ensure these are set up, you must create
-an object of type
-
-.. cpp:class:: LibraryInitializer
-
-prior to making any other library calls. Typically this will be named
-something like ``init`` or ``botan_init``. The object lifetime must
-exceed that of all other Botan objects your application creates; for
-this reason the best place to create the ``LibraryInitializer`` is at
-the start of your ``main`` function, since this guarantees that it
-will be created first and destroyed last (via standard C++ RAII
-rules). The initializer does things like setting up the memory
-allocation system and algorithm lookup tables, finding out if there is
-a high resolution timer available to use, and similar such
-matters. With no arguments, the library is initialized with various
-default settings. So (unless you are writing threaded code; see
-below), all you need is::
-
- Botan::LibraryInitializer init;
-
-at the start of your ``main``.
-
-If you do not create a ``LibraryInitializer`` object, all library
-operations will fail, because it will be unable to do basic things
-like allocate memory or get random bits. You should never create more
-than one ``LibraryInitializer``.
-
Pitfalls
----------------------------------------
-There are a few things to watch out for to prevent problems when using
-the library.
-
-Never allocate any kind of Botan object globally. The problem with
-doing this is that the constructor for such an object will be called
-before the library is initialized. Many Botan objects will, in their
-constructor, make one or more calls into the library global state
-object. Access to this object is checked, so an exception should be
-thrown (rather than a memory access violation or undetected
-uninitialized object access). A rough equivalent that will work is to
-keep a global pointer to the object, initializing it after creating
-your ``LibraryInitializer``. Merely making the
-``LibraryInitializer`` also global will probably not help, because
-C++ does not make very strong guarantees about the order that such
-objects will be created.
-
-The same rule applies for making sure the destructors of all your
-Botan objects are called before the ``LibraryInitializer`` is
-destroyed. This implies you can't have static variables that are Botan
-objects inside functions or classes; in many C++ runtimes, these
-objects will be destroyed after main has returned.
-
Use a ``try``/``catch`` block inside your ``main`` function, and catch
any ``std::exception`` throws (remember to catch by reference, as
``std::exception::what`` is polymorphic)::
diff --git a/doc/manual/index.rst b/doc/manual/index.rst
index 988d7732f..1bfc01d30 100644
--- a/doc/manual/index.rst
+++ b/doc/manual/index.rst
@@ -4,36 +4,6 @@ Introduction
If you need to build the library first, start with :doc:`building`.
-Books and other resources
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It's a very good idea if you have some knowledge of cryptography
-*before* trying to use the library. This is an area where it is very
-easy to make mistakes, and where things are often subtle and/or
-counterintuitive. Obviously the library tries to provide things at a
-high level precisely to minimize the number of ways things can go
-wrong, but naive use will almost certainly not result in a secure
-system.
-
-Especially recommended are:
-
-- *Cryptography Engineering*
- by Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
-
-- *Security Engineering -- A Guide to Building Dependable Distributed Systems*
- by Ross Anderson
-
-- *Handbook of Applied Cryptography*
- by Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
- (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_)
-
-If you're doing something non-trivial or unique, you might want to at
-the very least ask for review/input on a mailing list such as the
-`metzdowd <http://www.metzdowd.com/mailman/listinfo/cryptography>`_ or
-`randombit <http://lists.randombit.net/mailman/listinfo/cryptography>`_
-crypto lists. And (if possible) pay a professional cryptographer or
-security company to review your design and code.
-
References
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/manual/lowlevel.rst b/doc/manual/lowlevel.rst
index 398d52d85..ae7337c4e 100644
--- a/doc/manual/lowlevel.rst
+++ b/doc/manual/lowlevel.rst
@@ -16,29 +16,28 @@ Basic Algorithm Abilities
There are a small handful of functions implemented by most of Botan's
algorithm objects. Among these are:
-.. cpp:function:: std::string Algorithm::name()
+.. cpp:function:: std::string name()
Returns a human-readable string of the name of this
algorithm. Examples of names returned are "AES-128" and
"HMAC(SHA-512)". You can turn names back into algorithm objects using
the functions in ``lookup.h``.
-.. cpp:function:: void Algorithm::clear()
+.. cpp:function:: void clear()
Clear out the algorithm's internal state. A block cipher object will
"forget" its key, a hash function will "forget" any data put into it,
etc. The object will look and behave as it did when you initially
allocated it.
-.. cpp:function:: T* Algorithm::clone()
+.. cpp:function:: T* clone()
-This function is central to Botan's name-based interface. The
-``clone`` has many different return types, such as ``BlockCipher``\*
-and ``HashFunction``\*, depending on what kind of object it is called
-on. Note that unlike Java's clone, this returns a new object in a
-"pristine" state; that is, operations done on the initial object
-before calling ``clone`` do not affect the initial state of the new
-clone.
+The ``clone`` has many different return types, such as
+``BlockCipher``\* and ``HashFunction``\*, depending on what kind of
+object it is called on. Note that unlike Java's clone, this returns a
+new object in a "pristine" state; that is, operations done on the
+initial object before calling ``clone`` do not affect the initial
+state of the new clone.
Cloned objects can (and should) be deallocated with the C++ ``delete``
operator.
diff --git a/doc/manual/pbkdf.rst b/doc/manual/pbkdf.rst
index 14434f63e..079a598ff 100644
--- a/doc/manual/pbkdf.rst
+++ b/doc/manual/pbkdf.rst
@@ -19,10 +19,10 @@ The purpose of the iteration count is to make the algorithm take
longer to compute the final key (reducing the speed of brute-force
attacks of various kinds). Most standards recommend an iteration count
of at least 10000. Currently defined PBKDF algorithms are
-"PBKDF1(digest)", "PBKDF2(digest)", and "OpenPGP-S2K(digest)"; you can
-retrieve any of these using the ``get_pbkdf``, found in
-``lookup.h``. As of this writing, "PBKDF2(SHA-256)" with 10000
-iterations and a 16 byte salt is recommend for new applications.
+"PBKDF1(digest)", "PBKDF2(digest)"; you can retrieve any of these
+using the ``get_pbkdf``, found in ``lookup.h``. As of this writing,
+"PBKDF2(SHA-256)" with at least 100000 iterations and a 16 byte salt
+is recommend for new applications.
.. cpp:function:: OctetString PBKDF::derive_key( \
size_t output_len, const std::string& passphrase, \
diff --git a/doc/manual/pubkey.rst b/doc/manual/pubkey.rst
index efeea692c..1b3ed305a 100644
--- a/doc/manual/pubkey.rst
+++ b/doc/manual/pubkey.rst
@@ -66,7 +66,7 @@ Nyberg-Rueppel key pairs with
.. cpp:function:: ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng, \
const DL_Group& group, const BigInt& x = 0)
- The optional *x* parameter to each of these contructors is a private key
+ The optional *x* parameter to each of these constructors is a private key
value. This allows you to create keys where the private key is formed by
some special technique; for instance you can use the hash of a password (see
:ref:`pbkdf` for how to do that) as a private key value. Normally, you would
@@ -162,7 +162,7 @@ decrypt, if necessary) a PKCS #8 private key:
These functions will return an object allocated key object based on the data
from whatever source it is using (assuming, of course, the source is in fact
storing a representation of a private key, and the decryption was
-sucessful). The encoding used (PEM or BER) need not be specified; the format
+successful). The encoding used (PEM or BER) need not be specified; the format
will be detected automatically. The key is allocated with ``new``, and should
be released with ``delete`` when you are done with it. The first takes a
generic ``DataSource`` that you have to create - the other is a simple wrapper
@@ -286,7 +286,7 @@ where *format* is any of
* ``ANSI_X9_42`` (or ``DH_PARAMETERS``) for modp groups
* ``ANSI_X9_57`` (or ``DSA_PARAMETERS``) for DSA-style groups
* ``PKCS_3`` is an older format for modp groups; it should only
- be used for backwards compatability.
+ be used for backwards compatibility.
You can reload a serialized group using
@@ -366,7 +366,7 @@ these use the EME class:
method to use is specified in *eme*.
The recommended values for *eme* is "EME1(SHA-1)" or "EME1(SHA-256)". If
- you need compatability with protocols using the PKCS #1 v1.5 standard,
+ you need compatibility with protocols using the PKCS #1 v1.5 standard,
you can also use "EME-PKCS1-v1_5".
.. cpp:class:: DLIES_Encryptor
@@ -409,7 +409,7 @@ Signature generation is performed using
fail. Raw is not useful except in very specialized applications. Examples
are "EMSA1(SHA-1)" and "EMSA4(SHA-256)".
- For RSA, use EMSA4 (also called PSS) unless you need compatability with
+ For RSA, use EMSA4 (also called PSS) unless you need compatibility with
software that uses the older PKCS #1 v1.5 standard, in which case use
EMSA3 (also called "EMSA-PKCS1-v1_5"). For DSA, ECDSA, GOST 34.10-2001,
and Nyberg-Rueppel, you should use EMSA1.
diff --git a/doc/manual/python.rst b/doc/manual/python.rst
index cef9fddd2..a00aabd5e 100644
--- a/doc/manual/python.rst
+++ b/doc/manual/python.rst
@@ -110,7 +110,7 @@ Ciphers
.. py:method:: update_granularity()
Returns update block size. Call to update() must provide
- input of exactly this many bytes
+ input of exactly this many bytes
.. py:method:: is_authenticated()
@@ -190,7 +190,7 @@ Public Key
.. py:class:: private_key(algo, param, rng)
- Constructor creates a new private key. The paramater type/value
+ Constructor creates a new private key. The parameter type/value
depends on the algorithm. For "rsa" is is the size of the key in
bits. For "ecdsa" and "ecdh" it is a group name (for instance
"secp256r1"). For "ecdh" there is also a special case for group
diff --git a/doc/manual/secmem.rst b/doc/manual/secmem.rst
index 76751bb40..ce5ff205b 100644
--- a/doc/manual/secmem.rst
+++ b/doc/manual/secmem.rst
@@ -14,7 +14,7 @@ allocator, it has an identical API to the ``std::vector`` you know and
love.
Some operating systems offer the ability to lock memory into RAM,
-preventing swapping from occuring. Typically this operation is
+preventing swapping from occurring. Typically this operation is
restricted to privledged users (root or admin), however some OSes
including Linux and FreeBSD allow normal users to lock a small amount
of memory. On these systems, allocations first attempt to allocate out
diff --git a/doc/manual/tls.rst b/doc/manual/tls.rst
index 26ac6a801..554846c25 100644
--- a/doc/manual/tls.rst
+++ b/doc/manual/tls.rst
@@ -497,7 +497,7 @@ TLS Policies
``TLS::Policy`` is how an application can control details of what will
be negotiated during a handshake. The base class acts as the default
policy. There is also a ``Strict_Policy`` (which forces only secure
-options, reducing compatability) and ``Text_Policy`` which reads
+options, reducing compatibility) and ``Text_Policy`` which reads
policy settings from a file.
.. cpp:class:: TLS::Policy
diff --git a/doc/manual/x509.rst b/doc/manual/x509.rst
index 211ccbaf9..d4500d692 100644
--- a/doc/manual/x509.rst
+++ b/doc/manual/x509.rst
@@ -276,7 +276,7 @@ The result of the validation is returned as a class:
.. cpp:function:: Certificate_Status_Code result() const
- Returns the 'worst' error that occured during validation. For
+ Returns the 'worst' error that occurred during validation. For
instance, we do not want an expired certificate with an invalid
signature to be reported to the user as being simply expired (a
relativly innocuous and common error) when the signature isn't
diff --git a/doc/news.rst b/doc/news.rst
new file mode 100644
index 000000000..101dd370b
--- /dev/null
+++ b/doc/news.rst
@@ -0,0 +1,3272 @@
+Release Notes
+========================================
+
+Version 1.11.20, Not Yet Released
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Additional countermeasures were added to ECC point multiplications
+ to help protect against side channel attacks.
+
+* On OS X, rename libs to avoid trailing version numbers, e.g.
+ libbotan-1.11.dylib.19 -> libbotan-1.11.19.dylib. Gh #241
+
+Version 1.11.19, 2015-08-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* SECURITY: The BER decoder would crash due to reading from offset 0
+ of an empty vector if it encountered a BIT STRING which did not
+ contain any data at all. As the type requires a 1 byte field this is
+ not valid BER but could occur in malformed data. Found with afl.
+ CVE-2015-5726
+
+* SECURITY: The BER decoder would allocate a fairly arbitrary amount
+ of memory in a length field, even if there was no chance the read
+ request would succeed. This might cause the process to run out of
+ memory or invoke the OOM killer. Found with afl.
+ CVE-2015-5727
+
+* The TLS heartbeat extension is deprecated and unless strong arguments
+ are raised in its favor it will be removed in a future release.
+ Comment at https://github.com/randombit/botan/issues/187
+
+* The x86-32 assembly versions of MD4, MD5, SHA-1, and Serpent and the
+ x86-64 version of SHA-1 have been removed. With compilers from this
+ decade the C++ versions are significantly faster. The SSE2 versions
+ of SHA-1 and Serpent remain, as they are still the fastest version
+ for processors with SIMD extensions. GH #216
+
+* BigInt::to_u32bit would fail if the value was exactly 32 bits.
+ GH #220
+
+Version 1.10.10, 2015-08-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* SECURITY: The BER decoder would crash due to reading from offset 0
+ of an empty vector if it encountered a BIT STRING which did not
+ contain any data at all. As the type requires a 1 byte field this is
+ not valid BER but could occur in malformed data. Found with afl.
+ CVE-2015-5726
+
+* SECURITY: The BER decoder would allocate a fairly arbitrary amount
+ of memory in a length field, even if there was no chance the read
+ request would succeed. This might cause the process to run out of
+ memory or invoke the OOM killer. Found with afl.
+ CVE-2015-5727
+
+* Due to an ABI incompatible (though not API incompatible) change in
+ this release, the version number of the shared object has been
+ increased.
+
+* The default TLS policy no longer allows RC4.
+
+* Fix a signed integer overflow in Blue Midnight Wish that may cause
+ incorrect computations or undefined behavior.
+
+Version 1.11.18, 2015-07-05
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* In this release Botan has switched VCS from ``monotone`` to ``git``,
+ and is now hosted on github at https://github.com/randombit/botan
+
+* The TLS client called ``std::set_difference`` on an invalid iterator
+ pair. This could potentially lead to a crash depending on the
+ compiler and STL implementation. It also would trigger assertion
+ failures when using checked iterators. GH #73
+
+* Remove code constructs which triggered errors under MSVC and GCC
+ debug iterators. The primary of these was an idiom of ``&vec[x]`` to
+ create a pointer offset of a ``std::vector``. This failed when x was
+ set equal to ``vec.size()`` to create the one-past-the-end address.
+ The pointer in question was never dereferenced, but it triggered
+ the iterator debugging checks which prevented using these valuble
+ analysis tools. From Simon Warta and Daniel Seither. GH #125
+
+* Several incorrect or missing module dependencies have been fixed. These
+ often prevented a successful build of a minimized amalgamation when
+ only a small set of algorithms were specified. GH #71
+ From Simon Warta.
+
+* Add an initial binding to OCaml. Currently only hashes, RNGs, and
+ bcrypt are supported.
+
+* The default key size generated by the ``keygen`` tool has increased
+ to 2048 bits. From Rene Korthaus.
+
+* The ``Botan_types`` namespace, which contained ``using`` declarations
+ for (just) ``Botan::byte`` and ``Botan::u32bit``, has been removed.
+ Any use should be replaced by ``using`` declarations for those types
+ directly.
+
+Version 1.11.17, 2015-06-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* All support for the insecure RC4 stream cipher has been removed
+ from the TLS implementation.
+
+* Fix decoding of TLS maximum fragment length. Regardless of what
+ value was actually negotiated, TLS would treat it as a negotiated
+ limit of 4096.
+
+* Fix the configure.py flag ``--disable-aes-ni`` which did nothing of
+ the sort.
+
+* Fixed nmake clean target. GitHub #104
+
+* Correct buffering logic in ``Compression_Filter``. GitHub #93 and #95
+
+Version 1.11.16, 2015-03-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* TLS has changed from using the non-standard NPN extension to the IETF
+ standardized ALPN extension for negotiating an application-level protocol.
+ Unfortunately the semantics of the exchange have changed with ALPN. Using
+ NPN, the server offered a list of protocols it advertised, and then the
+ client chose its favorite. With ALPN, the client offers a list of protocols
+ and the server chooses. The the signatures of both the TLS::Client and
+ TLS::Server constructors have changed to support this new flow.
+
+* Optimized ECDSA signature verification thanks to an observation by
+ Dr. Falko Strenzke. On some systems verifications are between 1.5
+ and 2 times faster than in 1.11.15.
+
+* RSA encrypt and decrypt operations using OpenSSL have been added.
+
+* Public key operation types now handle all aspects of the operation,
+ such as hashing and padding for signatures. This change allows
+ supporting specialized implementations which only support particular
+ padding types.
+
+* Added global timeout to HMAC_RNG entropy reseed. The defaults are
+ the values set in the build.h macros ``BOTAN_RNG_AUTO_RESEED_TIMEOUT``
+ and ``BOTAN_RNG_RESEED_DEFAULT_TIMEOUT``, but can be overriden
+ on a specific poll with the new API call reseed_with_timeout.
+
+* Fixed Python cipher update_granularity() and default_nonce_length()
+ functions
+
+* The library now builds on Visual C++ 2013
+
+* The GCM update granularity was reduced from 4096 to 16 bytes.
+
+* Fix a bug that prevented building the amalgamation until a non-amalgamation
+ configuration was performed first in the same directory.
+
+* Add Travis CI integration. Github pull 60.
+
+Version 1.11.15, 2015-03-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Support for RC4 in TLS, already disabled by default, is now deprecated.
+ The RC4 ciphersuites will be removed entirely in a future release.
+
+* A bug in ffi.cpp meant Python could only encrypt. Github issue 53.
+
+* When comparing two ASN.1 algorithm identifiers, consider empty and
+ NULL parameters the same.
+
+* Fixed memory leaks in TLS and cipher modes introduced in 1.11.14
+
+* MARK-4 failed when OpenSSL was enabled in the build in 1.11.14
+ because the OpenSSL version ignored the skip parameter.
+
+* Fix compilation problem on OS X/clang
+
+* Use BOTAN_NOEXCEPT macro to work around lack of noexcept in VS 2013
+
+Version 1.11.14, 2015-02-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The global state object previously used by the library has been removed.
+ This includes the global PRNG. The library can be safely initialized
+ multiple times without harm.
+
+ The engine code has also been removed, replaced by a much lighter-weight
+ object registry system which provides lookups in faster time and with less
+ memory overhead than the previous approach.
+
+ One caveat of the current system with regards to static linking: because only
+ symbols already mentioned elsewhere in the program are included in the final
+ link step, few algorithms will be available through the lookup system by
+ default, even though they were compiled into the library. Your application
+ must explicitly reference the types you require or they will not end up
+ being available in the final binary. See also Github issue #52
+
+ If you intend to build your application against a static library and don't
+ want to explicitly reference each algo object you might attempt to look up by
+ string, consider either building with ``--via-amalgamation``, or else (much
+ simpler) using the amalgamation directly.
+
+* The new ``ffi`` submodule provides a simple C API/ABI for a number of useful
+ operations (hashing, ciphers, public key operations, etc) which is easily
+ accessed using the FFI modules included in many languages.
+
+* A new Python wrapper (in ``src/lib/python/botan.py``) using ``ffi`` and the Python
+ ``ctypes`` module is available. The old Boost.Python wrapper has been removed.
+
+* Add specialized reducers for P-192, P-224, P-256, and P-384
+
+* OCB mode, which provides a fast and constant time AEAD mode without requiring
+ hardware support, is now supported in TLS, following
+ draft-zauner-tls-aes-ocb-01. Because this specification is not yet finalized
+ is not yet enabled by the default policy, and the ciphersuite numbers used are
+ in the experimental range and may conflict with other uses.
+
+* Add ability to read TLS policy from a text file using ``TLS::Text_Policy``.
+
+* The amalgamation now splits off any ISA specific code (for instance, that
+ requiring SSSE3 instruction sets) into a new file named (for instance)
+ ``botan_all_ssse3.cpp``. This allows the main amalgamation file to be compiled
+ without any special flags, so ``--via-amalgamation`` builds actually work now.
+ This is disabled with the build option ``--single-amalgamation-file``
+
+* PBKDF and KDF operations now provide a way to write the desired output
+ directly to an application-specified area rather than always allocating a new
+ heap buffer.
+
+* HKDF, previously provided using a non-standard interface, now uses the
+ standard KDF interface and is retrievable using get_kdf.
+
+* It is once again possible to build the complete test suite without requiring
+ any boost libraries. This is currently only supported on systems supporting
+ the readdir interface.
+
+* Remove use of memset_s which caused problems with amalgamation on OS X.
+ Github 42, 45
+
+* The memory usage of the counter mode implementation has been reduced.
+ Previously it encrypted 256 blocks in parallel as this leads to a slightly
+ faster counter increment operation. Instead CTR_BE simply encrypts a buffer
+ equal in size to the advertised parallelism of the cipher implementation.
+ This is not measurably slower, and dramatically reduces the memory use of
+ CTR mode.
+
+* The memory allocator available on Unix systems which uses mmap and mlock to
+ lock a pool of memory now checks environment variable BOTAN_MLOCK_POOL_SIZE
+ and interprets it as an integer. If the value set to a smaller value then the
+ library would originally have allocated (based on resource limits) the user
+ specified size is used instead. You can also set the variable to 0 to
+ disable the pool entirely. Previously the allocator would consume all
+ available mlocked memory, this allows botan to coexist with an application
+ which wants to mlock memory for its own uses.
+
+* The botan-config script previously installed on Unix systems has been
+ removed. Its functionality is replaced by the ``config`` command of the
+ ``botan`` tool executable, for example ``botan config cflags`` instead of
+ ``botan-config --cflags``.
+
+* Added a target for POWER8 processors
+
+Version 1.11.13, 2015-01-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* All support for the insecure SSLv3 protocol and the server support
+ for processing SSLv2 client hellos has been removed.
+
+* The command line tool now has ``tls_proxy`` which negotiates TLS with
+ clients and forwards the plaintext to a specified port.
+
+* Add MCEIES, a McEliece-based integrated encryption system using
+ AES-256 in OCB mode for message encryption/authentication.
+
+* Add DTLS-SRTP negotiation defined in RFC 5764
+
+* Add SipHash
+
+* Add SHA-512/256
+
+* The format of serialized TLS sessions has changed. Additiionally, PEM
+ formatted sessions now use the label of "TLS SESSION" instead of "SSL SESSION"
+
+* Serialized TLS sessions are now encrypted using AES-256/GCM instead of a
+ CBC+HMAC construction.
+
+* The cryptobox_psk module added in 1.11.4 and previously used for TLS session
+ encryption has been removed.
+
+* When sending a TLS heartbeat message, the number of pad bytes to use can now
+ be specified, making it easier to use for PMTU discovery.
+
+* If available, zero_mem now uses RtlSecureZeroMemory or memset_s instead of a
+ byte-at-a-time loop.
+
+* The functions base64_encode and base64_decode would erroneously
+ throw an exception if passed a zero-length input. Github issue 37.
+
+* The Python install script added in version 1.11.10 failed to place the
+ headers into a versioned subdirectory.
+
+* Fix the install script when running under Python3.
+
+* Avoid code that triggers iterator debugging asserts under MSVC 2013. Github
+ pull 36 from Simon Warta.
+
+Version 1.11.12, 2015-01-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add Curve25519. The implementation is based on curve25519-donna-c64.c
+ by Adam Langley. New (completely non-standard) OIDs and formats for
+ encrypting Curve25519 keys under PKCS #8 and including them in
+ certificates and CRLs have been defined.
+
+* Add Poly1305, based on the implementation poly1305-donna by Andrew Moon.
+
+* Add the ChaCha20Poly1305 AEADs defined in draft-irtf-cfrg-chacha20-poly1305-03
+ and draft-agl-tls-chacha20poly1305-04.
+
+* Add ChaCha20Poly1305 ciphersuites for TLS compatible with Google's servers
+ following draft-agl-tls-chacha20poly1305-04
+
+* When encrypted as PKCS #8 structures, Curve25519 and McEliece
+ private keys default to using AES-256/GCM instead of AES-256/CBC
+
+* Define OIDs for OCB mode with AES, Serpent and Twofish.
+
+Version 1.11.11, 2014-12-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The Sqlite3 wrapper has been abstracted to a simple interface for
+ SQL dbs in general, though Sqlite3 remains the only implementation.
+ The main logic of the TLS session manager which stored encrypted
+ sessions to a Sqlite3 database (``TLS::Session_Manager_SQLite``) has
+ been moved to the new ``TLS::Session_Manager_SQL``. The Sqlite3
+ manager API remains the same but now just subclasses
+ ``TLS::Session_Manager_SQL`` and has a constructor instantiate the
+ concrete database instance.
+
+ Applications which would like to use a different db can now do so
+ without having to reimplement the session cache logic simply by
+ implementing a database wrapper subtype.
+
+* The CryptGenRandom entropy source is now also used on MinGW.
+
+* The system_rng API is now also available on systems with CryptGenRandom
+
+* With GCC use -fstack-protector for linking as well as compiling,
+ as this is required on MinGW. Github issue 34.
+
+* Fix missing dependency in filters that caused compilation problem
+ in amalgamation builds. Github issue 33.
+
+* SSLv3 support is officially deprecated and will be removed in a
+ future release.
+
+Version 1.10.9, 2014-12-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed EAX tag verification to run in constant time
+
+* The default TLS policy now disables SSLv3.
+
+* A crash could occur when reading from a blocking random device if
+ the device initially indicated that entropy was available but
+ a concurrent process drained the entropy pool before the
+ read was initiated.
+
+* Fix decoding indefinite length BER constructs that contain a context
+ sensitive tag of zero. Github pull 26 from Janusz Chorko.
+
+* The ``botan-config`` script previously tried to guess its prefix from
+ the location of the binary. However this was error prone, and now
+ the script assumes the final installation prefix matches the value
+ set during the build. Github issue 29.
+
+Version 1.11.10, 2014-12-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* An implementation of McEliece code-based public key encryption based
+ on INRIA's HyMES and secured against a variety of side-channels was
+ contributed by cryptosource GmbH. The original version is LGPL but
+ cryptosource has secured permission to release an adaptation under a
+ BSD license. A CCA2-secure KEM scheme is also included.
+
+ The implementation is further described in
+ http://www.cryptosource.de/docs/mceliece_in_botan.pdf and
+ http://cryptosource.de/news_mce_in_botan_en.html
+
+* DSA and ECDSA now create RFC 6979 deterministic signatures.
+
+* Add support for TLS fallback signaling (draft-ietf-tls-downgrade-scsv-00).
+ Clients will send a fallback SCSV if the version passed to the Client
+ constructor is less than the latest version supported by local policy, so
+ applications implementing fallback are protected. Servers always check the
+ SCSV.
+
+* In previous versions a TLS::Server could service either TLS or DTLS
+ connections depending on policy settings and what type of client hello it
+ received. This has changed and now a Server object is initialized for
+ either TLS or DTLS operation. The default policy previously prohibited
+ DTLS, precisely to prevent a TCP server from being surprised by a DTLS
+ connection. The default policy now allows TLS v1.0 or higher or DTLS v1.2.
+
+* Fixed a bug in CCM mode which caused it to produce incorrect tags when used
+ with a value of L other than 2. This affected CCM TLS ciphersuites, which
+ use L=3. Thanks to Manuel Pégourié-Gonnard for the anaylsis and patch.
+ Bugzilla 270.
+
+* DTLS now supports timeouts and handshake retransmits. Timeout checking
+ is triggered by the application calling the new TLS::Channel::timeout_check.
+
+* Add a TLS policy hook to disable putting the value of the local clock in hello
+ random fields.
+
+* All compression operations previously available as Filters are now
+ performed via the Transformation API, which minimizes memory copies.
+ Compression operations are still available through the Filter API
+ using new general compression/decompression filters in comp_filter.h
+
+* The zlib module now also supports gzip compression and decompression.
+
+* Avoid a crash in low-entropy situations when reading from /dev/random, when
+ select indicated the device was readable but by the time we start the read the
+ entropy pool had been depleted.
+
+* The Miller-Rabin primality test function now takes a parameter allowing the
+ user to directly specify the maximum false negative probability they are
+ willing to accept.
+
+* PKCS #8 private keys can now be encrypted using GCM mode instead of
+ unauthenticated CBC. The default remains CBC for compatibility.
+
+* The default PKCS #8 encryption scheme has changed to use PBKDF2 with
+ SHA-256 instead of SHA-1
+
+* A specialized reducer for P-521 was added.
+
+* On Linux the mlock allocator will use MADV_DONTDUMP on the pool so
+ that the contents are not included in coredumps.
+
+* A new interface for directly using a system-provided PRNG is
+ available in system_rng.h. Currently only systems with /dev/urandom
+ are supported.
+
+* Fix decoding indefinite length BER constructs that contain a context sensitive
+ tag of zero. Github pull 26 from Janusz Chorko.
+
+* The GNU MP engine has been removed.
+
+* Added AltiVec detection for POWER8 processors.
+
+* Add a new install script written in Python which replaces shell hackery in the
+ makefiles.
+
+* Various modifications to better support Visual C++ 2013 and 2015. Github
+ issues 11, 17, 18, 21, 22.
+
+Version 1.10.8, 2014-04-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* SECURITY: Fix a bug in primality testing introduced in 1.8.3 which
+ caused only a single random base, rather than a sequence of random
+ bases, to be used in the Miller-Rabin test. This increased the
+ probability that a non-prime would be accepted, for instance a 1024
+ bit number would be incorrectly classed as prime with probability
+ around 2^-40. Reported by Jeff Marrison. CVE-2014-9742
+
+* The key length limit on HMAC has been raised to 512 bytes, allowing
+ the use of very long passphrases with PBKDF2.
+
+Version 1.11.9, 2014-04-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* SECURITY: Fix a bug in primality testing introduced in 1.8.3 which
+ caused only a single random base, rather than a sequence of random
+ bases, to be used in the Miller-Rabin test. This increased the
+ probability that a non-prime would be accepted, for instance a 1024
+ bit number would be incorrectly classed as prime with probability
+ around 2^-40. Reported by Jeff Marrison. CVE-2014-9742
+
+* X.509 path validation now returns a set of all errors that occurred
+ during validation, rather than immediately returning the first
+ detected error. This prevents a seemingly innocuous error (such as
+ an expired certificate) from hiding an obviously serious error
+ (such as an invalid signature). The Certificate_Status_Code enum is
+ now ordered by severity, and the most severe error is returned by
+ Path_Validation_Result::result(). The entire set of status codes is
+ available with the new all_statuses call.
+
+* Fixed a bug in OCSP response decoding which would cause an error
+ when attempting to decode responses from some widely used
+ responders.
+
+* An implementation of HMAC_DRBG RNG from NIST SP800-90A has been
+ added. Like the X9.31 PRNG implementation, it uses another
+ underlying RNG for seeding material.
+
+* An implementation of the RFC 6979 deterministic nonce generator has
+ been added.
+
+* Fix a bug in certificate path validation which prevented successful
+ validation if intermediate certificates were presented out of order.
+
+* Fix a bug introduced in 1.11.5 which could cause crashes or other
+ incorrect behavior when a cipher mode filter was followed in the
+ pipe by another filter, and that filter had a non-empty start_msg.
+
+* The types.h header now uses stdint.h rather than cstdint to avoid
+ problems with Clang on OS X.
+
+Version 1.11.8, 2014-02-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The ``botan`` command line application introduced in 1.11.7 is now
+ installed along with the library.
+
+* A bug in certificate path validation introduced in 1.11.6 which
+ caused all CRL signature checks to fail has been corrected.
+
+* The ChaCha20 stream cipher has been added.
+
+* The ``Transformation`` class no longer implements an interface for keying,
+ this has been moved to a new subclass ``Keyed_Transformation``.
+
+* The ``Algorithm`` class, which previously acted as a global base for
+ various types (ciphers, hashes, etc) has been removed.
+
+* CMAC now supports 256 and 512 bit block ciphers, which also allows
+ the use of larger block ciphers with EAX mode. In particular this
+ allows using Threefish in EAX mode.
+
+* The antique PBES1 private key encryption scheme (which only supports
+ DES or 64-bit RC2) has been removed.
+
+* The Square, Skipjack, and Luby-Rackoff block ciphers have been removed.
+
+* The Blue Midnight Wish hash function has been removed.
+
+* Skein-512 no longer supports output lengths greater than 512 bits.
+
+* Skein did not reset its internal state properly if clear() was
+ called, causing it to produce incorrect results for the following
+ message. It was reset correctly in final() so most usages should not
+ be affected.
+
+* A number of public key padding schemes have been renamed to match
+ the most common notation; for instance EME1 is now called OAEP and
+ EMSA4 is now called PSSR. Aliases are set which should allow all
+ current applications to continue to work unmodified.
+
+* A bug in CFB encryption caused a few bytes past the end of the final
+ block to be read. The actual output was not affected.
+
+* Fix compilation errors in the tests that occurred with minimized
+ builds. Contributed by Markus Wanner.
+
+* Add a new ``--destdir`` option to ``configure.py`` which controls
+ where the install target will place the output. The ``--prefix``
+ option continues to set the location where the library expects to be
+ eventually installed.
+
+* Many class destructors which previously deleted memory have been
+ removed in favor of using ``unique_ptr``.
+
+* Various portability fixes for Clang, Windows, Visual C++ 2013, OS X,
+ and x86-32.
+
+Version 1.11.7, 2014-01-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Botan's basic numeric types are now defined in terms of the
+ C99/C++11 standard integer types. For instance ``u32bit`` is now a
+ typedef for ``uint32_t``, and both names are included in the library
+ namespace. This should not result in any application-visible
+ changes.
+
+* There are now two executable outputs of the build, ``botan-test``,
+ which runs the tests, and ``botan`` which is used as a driver to call
+ into various subcommands which can also act as examples of library
+ use, much in the manner of the ``openssl`` command. It understands the
+ commands ``base64``, ``asn1``, ``x509``, ``tls_client``, ``tls_server``,
+ ``bcrypt``, ``keygen``, ``speed``, and various others. As part of this
+ change many obsolete, duplicated, or one-off examples were removed,
+ while others were extended with new functionality. Contributions of
+ new subcommands, new bling for exising ones, or documentation in any
+ form is welcome.
+
+* Fix a bug in Lion, which was broken by a change in 1.11.0. The
+ problem was not noticed before as Lion was also missing a test vector
+ in previous releases.
+
+Version 1.10.7, 2013-12-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* OAEP had two bugs, one of which allowed it to be used even if the
+ key was too small, and the other of which would cause a crash during
+ decryption if the EME data was too large for the associated key.
+
+Version 1.11.6, 2013-12-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The Boost filesystem and asio libraries are now being used by default.
+ Pass ``--without-boost`` to ``configure.py`` to disable.
+
+* The default TLS policy no longer allows SSLv3 or RC4.
+
+* OAEP had two bugs, one of which allowed it to be used even if the
+ key was too small, and the other of which would cause a crash during
+ decryption if the EME data was too large for the associated key.
+
+* GCM mode now uses the Intel clmul instruction when available
+
+* Add the Threefish-512 tweakable block cipher, including an AVX2 version
+
+* Add SIV (from :rfc:`5297`) as a nonce-based AEAD
+
+* Add HKDF (from :rfc:`5869`) using an experimental PRF interface
+
+* Add HTTP utility functions and OCSP online checking
+
+* Add TLS::Policy::acceptable_ciphersuite hook to disable ciphersuites
+ on an ad-hoc basis.
+
+* TLS::Session_Manager_In_Memory's constructor now requires a RNG
+
+Version 1.10.6, 2013-11-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The device reading entropy source now attempts to read from all
+ available devices. Previously it would break out early if a partial
+ read from a blocking source occurred, not continuing to read from a
+ non-blocking device. This would cause the library to fall back on
+ slower and less reliable techniques for collecting PRNG seed
+ material. Reported by Rickard Bellgrim.
+
+* HMAC_RNG (the default PRNG implementation) now automatically reseeds
+ itself periodically. Previously reseeds only occurred on explicit
+ application request.
+
+* Fix an encoding error in EC_Group when encoding using EC_DOMPAR_ENC_OID.
+ Reported by fxdupont on github.
+
+* In EMSA2 and Randpool, avoid calling name() on objects after deleting them if
+ the provided algorithm objects are not suitable for use. Found by Clang
+ analyzer, reported by Jeffrey Walton.
+
+* If X509_Store was copied, the u32bit containing how long to cache validation
+ results was not initialized, potentially causing results to be cached for
+ significant amounts of time. This could allow a certificate to be considered
+ valid after its issuing CA's cert expired. Expiration of the end-entity cert
+ is always checked, and reading a CRL always causes the status to be reset, so
+ this issue does not affect revocation. Found by Coverity scanner.
+
+* Avoid off by one causing a potentially unterminated string to be passed to
+ the connect system call if the library was configured to use a very long path
+ name for the EGD socket. Found by Coverity Scanner.
+
+* In PK_Encryptor_EME, PK_Decryptor_EME, PK_Verifier, and PK_Key_Agreement,
+ avoid dereferencing an unitialized pointer if no engine supported operations
+ on the key object given. Found by Coverity scanner.
+
+* Avoid leaking a file descriptor in the /dev/random and EGD entropy sources if
+ stdin (file descriptor 0) was closed. Found by Coverity scanner.
+
+* Avoid a potentially undefined operation in the bit rotation operations. Not
+ known to have caused problems under any existing compiler, but might have
+ caused problems in the future. Caught by Clang sanitizer, reported by Jeffrey
+ Walton.
+
+* Increase default hash iterations from 10000 to 50000 in PBES1 and PBES2
+
+* Add a fix for mips64el builds from Brad Smith.
+
+Version 1.11.5, 2013-11-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The TLS callback signatures have changed - there are now two distinct
+ callbacks for application data and alerts. TLS::Client and TLS::Server have
+ constructors which continue to accept the old callback and use it for both
+ operations.
+
+* The entropy collector that read from randomness devices had two bugs - it
+ would break out of the poll as soon as any read succeeded, and it selected on
+ each device individually. When a blocking source was first in the device list
+ and the entropy pool was running low, the reader might either block in select
+ until eventually timing out (continuing on to read from /dev/urandom instead),
+ or read just a few bytes, skip /dev/urandom, fail to satisfy the entropy
+ target, and the poll would continue using other (slower) sources. This caused
+ substantial performance/latency problems in RNG heavy applications. Now all
+ devices are selected over at once, with the effect that a full read from
+ urandom always occurs, along with however much (if any) output is available
+ from blocking sources.
+
+* Previously AutoSeeded_RNG referenced a globally shared PRNG instance.
+ Now each instance has distinct state.
+
+* The entropy collector that runs Unix programs to collect statistical
+ data now runs multiple processes in parallel, greatly reducing poll
+ times on some systems.
+
+* The Randpool RNG implementation was removed.
+
+* All existing cipher mode implementations (such as CBC and XTS) have been
+ converted from filters to using the interface previously provided by
+ AEAD modes which allows for in-place message
+ processing. Code which directly references the filter objects will break, but
+ an adaptor filter allows usage through get_cipher as usual.
+
+* An implementation of CCM mode from RFC 3601 has been added, as well as CCM
+ ciphersuites for TLS.
+
+* The implementation of OCB mode now supports 64 and 96 bit tags
+
+* Optimized computation of XTS tweaks, producing a substantial speedup
+
+* Add support for negotiating Brainpool ECC curves in TLS
+
+* TLS v1.2 will not negotiate plain SHA-1 signatures by default.
+
+* TLS channels now support sending a ``std::vector``
+
+* Add a generic 64x64->128 bit multiply instruction operation in mul128.h
+
+* Avoid potentially undefined operations in the bit rotation operations. Not
+ known to have caused problems under existing compilers but might break in the
+ future. Found by Clang sanitizer, reported by Jeffrey Walton.
+
+Version 1.11.4, 2013-07-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* CPU specific extensions are now always compiled if support for the
+ operations is available at build time, and flags enabling use of
+ extra operations (such as SSE2) are only included when compiling
+ files which specifically request support. This means, for instance,
+ that the SSSE3 and AES-NI implementations of AES are always included
+ in x86 builds, relying on runtime cpuid checking to prevent their
+ use on CPUs that do not support those operations.
+
+* The default TLS policy now only accepts TLS, to minimize surprise
+ for servers which might not expect to negotiate DTLS. Previously a
+ server would by default negotiate either protocol type (clients
+ would only accept the same protocol type as they
+ offered). Applications which use DTLS or combined TLS/DTLS need to
+ override ``Policy::acceptable_protocol_version``.
+
+* The TLS channels now accept a new parameter specifying how many
+ bytes to preallocate for the record handling buffers, which allows
+ an application some control over how much memory is used at runtime
+ for a particular connection.
+
+* Applications can now send arbitrary TLS alert messages using
+ ``TLS::Channel::send_alert``
+
+* A new TLS policy ``NSA_Suite_B_128`` is available, which
+ will negotiate only the 128-bit security NSA Suite B. See
+ :rfc:`6460` for more information about Suite B.
+
+* Adds a new interface for benchmarking, ``time_algorithm_ops``,
+ which returns a map of operations to operations per second. For
+ instance now both encrypt and decrypt speed of a block cipher can be
+ checked, as well as the key schedule of all keyed algorithms. It
+ additionally supports AEAD modes.
+
+* Rename ARC4 to RC4
+
+Version 1.11.3, 2013-04-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add a new interface for AEAD modes (``AEAD_Mode``).
+
+* Implementations of the OCB and GCM authenticated cipher modes are
+ now included.
+
+* Support for TLS GCM ciphersuites is now available.
+
+* A new TLS policy mechanism
+ ``TLS::Policy::server_uses_own_ciphersuite_preferences``
+ controls how a server chooses a ciphersuite. Previously it always
+ chose its most preferred cipher out of the client's list, but this
+ can allow configuring a server to choose by the client's preferences
+ instead.
+
+* ``Keyed_Filter`` now supports returning a
+ ``Key_Length_Specification`` so the full details of what
+ keylengths are supported is now available in keyed filters.
+
+* The experimental and rarely used Turing and WiderWAKE stream ciphers
+ have been removed
+
+* New functions for symmetric encryption are included in cryptobox.h
+ though interfaces and formats are subject to change.
+
+* A new function ``algorithm_kat_detailed`` returns a string
+ providing information about failures, instead of just a pass/fail
+ indicator as in ``algorithm_kat``.
+
+Version 1.10.5, 2013-03-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A potential crash in the AES-NI implementation of the AES-192 key
+ schedule (caused by misaligned loads) has been fixed.
+
+* A previously conditional operation in Montgomery multiplication and
+ squaring is now always performed, removing a possible timing
+ channel.
+
+* Use correct flags for creating a shared library on OS X under Clang.
+
+* Fix a compile time incompatibility with Visual C++ 2012.
+
+Version 1.11.2, 2013-03-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A bug in the release script caused the ``botan_version.py`` included
+ in 1.11.1`` to be invalid, which required a manual edit to fix
+ (Bugzilla 226)
+
+* Previously ``clear_mem`` was implemented by an inlined call to
+ ``std::memset``. However an optimizing compiler might notice cases
+ where the memset could be skipped in cases allowed by the standard.
+ Now ``clear_mem`` calls ``zero_mem`` which is compiled separately and
+ which zeros out the array through a volatile pointer. It is possible
+ some compiler with some optimization setting (especially with
+ something like LTO) might still skip the writes. It would be nice if
+ there was an automated way to test this.
+
+* The new filter ``Threaded_Fork`` acts like a normal
+ ``Fork``, sending its input to a number of different
+ filters, but each subchain of filters in the fork runs in its own
+ thread. Contributed by Joel Low.
+
+* The default TLS policy formerly preferred AES over RC4, and allowed
+ 3DES by default. Now the default policy is to negotiate only either
+ AES or RC4, and to prefer RC4.
+
+* New TLS ``Blocking_Client`` provides a thread per
+ connection style API similar to that provided in 1.10
+
+* The API of ``Credentials_Manager::trusted_certificate_authorities``
+ has changed to return a vector of ``Certificate_Store*`` instead of
+ ``X509_Certificate``. This allows the list of trusted CAs to be
+ more easily updated dynamically or loaded lazily.
+
+* The ``asn1_int.h`` header was split into ``asn1_alt_name.h``,
+ ``asn1_attribute.h`` and ``asn1_time.h``.
+
+Version 1.10.4, 2013-01-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Avoid a conditional operation in the power mod implementations on if
+ a nibble of the exponent was zero or not. This may help protect
+ against certain forms of side channel attacks.
+
+* The SRP6 code was checking for invalid values as specified in RFC
+ 5054, specifically values equal to zero mod p. However SRP would
+ accept negative A/B values, or ones larger than p, neither of which
+ should occur in a normal run of the protocol. These values are now
+ rejected. Credits to Timothy Prepscius for pointing out these values
+ are not normally used and probably signal something fishy.
+
+* The return value of version_string is now a compile time constant
+ string, so version information can be more easily extracted from
+ binaries.
+
+Version 1.11.1, 2012-10-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Initial support for DTLS (both v1.0 and v1.2) is available in this
+release, though it should be considered highly experimental. Currently
+timeouts and retransmissions are not handled.
+
+The ``TLS::Client`` constructor now takes the version to
+offer to the server. The policy hook ``TLS::Policy`` function
+`pref_version``, which previously controlled this, has been removed.
+
+`TLS::Session_Manager_In_Memory`` now chooses a random
+256-bit key at startup and encrypts all sessions (using the existing
+`TLS::Session::encrypt`` mechanism) while they are stored in
+memory. This is primarily to reduce pressure on locked memory, as each
+session normally requires 48 bytes of locked memory for the master
+secret, whereas now only 32 bytes are needed total. This change may
+also make it slightly harder for an attacker to extract session data
+from memory dumps (eg with a cold boot attack).
+
+The keys used in TLS session encryption were previously uniquely
+determined by the master key. Now the encrypted session blob includes
+two 80 bit salts which are used in the derivation of the cipher and
+MAC keys.
+
+The ``secure_renegotiation`` flag is now considered an aspect of the
+connection rather than the session, which matches the behavior of
+other implementations. As the format has changed, sessions saved to
+persistent storage by 1.11.0 will not load in this version and vice
+versa. In either case this will not cause any errors, the session will
+simply not resume and instead a full handshake will occur.
+
+New policy hooks ``TLS::Policy::acceptable_protocol_version``,
+`TLS::Policy::allow_server_initiated_renegotiation``, and
+`TLS::Policy::negotiate_heartbeat_support`` were added.
+
+TLS clients were not sending a next protocol message during a session
+resumption, which would cause resumption failures with servers that
+support NPN if NPN was being offered by the client.
+
+A bug caused heartbeat requests sent by the counterparty during a
+handshake to be passed to the application callback as if they were
+heartbeat responses.
+
+Support for TLS key material export as specified in :rfc:`5705` has
+been added, available via ``TLS::Channel::key_material_export``
+
+A new function ``Public_Key::estimated_strength`` returns
+an estimate for the upper bound of the strength of the key. For
+instance for an RSA key, it will return an estimate of how many
+operations GNFS would take to factor the key.
+
+A new ``Path_Validation_Result`` code has been added
+``SIGNATURE_METHOD_TOO_WEAK``. By default signatures created with keys
+below 80 bits of strength (as estimated by ``estimated_strength``) are
+rejected. This level can be modified using a parameter to the
+``Path_Validation_Restrictions`` constructor.
+
+The SRP6 code was checking for invalid values as specified in
+:rfc:`5054`, ones equal to zero mod p, however it would accept
+negative A/B values, or ones larger than p, neither of which should
+occur in a normal run of the protocol. These values are now
+rejected. Credits to Timothy Prepscius for pointing out these values
+are not normally used and probably signal something fishy.
+
+Several ``BigInt`` functions have been removed, including
+``operator[]``, ``assign``, ``get_reg``, and ``grow_reg``. The version
+of ``data`` that returns a mutable pointer has been renamed
+``mutable_data``. Support for octal conversions has been removed.
+
+The constructor ``BigInt(NumberType type, size_t n)`` has been
+removed, replaced by ``BigInt::power_of_2``.
+
+In 1.11.0, when compiled by GCC, the AES-NI implementation of AES-192
+would crash if the mlock-based allocator was used due to an alignment
+issue.
+
+Version 1.11.0, 2012-07-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+ In this release, many new features of C++11 are being used in the
+ library. Currently GCC 4.7 and Clang 3.1 are known to work well.
+ This version of the library cannot be compiled by or used with a
+ C++98 compiler.
+
+There have been many changes and improvements to TLS. The interface
+is now purely event driven and does not directly interact with
+sockets. New TLS features include TLS v1.2 support, client
+certificate authentication, renegotiation, session tickets, and
+session resumption. Session information can be saved in memory or to
+an encrypted SQLite3 database. Newly supported TLS ciphersuite
+algorithms include using SHA-2 for message authentication, pre shared
+keys and SRP for authentication and key exchange, ECC algorithms for
+key exchange and signatures, and anonymous DH/ECDH key exchange.
+
+Support for OCSP has been added. Currently only client-side support
+exists.
+
+The API for X.509 path validation has changed, with
+``x509_path_validate`` in x509path.h now handles path validation and
+``Certificate_Store`` handles storage of certificates and CRLs.
+
+The memory container types have changed substantially. The
+``MemoryVector`` and ``SecureVector`` container types have been
+removed, and an alias of ``std::vector`` using an allocator that
+clears memory named ``secure_vector`` is used for key material, with
+plain ``std::vector`` being used for everything else.
+
+The technique used for mlock'ing memory on Linux and BSD systems is
+much improved. Now a single page-aligned block of memory (the exact
+limit of what we can mlock) is mmap'ed, with allocations being done
+using a best-fit allocator and all metadata held outside the mmap'ed
+range, in an effort to make best use of the very limited amount of
+memory current Linux kernels allow unpriveledged users to lock.
+
+A filter using LZMA was contributed by Vojtech Kral. It is available
+if LZMA support was enabled at compilation time by passing
+``--with-lzma`` to ``configure.py``.
+
+:rfc:`5915` adds some extended information which can be included in
+ECC private keys which the ECC key decoder did not expect, causing an
+exception when such a key was loaded. In particular, recent versions
+of OpenSSL use these fields. Now these fields are decoded properly,
+and if the public key value is included it is used, as otherwise the
+public key needs to be rederived from the private key. However the
+library does not include these fields on encoding keys for
+compatibility with software that does not expect them (including older
+versions of botan).
+
+Version 1.8.14, 2012-07-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The malloc allocator would return null instead of throwing in the
+ event of an allocation failure, which could cause an application
+ crash due to null pointer dereference where normally an exception
+ would occur.
+
+* Recent versions of OpenSSL include extra information in ECC private
+ keys, the presence of which caused an exception when such a key was
+ loaded by botan. The decoding of ECC private keys has been changed to
+ ignore these fields if they are set.
+
+* AutoSeeded_RNG has been changed to prefer ``/dev/random`` over
+ ``/dev/urandom``
+
+* Fix detection of s390x (Debian bug 638347)
+
+Version 1.10.3, 2012-07-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A change in 1.10.2 accidentally broke ABI compatibility with 1.10.1
+and earlier versions, causing programs compiled against 1.10.1 to
+crash if linked with 1.10.2 at runtime.
+
+Recent versions of OpenSSL include extra information in ECC private
+keys, the presence of which caused an exception when such a key was
+loaded by botan. The decoding of ECC private keys has been changed to
+ignore these fields if they are set.
+
+Version 1.10.2, 2012-06-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Several TLS bugs were fixed in this release, including a major
+omission that the renegotiation extension was not being used. As the
+1.10 implementation of TLS does not properly support renegotiation,
+the approach in this release is simply to send the renegotiation
+extension SCSV, which should protect the client against any handshake
+splicing. In addition renegotiation attempts are handled properly
+instead of causing handshake failures - all hello requests, and all
+client hellos after the initial negotiation, are ignored. Some
+bugs affecting DSA server authentication were also fixed.
+
+By popular request, ``Pipe::reset`` no longer requires that message
+processing be completed, a requirement that caused problems when a
+Filter's end_msg call threw an exception, after which point the Pipe
+object was no longer usable.
+
+Support for getting entropy using the rdrand instruction introduced in
+Intel's Ivy Bridge processors has been added. In previous releases,
+the ``CPUID::has_rdrand`` function was checking the wrong cpuid bit,
+and would false positive on AMD Bulldozer processors.
+
+An implementation of SRP-6a compatible with the specification in RFC
+5054 is now available in ``srp6.h``. In 1.11, this is being used for
+TLS-SRP, but may be useful in other environments as well.
+
+An implementation of the Camellia block cipher was added, again largely
+for use in TLS.
+
+If ``clock_gettime`` is available on the system, hres_timer will poll all
+the available clock types.
+
+AltiVec is now detected on IBM POWER7 processors and on OpenBSD systems.
+The OpenBSD support was contributed by Brad Smith.
+
+The Qt mutex wrapper was broken and would not compile with any recent
+version of Qt. Taking this as a clear indication that it is not in use,
+it has been removed.
+
+Avoid setting the soname on OpenBSD, as it doesn't support it (Bugzilla 158)
+
+A compilation problem in the dynamic loader that prevented using
+dyn_load under MinGW GCC has been fixed.
+
+A common error for people using MinGW is to target GCC on Windows,
+however the 'Windows' target assumes the existence of Visual C++
+runtime functions which do not exist in MinGW. Now, configuring for
+GCC on Windows will cause the configure.py to warn that likely you
+wanted to configure for either MinGW or Cygwin, not the generic
+Windows target.
+
+A bug in configure.py would cause it to interpret ``--cpu=s390x`` as
+``s390``. This may have affected other CPUs as well. Now configure.py
+searches for an exact match, and only if no exact match is found will
+it search for substring matches.
+
+An incompatibility in configure.py with the subprocess module included
+in Python 3.1 has been fixed (Bugzilla 157).
+
+The exception catching syntax of configure.py has been changed to the
+Python 3.x syntax. This syntax also works with Python 2.6 and 2.7, but
+not with any earlier Python 2 release. A simple search and replace
+will allow running it under Python 2.5::
+
+ perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py
+
+Note that Python 2.4 is not supported at all.
+
+Version 1.10.1, 2011-07-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A race condition in ``Algorithm_Factory`` could cause crashes in
+ multithreaded code.
+
+* The return value of ``name`` has changed for GOST 28147-89 and
+ Skein-512. GOST's ``name`` now includes the name of the sbox, and
+ Skein's includes the personalization string (if nonempty). This
+ allows an object to be properly roundtripped, which is necessary to
+ fix the race condition described above.
+
+* A new distribution script is now included, as
+ ``src/build-data/scripts/dist.py``
+
+* The ``build.h`` header now includes, if available, an identifier of
+ the source revision that was used. This identifier is also included
+ in the result of ``version_string``.
+
+Version 1.8.13, 2011-07-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A race condition in ``Algorithm_Factory`` could cause crashes in
+ multithreaded code.
+
+Version 1.10.0, 2011-06-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Detection for the rdrand instruction being added to upcoming Intel
+ Ivy Bridge processors has been added.
+
+* A template specialization of std::swap was added for the memory
+ container types.
+
+Version 1.8.12, 2011-06-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* If EMSA3(Raw) was used for more than one signature, it would produce
+ incorrect output.
+
+* Fix the --enable-debug option to configure.py
+
+* Improve OS detection on Cygwin
+
+* Fix compilation under Sun Studio 12 on Solaris
+
+* Fix a memory leak in the constructors of DataSource_Stream and
+ DataSink_Stream which would occur if opening the file failed (Bugzilla 144)
+
+Version 1.9.18, 2011-06-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fourth release candidate for 1.10.0
+
+* The GOST 34.10 verification operation was not ensuring that s and r
+ were both greater than zero. This could potentially have meant it
+ would have accepted an invalid all-zero signature as valid for any
+ message. Due to how ECC points are internally represented it instead
+ resulted in an exception being thrown.
+
+* A simple multiexponentation algorithm is now used in ECDSA and
+ GOST-34.10 signature verification, leading to 20 to 25% improvements
+ in ECDSA and 25% to 40% improvements in GOST-34.10 verification
+ performance.
+
+* The internal representation of elliptic curve points has been
+ modified to use Montgomery representation exclusively, resulting in
+ reduced memory usage and a 10 to 20% performance improvement for
+ ECDSA and ECDH.
+
+* In OAEP decoding, scan for the delimiter bytes using a loop that is
+ written without conditionals so as to help avoid timing analysis.
+ Unfortunately GCC at least is 'smart' enough to compile it to
+ jumps anyway.
+
+* The SSE2 implementation of IDEA did not work correctly when compiled
+ by Clang, because the trick it used to emulate a 16 bit unsigned
+ compare in SSE (which doesn't contain one natively) relied on signed
+ overflow working in the 'usual' way. A different method that doesn't
+ rely on signed overflow is now used.
+
+* Add support for compiling SSL using Visual C++ 2010's TR1
+ implementation.
+
+* Fix a bug under Visual C++ 2010 which would cause ``hex_encode`` to
+ crash if given a zero-sized input to encode.
+
+* A new build option ``--via-amalgamation`` will first generate the
+ single-file amalgamation, then build the library from that single
+ file. This option requires a lot of memory and does not parallelize,
+ but the resulting library is smaller and may be faster.
+
+* On Unix, the library and header paths have been changed to allow
+ parallel installation of different versions of the library. Headers
+ are installed into ``<prefix>/include/botan-1.9/botan``, libraries
+ are named ``libbotan-1.9``, and ``botan-config`` is now namespaced
+ (so in this release ``botan-config-1.9``). All of these embedded
+ versions will be 1.10 in the upcoming stable release.
+
+* The soname system has been modified. In this release the library
+ soname is ``libbotan-1.9.so.0``, with the full library being named
+ ``libbotan-1.9.so.0.18``. The ``0`` is the ABI version, and will be
+ incremented whenever a breaking ABI change is made.
+
+* TR1 support is not longer automatically assumed under older versions
+ of GCC
+
+* Functions for base64 decoding that work standalone (without needing
+ to use a pipe) have been added to ``base64.h``
+
+* The function ``BigInt::to_u32bit`` was inadvertently removed in 1.9.11
+ and has been added back.
+
+* The function ``BigInt::get_substring`` did not work correctly with a
+ *length* argument of 32.
+
+* The implementation of ``FD_ZERO`` on Solaris uses ``memset`` and
+ assumes the caller included ``string.h`` on its behalf. Do so to
+ fix compilation in the ``dev_random`` and ``unix_procs`` entropy
+ sources. Patch from Jeremy C. Reed.
+
+* Add two different configuration targets for Atom, since some are
+ 32-bit and some are 64-bit. The 'atom' target now refers to the
+ 64-bit implementations, use 'atom32' to target the 32-bit
+ processors.
+
+* The (incomplete) support for CMS and card verifiable certificates
+ are disabled by default; add ``--enable-modules=cms`` or
+ ``--enable-modules=cvc`` during configuration to turn them back on.
+
+Version 1.9.17, 2011-04-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Third release candidate for 1.10.0
+
+* The format preserving encryption method currently available was
+ presented in the header ``fpe.h`` and the functions ``fpe_encrypt``
+ and ``fpe_decrypt``. These were renamed as it is likely that other
+ FPE schemes will be included in the future. The header is now
+ ``fpe_fe1.h``, and the functions are named ``fe1_encrypt`` and
+ ``fe1_decrypt``.
+
+* New options to ``configure.py`` control what tools are used for
+ documentation generation. The ``--with-sphinx`` option enables using
+ Sphinx to convert ReST into HTML; otherwise the ReST sources are
+ installed directly. If ``--with-doxygen`` is used, Doxygen will run
+ as well. Documentation generation can be triggered via the ``docs``
+ target in the makefile; it will also be installed by the install
+ target on Unix.
+
+* A bug in 1.9.16 effectively disabled support for runtime CPU feature
+ detection on x86 under GCC in that release.
+
+* A mostly internal change, all references to "ia32" and "amd64" have
+ been changed to the vendor neutral and probably easier to understand
+ "x86-32" and "x86-64". For instance, the "mp_amd64" module has been
+ renamed "mp_x86_64", and the macro indicating x86-32 has changed
+ from ``BOTAN_TARGET_ARCH_IS_IA32`` to
+ ``BOTAN_TARGET_ARCH_IS_X86_32``. The classes calling assembly have
+ also been renamed.
+
+* Similiarly to the above change, the AES implemenations using the
+ AES-NI instruction set have been renamed from AES_XXX_Intel to
+ AES_XXX_NI.
+
+* Systems that are identified as ``sun4u`` will default to compiling for
+ 32-bit SPARCv9 code rather than 64-bit. This matches the still
+ common convention for 32-bit SPARC userspaces. If you want 64-bit
+ code on such as system, use ``--cpu=sparc64``.
+
+* Some minor fixes for compiling botan under the BeOS
+ clone/continuation `Haiku <http://haiku-os.org>`_.
+
+* Further updates to the documentation
+
+Version 1.9.16, 2011-04-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Second release candidate for 1.10.0
+
+* The documentation, previously written in LaTeX, is now in
+ reStructuredText suitable for processing by `Sphinx
+ <http://sphinx.pocoo.org>`_, which can generate nicely formatted
+ HTML and PDFs. The documentation has also been greatly updated and
+ expanded.
+
+* The class ``EC_Domain_Params`` has been renamed ``EC_Group``, with a
+ typedef for backwards compatibility.
+
+* The ``EC_Group`` string constructor didn't understand the standard
+ names like "secp160r1", forcing use of the OIDs.
+
+* Two constructors for ECDSA private keys, the one that creates a new
+ random key, and the one that provides a preset private key as a
+ ``BigInt``, have been merged. This matches the existing interface
+ for DSA and DH keys. If you previously used the version taking a
+ ``BigInt`` private key, you'll have to additionally pass in a
+ ``RandomNumberGenerator`` object starting in this release.
+
+* It is now possible to create ECDH keys with a preset ``BigInt``
+ private key; previously no method for this was available.
+
+* The overload of ``generate_passhash9`` that takes an explicit
+ algorithm identifier has been merged with the one that does not.
+ The algorithm identifier code has been moved from the second
+ parameter to the fourth.
+
+* Change shared library versioning to match the normal Unix
+ conventions. Instead of ``libbotan-X.Y.Z.so``, the shared lib is
+ named ``libbotan-X.Y.so.Z``; this allows the runtime linker to do
+ its runtime linky magic. It can be safely presumed that any change
+ in the major or minor version indicates ABI incompatibility.
+
+* Remove the socket wrapper code; it was not actually used by anything
+ in the library, only in the examples, and you can use whatever kind
+ of (blocking) socket interface you like with the SSL/TLS code. It's
+ available as socket.h in the examples directory if you want to use
+ it.
+
+* Disable the by-default 'strong' checking of private keys that are
+ loaded from storage. You can always request key material sanity
+ checking using Private_Key::check_key.
+
+* Bring back removed functions ``min_keylength_of``,
+ ``max_keylength_of``, ``keylength_multiple_of`` in ``lookup.h`` to
+ avoid breaking applications written against 1.8
+
+Version 1.9.15, 2011-03-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* First release candidate for 1.10.0
+
+* Modify how message expansion is done in SHA-256 and SHA-512.
+ Instead of expanding the entire message at the start, compute them
+ in the minimum number of registers. Values are computed 15 rounds
+ before they are needed. On a Core i7-860, GCC 4.5.2, went from 143
+ to 157 MiB/s in SHA-256, and 211 to 256 MiB/s in SHA-512.
+
+* Pipe will delete empty output queues as soon as they are no longer
+ needed, even if earlier messages still have data unread. However an
+ (empty) entry in a deque of pointers will remain until all prior
+ messages are completely emptied.
+
+* Avoid reading the SPARC ``%tick`` register on OpenBSD as unlike the
+ Linux and NetBSD kernels, it will not trap and emulate it for us,
+ causing a illegal instruction crash.
+
+* Improve detection and autoconfiguration for ARM processors. Thanks
+ go out to the the `Tahoe-LAFS Software Foundation
+ <http://tahoe-lafs.org>`_, who donated a Sheevaplug that I'll be
+ using to figure out how to make the cryptographic primitives
+ Tahoe-LAFS relies on faster, particularly targeting the ARMv5TE.
+
+Version 1.9.14, 2011-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add support for bcrypt, OpenBSD's password hashing scheme.
+
+* Add support for NIST's AES key wrapping algorithm, as described in
+ :rfc:`3394`. It is available by including ``rfc3394.h``.
+
+* Fix an infinite loop in zlib filters introduced in 1.9.11 (Bugzilla 142)
+
+Version 1.9.13, 2011-02-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+GOST 34.10 signatures were being formatted in a way that was not
+compatible with other implemenations, and specifically how GOST is
+used in DNSSEC.
+
+The Keccak hash function was updated to the tweaked variant proposed
+for round 3 of the NIST hash competition. This version is not
+compatible with the previous algorithm.
+
+A new option ``--distribution-info`` was added to the configure
+script. It allows the user building the library to set any
+distribution-specific notes on the build, which are available as a
+macro ``BOTAN_DISTRIBUTION_INFO``. The default value is
+'unspecified'. If you are building an unmodified version of botan
+(especially for distribution), and want to indicate to applications
+that this is the case, consider using
+``--distribution-info=pristine``. If you are making any patches or
+modifications, it is recommended to use
+``--distribution-info=[Distribution Name] [Version]``, for instance
+'FooNix 1.9.13-r3'.
+
+Some bugs preventing compilation under Clang 2.9 and Sun Studio 12
+were fixed.
+
+The DER/BER codecs use ``size_t`` instead of ``u32bit`` for small
+integers
+
+Version 1.9.12, 2010-12-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add the Keccak hash function
+* Fix compilation problems in Python wrappers
+* Fix compilation problem in OpenSSL engine
+* Update SQLite3 database encryption codec
+
+Version 1.9.11, 2010-11-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The TLS API has changed substantially and now relies heavily on
+ TR1's ``std::function`` is now required. Additionally, it is
+ required that all callers derive a subclass of TLS_Policy and pass
+ it to a client or server object. Please remember that the TLS
+ interface/API is currently unstable and will very likely change
+ further before TLS is included in a stable release. A handshake
+ failure that occurred when RC4 was negotiated has also been fixed.
+
+* Some possible timing channels in the implementations of Montgomery
+ reduction and the IDEA key schedule were removed. The table-based
+ AES implementation uses smaller tables in the first round to help
+ make some timing/cache attacks harder.
+
+* The library now uses size_t instead of u32bit to represent
+ lengths. Also the interfaces for the memory containers have changed
+ substantially to better match STL container interfaces;
+ MemoryRegion::append, MemoryRegion::destroy, and MemoryRegion::set
+ were all removed, and several other functions, like clear and
+ resize, have changed meaning.
+
+* Update Skein-512 to match the v1.3 specification
+* Fix a number of CRL encoding and decoding bugs
+* Counter mode now always encrypts 256 blocks in parallel
+* Use small tables in the first round of AES
+* Removed AES class: app must choose AES-128, AES-192, or AES-256
+* Add hex encoding/decoding functions that can be used without a Pipe
+* Add base64 encoding functions that can be used without a Pipe
+* Add to_string function to X509_Certificate
+* Add support for dynamic engine loading on Windows
+* Replace BlockCipher::BLOCK_SIZE attribute with function block_size()
+* Replace HashFunction::HASH_BLOCK_SIZE attribute with hash_block_size()
+* Move PBKDF lookup to engine system
+* The IDEA key schedule has been changed to run in constant time
+* Add Algorithm and Key_Length_Specification classes
+* Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
+* Allow using PBKDF2 with empty passphrases
+* Add compile-time deprecation warnings for GCC, Clang, and MSVC
+* Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
+* Improve support for Intel Atom processors
+* Fix compilation problems under Sun Studio and Clang
+
+Version 1.8.11, 2010-11-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a number of CRL encoding and decoding bugs
+* When building a debug library under VC++, use the debug runtime
+* Fix compilation under Sun Studio on Linux and Solaris
+* Add several functions for compatibility with 1.9
+* In the examples, read most input files as binary
+* The Perl build script has been removed in this release
+
+Version 1.8.10, 2010-08-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Switch default PKCS #8 encryption algorithm from 3DES to AES-256
+* Increase default hash iterations from 2048 to 10000 in PBES1 and PBES2
+* Use small tables in the first round of AES
+* Add PBKDF typedef and get_pbkdf for better compatibility with 1.9
+* Add version of S2K::derive_key taking salt and iteration count
+* Enable the /proc-walking entropy source on NetBSD
+* Fix the doxygen makefile target
+
+Version 1.9.10, 2010-08-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add a constant-time AES implementation using SSSE3. This code is
+ based on public domain assembly written by `Mike Hamburg
+ <http://crypto.stanford.edu/vpaes/>`_, and described in his CHES
+ 2009 paper "Accelerating AES with Vector Permute Instructions". In
+ addition to being constant time, it is also significantly faster
+ than the table-based implementation on some processors. The current
+ code has been tested with GCC 4.5, Visual C++ 2008, and Clang 2.8.
+
+* Support for dynamically loading Engine objects at runtime was also
+ added. Currently only system that use ``dlopen``-style dynamic
+ linking are supported.
+
+* On GCC 4.3 and later, use the byteswap intrinsic functions.
+
+* Drop support for building with Python 2.4
+
+* Fix benchmarking of block ciphers in ECB mode
+
+* Consolidate the two x86 assembly engines
+
+* Rename S2K to PBKDF
+
+Version 1.9.9, 2010-06-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A new pure virtual function has been added to ``Filter``, ``name``
+which simply returns some useful identifier for the object. Any
+out-of-tree ``Filter`` implementations will need to be updated.
+
+Add ``Keyed_Filter::valid_iv_length`` which makes it possible to query
+as to what IV length(s) a particular filter allows. Previously,
+partially because there was no such query mechanism, if a filter did
+not support IVs at all, then calls to ``set_iv`` would be silently
+ignored. Now an exception about the invalid IV length will be thrown.
+
+The default iteration count for the password based encryption schemes
+has been increased from 2048 to 10000. This should make
+password-guessing attacks against private keys encrypted with versions
+after this release somewhat harder.
+
+New functions for encoding public and private keys to binary,
+``X509::BER_encode`` and ``PKCS8::BER_encode`` have been added.
+
+Problems compiling under Apple's version of GCC 4.2.1 and on 64-bit
+MIPS systems using GCC 4.4 or later were fixed.
+
+The coverage of Doxygen documentation comments has significantly
+improved in this release.
+
+Version 1.8.9, 2010-06-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Use constant time multiplication in IDEA
+
+* Avoid possible timing attack against OAEP decoding
+
+* Add new X509::BER_encode and PKCS8::BER_encode
+
+* Enable DLL builds under Windows
+
+* Add Win32 installer support
+
+* Add support for the Clang compiler
+
+* Fix problem in semcem.h preventing build under Clang or GCC 3.4
+
+* Fix bug that prevented creation of DSA groups under 1024 bits
+
+* Fix crash in GMP_Engine if library is shutdown and reinitialized and
+ a PK algorithm was used after the second init
+
+* Work around problem with recent binutils in x86-64 SHA-1
+
+* The Perl build script is no longer supported and refuses to run by
+ default. If you really want to use it, pass
+ ``--i-know-this-is-broken`` to the script.
+
+Version 1.9.8, 2010-06-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add support for wide multiplications on 64-bit Windows
+* Use constant time multiplication in IDEA
+* Avoid possible timing attack against OAEP decoding
+* Removed FORK-256; rarely used and it has been broken
+* Rename ``--use-boost-python`` to ``--with-boost-python``
+* Skip building shared libraries on MinGW/Cygwin
+* Fix creation of 512 and 768 bit DL groups using the DSA kosherizer
+* Fix compilation on GCC versions before 4.3 (missing cpuid.h)
+* Fix compilation under the Clang compiler
+
+Version 1.9.7, 2010-04-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* TLS: Support reading SSLv2 client hellos
+* TLS: Add support for SEED ciphersuites (RFC 4162)
+* Add Comb4P hash combiner function
+
+* Fix checking of EMSA_Raw signatures with leading 0 bytes, valid
+ signatures could be rejected in certain scenarios.
+
+Version 1.9.6, 2010-04-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* TLS: Add support for TLS v1.1
+* TLS: Support server name indicator extension
+* TLS: Fix server handshake
+* TLS: Fix server using DSA certificates
+* TLS: Avoid timing channel between CBC padding check and MAC verification
+
+Version 1.9.5, 2010-03-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Numerous ECC optimizations
+* Fix GOST 34.10-2001 X.509 key loading
+* Allow PK_Signer's fault protection checks to be toggled off
+* Avoid using pool-based locking allocator if we can't mlock
+* Remove all runtime options
+* New BER_Decoder::{decode_and_check, decode_octet_string_bigint}
+* Remove SecureBuffer in favor of SecureVector length parameter
+* HMAC_RNG: Perform a poll along with user-supplied entropy
+* Fix crash in MemoryRegion if Allocator::get failed
+* Fix small compilation problem on FreeBSD
+
+Version 1.9.4, 2010-03-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add the Ajisai SSLv3/TLSv1.0 implementation
+
+* Add GOST 34.10-2001 public key signature scheme
+* Add SIMD implementation of Noekeon
+
+* Add SSE2 implementation of IDEA
+
+* Extend Salsa20 to support longer IVs (XSalsa20)
+
+* Perform XTS encryption and decryption in parallel where possible
+
+* Perform CBC decryption in parallel where possible
+
+* Add SQLite3 db encryption codec, contributed by Olivier de Gaalon
+
+* Add a block cipher cascade construction
+
+* Add support for password hashing for authentication (passhash9.h)
+
+* Add support for Win32 high resolution system timers
+
+* Major refactoring and API changes in the public key code
+
+* PK_Signer class now verifies all signatures before releasing them to
+ the caller; this should help prevent a wide variety of fault
+ attacks, though it does have the downside of hurting signature
+ performance, particularly for DSA/ECDSA.
+
+* Changed S2K interface: derive_key now takes salt, iteration count
+
+* Remove dependency on TR1 shared_ptr in ECC and CVC code
+
+* Renamed ECKAEG to its more usual name, ECDH
+
+* Fix crash in GMP_Engine if library is shutdown and reinitialized
+
+* Fix an invalid memory read in MD4
+
+* Fix Visual C++ static builds
+
+* Remove Timer class entirely
+
+* Switch default PKCS #8 encryption algorithm from 3DES to AES-128
+
+* New configuration option, ``--gen-amalgamation``, creates a pair of
+ files (``botan_all.cpp`` and ``botan_all.h``) which contain the
+ contents of the library as it would have normally been compiled
+ based on the set configuration.
+
+* Many headers are now explicitly internal-use-only and are not installed
+
+* Greatly improve the Win32 installer
+
+* Several fixes for Visual C++ debug builds
+
+Version 1.9.3, 2009-11-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add new AES implementation using Intel's AES instruction intrinsics
+* Add an implementation of format preserving encryption
+* Allow use of any hash function in X.509 certificate creation
+* Optimizations for MARS, Skipjack, and AES
+* Set macros for available SIMD instructions in build.h
+* Add support for using InnoSetup to package Windows builds
+* By default build a DLL on Windows
+
+Version 1.8.8, 2009-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Alter Skein-512 to match the tweaked 1.2 specification
+* Fix use of inline asm for access to x86 bswap function
+* Allow building the library without AES enabled
+* Add 'powerpc64' alias to ppc64 arch for Gentoo ebuild
+
+Version 1.9.2, 2009-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add SIMD version of XTEA
+* Support both SSE2 and AltiVec SIMD for Serpent and XTEA
+* Optimizations for SHA-1 and SHA-2
+* Add AltiVec runtime detection
+* Fix x86 CPU identification with Intel C++ and Visual C++
+
+Version 1.9.1, 2009-10-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Better support for Python and Perl wrappers
+* Add an implementation of Blue Midnight Wish (Round 2 tweak version)
+* Modify Skein-512 to match the tweaked 1.2 specification
+* Add threshold secret sharing (draft-mcgrew-tss-02)
+* Add runtime cpu feature detection for x86/x86-64
+* Add code for general runtime self testing for hashes, MACs, and ciphers
+* Optimize XTEA; twice as fast as before on Core2 and Opteron
+* Convert CTR_BE and OFB from filters to stream ciphers
+* New parsing code for SCAN algorithm names
+* Enable SSE2 optimizations under Visual C++
+* Remove all use of C++ exception specifications
+* Add support for GNU/Hurd and Clang/LLVM
+
+Version 1.8.7, 2009-09-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix processing multiple messages in XTS mode
+* Add --no-autoload option to configure.py, for minimized builds
+
+Version 1.9.0, 2009-09-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add support for parallel invocation of block ciphers where possible
+* Add SSE2 implementation of Serpent
+* Add Rivest's package transform (an all or nothing transform)
+* Minor speedups to the Turing key schedule
+* Fix processing multiple messages in XTS mode
+* Add --no-autoload option to configure.py, for minimized builds
+* The previously used configure.pl script is no longer supported
+
+Version 1.8.6, 2009-08-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add Cryptobox, a set of simple password-based encryption routines
+* Only read world-readable files when walking /proc for entropy
+* Fix building with TR1 disabled
+* Fix x86 bswap support for Visual C++
+* Fixes for compilation under Sun C++
+* Add support for Dragonfly BSD (contributed by Patrick Georgi)
+* Add support for the Open64 C++ compiler
+* Build fixes for MIPS systems running Linux
+* Minor changes to license, now equivalent to the FreeBSD/NetBSD license
+
+Version 1.8.5, 2009-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Change configure.py to work on stock Python 2.4
+* Avoid a crash in Skein_512::add_data processing a zero-length input
+* Small build fixes for SPARC, ARM, and HP-PA processors
+* The test suite now returns an error code from main() if any tests failed
+
+Version 1.8.4, 2009-07-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a bug in nonce generation in the Miller-Rabin test
+
+Version 1.8.3, 2009-07-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add a new Python configuration script
+* Add the Skein-512 SHA-3 candidate hash function
+* Add the XTS block cipher mode from IEEE P1619
+* Fix random_prime when generating a prime of less than 7 bits
+* Improve handling of low-entropy situations during PRNG seeding
+* Change random device polling to prefer /dev/urandom over /dev/random
+* Use an input insensitive implementation of same_mem instead of memcmp
+* Correct DataSource::discard_next to return the number of discarded bytes
+* Provide a default value for AutoSeeded_RNG::reseed
+* Fix Gentoo bug 272242
+
+Version 1.8.2, 2009-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Make entropy polling more flexible and in most cases faster
+* GOST 28147 now supports multiple sbox parameters
+* Added the GOST 34.11 hash function
+* Fix botan-config problems on MacOS X
+
+Version 1.8.1, 2009-01-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Avoid a valgrind warning in es_unix.cpp on 32-bit Linux
+* Fix memory leak in PKCS8 load_key and encrypt_key
+* Relicense api.tex from CC-By-SA 2.5 to BSD
+* Fix botan-config on MacOS X, Solaris
+
+Version 1.8.0, 2008-12-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix compilation on Solaris with GCC
+
+Version 1.7.24, 2008-12-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a compatibility problem with SHA-512/EMSA3 signature padding
+* Fix bug preventing EGD/PRNGD entropy poller from working
+* Fix integer overflow in Pooling_Allocator::get_more_core (bug id #27)
+* Add EMSA3_Raw, a variant of EMSA3 called CKM_RSA_PKCS in PKCS #11
+* Add support for SHA-224 in EMSA2 and EMSA3 PK signature padding schemes
+* Add many more test vectors for RSA with EMSA2, EMSA3, and EMSA4
+* Wrap private structs in SSE2 SHA-1 code in anonymous namespace
+* Change configure.pl's CPU autodetection output to be more consistent
+* Disable using OpenSSL's AES due to crashes of unknown cause
+* Fix warning in /proc walking entropy poller
+* Fix compilation with IBM XLC for Cell 0.9-200709
+
+Version 1.7.23, 2008-11-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Change to use TR1 (thus enabling ECDSA) with GCC and ICC
+* Optimize almost all hash functions, especially MD4 and Tiger
+* Add configure.pl options --{with,without}-{bzip2,zlib,openssl,gnump}
+* Change Timer to be pure virtual, and add ANSI_Clock_Timer
+* Cache socket descriptors in the EGD entropy source
+* Avoid bogging down startup in /proc walking entropy source
+* Remove Buffered_EntropySource helper class
+* Add a Default_Benchmark_Timer typedef in benchmark.h
+* Add examples using benchmark.h and Algorithm_Factory
+* Add ECC tests from InSiTo
+* Minor documentation updates
+
+Version 1.7.22, 2008-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add provider preferences to Algorithm_Factory
+* Fix memory leaks in PBE_PKCS5v20 and get_pbe introduced in 1.7.21
+* Optimize AES encryption and decryption (about 10% faster)
+* Enable SSE2 optimized SHA-1 implementation on Intel Prescott CPUs
+* Fix nanoseconds overflow in benchmark code
+* Remove Engine::add_engine
+
+Version 1.7.21, 2008-11-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Make algorithm lookup much more configuable
+* Add facilities for runtime performance testing of algorithms
+* Drop use of entropy estimation in the PRNGs
+* Increase intervals between HMAC_RNG automatic reseeding
+* Drop InitializerOptions class, all options but thread safety
+
+Version 1.7.20, 2008-11-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Namespace pkg-config file by major and minor versions
+* Cache device descriptors in Device_EntropySource
+* Split base.h into {block_cipher,stream_cipher,mac,hash}.h
+* Removed get_mgf function from lookup.h
+
+Version 1.7.19, 2008-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add HMAC_RNG, based on a design by Hugo Krawczyk
+* Optimized the Turing stream cipher (about 20% faster on x86-64)
+* Modify Randpool's reseeding algorithm to poll more sources
+* Add a new AutoSeeded_RNG in auto_rng.h
+* OpenPGP_S2K changed to take hash object instead of name
+* Add automatic identification for Intel's Prescott processors
+
+Version 1.7.18, 2008-10-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add Doxygen comments from InSiTo
+* Add ECDSA and ECKAEG benchmarks
+* Add configure.pl switch --with-tr1-implementation
+* Fix configure.pl's --with-endian and --with-unaligned-mem options
+* Added support for pkg-config
+* Optimize byteswap with x86 inline asm for Visual C++ by Yves Jerschow
+* Use const references to avoid copying overhead in CurveGFp, GFpModulus
+
+Version 1.7.17, 2008-10-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add missing ECDSA object identifiers
+* Fix error in x86 and x86-64 assembler affecting GF(p) math
+* Remove Boost dependency from GF(p) math
+* Modify botan-config to not print -L/usr/lib or -L/usr/local/lib
+* Add BOTAN_DLL macro to over 30 classes missing it
+* Rename the two SHA-2 base classes for consistency
+
+Version 1.7.16, 2008-10-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add several missing pieces needed for ECDSA and ECKAEG
+* Add Card Verifiable Certificates from InSiTo
+* Add SHA-224 from InSiTo
+* Add BSI variant of EMSA1 from InSiTo
+* Add GF(p) and ECDSA tests from InSiTo
+* Split ECDSA and ECKAEG into distinct modules
+* Allow OpenSSL and GNU MP engines to be built with public key algos disabled
+* Rename sha256.h to sha2_32.h and sha_64.h to sha2_64.h
+
+Version 1.7.15, 2008-10-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add GF(p) arithmetic from InSiTo
+* Add ECDSA and ECKAEG implementations from InSiTo
+* Minimize internal dependencies, allowing for smaller build configurations
+* Add new User Manual and Architecture Guide from FlexSecure GmbH
+* Alter configure.pl options for better autotools compatibility
+* Update build instructions for recent changes to configure.pl
+* Fix CPU detection using /proc/cpuinfo
+
+Version 1.7.14, 2008-09-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Split library into parts allowing modular builds
+* Add (very preliminary) CMS support to the main library
+* Some constructors now require object pointers instead of names
+* Support multiple implementations of the same algorithm
+* Build support for Pentium-M processors, from Derek Scherger
+* Build support for MinGW/MSYS, from Zbigniew Zagorski
+* Use inline assembly for bswap on 32-bit x86
+
+Version 1.7.13, 2008-09-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add SSLv3 MAC, SSLv3 PRF, and TLS v1.0 PRF from Ajisai
+* Allow all examples to compile even if compression not enabled
+* Make CMAC's polynomial doubling operation a public class method
+* Use the -m64 flag when compiling with Sun Forte on x86-64
+* Clean up and slightly optimize CMAC::final_result
+
+Version 1.7.12, 2008-09-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add x86 assembly for Visual Studio C++, by Luca Piccarreta
+* Add a Perl XS module, by Vaclav Ovsik
+* Add SWIG-based wrapper for Botan
+* Add SSE2 implementation of SHA-1, by Dean Gaudet
+* Remove the BigInt::sig_words cache due to bugs
+* Combined the 4 Blowfish sboxes, suggested by Yves Jerschow
+* Changed BigInt::grow_by and BigInt::grow_to to be non-const
+* Add private assignment operators to classes that don't support assignment
+* Benchmark RSA encryption and signatures
+* Added test programs for random_prime and ressol
+* Add high resolution timers for IA-64, HP-PA, S390x
+* Reduce use of the RNG during benchmarks
+* Fix builds on STI Cell PPU
+* Add support for IBM's XLC compiler
+* Add IETF 8192 bit MODP group
+
+Version 1.7.11, 2008-09-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the Salsa20 stream cipher
+* Optimized Montgomery reduction, Karatsuba squaring
+* Added 16x16->32 word Comba multiplication and squaring
+* Use a much larger Karatsuba cutoff point
+* Remove bigint_mul_add_words
+* Inlined several BigInt functions
+* Add useful information to the generated build.h
+* Rename alg_{ia32,amd64} modules to asm_{ia32,amd64}
+* Fix the Windows build
+
+Version 1.7.10, 2008-09-05
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Public key benchmarks run using a selection of random keys
+* New benchmark timer options are clock_gettime, gettimeofday, times, clock
+* Including reinterpret_cast optimization for xor_buf in default header
+* Split byte swapping and word rotation functions into distinct headers
+* Add IETF modp 6144 group and 2048 and 3072 bit DSS groups
+* Optimizes BigInt right shift
+* Add aliases in DL_Group::Format enum
+* BigInt now caches the significant word count
+
+Version 1.6.5, 2008-08-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add noexec stack marker for GNU linker in assembly code
+* Fix autoconfiguration problem on x86 with GCC 4.2 and 4.3
+
+Version 1.7.9, 2008-08-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Make clear() in most algorithm base classes a pure virtual
+* Add noexec stack marker for GNU linker in assembly code
+* Avoid string operations in ressol
+* Compilation fixes for MinGW and Visual Studio C++ 2008
+* Some autoconfiguration fixes for Windows
+
+Version 1.7.8, 2008-07-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the block cipher Noekeon
+* Remove global deref_alias function
+* X509_Store takes timeout options as constructor arguments
+* Add Shanks-Tonelli algorithm, contributed by FlexSecure GmbH
+* Extend random_prime() for generating primes of any bit length
+* Remove Config class
+* Allow adding new entropy via base RNG interface
+* Reseeding a X9.31 PRNG also reseeds the underlying PRNG
+
+Version 1.7.7, 2008-06-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Remove the global PRNG object
+* The PK filter objects were removed
+* Add a test suite for the ANSI X9.31 PRNG
+* Much cleaner and (mostly) thread-safe reimplementation of es_ftw
+* Remove both default arguments to ANSI_X931_RNG's constructor
+* Remove the randomizing version of OctetString::change
+* Make the cipher and MAC to use in Randpool configurable
+* Move RandomNumberGenerator declaration to rng.h
+* RSA_PrivateKey will not generate keys smaller than 1024 bits
+* Fix an error decoding BER UNIVERSAL types with special taggings
+
+Version 1.7.6, 2008-05-05
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Initial support for Windows DLLs, from Joel Low
+* Reset the position pointer when a new block is generated in X9.32 PRNG
+* Timer objects are now treated as entropy sources
+* Moved several ASN.1-related enums from enums.h to an appropriate header
+* Removed the AEP module, due to inability to test
+* Removed Global_RNG and rng.h
+* Removed system_clock
+* Removed Library_State::UI and the pulse callback logic
+
+Version 1.7.5, 2008-04-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The API of X509_CA::sign_request was altered to avoid race conditions
+* New type Pipe::message_id to represent the Pipe message number
+* Remove the Named_Mutex_Holder for a small performance gain
+* Removed several unused or rarely used functions from Config
+* Ignore spaces inside of a decimal string in BigInt::decode
+* Allow using a std::istream to initialize a DataSource_Stream object
+* Fix compilation problem in zlib compression module
+* The chunk sized used by Pooling_Allocator is now a compile time setting
+* The size of random blinding factors is now a compile time setting
+* The install target no longer tries to set a particular owner/group
+
+Version 1.7.4, 2008-03-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Use unaligned memory read/writes on systems that allow it, for performance
+* Assembly for x86-64 for accessing the bswap instruction
+* Use larger buffers in ARC4 and WiderWAKE for significant throughput increase
+* Unroll loops in SHA-160 for a few percent increase in performance
+* Fix compilation with GCC 3.2 in es_ftw and es_unix
+* Build fix for NetBSD systems
+* Prevent es_dev from being built except on Unix systems
+
+Version 1.6.4, 2008-03-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a compilation problem with Visual Studio C++ 2003
+
+Version 1.7.3, 2008-01-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* New invocation syntax for configure.pl with several new options
+* Support for IPv4 addresses in a subject alternative name
+* New fast poll for the generic Unix entropy source (es_unix)
+* The es_file entropy source has been replaced by the es_dev module
+* The malloc allocator does not inherit from Pooling_Allocator anymore
+* The path that es_unix will search in are now fully user-configurable
+* Truncate X9.42 PRF output rather than allow counter overflow
+* PowerPC is now assumed to be big-endian
+
+Version 1.7.2, 2007-10-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Initialize the global library state lazily
+* Add plain CBC-MAC for backwards compatibility with old systems
+* Clean up some of the self test code
+* Throw a sensible exception if a DL_Group is not found
+* Truncate KDF2 output rather than allowing counter overflow
+* Add newly assigned OIDs for SHA-2 and DSA with SHA-224/256
+* Fix a Visual Studio compilation problem in x509stat.cpp
+
+Version 1.6.3, 2007-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a race condition in the algorithm lookup cache
+* Fix problems building the memory pool on some versions of Visual C++
+
+Version 1.7.1, 2007-07-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix a race condition in the algorithm object cache
+* HMAC key schedule optimization
+* The build header sets a macro defining endianness, if known
+* New word load/store abstraction allowing further optimization
+* Modify most of the library to avoid use the C-style casts
+* Use higher resolution timers in symmetric benchmarks
+
+Version 1.7.0, 2007-05-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* DSA parameter generation now follows FIPS 186-3
+* Added OIDs for Rabin-Williams and Nyberg-Rueppel
+* Somewhat better support for out of tree builds
+* Minor optimizations for RC2 and Tiger
+* Documentation updates
+* Update the todo list
+
+Version 1.6.2, 2007-03-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix autodection on Athlon64s running Linux
+* Fix builds on QNX and compilers using STLport
+* Remove a call to abort() that crept into production
+
+Version 1.6.1, 2007-01-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix some base64 decoder bugs
+* Add a new option to base64 encoding, to always append a newline
+* Fix some build problems under Visual Studio with debug enabled
+* Fix a bug in BER_Decoder that was triggered under some compilers
+
+Version 1.6.0, 2006-12-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Minor cleanups versus 1.5.13
+
+Version 1.5.13, 2006-12-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Compilation fixes for the bzip2, zlib, and GNU MP modules
+* Better support for Intel C++ and EKOpath C++ on x86-64
+
+Version 1.5.12, 2006-10-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Cleanups in the initialization routines
+* Add some x86-64 assembly for multiply-add
+* Fix problems generating very small (below 384 bit) RSA keys
+* Support out of tree builds
+* Bring some of the documentation up to date
+* More improvements to the Python bindings
+
+Version 1.5.11, 2006-09-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Removed the Algorithm base class
+* Various cleanups in the public key inheritance hierarchy
+* Major overhaul of the configure/build setup
+* Added x86 assembler implementations of Serpent and low-level MPI code
+* Optimizations for the SHA-1 x86 assembler
+* Various improvements to the Python wrappers
+* Work around a Visual Studio compiler bug
+
+Version 1.5.10, 2006-08-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add x86 assembler versions of MD4, MD5, and SHA-1
+* Expand InitializerOptions' language to support on/off switches
+* Fix definition of OID 2.5.4.8; was accidentally changed in 1.5.9
+* Fix possible resource leaks in the mmap allocator
+* Slightly optimized buffering in MDx_HashFunction
+* Initialization failures are dealt with somewhat better
+* Add an example implementing Pollard's Rho algorithm
+* Better option handling in the test/benchmark tool
+* Expand the xor_ciph example to support longer keys
+* Some updates to the documentation
+
+Version 1.5.9, 2006-07-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed bitrot in the AEP engine
+* Fix support for marking certificate/CRL extensions as critical
+* Significant cleanups in the library state / initialization code
+* LibraryInitializer takes an explicit InitializerOptions object
+* Make Mutex_Factory an abstract class, add Default_Mutex_Factory
+* Change configuration access to using global_state()
+* Add support for global named mutexes throughout the library
+* Add some STL wrappers for the delete operator
+* Change how certificates are created to be more flexible and general
+
+Version 1.5.8, 2006-06-23
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Many internal cleanups to the X.509 cert/CRL code
+* Allow for application code to support new X.509 extensions
+* Change the return type of X509_Certificate::{subject,issuer}_info
+* Allow for alternate character set handling mechanisms
+* Fix a bug that was slowing squaring performance somewhat
+* Fix a very hard to hit overflow bug in the C version of word3_muladd
+* Minor cleanups to the assembler modules
+* Disable es_unix module on FreeBSD due to build problem on FreeBSD 6.1
+* Support for GCC 2.95.x has been dropped in this release
+
+Version 1.5.7, 2006-05-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Further, major changes to the BER/DER coding system
+* Updated the Qt mutex module to use Mutex_Factory
+* Moved the library global state object into an anonymous namespace
+* Drop the Visual C++ x86 assembly module due to bugs
+
+Version 1.5.6, 2006-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The low-level DER/BER coding system was redesigned and rewritten
+* Portions of the certificate code were cleaned up internally
+* Use macros to substantially clean up the GCC assembly code
+* Added 32-bit x86 assembly for Visual C++ (by Luca Piccarreta)
+* Avoid a couple of spurious warnings under Visual C++
+* Some slight cleanups in X509_PublicKey::key_id
+
+Version 1.5.5, 2006-02-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a potential infinite loop in the memory pool code (Matt Johnston)
+* Made Pooling_Allocator::Memory_Block an actual class of sorts
+* Some small optimizations to the division and modulo computations
+* Cleaned up the implementation of some of the BigInt operators
+* Reduced use of dynamic memory allocation in low-level BigInt functions
+* A few simplifications in the Randpool mixing function
+* Removed power(), as it was not particularly useful (or fast)
+* Fixed some annoying bugs in the benchmark code
+* Added a real credits file
+
+Version 1.5.4, 2006-01-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Integrated x86 and amd64 assembly code, contributed by Luca Piccarreta
+* Fixed a memory access off-by-one in the Karatsuba code
+* Changed Pooling_Allocator's free list search to a log(N) algorithm
+* Merged ModularReducer with its only subclass, Barrett_Reducer
+* Fixed sign-handling bugs in some of the division and modulo code
+* Renamed the module description files to modinfo.txt
+* Further cleanups in the initialization code
+* Removed BigInt::add and BigInt::sub
+* Merged all the division-related functions into just divide()
+* Modified the <mp_asmi.h> functions to allow for better optimizations
+* Made the number of bits polled from an EntropySource user configurable
+* Avoid including <algorithm> in <botan/secmem.h>
+* Fixed some build problems with Sun Forte
+* Removed some dead code from bigint_modop
+* Fix the definition of same_mem
+
+Version 1.5.3, 2006-01-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Many optimizations in the low-level multiple precision integer code
+* Added hooks for assembly implementations of the MPI code
+* Support for the X.509 issuer alternative name extension in new certs
+* Fixed a bug in the decompression modules; found and patched by Matt Johnston
+* New Windows mutex module (mux_win32), by Luca Piccarreta
+* Changed the Windows timer module to use QueryPerformanceCounter
+* mem_pool.cpp was using std::set iterators instead of std::multiset ones
+* Fixed a bug in X509_CA preventing users from disabling particular extensions
+* Fixed the mp_asm64 module, which was entirely broken in 1.5.2
+* Fixed some module build problems on FreeBSD and Tru64
+
+Version 1.4.12, 2006-01-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed an off-by-one memory read in MISTY1::key()
+* Fixed a nasty memory leak in Output_Buffers::retire()
+* Changed maximum HMAC keylength to 1024 bits
+* Fixed a build problem in the hardware timer module on 64-bit PowerPC
+
+Version 1.5.2, 2006-01-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed an off-by-one memory read in MISTY1::key()
+* Fixed a nasty memory leak in Output_Buffers::retire()
+* Reimplemented the memory allocator from scratch
+* Improved memory caching in Montgomery exponentiation
+* Optimizations for multiple precision addition and subtraction
+* Fixed a build problem in the hardware timer module on 64-bit PowerPC
+* Changed default Karatsuba cutoff to 12 words (was 14)
+* Removed MemoryRegion::bits(), which was unused and incorrect
+* Changed maximum HMAC keylength to 1024 bits
+* Various minor Makefile and build system changes
+* Avoid using std::min in <secmem.h> to bypass Windows libc macro pollution
+* Switched checks/clock.cpp back to using clock() by default
+* Enabled the symmetric algorithm tests, which were accidentally off in 1.5.1
+* Removed the Default_Mutex's unused clone() member function
+
+Version 1.5.1, 2006-01-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Implemented Montgomery exponentiation
+* Implemented generalized Karatsuba multiplication and squaring
+* Implemented Comba squaring for 4, 6, and 8 word inputs
+* Added new Modular_Exponentiator and Power_Mod classes
+* Removed FixedBase_Exp and FixedExponent_Exp
+* Fixed a performance regression in get_allocator introduced in 1.5.0
+* Engines can now offer S2K algorithms and block cipher padding methods
+* Merged the remaining global 'algolist' code into Default_Engine
+* The low-level MPI code is linked as C again
+* Replaced BigInt's get_nibble with the more general get_substring
+* Some documentation updates
+
+Version 1.5.0, 2006-01-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Moved all global/shared library state into a single object
+* Mutex objects are created through mutex factories instead of a global
+* Removed ::get_mutex(), ::initialize_mutex(), and Mutex::clone()
+* Removed the RNG_Quality enum entirely
+* There is now only a single global-use PRNG
+* Removed the no_aliases and no_oids options for LibraryInitializer
+* Removed the deprecated algorithms SEAL, ISAAC, and HAVAL
+* Change es_ftw to use unbuffered I/O
+
+Version 1.4.11, 2005-12-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Changed Whirlpool diffusion matrix to match updated algorithm spec
+* Fixed several engine module build errors introduced in 1.4.10
+* Fixed two build problems in es_capi; reported by Matthew Gregan
+* Added a constructor to DataSource_Memory taking a std::string
+* Placing the same Filter in multiple Pipes triggers an exception
+* The configure script accepts --docdir and --libdir
+* Merged doc/rngs.txt into the main API document
+* Thanks to Joel Low for several bug reports on early tarballs of 1.4.11
+
+Version 1.4.10, 2005-12-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added an implementation of KASUMI, the block cipher used in 3G phones
+* Refactored Pipe; output queues are now managed by a distinct class
+* Made certain Filter facilities only available to subclasses of Fanout_Filter
+* There is no longer any overhead in Pipe for a message that has been read out
+* It is now possible to generate RSA keys as small as 128 bits
+* Changed some of the core classes to derive from Algorithm as a virtual base
+* Changed Randpool to use HMAC instead of a plain hash as the mixing function
+* Fixed a bug in the allocators; found and fixed by Matthew Gregan
+* Enabled the use of binary file I/O, when requested by the application
+* The OpenSSL engine's block cipher code was missing some deallocation calls
+* Disabled the es_ftw module on NetBSD, due to header problems there
+* Fixed a problem preventing tm_hard from building on MacOS X on PowerPC
+* Some cleanups for the modules that use inline assembler
+* config.h is now stored in build/ instead of build/include/botan/
+* The header util.h was split into bit_ops.h, parsing.h, and util.h
+* Cleaned up some redundant include directives
+
+Version 1.4.9, 2005-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the IBM-created AES candidate algorithm MARS
+* Added the South Korean block cipher SEED
+* Added the stream cipher Turing
+* Added the new hash function FORK-256
+* Deprecated the ISAAC stream cipher
+* Twofish and RC6 are significantly faster with GCC
+* Much better support for 64-bit PowerPC
+* Added support for high-resolution PowerPC timers
+* Fixed a bug in the configure script causing problems on FreeBSD
+* Changed ANSI X9.31 to support arbitrary block ciphers
+* Make the configure script a bit less noisy
+* Added more test vectors for some algorithms, including all the AES finalists
+* Various cosmetic source code cleanups
+
+Version 1.4.8, 2005-10-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Resolved a bad performance problem in the allocators; fix by Matt Johnston
+* Worked around a Visual Studio 2003 compilation problem introduced in 1.4.7
+* Renamed OMAC to CMAC to match the official NIST naming
+* Added single byte versions of update() to PK_Signer and PK_Verifier
+* Removed the unused reverse_bits and reverse_bytes functions
+
+Version 1.4.7, 2005-09-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed major performance problems with recent versions of GNU C++
+* Added an implementation of the X9.31 PRNG
+* Removed the X9.17 and FIPS 186-2 PRNG algorithms
+* Changed defaults to use X9.31 PRNGs as global PRNG objects
+* Documentation updates to reflect the PRNG changes
+* Some cleanups related to the engine code
+* Removed two useless headers, base_eng.h and secalloc.h
+* Removed PK_Verifier::valid_signature
+* Fixed configure/build system bugs affecting MacOS X builds
+* Added support for the EKOPath x86-64 compiler
+* Added missing destructor for BlockCipherModePaddingMethod
+* Fix some build problems with Visual C++ 2005 beta
+* Fix some build problems with Visual C++ 2003 Workshop
+
+Version 1.4.6, 2005-03-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix an error in the shutdown code introduced in 1.4.5
+* Setting base/pkcs8_tries to 0 disables the builtin fail-out
+* Support for XMPP identifiers in X.509 certificates
+* Duplicate entries in X.509 DNs are removed
+* More fixes for Borland C++, from Friedemann Kleint
+* Add a workaround for buggy iostreams
+
+Version 1.4.5, 2005-02-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add support for AES encryption of private keys
+* Minor fixes for PBES2 parameter decoding
+* Internal cleanups for global state variables
+* GCC 3.x version detection was broken in non-English locales
+* Work around a Sun Forte bug affecting mem_pool.h
+* Several fixes for Borland C++ 5.5, from Friedemann Kleint
+* Removed inclusion of init.h into base.h
+* Fixed a major bug in reading from certificate stores
+* Cleaned up a couple of mutex leaks
+* Removed some left-over debugging code
+* Removed SSL3_MAC, SSL3_PRF, and TLS_PRF
+
+Version 1.4.4, 2004-12-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Further tweaks to the pooling allocator
+* Modified EMSA3 to support SSL/TLS signatures
+* Changes to support Qt/QCA, from Justin Karneges
+* Moved mux_qt module code into mod_qt
+* Fixes for HP-UX from Mike Desjardins
+
+Version 1.4.3, 2004-11-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Split up SecureAllocator into Allocator and Pooling_Allocator
+* Memory locking allocators are more likely to be used
+* Fixed the placement of includes in some modules
+* Fixed broken installation procedure
+* Fixes in configure script to support alternate install programs
+* Modules can specify the minimum version they support
+
+Version 1.4.2, 2004-10-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a major CRL handling bug
+* Cipher and hash operations can be offloaded to engines
+* Added support for cipher and hash offload in OpenSSL engine
+* Improvements for 64-bit CPUs without a widening multiply instruction
+* Support for SHA2-* and Whirlpool with EMSA2
+* Fixed a long-standing build problem with conflicting include files
+* Fixed some examples that hadn't been updated for 1.4.x
+* Portability fixes for Solaris, BSD, HP-UX, and others
+* Lots of fixes and cleanups in the configure script
+* Updated the Gentoo ebuild file
+
+Version 1.4.1, 2004-10-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed major errors in the X.509 and PKCS #8 copy_key functions
+* Added a LAST_MESSAGE meta-message number for Pipe
+* Added new aliases (3DES and DES-EDE) for Triple-DES
+* Added some new functions to PK_Verifier
+* Cleaned up the KDF interface
+* Disabled tm_posix on BSD due to header issues
+* Fixed a build problem on PowerPC with GNU C++ pre-3.4
+
+Version 1.4.0, 2004-06-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the FIPS 186 RNG back
+* Added copy_key functions for X.509 public keys and PKCS #8 private keys
+* Fixed PKCS #1 signatures with RIPEMD-128
+* Moved some code around to avoid warnings with Sun ONE compiler
+* Fixed a bug in botan-config affecting OpenBSD
+* Fixed some build problems on Tru64, HP-UX
+* Fixed compile problems with Intel C++, Compaq C++
+
+Version 1.3.14, 2004-06-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added support for AEP's AEP1000/AEP2000 crypto cards
+* Added a Mutex module using Qt, from Justin Karneges
+* Added support for engine loading in LibraryInitializer
+* Tweaked SecureAllocator, giving 20% better performance under heavy load
+* Added timer and memory locking modules for Win32 (tm_win32, ml_win32)
+* Renamed PK_Engine to Engine_Core
+* Improved the Karatsuba cutoff points
+* Fixes for compiling with GCC 3.4 and Sun C++ 5.5
+* Fixes for Linux/s390, OpenBSD, and Solaris
+* Added support for Linux/s390x
+* The configure script was totally broken for 'generic' OS
+* Removed Montgomery reduction due to bugs
+* Removed an unused header, pkcs8alg.h
+* check --validate returns an error code if any tests failed
+* Removed duplicate entry in Unix command list for es_unix
+* Moved the Cert_Usage enumeration into X509_Store
+* Added new timing methods for PK benchmarks, clock_gettime and RDTSC
+* Fixed a few minor bugs in the configure script
+* Removed some deprecated functions from x509cert.h and pkcs10.h
+* Removed the 'minimal' module, has to be updated for Engine support
+* Changed MP_WORD_BITS macro to BOTAN_MP_WORD_BITS to clean up namespace
+* Documentation updates
+
+Version 1.3.13, 2004-05-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major fixes for Cygwin builds
+* Minor MacOS X install fixes
+* The configure script is a little better at picking the right modules
+* Removed ml_unix from the 'unix' module set for Cygwin compatibility
+* Fixed a stupid compile problem in pkcs10.h
+
+Version 1.3.12, 2004-05-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added ability to remove old entries from CRLs
+* Swapped the first two arguments of X509_CA::update_crl()
+* Added an < operator for MemoryRegion, so it can be used as a std::map key
+* Changed X.509 searching by DNS name from substring to full string compares
+* Renamed a few X509_Certificate and PKCS10_Request member functions
+* Fixed a problem when decoding some PKCS #10 requests
+* Hex_Decoder would not check inputs, reported by Vaclav Ovsik
+* Changed default CRL expire time from 30 days to 7 days
+* X509_CRL's default PEM header is now "X509 CRL", for OpenSSL compatibility
+* Corrected errors in the API doc, fixes from Ken Perano
+* More documentation about the Pipe/Filter code
+
+Version 1.3.11, 2004-04-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed two show-stopping bugs in PKCS10_Request
+* Added some sanity checks in Pipe/Filter
+* The DNS and URI entries would get swapped in subjectAlternativeNames
+* MAC_Filter is now willing to not take a key at creation time
+* Setting the expiration times of certs and CRLs is more flexible
+* Fixed problems building on AIX with GCC
+* Fixed some problems in the tutorial pointed out by Dominik Vogt
+* Documentation updates
+
+Version 1.3.10, 2004-03-27
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added support for OpenPGP's ASCII armor format
+* Cleaned up the RNG system; seeding is much more flexible
+* Added simple autoconfiguration abilities to configure.pl
+* Fixed a GCC 2.95.x compile problem
+* Updated the example configuration file
+* Documentation updates
+
+Version 1.3.9, 2004-03-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added an engine using OpenSSL (requires 0.9.7 or later)
+* X509_Certificate would lose email addresses stored in the DN
+* Fixed a missing initialization in a BigInt constructor
+* Fixed several Visual C++ compile problems
+* Fixed some BeOS build problems
+* Fixed the WiderWake benchmark
+
+Version 1.3.8, 2003-12-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Initial introduction of engine support, which separates PK keys from
+ the underlying operations. An engine using GNU MP was added.
+
+* DSA, DH, NR, and ElGamal constructors accept taking just the private
+ key again since the public key is easily derived from it.
+
+* Montgomery reduction support was added.
+* ElGamal keys now support being imported/exported as ASN.1 objects
+* Added Montgomery reductions
+* Added an engine that uses GNU MP (requires 4.1 or later)
+* Removed the obsolete mp_gmp module
+* Moved several initialization/shutdown functions to init.h
+* Major refactoring of the memory containers
+* New non-locking container, MemoryVector
+* Fixed 64-bit problems in BigInt::set_bit/clear_bit
+* Renamed PK_Key::check_params() to check_key()
+* Some incompatible changes to OctetString
+* Added version checking macros in version.h
+* Removed the fips140 module pending rewrite
+* Added some functions and hooks to help GUIs
+* Moved more shared code into MDx_HashFunction
+* Added a policy hook for specifying the encoding of X.509 strings
+
+Version 1.3.7, 2003-12-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a big security problem in es_unix (use of untrusted PATH)
+* Fixed several stability problems in es_unix
+* Expanded the list of programs es_unix will try to use
+* SecureAllocator now only preallocates blocks in special cases
+* Added a special case in Global_RNG::seed for forcing a full poll
+* Removed the FIPS 186 RNG added in 1.3.5 pending further testing
+* Configure updates for PowerPC CPUs
+* Removed the (never tested) VAX support
+* Added support for S/390 Linux
+
+Version 1.3.6, 2003-12-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added a new module 'minimal', which disables most algorithms
+* SecureAllocator allocates a few blocks at startup
+* A few minor MPI cleanups
+* RPM spec file cleanups and fixes
+
+Version 1.3.5, 2003-11-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major improvements in ASN.1 string handling
+* Added partial support for ASN.1 UTF8 STRINGs and BMP STRINGs
+* Added partial support for the X.509v3 certificate policies extension
+* Centralized the handling of character set information
+* Added FIPS 140-2 startup self tests
+* Added a module (fips140) for doing extra FIPS 140-2 tests
+* Added FIPS 186-2 RNG
+* Improved ASN.1 BIT STRING handling
+* Removed a memory leak in PKCS10_Request
+* The encoding of DirectoryString now follows PKIX guidelines
+* Fixed some of the character set dependencies
+* Fixed a DER encoding error for tags greater than 30
+* The BER decoder can now handle tags larger than 30
+* Fixed tm_hard.cpp to recognize SPARC on more systems
+* Workarounds for a GCC 2.95.x bug in x509find.cpp
+* RPM changed to install into /usr instead of /usr/local
+* Added support for QNX
+
+Version 1.2.8, 2003-11-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Merged several important bug fixes from 1.3.x
+
+Version 1.3.4, 2003-11-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added a module that does certain MPI operations using GNU MP
+* Added the X9.42 Diffie-Hellman PRF
+* The Zlib and Bzip2 objects now use custom allocators
+* Added member functions for directly hashing/MACing SecureVectors
+* Minor optimizations to the MPI addition and subtraction algorithms
+* Some cleanups in the low-level MPI code
+* Created separate AES-{128,192,256} objects
+
+Version 1.3.3, 2003-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The library can now be repeatedly initialized and shutdown without crashing
+* Fixed an off-by-one error in the CTS code
+* Fixed an error in the EMSA4 verification code
+* Fixed a memory leak in mutex.cpp (pointed out by James Widener)
+* Fixed a memory leak in Pthread_Mutex
+* Fixed several memory leaks in the testing code
+* Bulletproofed the EMSA/EME/KDF/MGF retrieval functions
+* Minor cleanups in SecureAllocator
+* Removed a needless mutex guarding the (stateless) global timer
+* Fixed a piece of bash-specific code in botan-config
+* X.509 objects report more information about decoding errors
+* Cleaned up some of the exception handling
+* Updated the example config file with new OIDSs
+* Moved the build instructions into a separate document, building.tex
+
+Version 1.3.2, 2003-11-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a bug preventing DSA signatures from verifying on X.509 objects
+* Made the X509_Store search routines more efficient and flexible
+* Added a function to X509_PublicKey to do easy public/private key matching
+* Added support for decoding indefinite length BER data
+* Changed Pipe's peek() to take an offset
+* Removed Filter::set_owns in favor of the new incr_owns function
+* Removed BigInt::zero() and BigInt::one()
+* Renamed the PEM related options from base/pem_* to pem/*
+* Added an option to specify the line width when encoding PEM
+* Removed the "rng/safe_longterm" option; it's always on now
+* Changed the cipher used for RNG super-encryption from ARC4 to WiderWake4+1
+* Cleaned up the base64/hex encoders and decoders
+* Added an ASN.1/BER decoder as an example
+* AES had its internals marked 'public' in previous versions
+* Changed the value of the ASN.1 NO_OBJECT enum
+* Various new hacks in the configure script
+* Removed the already nominal support for SunOS
+
+Version 1.3.1, 2003-11-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Generalized a few pieces of the DER encoder
+* PKCS8::load_key would fail if handed an unencrypted key
+* Added a failsafe so PKCS #8 key decoding can't go into an infinite loop
+
+Version 1.3.0, 2003-11-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major redesign of the PKCS #8 private key import/export system
+* Added a small amount of UI interface code for getting passphrases
+* Added heuristics that tell if a key, cert, etc is stored as PEM or BER
+* Removed CS-Cipher, SHARK, ThreeWay, MD5-MAC, and EMAC
+* Removed certain deprecated constructors of RSA, DSA, DH, RW, NR
+* Made PEM decoding more forgiving of extra text before the header
+
+Version 1.2.7, 2003-10-31
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added support for reading configuration files
+* Added constructors so NR and RW keys can be imported easily
+* Fixed mp_asm64, which was completely broken in 1.2.6
+* Removed tm_hw_ia32 module; replaced by tm_hard
+* Added support for loading certain oddly formed RSA certificates
+* Fixed spelling of NON_REPUDIATION enum
+* Renamed the option default_to_ca to v1_assume_ca
+* Fixed a minor bug in X.509 certificate generation
+* Fixed a latent bug in the OID lookup code
+* Updated the RPM spec file
+* Added to the tutorial
+
+Version 1.2.6, 2003-07-04
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major performance increase for PK algorithms on most 64-bit systems
+* Cleanups in the low-level MPI code to support asm implementations
+* Fixed build problems with some versions of Compaq's C++ compiler
+* Removed useless constructors for NR public and private keys
+* Removed support for the patch_file directive in module files
+* Removed several deprecated functions
+
+Version 1.2.5, 2003-06-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a tricky and long-standing memory leak in Pipe
+* Major cleanups and fixes in the memory allocation system
+* Removed alloc_mlock, which has been superseded by the ml_unix module
+* Removed a denial of service vulnerability in X509_Store
+* Fixed compilation problems with VS .NET 2003 and Codewarrior 8
+* Added another variant of PKCS8::load_key, taking a memory buffer
+* Fixed various minor/obscure bugs which occurred when MP_WORD_BITS != 32
+* BigInt::operator%=(word) was a no-op if the input was a power of 2
+* Fixed portability problems in BigInt::to_u32bit
+* Fixed major bugs in SSL3-MAC
+* Cleaned up some messes in the PK algorithms
+* Cleanups and extensions for OMAC and EAX
+* Made changes to the entropy estimation function
+* Added a 'beos' module set for use on BeOS
+* Officially deprecated a few X509:: and PKCS8:: functions
+* Moved the contents of primes.h to numthry.h
+* Moved the contents of x509opt.h to x509self.h
+* Removed the (empty) desx.h header
+* Documentation updates
+
+Version 1.2.4, 2003-05-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a bug in EMSA1 affecting NR signature verification
+* Fixed a few latent bugs in BigInt related to word size
+* Removed an unused function, mp_add2_nc, from the MPI implementation
+* Reorganized the core MPI files
+
+Version 1.2.3, 2003-05-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a bug that prevented DSA/NR key generation
+* Fixed a bug that prevented importing some root CA certs
+* Fixed a bug in the BER decoder when handing optional bit or byte strings
+* Fixed the encoding of authorityKeyIdentifier in X509_CA
+* Added a sanity check in PBKDF2 for zero length passphrases
+* Added versions of X509::load_key and PKCS8::load_key that take a file name
+* X509_CA generates 128 bit serial numbers now
+* Added tests to check PK key generation
+* Added a simplistic X.509 CA example
+* Cleaned up some of the examples
+
+Version 1.2.2, 2003-05-13
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Add checks to prevent any BigInt bugs from revealing an RSA or RW key
+* Changed the interface of Global_RNG::seed
+* Major improvements for the es_unix module
+* Added another Win32 entropy source, es_win32
+* The Win32 CryptoAPI entropy source can now poll multiple providers
+* Improved the BeOS entropy source
+* Renamed pipe_unixfd module to fd_unix
+* Fixed a file descriptor leak in the EGD module
+* Fixed a few locking bugs
+
+Version 1.2.1, 2003-05-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added ANSI X9.23 compatible CBC padding
+* Added an entropy source using Win32 CryptoAPI
+* Removed the Pipe I/O operators taking a FILE*
+* Moved the BigInt encoding/decoding functions into the BigInt class
+* Integrated several fixes for VC++ 7 (from Hany Greiss)
+* Fixed the configure.pl script for Windows builds
+
+Version 1.2.0, 2003-04-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Tweaked the Karatsuba cut-off points
+* Increased the allowed keylength of HMAC and Blowfish
+* Removed the 'mpi_ia32' module, pending rewrite
+* Workaround a GCC 2.95.x bug in eme1.cpp
+
+Version 1.1.13, 2003-04-22
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added OMAC
+* Added EAX authenticated cipher mode
+* Diffie-Hellman would not do blinding in some cases
+* Optimized the OFB and CTR modes
+* Corrected Skipjack's word ordering, as per NIST clarification
+* Support for all subject/issuer attribute types required by RFC 3280
+* The removeFromCRL CRL reason code is now handled correctly
+* Increased the flexibility of the allocators
+* Renamed Rijndael to AES, created aes.h, deleted rijndael.h
+* Removed support for the 'no_timer' LibraryInitializer option
+* Removed 'es_pthr' module, pending further testing
+* Cleaned up get_ciph.cpp
+
+Version 1.1.12, 2003-04-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a ASN.1 string encoding bug
+* Fixed a pair of X509_DN encoding problems
+* Base64_Decoder and Hex_Decoder can now validate input
+* Removed support for the LibraryInitializer option 'egd_path'
+* Added tests for DSA X.509 and PKCS #8 key formats
+* Removed a long deprecated feature of DH_PrivateKey's constructor
+* Updated the RPM .spec file
+* Major documentation updates
+
+Version 1.1.11, 2003-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added PKCS #10 certificate requests
+* Changed X509_Store searching interface to be more flexible
+* Added a generic Certificate_Store interface
+* Added a function for generating self-signed X.509 certs
+* Cleanups and changes to X509_CA
+* New examples for PKCS #10 and self-signed certificates
+* Some documentation updates
+
+Version 1.1.10, 2003-04-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* X509_CA can now generate new X.509 CRLs
+* Added blinding for RSA, RW, DH, and ElGamal to prevent timing attacks
+* More certificate and CRL extensions/attributes are supported
+* Better DN handling in X.509 certificates/CRLs
+* Added a DataSink hierarchy (suggested by Jim Darby)
+* Consolidated SecureAllocator and ManagedAllocator
+* Many cleanups and generalizations
+* Added a (slow) pthreads based EntropySource
+* Fixed some threading bugs
+
+Version 1.1.9, 2003-02-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added support for using X.509v2 CRLs
+* Fixed several bugs in the path validation algorithm
+* Certificates can be verified for a particular usage
+* Algorithm for comparing distinguished names now follows X.509
+* Cleaned up the code for the es_beos, es_ftw, es_unix modules
+* Documentation updates
+
+Version 1.1.8, 2003-01-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixes for the certificate path validation algorithm in X509_Store
+* Fixed a bug affecting X509_Certificate::is_ca_cert()
+* Added a general configuration interface for policy issues
+* Cleanups and API changes in the X.509 CA, cert, and store code
+* Made various options available for X509_CA users
+* Changed X509_Time's interface to work around time_t problems
+* Fixed a theoretical weakness in Randpool's entropy mixing function
+* Fixed problems compiling with GCC 2.95.3 and GCC 2.96
+* Fixed a configure bug (reported by Jon Wilson) affecting MinGW
+
+Version 1.0.2, 2003-01-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed an obscure SEGFAULT causing bug in Pipe
+* Fixed an obscure but dangerous bug in SecureVector::swap
+
+Version 1.1.7, 2003-01-12
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed an obscure but dangerous bug in SecureVector::swap
+* Consolidated SHA-384 and SHA-512 to save code space
+* Added SSL3-MAC and SSL3-PRF
+* Documentation updates, including a new tutorial
+
+Version 1.1.6, 2002-12-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Initial support for X.509v3 certificates and CAs
+* Major redesign/rewrite of the ASN.1 encoding/decoding code
+* Added handling for DSA/NR signatures encoded as DER SEQUENCEs
+* Documented the generic cipher lookup interface
+* Added an (untested) entropy source for BeOS
+* Various cleanups and bug fixes
+
+Version 1.1.5, 2002-11-17
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the discrete logarithm integrated encryption system (DLIES)
+* Various optimizations for BigInt
+* Added support for assembler optimizations in modules
+* Added BigInt x86 optimizations module (mpi_ia32)
+
+Version 1.1.4, 2002-11-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Speedup of 15-30% for PK algorithms
+* Implemented the PBES2 encryption scheme
+* Fixed a potential bug in decoding RSA and RW private keys
+* Changed the DL_Group class interface to handle different formats better
+* Added support for PKCS #3 encoded DH parameters
+* X9.42 DH parameters use a PEM label of 'X942 DH PARAMETERS'
+* Added key pair consistency checking
+* Fixed a compatibility problem with gcc 2.96 (pointed out by Hany Greiss)
+* A botan-config script is generated at configure time
+* Documentation updates
+
+Version 1.1.3, 2002-11-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added a generic public/private key loading interface
+* Fixed a small encoding bug in RSA, RW, and DH
+* Changed the PK encryption/decryption interface classes
+* ECB supports using padding methods
+* Added a function-based interface for library initialization
+* Added support for RIPEMD-128 and Tiger PKCS#1 v1.5 signatures
+* The cipher mode benchmarks now use 128-bit AES instead of DES
+* Removed some obsolete typedefs
+* Removed OpenCL support (opencl.h, the OPENCL_* macros, etc)
+* Added tests for PKCS #8 encoding/decoding
+* Added more tests for ECB and CBC
+
+Version 1.1.2, 2002-10-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Support for PKCS #8 encoded RSA, DSA, and DH private keys
+* Support for Diffie-Hellman X.509 public keys
+* Major reorganization of how X.509 keys are handled
+* Added PKCS #5 v2.0's PBES1 encryption scheme
+* Added a generic cipher lookup interface
+* Added the WiderWake4+1 stream cipher
+* Added support for sync-able stream ciphers
+* Added a 'paranoia level' option for the LibraryInitializer
+* More security for RNG output meant for long term keys
+* Added documentation for some of the new 1.1.x features
+* CFB's feedback argument is now specified in bits
+* Renamed CTR class to CTR_BE
+* Updated the RSA and DSA examples to use X.509 and PKCS #8 key formats
+
+Version 1.1.1, 2002-10-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added the Korean hash function HAS-160
+* Partial support for RSA and DSA X.509 public keys
+* Added a mostly functional BER encoder/decoder
+* Added support for non-deterministic MAC functions
+* Initial support for PEM encoding/decoding
+* Internal cleanups in the PK algorithms
+* Several new convenience functions in Pipe
+* Fixed two nasty bugs in Pipe
+* Messed with the entropy sources for es_unix
+* Discrete logarithm groups are checked for safety more closely now
+* For compatibility with GnuPG, ElGamal now supports DSA-style groups
+
+Version 1.0.1, 2002-09-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed a minor bug in Randpool::random()
+* Added some new aliases and typedefs for 1.1.x compatibility
+* The 4096-bit RSA benchmark key was decimal instead of hex
+* EMAC was returning an incorrect name
+
+Version 1.1.0, 2002-09-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added entropy estimation to the RNGs
+* Improved the overall design of both Randpool and ANSI_X917_RNG
+* Added a separate RNG for nonce generation
+* Added window exponentiation support in power_mod
+* Added a get_s2k function and the PKCS #5 S2K algorithms
+* Added the TLSv1 PRF
+* Replaced BlockCipherModeIV typedef with InitializationVector class
+* Renamed PK_Key_Agreement_Scheme to PK_Key_Agreement
+* Renamed SHA1 -> SHA_160 and SHA2_x -> SHA_x
+* Added support for RIPEMD-160 PKCS#1 v1.5 signatures
+* Changed the key agreement scheme interface
+* Changed the S2K and KDF interfaces
+* Better SCAN compatibility for HAVAL, Tiger, MISTY1, SEAL, RC5, SAFER-SK
+* Added support for variable-pass Tiger
+* Major speedup for Rabin-Williams key generation
+
+Version 1.0.0, 2002-08-26
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Octal I/O of BigInt is now supported
+* Fixed portability problems in the es_egd module
+* Generalized IV handling in the block cipher modes
+* Added Karatsuba multiplication and k-ary exponentiation
+* Fixed a problem in the multiplication routines
+
+Version 0.9.2, 2002-08-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* DH_PrivateKey::public_value() was returning the wrong value
+* Various BigInt optimizations
+* The filters.h header now includes hex.h and base64.h
+* Moved Counter mode to ctr.h
+* Fixed a couple minor problems with VC++ 7
+* Fixed problems with the RPM spec file
+
+Version 0.9.1, 2002-08-10
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Grand rename from OpenCL to Botan
+* Major optimizations for the PK algorithms
+* Added ElGamal encryption
+* Added Whirlpool
+* Tweaked memory allocation parameters
+* Improved the method of seeding the global RNG
+* Moved pkcs1.h to eme_pkcs.h
+* Added more test vectors for some algorithms
+* Fixed error reporting in the BigInt tests
+* Removed Default_Timer, it was pointless
+* Added some new example applications
+* Removed some old examples that weren't that interesting
+* Documented the compression modules
+
+Version 0.9.0, 2002-08-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* EMSA4 supports variable salt size
+* PK_* can take a string naming the encoding method to use
+* Started writing some internals documentation
+
+Version 0.8.7, 2002-07-30
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed bugs in EME1 and EMSA4
+* Fixed a potential crash at shutdown
+* Cipher modes returned an ill-formed name
+* Removed various deprecated types and headers
+* Cleaned up the Pipe interface a bit
+* Minor additions to the documentation
+* First stab at a Visual C++ makefile (doc/Makefile.vc7)
+
+Version 0.8.6, 2002-07-25
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added EMSA4 (aka PSS)
+* Brought the manual up to date; many corrections and additions
+* Added a parallel hash function construction
+* Lookup supports all available algorithms now
+* Lazy initialization of the lookup tables
+* Made more discrete logarithm groups available through get_dl_group()
+* StreamCipher_Filter supports seeking (if the underlying cipher does)
+* Minor optimization for GCD calculations
+* Renamed SAFER_SK128 to SAFER_SK
+* Removed many previously deprecated functions
+* Some now-obsolete functions, headers, and types have been deprecated
+* Fixed some bugs in DSA prime generation
+* DL_Group had a constructor for DSA-style prime gen but it wasn't defined
+* Reversed the ordering of the two arguments to SEAL's constructor
+* Fixed a threading problem in the PK algorithms
+* Fixed a minor memory leak in lookup.cpp
+* Fixed pk_types.h (it was broken in 0.8.5)
+* Made validation tests more verbose
+* Updated the check and example applications
+
+Version 0.8.5, 2002-07-21
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major changes to constructors for DL-based cryptosystems (DSA, NR, DH)
+* Added a DL_Group class
+* Reworking of the pubkey internals
+* Support in lookup for aliases and PK algorithms
+* Renamed CAST5 to CAST_128 and CAST256 to CAST_256
+* Added EMSA1
+* Reorganization of header files
+* LibraryInitializer will install new allocator types if requested
+* Fixed a bug in Diffie-Hellman key generation
+* Did a workaround in pipe.cpp for GCC 2.95.x on Linux
+* Removed some debugging code from init.cpp that made FTW ES useless
+* Better checking for invalid arguments in the PK algorithms
+* Reduced Base64 and Hex default line length (if line breaking is used)
+* Fixes for HP's aCC compiler
+* Cleanups in BigInt
+
+Version 0.8.4, 2002-07-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added Nyberg-Rueppel signatures
+* Added Diffie-Hellman key exchange (kex interface is subject to change)
+* Added KDF2
+* Enhancements to the lookup API
+* Many things formerly taking pointers to algorithms now take names
+* Speedups for prime generation
+* LibraryInitializer has support for seeding the global RNG
+* Reduced SAFER-SK128 memory consumption
+* Reversed the ordering of public and private key values in DSA constructor
+* Fixed serious bugs in MemoryMapping_Allocator
+* Fixed memory leak in Lion
+* FTW_EntropySource was not closing the files it read
+* Fixed line breaking problem in Hex_Encoder
+
+Version 0.8.3, 2002-06-09
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added DSA and Rabin-Williams signature schemes
+* Added EMSA3
+* Added PKCS#1 v1.5 encryption padding
+* Added Filters for PK algorithms
+* Added a Keyed_Filter class
+* LibraryInitializer processes arguments now
+* Major revamp of the PK interface classes
+* Changed almost all of the Filters for non-template operation
+* Changed HMAC, Lion, Luby-Rackoff to non-template classes
+* Some fairly minor BigInt optimizations
+* Added simple benchmarking for PK algorithms
+* Added hooks for fixed base and fixed exponent modular exponentiation
+* Added some examples for using RSA
+* Numerous bugfixes and cleanups
+* Documentation updates
+
+Version 0.8.2, 2002-05-18
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added an (experimental) algorithm lookup interface
+* Added code for directly testing BigInt
+* Added SHA2-384
+* Optimized SHA2-512
+* Major optimization for Adler32 (thanks to Dan Nicolaescu)
+* Various minor optimizations in BigInt and related areas
+* Fixed two bugs in X9.19 MAC, both reported by Darren Starsmore
+* Fixed a bug in BufferingFilter
+* Made a few fixes for MacOS X
+* Added a workaround in configure.pl for GCC 2.95.x
+* Better support for PowerPC, ARM, and Alpha
+* Some more cleanups
+
+Version 0.8.1, 2002-05-06
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Major code cleanup (check doc/deprecated.txt)
+* Various bugs fixed, including several portability problems
+* Renamed MessageAuthCode to MessageAuthenticationCode
+* A replacement for X917 is in x917_rng.h
+* Changed EMAC to non-template class
+* Added ANSI X9.19 compatible CBC-MAC
+* TripleDES now supports 128 bit keys
+
+Version 0.8.0, 2002-04-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Merged BigInt: many bugfixes and optimizations since alpha2
+* Added RSA (rsa.h)
+* Added EMSA2 (emsa2.h)
+* Lots of new interface code for public key algorithms (pk_base.h, pubkey.h)
+* Changed some interfaces, including SymmetricKey, to support the global rng
+* Fixed a serious bug in ManagedAllocator
+* Renamed RIPEMD128 to RIPEMD_128 and RIPEMD160 to RIPEMD_160
+* Removed some deprecated stuff
+* Added a global random number generator (rng.h)
+* Added clone functions to most of the basic algorithms
+* Added a library initializer class (init.h)
+* Version macros in version.h
+* Moved the base classes from opencl.h to base.h
+* Renamed the bzip2 module to comp_bzip2 and zlib to comp_zlib
+* Documentation updates for the new stuff (still incomplete)
+* Many new deprecated things: check doc/deprecated.txt
+
+Version 0.7.10, 2002-04-07
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Added EGD_EntropySource module (es_egd)
+* Added a file tree walking EntropySource (es_ftw)
+* Added MemoryLocking_Allocator module (alloc_mlock)
+* Renamed the pthr_mux, unix_rnd, and mmap_mem modules
+* Changed timer mechanism; the clock method can be switched on the fly.
+* Renamed MmapDisk_Allocator to MemoryMapping_Allocator
+* Renamed ent_file.h to es_file.h (ent_file.h is around, but deprecated)
+* Fixed several bugs in MemoryMapping_Allocator
+* Added more default sources for Unix_EntropySource
+* Changed SecureBuffer to use same allocation methods as SecureVector
+* Added bigint_divcore into mp_core to support BigInt alpha2 release
+* Removed some Pipe functions deprecated since 0.7.8
+* Some fixes for the configure program
+
+Version 0.7.9, 2002-03-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Memory allocation substantially revamped
+* Added memory allocation method based on mmap(2) in the mmap_mem module
+* Added ECB and CTS block cipher modes (ecb.h, cts.h)
+* Added a Mutex interface (mutex.h)
+* Added module pthr_mux, implementing the Mutex interface
+* Added Threaded Filter interface (thr_filt.h)
+* All algorithms can now by keyed with SymmetricKey objects
+* More testing occurs with --validate (expected failures)
+* Fixed two bugs reported by Hany Greiss, in Luby-Rackoff and RC6
+* Fixed a buffering bug in Bzip_Decompress and Zlib_Decompress
+* Made X917 safer (and about 1/3 as fast)
+* Documentation updates
+
+Version 0.7.8, 2002-02-28
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* More capabilities for Pipe, inspired by SysV STREAMS, including peeking,
+ better buffering, and stack ops. NOT BACKWARDS COMPATIBLE: SEE DOCUMENTATION
+* Added a BufferingFilter class
+* Added popen() based EntropySource for generic Unix systems (unix_rnd)
+* Moved 'devrand' module into main distribution (ent_file.h), renamed to
+ File_EntropySource, and changed interface somewhat.
+* Made Randpool somewhat more conservative and also 25% faster
+* Minor fixes and updates for the configure script
+* Added some tweaks for memory allocation
+* Documentation updates for the new Pipe interface
+* Fixed various minor bugs
+* Added a couple of new example programs (stack and hasher2)
+
+Version 0.7.7, 2001-11-24
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Filter::send now works in the constructor of a Filter subclass
+* You may now have to include <opencl/pipe.h> explicitly in some code
+* Added preliminary PK infrastructure classes in pubkey.h and pkbase.h
+* Enhancements to SecureVector (append, destroy functions)
+* New infrastructure for secure memory allocation
+* Added IEEE P1363 primitives MGF1, EME1, KDF1
+* Rijndael optimizations and cleanups
+* Changed CipherMode<B> to BlockCipherMode(B*)
+* Fixed a nasty bug in pipe_unixfd
+* Added portions of the BigInt code into the main library
+* Support for VAX, SH, POWER, PowerPC-64, Intel C++
+
+Version 0.7.6, 2001-10-14
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fixed several serious bugs in SecureVector created in 0.7.5
+* Square optimizations
+* Fixed shared objects on MacOS X and HP-UX
+* Fixed static libs for KCC 4.0; works with KCC 3.4g as well
+* Full support for Athlon and K6 processors using GCC
+* Added a table of prime numbers < 2**16 (primes.h)
+* Some minor documentation updates
+
+Version 0.7.5, 2001-08-19
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Split checksum.h into adler32.h, crc24.h, and crc32.h
+* Split modes.h into cbc.h, cfb.h, and ofb.h
+* CBC_wPadding* has been replaced by CBC_Encryption and CBC_Decryption
+* Added OneAndZeros and NoPadding methods for CBC
+* Added Lion, a very fast block cipher construction
+* Added an S2K base class (s2k.h) and an OpenPGP_S2K class (pgp_s2k.h)
+* Basic types (ciphers, hashes, etc) know their names now (call name())
+* Changed the EntropySource type somewhat
+* Big speed-ups for ISAAC, Adler32, CRC24, and CRC32
+* Optimized CAST-256, DES, SAFER-SK, Serpent, SEAL, MD2, and RIPEMD-160
+* Some semantics of SecureVector have changed slightly
+* The mlock module has been removed for the time being
+* Added string handling functions for hashes and MACs
+* Various non-user-visible cleanups
+* Shared library soname is now set to the full version number
+
+Version 0.7.4, 2001-07-15
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* New modules: Zlib, gettimeofday and x86 RTC timers, Unix I/O for Pipe
+* Fixed a vast number of errors in the config script/makefile/specfile
+* Pipe now has a stdio(3) interface as well as C++ iostreams
+* ARC4 supports skipping the first N bytes of the cipher stream (ala MARK4)
+* Bzip2 supports decompressing multiple concatenated streams, and flushing
+* Added a simple 'overall average' score to the benchmarks
+* Fixed a small bug in the POSIX timer module
+* Removed a very-unlikely-to-occur bug in most of the hash functions
+* filtbase.h now includes <iosfwd>, not <iostream>
+* Minor documentation updates
+
+Version 0.7.3, 2001-06-08
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fix build problems on Solaris/SPARC
+* Fix build problems with Perl versions < 5.6
+* Fixed some stupid code that broke on a few compilers
+* Added string handling functions to Pipe
+* MISTY1 optimizations
+
+Version 0.7.2, 2001-06-03
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Build system supports modules
+* Added modules for mlock, a /dev/random EntropySource, POSIX1.b timers
+* Added Bzip2 compression filter, contributed by Peter Jones
+* GNU make no longer required (tested with 4.4BSD pmake and Solaris make)
+* Fixed minor bug in several of the hash functions
+* Various other minor fixes and changes
+* Updates to the documentation
+
+Version 0.7.1, 2001-05-16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Rewrote configure script: more consistent and complete
+* Made it easier to find out parameters of types at run time (opencl.h)
+* New functions for finding the version being used (version.h)
+* New SymmetricKey interface for Filters (symkey.h)
+* InvalidKeyLength now records what the invalid key length was
+* Optimized DES, CS-Cipher, MISTY1, Skipjack, XTEA
+* Changed GOST to use correct S-box ordering (incompatible change)
+* Benchmark code was almost totally rewritten
+* Many more entries in the test vector file
+* Fixed minor and idiotic bug in check.cpp
+
+Version 0.7.0, 2001-03-01
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* First public release
+
+
diff --git a/doc/os.rst b/doc/os.rst
new file mode 100644
index 000000000..9e1ee641e
--- /dev/null
+++ b/doc/os.rst
@@ -0,0 +1,54 @@
+Botan OS information
+========================================
+
+OS Features
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A summary of OS features as defined in ``src/build-data/os``.
+
+::
+
+ a: aix
+ a: android
+ c: cygwin
+ d: darwin
+ d: dragonfly
+ f: freebsd
+ h: haiku
+ h: hpux
+ h: hurd
+ i: irix
+ l: linux
+ m: mingw
+ n: nacl
+ n: netbsd
+ o: openbsd
+ q: qnx
+ s: solaris
+ w: windows
+
+.. csv-table::
+ :header: "Feature", "a", "a", "c", "d", "d", "f", "h", "h", "h", "i", "l", "m", "n", "n", "o", "q", "s", "w"
+
+ "clock_gettime", " ", "X", " ", " ", "X", "X", " ", " ", " ", " ", "X", " ", " ", "X", "X", "X", " ", " "
+ "cryptgenrandom", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X"
+ "dlopen", " ", "X", " ", "X", " ", "X", " ", " ", " ", " ", "X", " ", " ", "X", "X", "X", " ", " "
+ "getsid", "X", " ", "X", "X", " ", "X", "X", "X", " ", "X", "X", " ", " ", "X", " ", "X", "X", " "
+ "gettimeofday", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", " ", "X", "X", "X", "X", "X", " "
+ "gmtime_r", " ", "X", " ", "X", " ", "X", "X", " ", " ", " ", "X", " ", " ", "X", "X", "X", " ", " "
+ "gmtime_s", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"
+ "loadlibrary", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X"
+ "memset_s", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
+ "mkgmtime", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X"
+ "posix_mlock", " ", "X", " ", " ", "X", "X", " ", " ", "X", " ", "X", " ", " ", "X", "X", "X", "X", " "
+ "query_perf_counter", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"
+ "readdir", " ", "X", " ", "X", " ", "X", " ", " ", " ", " ", "X", " ", " ", "X", "X", " ", " ", " "
+ "rtlsecurezeromemory", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"
+ "stl_filesystem_msvc", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"
+ "timegm", " ", " ", "X", "X", " ", "X", " ", " ", " ", " ", "X", " ", " ", "X", "X", " ", " ", " "
+ "virtual_lock", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"
+ "win32_get_systemtime", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " "
+ "win32_virtual_lock", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " "
+
+.. note::
+ This file is auto generated by ``src/scripts/update_docs.py``. Dont modify it manually.
diff --git a/doc/pgpkey.txt b/doc/pgpkey.txt
new file mode 100644
index 000000000..e4b5a83f3
--- /dev/null
+++ b/doc/pgpkey.txt
@@ -0,0 +1,37 @@
+The following PGP key is used to sign all releases:
+
+pub 2048R/EFBADFBC 2004-10-30
+ Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
+uid Botan Distribution Key
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.17 (GNU/Linux)
+
+mQELBEGD1j0BCADHxPJkPcjJE+4Dlisx2hVc0Dj6JI1MSLrkM8R+2bOhVUSferxP
+T1EMPhfrAdOHTAloyvRThJztnZsNKqfLL49GGcBLdEGAVNks1pG37Teze5Lx1XIu
+zJFrozL2sqBy5C6nHpFgd1tcD68Rah2wp0u2cR9owXf1IqKdEfuo661+MTv7wTB1
+4hKV75nB7ZO6676SEZRILYM+7RJwKAKEmEPJc6hEf94VXn9ecNzaTlHgYkjhz9db
+LOd3od9XvuUw+LMR1dwBqMxbvR90MiXjbedDEkbArcZB9YOAIvEX/lC3qaW4XJt4
+iwHWl/YVZEfALcvQywe2CDrH5hO794wd9MpBAAYptBZCb3RhbiBEaXN0cmlidXRp
+b24gS2V5iQEqBBMBAgAUAhsDAh4BAheABQJKfFpnBBUKCQgACgkQYhHr8e+637xk
+PQf/aOi78XenwwvFrwXOVIVTdZIf8rK1zJksf26h09UD8uVV6z5iiTcpn86+eN9p
+6Ar8IH3tD+JuFnPSwZ/r9MNC2XZwenYo4Gb14jqM6/9hBe328vmeM4Y1G7bD4HrL
+kgV5WEyokqm3zbp3FBLr3Vh68TAC5JB9aHevra+cCA2u3vBNI3YUM5z4TdO150P3
+J00whkqImQEUni8bgxvllBLFM+uhucsX3HZWkoDEpotbg8yd0bqMkiPEyMr1OnJq
+eDVDMrB5wnyLgLFfRAAw3mopM0C1PNOAHr/BIYiaDHX2OwnOfep8rMDoRVf2Ge0D
+DBgsJJ6LduQHLeg403SHWL2F6YkCHAQTAQIABgUCQYPWUgAKCRBcD5boTsFta+r9
+EACWVis7YcaGkKKgRB/5ox8rM36XVhMXdh/hnnGHt5rapbbRRkRHRcWU8WIcFO1A
+59+TfwNNd8gN1MEt/5aX5KHWVKHBDexJgIxm6Dm1pisYHf/dnYQPM18hmqqwNlKY
+97hFkPpHd7enrtc/SvGbQhhLXYlpwBrdMl76e9xJLnnrRQksxegGPo8cr+C9HTs1
+Lwa8zzBxyBwYBYX+0moDkDShEhuXx6mEOXrGvQanJuIvpoIwGH+62E65MbJGlwWp
+w/MAtm2jFhBIhGV0bqJCFp9zIgdNgfskBaPr0oilbuJQZqP0Iqe/6CCt4XkS51yW
+ZqxjLAFpEpvDec4PGw3witKf/koGon9X8C035+nEjLBrWy18Q91vw2USyLI+mm9d
+iMAS8pY2gomfxBO2VwYHJryZykjCYQkccRA1tHteRj4gqTObo0Ak47y5MnplTWwi
+40oP7K2cfhCRBmMioxmYES4xsHEupfRBo3xr1Jq9q0t688WTT1NXHPMPoueF9mKZ
+Cf2pa9aHsqBmWTm3sCaNQKGubCDBEUmJUyndmSatJyYM7NVYoUp6EfqMACFuTNdB
+sjKMh7aWVikQpbJDfA1BIU3lZeqgjgrghVAWkEOBfhG0IVZj+RVCJpsqoTJ8asY2
+VreArSCyr/VnLEnfuH/QpgvCiCbepo3E34DJt4SaAOO2ZohGBBARAgAGBQJMGVc1
+AAoJEKY/LL36AvvMgsoAn2G7kXd09BF7ffk1Sfh174SVrvM9AKC7+R7x0+yV3SCd
+JkkUOo3xR5cOxw==
+=1QuR
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/doc/dev/release_process.rst b/doc/release_process.rst
index 7f7f97abc..603a46a27 100644
--- a/doc/dev/release_process.rst
+++ b/doc/release_process.rst
@@ -9,41 +9,33 @@ Release Process and Checklist
Pre Release Checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Confirm that the release notes under ``doc/relnotes`` are accurate and
+Confirm that the release notes in ``news.rst`` are accurate and
complete and that the version number in ``botan_version.py`` is
correct. Update the release date in the release notes and change the
-entry for the appropriate branch in ``doc/website/download.rst`` to
-point to the new release. Add the new release to
-``doc/relnotes/index.rst``.
+entry for the appropriate branch in ``readme.rst`` to point to the new
+release.
Check in these changes (alone, with no other modifications) with a
checkin message along the lines of "Update for X.Y.Z release", then
-tag the release with the version in monotone (eg tag '1.11.8', no
-prefix).
+tag the release with the version in git (eg tag '1.11.8', no prefix).
-Build The Release
+Build The Release Tarballs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The release script is ``src/scripts/dist.py`` and runs from
-a monotone repository by pulling the revision matching the tag set
-previously. For instance::
+The release script is ``src/scripts/dist.py`` and must be
+run from a git workspace.
- $ src/scripts/dist.py --mtn-db ~/var/mtn/botan.mtn 1.11.8
+ $ src/scripts/dist.py 1.11.18
-The ``--mtn-db`` 'option' is mandatory, unless the environmental
-variable ``BOTAN_MTN_DB`` is set, in which case that value is used if
-``--mtn-db`` is not provided.
-
-Another useful option is ``--output-dir``, which specifies where
-the output will be placed.
+One useful option is ``--output-dir``, which specifies where the
+output will be placed.
The ``--pgp-key-id`` option is used to specifiy a PGP keyid. If set,
the script assumes that it can execute GnuPG and will attempt to
create signatures for the tarballs. The default value is ``EFBADFBC``,
-matching :doc:`the official signing key <pgpkey>`. You can set it to
-an empty value (``--pgp-key-id=``) to avoid creating signatures though
-official distributed releases *should not* be released without
-signatures.
+which is the official signing key. You can use ``--pgp-key-id=none``
+to avoid creating any signature, though official distributed releases
+*should not* be released without signatures.
Build The Windows Installer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,20 +51,16 @@ placed in ``build/botan.iss`` by ``configure.py``. Create the
installer either via the InnoSetup GUI by opening the ``iss`` file and
selecting the 'Compile' option, or using the ``iscc`` command line
tool. If all goes well it will produce an executable with a name like
-``botan-1.11.8-x86_64.exe``. Sign the installers with GPG.
+``botan-1.11.18-x86_64.exe``. Sign the installers with GPG.
Update The Website
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The current botan website is derived entirely from the ReST content in
-``docs`` using Sphinx (plus Doxygen generated documentation). A script
-called ``mtn-watch`` periodically checks for new updates on the
-``net.randombit.botan`` branch (only), and if found regenerates the
-site content. Thus as soon as the changes are synced to the server
-running on ``mtn.randombit.net``, the website will be updated.
+The website content is created by ``src/scripts/website.sh``.
+Currently refreshing the website is a manual process.
Announce The Release
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Send an email to the announce and devel mailing lists noting that a
-new release is available.
+Send an email to the botan-announce and botan-devel mailing lists
+noting that a new release is available.
diff --git a/doc/relnotes/0_7_0.rst b/doc/relnotes/0_7_0.rst
deleted file mode 100644
index 5339b7b10..000000000
--- a/doc/relnotes/0_7_0.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Version 0.7.0, 2001-03-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* First public release
-
diff --git a/doc/relnotes/0_7_1.rst b/doc/relnotes/0_7_1.rst
deleted file mode 100644
index cc57ef0ee..000000000
--- a/doc/relnotes/0_7_1.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 0.7.1, 2001-05-16
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Rewrote configure script: more consistent and complete
-* Made it easier to find out parameters of types at run time (opencl.h)
-* New functions for finding the version being used (version.h)
-* New SymmetricKey interface for Filters (symkey.h)
-* InvalidKeyLength now records what the invalid key length was
-* Optimized DES, CS-Cipher, MISTY1, Skipjack, XTEA
-* Changed GOST to use correct S-box ordering (incompatible change)
-* Benchmark code was almost totally rewritten
-* Many more entries in the test vector file
-* Fixed minor and idiotic bug in check.cpp
-
diff --git a/doc/relnotes/0_7_10.rst b/doc/relnotes/0_7_10.rst
deleted file mode 100644
index df08df532..000000000
--- a/doc/relnotes/0_7_10.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 0.7.10, 2002-04-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added EGD_EntropySource module (es_egd)
-* Added a file tree walking EntropySource (es_ftw)
-* Added MemoryLocking_Allocator module (alloc_mlock)
-* Renamed the pthr_mux, unix_rnd, and mmap_mem modules
-* Changed timer mechanism; the clock method can be switched on the fly.
-* Renamed MmapDisk_Allocator to MemoryMapping_Allocator
-* Renamed ent_file.h to es_file.h (ent_file.h is around, but deprecated)
-* Fixed several bugs in MemoryMapping_Allocator
-* Added more default sources for Unix_EntropySource
-* Changed SecureBuffer to use same allocation methods as SecureVector
-* Added bigint_divcore into mp_core to support BigInt alpha2 release
-* Removed some Pipe functions deprecated since 0.7.8
-* Some fixes for the configure program
-
diff --git a/doc/relnotes/0_7_2.rst b/doc/relnotes/0_7_2.rst
deleted file mode 100644
index a9b6ae452..000000000
--- a/doc/relnotes/0_7_2.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 0.7.2, 2001-06-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Build system supports modules
-* Added modules for mlock, a /dev/random EntropySource, POSIX1.b timers
-* Added Bzip2 compression filter, contributed by Peter Jones
-* GNU make no longer required (tested with 4.4BSD pmake and Solaris make)
-* Fixed minor bug in several of the hash functions
-* Various other minor fixes and changes
-* Updates to the documentation
-
diff --git a/doc/relnotes/0_7_3.rst b/doc/relnotes/0_7_3.rst
deleted file mode 100644
index 57b7a630a..000000000
--- a/doc/relnotes/0_7_3.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 0.7.3, 2001-06-08
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix build problems on Solaris/SPARC
-* Fix build problems with Perl versions < 5.6
-* Fixed some stupid code that broke on a few compilers
-* Added string handling functions to Pipe
-* MISTY1 optimizations
-
diff --git a/doc/relnotes/0_7_4.rst b/doc/relnotes/0_7_4.rst
deleted file mode 100644
index 523a6bccc..000000000
--- a/doc/relnotes/0_7_4.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 0.7.4, 2001-07-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* New modules: Zlib, gettimeofday and x86 RTC timers, Unix I/O for Pipe
-* Fixed a vast number of errors in the config script/makefile/specfile
-* Pipe now has a stdio(3) interface as well as C++ iostreams
-* ARC4 supports skipping the first N bytes of the cipher stream (ala MARK4)
-* Bzip2 supports decompressing multiple concatenated streams, and flushing
-* Added a simple 'overall average' score to the benchmarks
-* Fixed a small bug in the POSIX timer module
-* Removed a very-unlikely-to-occur bug in most of the hash functions
-* filtbase.h now includes <iosfwd>, not <iostream>
-* Minor documentation updates
-
diff --git a/doc/relnotes/0_7_5.rst b/doc/relnotes/0_7_5.rst
deleted file mode 100644
index cb729d182..000000000
--- a/doc/relnotes/0_7_5.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 0.7.5, 2001-08-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Split checksum.h into adler32.h, crc24.h, and crc32.h
-* Split modes.h into cbc.h, cfb.h, and ofb.h
-* CBC_wPadding* has been replaced by CBC_Encryption and CBC_Decryption
-* Added OneAndZeros and NoPadding methods for CBC
-* Added Lion, a very fast block cipher construction
-* Added an S2K base class (s2k.h) and an OpenPGP_S2K class (pgp_s2k.h)
-* Basic types (ciphers, hashes, etc) know their names now (call name())
-* Changed the EntropySource type somewhat
-* Big speed-ups for ISAAC, Adler32, CRC24, and CRC32
-* Optimized CAST-256, DES, SAFER-SK, Serpent, SEAL, MD2, and RIPEMD-160
-* Some semantics of SecureVector have changed slightly
-* The mlock module has been removed for the time being
-* Added string handling functions for hashes and MACs
-* Various non-user-visible cleanups
-* Shared library soname is now set to the full version number
-
diff --git a/doc/relnotes/0_7_6.rst b/doc/relnotes/0_7_6.rst
deleted file mode 100644
index 13294e7a5..000000000
--- a/doc/relnotes/0_7_6.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 0.7.6, 2001-10-14
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed several serious bugs in SecureVector created in 0.7.5
-* Square optimizations
-* Fixed shared objects on MacOS X and HP-UX
-* Fixed static libs for KCC 4.0; works with KCC 3.4g as well
-* Full support for Athlon and K6 processors using GCC
-* Added a table of prime numbers < 2**16 (primes.h)
-* Some minor documentation updates
-
diff --git a/doc/relnotes/0_7_7.rst b/doc/relnotes/0_7_7.rst
deleted file mode 100644
index 83dfd2d2f..000000000
--- a/doc/relnotes/0_7_7.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 0.7.7, 2001-11-24
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Filter::send now works in the constructor of a Filter subclass
-* You may now have to include <opencl/pipe.h> explicitly in some code
-* Added preliminary PK infrastructure classes in pubkey.h and pkbase.h
-* Enhancements to SecureVector (append, destroy functions)
-* New infrastructure for secure memory allocation
-* Added IEEE P1363 primitives MGF1, EME1, KDF1
-* Rijndael optimizations and cleanups
-* Changed CipherMode<B> to BlockCipherMode(B*)
-* Fixed a nasty bug in pipe_unixfd
-* Added portions of the BigInt code into the main library
-* Support for VAX, SH, POWER, PowerPC-64, Intel C++
-
diff --git a/doc/relnotes/0_7_8.rst b/doc/relnotes/0_7_8.rst
deleted file mode 100644
index 92b9291b1..000000000
--- a/doc/relnotes/0_7_8.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 0.7.8, 2002-02-28
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* More capabilities for Pipe, inspired by SysV STREAMS, including peeking,
- better buffering, and stack ops. NOT BACKWARDS COMPATIBLE: SEE DOCUMENTATION
-* Added a BufferingFilter class
-* Added popen() based EntropySource for generic Unix systems (unix_rnd)
-* Moved 'devrand' module into main distribution (ent_file.h), renamed to
- File_EntropySource, and changed interface somewhat.
-* Made Randpool somewhat more conservative and also 25% faster
-* Minor fixes and updates for the configure script
-* Added some tweaks for memory allocation
-* Documentation updates for the new Pipe interface
-* Fixed various minor bugs
-* Added a couple of new example programs (stack and hasher2)
-
diff --git a/doc/relnotes/0_7_9.rst b/doc/relnotes/0_7_9.rst
deleted file mode 100644
index cb48eef3e..000000000
--- a/doc/relnotes/0_7_9.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 0.7.9, 2002-03-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Memory allocation substantially revamped
-* Added memory allocation method based on mmap(2) in the mmap_mem module
-* Added ECB and CTS block cipher modes (ecb.h, cts.h)
-* Added a Mutex interface (mutex.h)
-* Added module pthr_mux, implementing the Mutex interface
-* Added Threaded Filter interface (thr_filt.h)
-* All algorithms can now by keyed with SymmetricKey objects
-* More testing occurs with --validate (expected failures)
-* Fixed two bugs reported by Hany Greiss, in Luby-Rackoff and RC6
-* Fixed a buffering bug in Bzip_Decompress and Zlib_Decompress
-* Made X917 safer (and about 1/3 as fast)
-* Documentation updates
-
diff --git a/doc/relnotes/0_8_0.rst b/doc/relnotes/0_8_0.rst
deleted file mode 100644
index 62c3a0384..000000000
--- a/doc/relnotes/0_8_0.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-Version 0.8.0, 2002-04-24
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Merged BigInt: many bugfixes and optimizations since alpha2
-* Added RSA (rsa.h)
-* Added EMSA2 (emsa2.h)
-* Lots of new interface code for public key algorithms (pk_base.h, pubkey.h)
-* Changed some interfaces, including SymmetricKey, to support the global rng
-* Fixed a serious bug in ManagedAllocator
-* Renamed RIPEMD128 to RIPEMD_128 and RIPEMD160 to RIPEMD_160
-* Removed some deprecated stuff
-* Added a global random number generator (rng.h)
-* Added clone functions to most of the basic algorithms
-* Added a library initializer class (init.h)
-* Version macros in version.h
-* Moved the base classes from opencl.h to base.h
-* Renamed the bzip2 module to comp_bzip2 and zlib to comp_zlib
-* Documentation updates for the new stuff (still incomplete)
-* Many new deprecated things: check doc/deprecated.txt
-
-
diff --git a/doc/relnotes/0_8_1.rst b/doc/relnotes/0_8_1.rst
deleted file mode 100644
index 98175994e..000000000
--- a/doc/relnotes/0_8_1.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 0.8.1, 2002-05-06
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major code cleanup (check doc/deprecated.txt)
-* Various bugs fixed, including several portability problems
-* Renamed MessageAuthCode to MessageAuthenticationCode
-* A replacement for X917 is in x917_rng.h
-* Changed EMAC to non-template class
-* Added ANSI X9.19 compatible CBC-MAC
-* TripleDES now supports 128 bit keys
-
diff --git a/doc/relnotes/0_8_2.rst b/doc/relnotes/0_8_2.rst
deleted file mode 100644
index 1f4c540e8..000000000
--- a/doc/relnotes/0_8_2.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 0.8.2, 2002-05-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added an (experimental) algorithm lookup interface
-* Added code for directly testing BigInt
-* Added SHA2-384
-* Optimized SHA2-512
-* Major optimization for Adler32 (thanks to Dan Nicolaescu)
-* Various minor optimizations in BigInt and related areas
-* Fixed two bugs in X9.19 MAC, both reported by Darren Starsmore
-* Fixed a bug in BufferingFilter
-* Made a few fixes for MacOS X
-* Added a workaround in configure.pl for GCC 2.95.x
-* Better support for PowerPC, ARM, and Alpha
-* Some more cleanups
-
diff --git a/doc/relnotes/0_8_3.rst b/doc/relnotes/0_8_3.rst
deleted file mode 100644
index 88012db05..000000000
--- a/doc/relnotes/0_8_3.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 0.8.3, 2002-06-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added DSA and Rabin-Williams signature schemes
-* Added EMSA3
-* Added PKCS#1 v1.5 encryption padding
-* Added Filters for PK algorithms
-* Added a Keyed_Filter class
-* LibraryInitializer processes arguments now
-* Major revamp of the PK interface classes
-* Changed almost all of the Filters for non-template operation
-* Changed HMAC, Lion, Luby-Rackoff to non-template classes
-* Some fairly minor BigInt optimizations
-* Added simple benchmarking for PK algorithms
-* Added hooks for fixed base and fixed exponent modular exponentiation
-* Added some examples for using RSA
-* Numerous bugfixes and cleanups
-* Documentation updates
-
diff --git a/doc/relnotes/0_8_4.rst b/doc/relnotes/0_8_4.rst
deleted file mode 100644
index 9b73ca88e..000000000
--- a/doc/relnotes/0_8_4.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 0.8.4, 2002-07-14
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added Nyberg-Rueppel signatures
-* Added Diffie-Hellman key exchange (kex interface is subject to change)
-* Added KDF2
-* Enhancements to the lookup API
-* Many things formerly taking pointers to algorithms now take names
-* Speedups for prime generation
-* LibraryInitializer has support for seeding the global RNG
-* Reduced SAFER-SK128 memory consumption
-* Reversed the ordering of public and private key values in DSA constructor
-* Fixed serious bugs in MemoryMapping_Allocator
-* Fixed memory leak in Lion
-* FTW_EntropySource was not closing the files it read
-* Fixed line breaking problem in Hex_Encoder
-
diff --git a/doc/relnotes/0_8_5.rst b/doc/relnotes/0_8_5.rst
deleted file mode 100644
index eced09cc2..000000000
--- a/doc/relnotes/0_8_5.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 0.8.5, 2002-07-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major changes to constructors for DL-based cryptosystems (DSA, NR, DH)
-* Added a DL_Group class
-* Reworking of the pubkey internals
-* Support in lookup for aliases and PK algorithms
-* Renamed CAST5 to CAST_128 and CAST256 to CAST_256
-* Added EMSA1
-* Reorganization of header files
-* LibraryInitializer will install new allocator types if requested
-* Fixed a bug in Diffie-Hellman key generation
-* Did a workaround in pipe.cpp for GCC 2.95.x on Linux
-* Removed some debugging code from init.cpp that made FTW ES useless
-* Better checking for invalid arguments in the PK algorithms
-* Reduced Base64 and Hex default line length (if line breaking is used)
-* Fixes for HP's aCC compiler
-* Cleanups in BigInt
-
diff --git a/doc/relnotes/0_8_6.rst b/doc/relnotes/0_8_6.rst
deleted file mode 100644
index 18c95db10..000000000
--- a/doc/relnotes/0_8_6.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-Version 0.8.6, 2002-07-25
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added EMSA4 (aka PSS)
-* Brought the manual up to date; many corrections and additions
-* Added a parallel hash function construction
-* Lookup supports all available algorithms now
-* Lazy initialization of the lookup tables
-* Made more discrete logarithm groups available through get_dl_group()
-* StreamCipher_Filter supports seeking (if the underlying cipher does)
-* Minor optimization for GCD calculations
-* Renamed SAFER_SK128 to SAFER_SK
-* Removed many previously deprecated functions
-* Some now-obsolete functions, headers, and types have been deprecated
-* Fixed some bugs in DSA prime generation
-* DL_Group had a constructor for DSA-style prime gen but it wasn't defined
-* Reversed the ordering of the two arguments to SEAL's constructor
-* Fixed a threading problem in the PK algorithms
-* Fixed a minor memory leak in lookup.cpp
-* Fixed pk_types.h (it was broken in 0.8.5)
-* Made validation tests more verbose
-* Updated the check and example applications
-
diff --git a/doc/relnotes/0_8_7.rst b/doc/relnotes/0_8_7.rst
deleted file mode 100644
index 28d4bda56..000000000
--- a/doc/relnotes/0_8_7.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 0.8.7, 2002-07-30
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed bugs in EME1 and EMSA4
-* Fixed a potential crash at shutdown
-* Cipher modes returned an ill-formed name
-* Removed various deprecated types and headers
-* Cleaned up the Pipe interface a bit
-* Minor additions to the documentation
-* First stab at a Visual C++ makefile (doc/Makefile.vc7)
-
diff --git a/doc/relnotes/0_9_0.rst b/doc/relnotes/0_9_0.rst
deleted file mode 100644
index ef73f6ae2..000000000
--- a/doc/relnotes/0_9_0.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 0.9.0, 2002-08-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* EMSA4 supports variable salt size
-* PK_* can take a string naming the encoding method to use
-* Started writing some internals documentation
-
-
diff --git a/doc/relnotes/0_9_1.rst b/doc/relnotes/0_9_1.rst
deleted file mode 100644
index 8d6398d58..000000000
--- a/doc/relnotes/0_9_1.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 0.9.1, 2002-08-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Grand rename from OpenCL to Botan
-* Major optimizations for the PK algorithms
-* Added ElGamal encryption
-* Added Whirlpool
-* Tweaked memory allocation parameters
-* Improved the method of seeding the global RNG
-* Moved pkcs1.h to eme_pkcs.h
-* Added more test vectors for some algorithms
-* Fixed error reporting in the BigInt tests
-* Removed Default_Timer, it was pointless
-* Added some new example applications
-* Removed some old examples that weren't that interesting
-* Documented the compression modules
-
diff --git a/doc/relnotes/0_9_2.rst b/doc/relnotes/0_9_2.rst
deleted file mode 100644
index 46eff06f5..000000000
--- a/doc/relnotes/0_9_2.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 0.9.2, 2002-08-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* DH_PrivateKey::public_value() was returning the wrong value
-* Various BigInt optimizations
-* The filters.h header now includes hex.h and base64.h
-* Moved Counter mode to ctr.h
-* Fixed a couple minor problems with VC++ 7
-* Fixed problems with the RPM spec file
-
diff --git a/doc/relnotes/1_0_0.rst b/doc/relnotes/1_0_0.rst
deleted file mode 100644
index 322aa1472..000000000
--- a/doc/relnotes/1_0_0.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.0.0, 2002-08-26
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Octal I/O of BigInt is now supported
-* Fixed portability problems in the es_egd module
-* Generalized IV handling in the block cipher modes
-* Added Karatsuba multiplication and k-ary exponentiation
-* Fixed a problem in the multiplication routines
-
-
diff --git a/doc/relnotes/1_0_1.rst b/doc/relnotes/1_0_1.rst
deleted file mode 100644
index d496099ad..000000000
--- a/doc/relnotes/1_0_1.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.0.1, 2002-09-14
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a minor bug in Randpool::random()
-* Added some new aliases and typedefs for 1.1.x compatibility
-* The 4096-bit RSA benchmark key was decimal instead of hex
-* EMAC was returning an incorrect name
-
diff --git a/doc/relnotes/1_0_2.rst b/doc/relnotes/1_0_2.rst
deleted file mode 100644
index 9e09f198a..000000000
--- a/doc/relnotes/1_0_2.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.0.2, 2003-01-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed an obscure SEGFAULT causing bug in Pipe
-* Fixed an obscure but dangerous bug in SecureVector::swap
-
diff --git a/doc/relnotes/1_10_0.rst b/doc/relnotes/1_10_0.rst
deleted file mode 100644
index 3b6ba56ac..000000000
--- a/doc/relnotes/1_10_0.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.10.0, 2011-06-20
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Detection for the rdrand instruction being added to upcoming Intel
- Ivy Bridge processors has been added.
-
-* A template specialization of std::swap was added for the memory
- container types.
-
-
diff --git a/doc/relnotes/1_10_1.rst b/doc/relnotes/1_10_1.rst
deleted file mode 100644
index 0620e59a3..000000000
--- a/doc/relnotes/1_10_1.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-Version 1.10.1, 2011-07-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* A race condition in `Algorithm_Factory` could cause crashes in
- multithreaded code. See
- :botan-devel:`this thread on botan-devel <2011-July/001455>`
- for details and workarounds.
-
-* The return value of ``name`` has changed for GOST 28147-89 and
- Skein-512. GOST's ``name`` now includes the name of the sbox, and
- Skein's includes the personalization string (if nonempty). This
- allows an object to be properly roundtripped, which is necessary to
- fix the race condition described above.
-
-* A new distribution script is now included, as
- ``src/build-data/scripts/dist.py``
-
-* The ``build.h`` header now includes, if available, an identifier of
- the source revision that was used. This identifier is also included
- in the result of ``version_string``.
-
diff --git a/doc/relnotes/1_10_2.rst b/doc/relnotes/1_10_2.rst
deleted file mode 100644
index de52d1115..000000000
--- a/doc/relnotes/1_10_2.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-Version 1.10.2, 2012-06-17
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Several TLS bugs were fixed in this release, including a major
-omission that the renegotiation extension was not being used. As the
-1.10 implementation of TLS does not properly support renegotiation,
-the approach in this release is simply to send the renegotiation
-extension SCSV, which should protect the client against any handshake
-splicing. In addition renegotiation attempts are handled properly
-instead of causing handshake failures - all hello requests, and all
-client hellos after the initial negotiation, are ignored. Some
-bugs affecting DSA server authentication were also fixed.
-
-By popular request, ``Pipe::reset`` no longer requires that message
-processing be completed, a requirement that caused problems when a
-Filter's end_msg call threw an exception, after which point the Pipe
-object was no longer usable.
-
-Support for getting entropy using the rdrand instruction introduced in
-Intel's Ivy Bridge processors has been added. In previous releases,
-the ``CPUID::has_rdrand`` function was checking the wrong cpuid bit,
-and would false positive on AMD Bulldozer processors.
-
-An implementation of SRP-6a compatible with the specification in RFC
-5054 is now available in ``srp6.h``. In 1.11, this is being used for
-TLS-SRP, but may be useful in other environments as well.
-
-An implementation of the Camellia block cipher was added, again largely
-for use in TLS.
-
-If ``clock_gettime`` is available on the system, hres_timer will poll all
-the available clock types.
-
-AltiVec is now detected on IBM POWER7 processors and on OpenBSD systems.
-The OpenBSD support was contributed by Brad Smith.
-
-The Qt mutex wrapper was broken and would not compile with any recent
-version of Qt. Taking this as a clear indication that it is not in use,
-it has been removed.
-
-Avoid setting the soname on OpenBSD, as it doesn't support it (:pr:`158`)
-
-A compilation problem in the dynamic loader that prevented using
-dyn_load under MinGW GCC has been fixed.
-
-A common error for people using MinGW is to target GCC on Windows,
-however the 'Windows' target assumes the existence of Visual C++
-runtime functions which do not exist in MinGW. Now, configuring for
-GCC on Windows will cause the configure.py to warn that likely you
-wanted to configure for either MinGW or Cygwin, not the generic
-Windows target.
-
-A bug in configure.py would cause it to interpret `--cpu=s390x` as
-`s390`. This may have affected other CPUs as well. Now configure.py
-searches for an exact match, and only if no exact match is found will
-it search for substring matches.
-
-An incompatability in configure.py with the subprocess module included
-in Python 3.1 has been fixed (:pr:`157`).
-
-The exception catching syntax of configure.py has been changed to the
-Python 3.x syntax. This syntax also works with Python 2.6 and 2.7, but
-not with any earlier Python 2 release. A simple search and replace
-will allow running it under Python 2.5::
-
- perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py
-
-Note that Python 2.4 is not supported at all.
diff --git a/doc/relnotes/1_10_3.rst b/doc/relnotes/1_10_3.rst
deleted file mode 100644
index 769f12a8f..000000000
--- a/doc/relnotes/1_10_3.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.10.3, 2012-07-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A change in :doc:`1.10.2 <1_10_2>` accidentally broke ABI
-compatibility with 1.10.1 and earlier versions, causing programs
-compiled against 1.10.1 to crash if linked with 1.10.2 at runtime.
-
-Recent versions of OpenSSL include extra information in ECC private
-keys, the presence of which caused an exception when such a key was
-loaded by botan. The decoding of ECC private keys has been changed to
-ignore these fields if they are set.
diff --git a/doc/relnotes/1_10_4.rst b/doc/relnotes/1_10_4.rst
deleted file mode 100644
index 14d1fb0f8..000000000
--- a/doc/relnotes/1_10_4.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 1.10.4, 2013-01-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Avoid a conditional operation in the power mod implementations on if
- a nibble of the exponent was zero or not. This may help protect
- against certain forms of side channel attacks.
-
-* The SRP6 code was checking for invalid values as specified in RFC
- 5054, specifically values equal to zero mod p. However SRP would
- accept negative A/B values, or ones larger than p, neither of which
- should occur in a normal run of the protocol. These values are now
- rejected. Credits to Timothy Prepscius for pointing out these values
- are not normally used and probably signal something fishy.
-
-* The return value of version_string is now a compile time constant
- string, so version information can be more easily extracted from
- binaries.
diff --git a/doc/relnotes/1_10_5.rst b/doc/relnotes/1_10_5.rst
deleted file mode 100644
index c5603f0a3..000000000
--- a/doc/relnotes/1_10_5.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.10.5, 2013-03-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* A potential crash in the AES-NI implementation of the AES-192 key
- schedule (caused by misaligned loads) has been fixed.
-
-* A previously conditional operation in Montgomery multiplication and
- squaring is now always performed, removing a possible timing
- channel.
-
-* Use correct flags for creating a shared library on OS X under Clang.
-
-* Fix a compile time incompatability with Visual C++ 2012.
diff --git a/doc/relnotes/1_10_6.rst b/doc/relnotes/1_10_6.rst
deleted file mode 100644
index 241ab801c..000000000
--- a/doc/relnotes/1_10_6.rst
+++ /dev/null
@@ -1,47 +0,0 @@
-Version 1.10.6, 2013-11-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The device reading entropy source now attempts to read from all
- available devices. Previously it would break out early if a partial
- read from a blocking source occured, not continuing to read from a
- non-blocking device. This would cause the library to fall back on
- slower and less reliable techniques for collecting PRNG seed
- material. Reported by Rickard Bellgrim.
-
-* HMAC_RNG (the default PRNG implementation) now automatically reseeds
- itself periodically. Previously reseeds only occured on explicit
- application request.
-
-* Fix an encoding error in EC_Group when encoding using EC_DOMPAR_ENC_OID.
- Reported by fxdupont on github.
-
-* In EMSA2 and Randpool, avoid calling name() on objects after deleting them if
- the provided algorithm objects are not suitable for use. Found by Clang
- analyzer, reported by Jeffrey Walton.
-
-* If X509_Store was copied, the u32bit containing how long to cache validation
- results was not initialized, potentially causing results to be cached for
- significant amounts of time. This could allow a certificate to be considered
- valid after its issuing CA's cert expired. Expiration of the end-entity cert
- is always checked, and reading a CRL always causes the status to be reset, so
- this issue does not affect revocation. Found by Coverity scanner.
-
-* Avoid off by one causing a potentially unterminated string to be passed to
- the connect system call if the library was configured to use a very long path
- name for the EGD socket. Found by Coverity Scanner.
-
-* In PK_Encryptor_EME, PK_Decryptor_EME, PK_Verifier, and PK_Key_Agreement,
- avoid dereferencing an unitialized pointer if no engine supported operations
- on the key object given. Found by Coverity scanner.
-
-* Avoid leaking a file descriptor in the /dev/random and EGD entropy sources if
- stdin (file descriptor 0) was closed. Found by Coverity scanner.
-
-* Avoid a potentially undefined operation in the bit rotation operations. Not
- known to have caused problems under any existing compiler, but might have
- caused problems in the future. Caught by Clang sanitizer, reported by Jeffrey
- Walton.
-
-* Increase default hash iterations from 10000 to 50000 in PBES1 and PBES2
-
-* Add a fix for mips64el builds from Brad Smith.
diff --git a/doc/relnotes/1_10_7.rst b/doc/relnotes/1_10_7.rst
deleted file mode 100644
index 6f26bd82f..000000000
--- a/doc/relnotes/1_10_7.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.10.7, 2013-12-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* OAEP had two bugs, one of which allowed it to be used even if the
- key was too small, and the other of which would cause a crash during
- decryption if the EME data was too large for the associated key.
diff --git a/doc/relnotes/1_10_8.rst b/doc/relnotes/1_10_8.rst
deleted file mode 100644
index 5aaaceb93..000000000
--- a/doc/relnotes/1_10_8.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.10.8, 2014-04-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a bug in primality testing introduced in 1.8.3 which caused only
- a single random base, rather than a sequence of random bases, to be
- used in the Miller-Rabin test. This increased the probability that a
- non-prime would be accepted, for instance a 1024 bit number would be
- incorrectly classed as prime with probability around 2^-40. Reported
- by Jeff Marrison.
-
-* The key length limit on HMAC has been raised to 512 bytes, allowing
- the use of very long passphrases with PBKDF2.
diff --git a/doc/relnotes/1_10_9.rst b/doc/relnotes/1_10_9.rst
deleted file mode 100644
index 729e84cd7..000000000
--- a/doc/relnotes/1_10_9.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-Version 1.10.9, 2014-12-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed EAX tag verification to run in constant time
-
-* The default TLS policy now disables SSLv3.
-
-* A crash could occur when reading from a blocking random device if
- the device initially indicated that entropy was available but
- a concurrent process drained the entropy pool before the
- read was initiated.
-
-* Fix decoding indefinite length BER constructs that contain a context
- sensitive tag of zero. Github pull 26 from Janusz Chorko.
-
-* The `botan-config` script previously tried to guess its prefix from
- the location of the binary. However this was error prone, and now
- the script assumes the final installation prefix matches the value
- set during the build. Github issue 29.
-
diff --git a/doc/relnotes/1_11_0.rst b/doc/relnotes/1_11_0.rst
deleted file mode 100644
index 9662afca9..000000000
--- a/doc/relnotes/1_11_0.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-Version 1.11.0, 2012-07-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. note::
-
- In this release, many new features of C++11 are being used in the
- library. Currently GCC 4.7 and Clang 3.1 are known to work well.
- This version of the library cannot be compiled by or used with a
- C++98 compiler.
-
-TLS and PKI Changes
-""""""""""""""""""""""""""""""""""""""""
-
-There have been many changes and improvements to TLS. The interface
-is now purely event driven and does not directly interact with
-sockets. New TLS features include TLS v1.2 support, client
-certificate authentication, renegotiation, session tickets, and
-session resumption. Session information can be saved in memory or to
-an encrypted SQLite3 database. Newly supported TLS ciphersuite
-algorithms include using SHA-2 for message authentication, pre shared
-keys and SRP for authentication and key exchange, ECC algorithms for
-key exchange and signatures, and anonymous DH/ECDH key exchange.
-
-Support for OCSP has been added. Currently only client-side support
-exists.
-
-The API for X.509 path validation has changed, with
-``x509_path_validate`` in x509path.h now handles path validation and
-``Certificate_Store`` handles storage of certificates and CRLs.
-
-Memory Container Changes
-""""""""""""""""""""""""""""""""""""""""
-
-The memory container types have changed substantially. The
-``MemoryVector`` and ``SecureVector`` container types have been
-removed, and an alias of ``std::vector`` using an allocator that
-clears memory named ``secure_vector`` is used for key material, with
-plain ``std::vector`` being used for everything else.
-
-The technique used for mlock'ing memory on Linux and BSD systems is
-much improved. Now a single page-aligned block of memory (the exact
-limit of what we can mlock) is mmap'ed, with allocations being done
-using a best-fit allocator and all metadata held outside the mmap'ed
-range, in an effort to make best use of the very limited amount of
-memory current Linux kernels allow unpriveledged users to lock.
-
-New LZMA Compression Filter
-""""""""""""""""""""""""""""""""""""""""
-
-A filter using LZMA was contributed by Vojtech Kral. It is available
-if LZMA support was enabled at compilation time by passing
-``--with-lzma`` to ``configure.py``.
-
-ECC Key Decoding Problem Resolved
-""""""""""""""""""""""""""""""""""""""""
-
-:rfc:`5915` adds some extended information which can be included in
-ECC private keys which the ECC key decoder did not expect, causing an
-exception when such a key was loaded. In particular, recent versions
-of OpenSSL use these fields. Now these fields are decoded properly,
-and if the public key value is included it is used, as otherwise the
-public key needs to be rederived from the private key. However the
-library does not include these fields on encoding keys for
-compatability with software that does not expect them (including older
-versions of botan).
diff --git a/doc/relnotes/1_11_1.rst b/doc/relnotes/1_11_1.rst
deleted file mode 100644
index 0e1fba4dc..000000000
--- a/doc/relnotes/1_11_1.rst
+++ /dev/null
@@ -1,91 +0,0 @@
-Version 1.11.1, 2012-10-30
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-TLS Enhancements and Bug Fixes
-""""""""""""""""""""""""""""""""""""""""
-
-Initial support for DTLS (both v1.0 and v1.2) is available in this
-release, though it should be considered highly experimental. Currently
-timeouts and retransmissions are not handled.
-
-The :cpp:class:`TLS::Client` constructor now takes the version to
-offer to the server. The policy hook :cpp:class:`TLS::Policy` function
-`pref_version`, which previously controlled this, has been removed.
-
-:cpp:class:`TLS::Session_Manager_In_Memory` now chooses a random
-256-bit key at startup and encrypts all sessions (using the existing
-:cpp:func:`TLS::Session::encrypt` mechanism) while they are stored in
-memory. This is primarily to reduce pressure on locked memory, as each
-session normally requires 48 bytes of locked memory for the master
-secret, whereas now only 32 bytes are needed total. This change may
-also make it slightly harder for an attacker to extract session data
-from memory dumps (eg with a cold boot attack).
-
-The keys used in :cpp:func:`session encryption <TLS::Session::encrypt>`
-were previously uniquely determined by the master key. Now the
-encrypted session blob includes two 80 bit salts which are used in the
-derivation of the cipher and MAC keys.
-
-The ``secure_renegotiation`` flag is now considered an aspect of the
-connection rather than the session, which matches the behavior of
-other implementations. As the format has changed, sessions saved to
-persistent storage by 1.11.0 will not load in this version and vice
-versa. In either case this will not cause any errors, the session will
-simply not resume and instead a full handshake will occur.
-
-New policy hooks :cpp:func:`TLS::Policy::acceptable_protocol_version`,
-:cpp:func:`TLS::Policy::allow_server_initiated_renegotiation`, and
-:cpp:func:`TLS::Policy::negotiate_heartbeat_support` were added.
-
-TLS clients were not sending a next protocol message during a session
-resumption, which would cause resumption failures with servers that
-support NPN if NPN was being offered by the client.
-
-A bug caused heartbeat requests sent by the counterparty during a
-handshake to be passed to the application callback as if they were
-heartbeat responses.
-
-Support for TLS key material export as specified in :rfc:`5705` has
-been added, available via :cpp:func:`TLS::Channel::key_material_export`
-
-New Feature: Public Key Strength Checking
-""""""""""""""""""""""""""""""""""""""""""
-
-A new function :cpp:func:`Public_Key::estimated_strength` returns
-an estimate for the upper bound of the strength of the key. For
-instance for an RSA key, it will return an estimate of how many
-operations GNFS would take to factor the key.
-
-A new :cpp:class:`Path_Validation_Result` code has been added
-``SIGNATURE_METHOD_TOO_WEAK``. By default signatures created with keys
-below 80 bits of strength (as estimated by ``estimated_strength``) are
-rejected. This level can be modified using a parameter to the
-:cpp:class:`Path_Validation_Restrictions` constructor.
-
-SRP6 Is Picker About Values
-""""""""""""""""""""""""""""""""""""""""
-
-The SRP6 code was checking for invalid values as specified in
-:rfc:`5054`, ones equal to zero mod p, however it would accept
-negative A/B values, or ones larger than p, neither of which should
-occur in a normal run of the protocol. These values are now
-rejected. Credits to Timothy Prepscius for pointing out these values
-are not normally used and probably signal something fishy.
-
-Removal of Various BigInt Functions
-""""""""""""""""""""""""""""""""""""""""
-
-Several :cpp:class:`BigInt` functions have been removed, including
-``operator[]``, ``assign``, ``get_reg``, and ``grow_reg``. The version
-of ``data`` that returns a mutable pointer has been renamed
-``mutable_data``. Support for octal conversions has been removed.
-
-The constructor ``BigInt(NumberType type, size_t n)`` has been
-removed, replaced by ``BigInt::power_of_2``.
-
-AES-NI Crash Fixed
-""""""""""""""""""""""""""""""""""""""""
-
-In 1.11.0, when compiled by GCC, the AES-NI implementation of AES-192
-would crash if the mlock-based allocator was used due to an alignment
-issue.
diff --git a/doc/relnotes/1_11_10.rst b/doc/relnotes/1_11_10.rst
deleted file mode 100644
index 9297a2278..000000000
--- a/doc/relnotes/1_11_10.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-Version 1.11.10, 2014-12-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* An implementation of McEliece code-based public key encryption based
- on INRIA's HyMES and secured against a variety of side-channels was
- contributed by cryptosource GmbH. The original version is LGPL but
- cryptosource has secured permission to release an adaptation under a
- BSD license. A CCA2-secure KEM scheme is also included.
-
- The implementation is further described in
- http://www.cryptosource.de/docs/mceliece_in_botan.pdf and
- http://cryptosource.de/news_mce_in_botan_en.html
-
-* DSA and ECDSA now create RFC 6979 deterministic signatures.
-
-* Add support for TLS fallback signaling (draft-ietf-tls-downgrade-scsv-00).
- Clients will send a fallback SCSV if the version passed to the Client
- constructor is less than the latest version supported by local policy, so
- applications implementing fallback are protected. Servers always check the
- SCSV.
-
-* In previous versions a TLS::Server could service either TLS or DTLS
- connections depending on policy settings and what type of client hello it
- received. This has changed and now a Server object is initialized for
- either TLS or DTLS operation. The default policy previously prohibited
- DTLS, precisely to prevent a TCP server from being surprised by a DTLS
- connection. The default policy now allows TLS v1.0 or higher or DTLS v1.2.
-
-* Fixed a bug in CCM mode which caused it to produce incorrect tags when used
- with a value of L other than 2. This affected CCM TLS ciphersuites, which
- use L=3. Thanks to Manuel Pégourié-Gonnard for the anaylsis and patch.
- Bugzilla 270.
-
-* DTLS now supports timeouts and handshake retransmits. Timeout checking
- is triggered by the application calling the new TLS::Channel::timeout_check.
-
-* Add a TLS policy hook to disable putting the value of the local clock in hello
- random fields.
-
-* All compression operations previously available as Filters are now
- performed via the Transformation API, which minimizes memory copies.
- Compression operations are still available through the Filter API
- using new general compression/decompression filters in comp_filter.h
-
-* The zlib module now also supports gzip compression and decompression.
-
-* Avoid a crash in low-entropy situations when reading from /dev/random, when
- select indicated the device was readable but by the time we start the read the
- entropy pool had been depleted.
-
-* The Miller-Rabin primality test function now takes a parameter allowing the
- user to directly specify the maximum false negative probability they are
- willing to accept.
-
-* PKCS #8 private keys can now be encrypted using GCM mode instead of
- unauthenticated CBC. The default remains CBC for compatability.
-
-* The default PKCS #8 encryption scheme has changed to use PBKDF2 with
- SHA-256 instead of SHA-1
-
-* A specialized reducer for P-521 was added.
-
-* On Linux the mlock allocator will use MADV_DONTDUMP on the pool so
- that the contents are not included in coredumps.
-
-* A new interface for directly using a system-provided PRNG is
- available in system_rng.h. Currently only systems with /dev/urandom
- are supported.
-
-* Fix decoding indefinite length BER constructs that contain a context sensitive
- tag of zero. Github pull 26 from Janusz Chorko.
-
-* The GNU MP engine has been removed.
-
-* Added AltiVec detection for POWER8 processors.
-
-* Add a new install script written in Python which replaces shell hackery in the
- makefiles.
-
-* Various modifications to better support Visual C++ 2013 and 2015. Github
- issues 11, 17, 18, 21, 22.
diff --git a/doc/relnotes/1_11_11.rst b/doc/relnotes/1_11_11.rst
deleted file mode 100644
index bd9706d1f..000000000
--- a/doc/relnotes/1_11_11.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-Version 1.11.11, 2014-12-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The Sqlite3 wrapper has been abstracted to a simple interface for
- SQL dbs in general, though Sqlite3 remains the only implementation.
- The main logic of the TLS session manager which stored encrypted
- sessions to a Sqlite3 database (`TLS::Session_Manager_SQLite`) has
- been moved to the new `TLS::Session_Manager_SQL`. The Sqlite3
- manager API remains the same but now just subclasses
- `TLS::Session_Manager_SQL` and has a constructor instantiate the
- concrete database instance.
-
- Applications which would like to use a different db can now do so
- without having to reimplement the session cache logic simply by
- implementing a database wrapper subtype.
-
-* The CryptGenRandom entropy source is now also used on MinGW.
-
-* The system_rng API is now also available on systems with CryptGenRandom
-
-* With GCC use -fstack-protector for linking as well as compiling,
- as this is required on MinGW. Github issue 34.
-
-* Fix missing dependency in filters that caused compilation problem
- in amalgamation builds. Github issue 33.
-
-* SSLv3 support is officially deprecated and will be removed in a
- future release.
diff --git a/doc/relnotes/1_11_12.rst b/doc/relnotes/1_11_12.rst
deleted file mode 100644
index cc304b824..000000000
--- a/doc/relnotes/1_11_12.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-Version 1.11.12, 2015-01-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add Curve25519. The implementation is based on curve25519-donna-c64.c
- by Adam Langley. New (completely non-standard) OIDs and formats for
- encrypting Curve25519 keys under PKCS #8 and including them in
- certificates and CRLs have been defined.
-
-* Add Poly1305, based on the implementation poly1305-donna by Andrew Moon.
-
-* Add the ChaCha20Poly1305 AEADs defined in draft-irtf-cfrg-chacha20-poly1305-03
- and draft-agl-tls-chacha20poly1305-04.
-
-* Add ChaCha20Poly1305 ciphersuites for TLS compatible with Google's servers
- following draft-agl-tls-chacha20poly1305-04
-
-* When encrypted as PKCS #8 structures, Curve25519 and McEliece
- private keys default to using AES-256/GCM instead of AES-256/CBC
-
-* Define OIDs for OCB mode with AES, Serpent and Twofish.
-
diff --git a/doc/relnotes/1_11_13.rst b/doc/relnotes/1_11_13.rst
deleted file mode 100644
index 7eaac8f37..000000000
--- a/doc/relnotes/1_11_13.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-Version 1.11.13, 2015-01-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* All support for the insecure SSLv3 protocol and the server support
- for processing SSLv2 client hellos has been removed.
-
-* The command line tool now has `tls_proxy` which negotiates TLS with
- clients and forwards the plaintext to a specified port.
-
-* Add MCEIES, a McEliece-based integrated encryption system using
- AES-256 in OCB mode for message encryption/authentication.
-
-* Add DTLS-SRTP negotiation defined in RFC 5764
-
-* Add SipHash
-
-* Add SHA-512/256
-
-* The format of serialized TLS sessions has changed. Additiionally, PEM
- formatted sessions now use the label of "TLS SESSION" instead of "SSL SESSION"
-
-* Serialized TLS sessions are now encrypted using AES-256/GCM instead of a
- CBC+HMAC construction.
-
-* The cryptobox_psk module added in 1.11.4 and previously used for TLS session
- encryption has been removed.
-
-* When sending a TLS heartbeat message, the number of pad bytes to use can now
- be specified, making it easier to use for PMTU discovery.
-
-* If available, zero_mem now uses RtlSecureZeroMemory or memset_s instead of a
- byte-at-a-time loop.
-
-* The functions base64_encode and base64_decode would erroneously
- throw an exception if passed a zero-length input. Github issue 37.
-
-* The Python install script added in version 1.11.10 failed to place the
- headers into a versioned subdirectory.
-
-* Fix the install script when running under Python3.
-
-* Avoid code that triggers iterator debugging asserts under MSVC 2013. Github
- pull 36 from Simon Warta.
diff --git a/doc/relnotes/1_11_14.rst b/doc/relnotes/1_11_14.rst
deleted file mode 100644
index 320a5f221..000000000
--- a/doc/relnotes/1_11_14.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-Version 1.11.14, 2015-02-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The global state object previously used by the library has been removed.
- This includes the global PRNG. The library can be safely initialized
- multiple times without harm.
-
- The engine code has also been removed, replaced by a much lighter-weight
- object registry system which provides lookups in faster time and with less
- memory overhead than the previous approach.
-
- One caveat of the current system with regards to static linking: because only
- symbols already mentioned elsewhere in the program are included in the final
- link step, few algorithms will be available through the lookup system by
- default, even though they were compiled into the library. Your application
- must explicitly reference the types you require or they will not end up
- being available in the final binary. See also Github issue #52
-
- If you intend to build your application against a static library and don't
- want to explicitly reference each algo object you might attempt to look up by
- string, consider either building with `--via-amalgamation`, or else (much
- simpler) using the amalgamation directly.
-
-* The new `ffi` submodule provides a simple C API/ABI for a number of useful
- operations (hashing, ciphers, public key operations, etc) which is easily
- accessed using the FFI modules included in many languages.
-
-* A new Python wrapper (in `src/lib/python/botan.py`) using `ffi` and the Python
- `ctypes` module is available. The old Boost.Python wrapper has been removed.
-
-* Add specialized reducers for P-192, P-224, P-256, and P-384
-
-* OCB mode, which provides a fast and constant time AEAD mode without requiring
- hardware support, is now supported in TLS, following
- draft-zauner-tls-aes-ocb-01. Because this specification is not yet finalized
- is not yet enabled by the default policy, and the ciphersuite numbers used are
- in the experimental range and may conflict with other uses.
-
-* Add ability to read TLS policy from a text file using `TLS::Text_Policy`.
-
-* The amalgamation now splits off any ISA specific code (for instance, that
- requiring SSSE3 instruction sets) into a new file named (for instance)
- `botan_all_ssse3.cpp`. This allows the main amalgamation file to be compiled
- without any special flags, so `--via-amalgamation` builds actually work now.
- This is disabled with the build option `--single-amalgamation-file`
-
-* PBKDF and KDF operations now provide a way to write the desired output
- directly to an application-specified area rather than always allocating a new
- heap buffer.
-
-* HKDF, previously provided using a non-standard interface, now uses the
- standard KDF interface and is retrievable using get_kdf.
-
-* It is once again possible to build the complete test suite without requiring
- any boost libraries. This is currently only supported on systems supporting
- the readdir interface.
-
-* Remove use of memset_s which caused problems with amalgamation on OS X.
- Github 42, 45
-
-* The memory usage of the counter mode implementation has been reduced.
- Previously it encrypted 256 blocks in parallel as this leads to a slightly
- faster counter increment operation. Instead CTR_BE simply encrypts a buffer
- equal in size to the advertised parallelism of the cipher implementation.
- This is not measurably slower, and dramatically reduces the memory use of
- CTR mode.
-
-* The memory allocator available on Unix systems which uses mmap and mlock to
- lock a pool of memory now checks environment variable BOTAN_MLOCK_POOL_SIZE
- and interprets it as an integer. If the value set to a smaller value then the
- library would originally have allocated (based on resource limits) the user
- specified size is used instead. You can also set the variable to 0 to
- disable the pool entirely. Previously the allocator would consume all
- available mlocked memory, this allows botan to coexist with an application
- which wants to mlock memory for its own uses.
-
-* The botan-config script previously installed on Unix systems has been
- removed. Its functionality is replaced by the `config` command of the
- `botan` tool executable, for example `botan config cflags` instead of
- `botan-config --cflags`.
-
-* Added a target for POWER8 processors
-
diff --git a/doc/relnotes/1_11_15.rst b/doc/relnotes/1_11_15.rst
deleted file mode 100644
index 028965eaf..000000000
--- a/doc/relnotes/1_11_15.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 1.11.15, 2015-03-08
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Support for RC4 in TLS, already disabled by default, is now deprecated.
- The RC4 ciphersuites will be removed entirely in a future release.
-
-* A bug in ffi.cpp meant Python could only encrypt. Github issue 53.
-
-* When comparing two ASN.1 algorithm identifiers, consider empty and
- NULL parameters the same.
-
-* Fixed memory leaks in TLS and cipher modes introduced in 1.11.14
-
-* MARK-4 failed when OpenSSL was enabled in the build in 1.11.14
- because the OpenSSL version ignored the skip parameter.
-
-* Fix compilation problem on OS X/clang
-
-* Use BOTAN_NOEXCEPT macro to work around lack of noexcept in VS 2013
diff --git a/doc/relnotes/1_11_16.rst b/doc/relnotes/1_11_16.rst
deleted file mode 100644
index c27e5a204..000000000
--- a/doc/relnotes/1_11_16.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-Version 1.11.16, 2015-03-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* TLS has changed from using the non-standard NPN extension to the IETF
- standardized ALPN extension for negotiating an application-level protocol.
- Unfortunately the semantics of the exchange have changed with ALPN. Using
- NPN, the server offered a list of protocols it advertised, and then the
- client chose its favorite. With ALPN, the client offers a list of protocols
- and the server chooses. The the signatures of both the TLS::Client and
- TLS::Server constructors have changed to support this new flow.
-
-* Optimized ECDSA signature verification thanks to an observation by
- Dr. Falko Strenzke. On some systems verifications are between 1.5
- and 2 times faster than in 1.11.15.
-
-* RSA encrypt and decrypt operations using OpenSSL have been added.
-
-* Public key operation types now handle all aspects of the operation,
- such as hashing and padding for signatures. This change allows
- supporting specialized implementations which only support particular
- padding types.
-
-* Added global timeout to HMAC_RNG entropy reseed. The defaults are
- the values set in the build.h macros `BOTAN_RNG_AUTO_RESEED_TIMEOUT`
- and `BOTAN_RNG_RESEED_DEFAULT_TIMEOUT`, but can be overriden
- on a specific poll with the new API call reseed_with_timeout.
-
-* Fixed Python cipher update_granularity() and default_nonce_length()
- functions
-
-* The library now builds on Visual C++ 2013
-
-* The GCM update granularity was reduced from 4096 to 16 bytes.
-
-* Fix a bug that prevented building the amalgamation until a non-amalgamation
- configuration was performed first in the same directory.
-
-* Add Travis CI integration. Github pull 60.
diff --git a/doc/relnotes/1_11_17.rst b/doc/relnotes/1_11_17.rst
deleted file mode 100644
index 646bbf34c..000000000
--- a/doc/relnotes/1_11_17.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 1.11.17, 2015-06-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* All support for the insecure RC4 stream cipher has been removed
- from the TLS implementation.
-
-* Fix decoding of TLS maximum fragment length. Regardless of what
- value was actually negotiated, TLS would treat it as a negotiated
- limit of 4096.
-
-* Fix the configure.py flag `--disable-aes-ni` which did nothing of
- the sort.
-
-* Fixed nmake clean target. GitHub #104
-
-* Correct buffering logic in `Compression_Filter`. GitHub #93 and #95
diff --git a/doc/relnotes/1_11_2.rst b/doc/relnotes/1_11_2.rst
deleted file mode 100644
index 767fbf624..000000000
--- a/doc/relnotes/1_11_2.rst
+++ /dev/null
@@ -1,47 +0,0 @@
-Version 1.11.2, 2013-03-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* A bug in the release script caused the `botan_version.py` included
- in :doc:`1.11.1 <1_11_1>` to be invalid, which required a manual
- edit to fix (:pr:`226`)
-
-Memory Zeroization Changes
-""""""""""""""""""""""""""""""""""""""""
-
-* Previously `clear_mem` was implemented by an inlined call to
- `std::memset`. However an optimizing compiler might notice cases
- where the memset could be skipped in cases allowed by the standard.
- Now `clear_mem` calls `zero_mem` which is compiled separately and
- which zeros out the array through a volatile pointer. It is possible
- some compiler with some optimization setting (especially with
- something like LTO) might still skip the writes. It would be nice if
- there was an automated way to test this.
-
-New Parallel Filter
-""""""""""""""""""""""""""""""""""""""""
-
-* The new filter :cpp:class:`Threaded_Fork` acts like a normal
- :cpp:class:`Fork`, sending its input to a number of different
- filters, but each subchain of filters in the fork runs in its own
- thread. Contributed by Joel Low.
-
-TLS Enhancements and Bug Fixes
-""""""""""""""""""""""""""""""""""""""""
-
-* The default TLS policy formerly preferred AES over RC4, and allowed
- 3DES by default. Now the default policy is to negotiate only either
- AES or RC4, and to prefer RC4.
-
-* New TLS :cpp:class:`Blocking_Client` provides a thread per
- connection style API similar to that provided in 1.10
-
-Other API Changes
-""""""""""""""""""""""""""""""""""""""""
-
-* The API of `Credentials_Manager::trusted_certificate_authorities`
- has changed to return a vector of `Certificate_Store*` instead of
- `X509_Certificate`. This allows the list of trusted CAs to be
- more easily updated dynamically or loaded lazily.
-
-* The `asn1_int.h` header was split into `asn1_alt_name.h`,
- `asn1_attribute.h` and `asn1_time.h`.
diff --git a/doc/relnotes/1_11_3.rst b/doc/relnotes/1_11_3.rst
deleted file mode 100644
index fc8eebe14..000000000
--- a/doc/relnotes/1_11_3.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-Version 1.11.3, 2013-04-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add a new interface for AEAD modes (:cpp:class:`AEAD_Mode`).
-
-* Implementations of the OCB and GCM authenticated cipher modes are
- now included.
-
-* Support for TLS GCM ciphersuites is now available.
-
-* A new TLS policy mechanism
- :cpp:func:`TLS::Policy::server_uses_own_ciphersuite_preferences`
- controls how a server chooses a ciphersuite. Previously it always
- chose its most preferred cipher out of the client's list, but this
- can allow configuring a server to choose by the client's preferences
- instead.
-
-* :cpp:class:`Keyed_Filter` now supports returning a
- :cpp:class:`Key_Length_Specification` so the full details of what
- keylengths are supported is now available in keyed filters.
-
-* The experimental and rarely used Turing and WiderWAKE stream ciphers
- have been removed
-
-* New functions for symmetric encryption are included in cryptobox.h
- though interfaces and formats are subject to change.
-
-* A new function :cpp:func:`algorithm_kat_detailed` returns a string
- providing information about failures, instead of just a pass/fail
- indicator as in :cpp:func:`algorithm_kat`.
diff --git a/doc/relnotes/1_11_4.rst b/doc/relnotes/1_11_4.rst
deleted file mode 100644
index a635531a7..000000000
--- a/doc/relnotes/1_11_4.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-Version 1.11.4, 2013-07-25
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* CPU specific extensions are now always compiled if support for the
- operations is available at build time, and flags enabling use of
- extra operations (such as SSE2) are only included when compiling
- files which specifically request support. This means, for instance,
- that the SSSE3 and AES-NI implementations of AES are always included
- in x86 builds, relying on runtime cpuid checking to prevent their
- use on CPUs that do not support those operations.
-
-* The default TLS policy now only accepts TLS, to minimize surprise
- for servers which might not expect to negotiate DTLS. Previously a
- server would by default negotiate either protocol type (clients
- would only accept the same protocol type as they
- offered). Applications which use DTLS or combined TLS/DTLS need to
- override :cpp:func:`Policy::acceptable_protocol_version`.
-
-* The TLS channels now accept a new parameter specifying how many
- bytes to preallocate for the record handling buffers, which allows
- an application some control over how much memory is used at runtime
- for a particular connection.
-
-* Applications can now send arbitrary TLS alert messages using
- :cpp:func:`TLS::Channel::send_alert`
-
-* A new TLS policy :cpp:class:`NSA_Suite_B_128` is available, which
- will negotiate only the 128-bit security NSA Suite B. See
- :rfc:`6460` for more information about Suite B.
-
-* Adds a new interface for benchmarking, :cpp:func:`time_algorithm_ops`,
- which returns a map of operations to operations per second. For
- instance now both encrypt and decrypt speed of a block cipher can be
- checked, as well as the key schedule of all keyed algorithms. It
- additionally supports AEAD modes.
-
-* Rename ARC4 to RC4
diff --git a/doc/relnotes/1_11_5.rst b/doc/relnotes/1_11_5.rst
deleted file mode 100644
index b327bfd82..000000000
--- a/doc/relnotes/1_11_5.rst
+++ /dev/null
@@ -1,53 +0,0 @@
-Version 1.11.5, 2013-11-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The TLS callback signatures have changed - there are now two distinct
- callbacks for application data and alerts. TLS::Client and TLS::Server have
- constructors which continue to accept the old callback and use it for both
- operations.
-
-* The entropy collector that read from randomness devices had two bugs - it
- would break out of the poll as soon as any read succeeded, and it selected on
- each device individually. When a blocking source was first in the device list
- and the entropy pool was running low, the reader might either block in select
- until eventually timing out (continuing on to read from /dev/urandom instead),
- or read just a few bytes, skip /dev/urandom, fail to satisfy the entropy
- target, and the poll would continue using other (slower) sources. This caused
- substantial performance/latency problems in RNG heavy applications. Now all
- devices are selected over at once, with the effect that a full read from
- urandom always occurs, along with however much (if any) output is available
- from blocking sources.
-
-* Previously AutoSeeded_RNG referenced a globally shared PRNG instance.
- Now each instance has distinct state.
-
-* The entropy collector that runs Unix programs to collect statistical
- data now runs multiple processes in parallel, greatly reducing poll
- times on some systems.
-
-* The Randpool RNG implementation was removed.
-
-* All existing cipher mode implementations (such as CBC and XTS) have been
- converted from filters to using the interface previously provided by
- AEAD modes which allows for in-place message
- processing. Code which directly references the filter objects will break, but
- an adaptor filter allows usage through get_cipher as usual.
-
-* An implementation of CCM mode from RFC 3601 has been added, as well as CCM
- ciphersuites for TLS.
-
-* The implementation of OCB mode now supports 64 and 96 bit tags
-
-* Optimized computation of XTS tweaks, producing a substantial speedup
-
-* Add support for negotiating Brainpool ECC curves in TLS
-
-* TLS v1.2 will not negotiate plain SHA-1 signatures by default.
-
-* TLS channels now support sending a ``std::vector``
-
-* Add a generic 64x64->128 bit multiply instruction operation in mul128.h
-
-* Avoid potentially undefined operations in the bit rotation operations. Not
- known to have caused problems under existing compilers but might break in the
- future. Found by Clang sanitizer, reported by Jeffrey Walton.
diff --git a/doc/relnotes/1_11_6.rst b/doc/relnotes/1_11_6.rst
deleted file mode 100644
index 8282e9e28..000000000
--- a/doc/relnotes/1_11_6.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-Version 1.11.6, 2013-12-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The Boost filesystem and asio libraries are now being used by default.
- Pass ``--without-boost`` to ``configure.py`` to disable.
-
-* The default TLS policy no longer allows SSLv3 or RC4.
-
-* OAEP had two bugs, one of which allowed it to be used even if the
- key was too small, and the other of which would cause a crash during
- decryption if the EME data was too large for the associated key.
-
-* GCM mode now uses the Intel clmul instruction when available
-
-* Add the Threefish-512 tweakable block cipher, including an AVX2 version
-
-* Add SIV (from :rfc:`5297`) as a nonce-based AEAD
-
-* Add HKDF (from :rfc:`5869`) using an experimental PRF interface
-
-* Add HTTP utility functions and OCSP online checking
-
-* Add TLS::Policy::acceptable_ciphersuite hook to disable ciphersuites
- on an ad-hoc basis.
-
-* TLS::Session_Manager_In_Memory's constructor now requires a RNG
-
diff --git a/doc/relnotes/1_11_7.rst b/doc/relnotes/1_11_7.rst
deleted file mode 100644
index 7d4703448..000000000
--- a/doc/relnotes/1_11_7.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-Version 1.11.7, 2014-01-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Botan's basic numeric types are now defined in terms of the
- C99/C++11 standard integer types. For instance `u32bit` is now a
- typedef for `uint32_t`, and both names are included in the library
- namespace. This should not result in any application-visible
- changes.
-
-* There are now two executable outputs of the build, `botan-test`,
- which runs the tests, and `botan` which is used as a driver to call
- into various subcommands which can also act as examples of library
- use, much in the manner of the `openssl` command. It understands the
- commands `base64`, `asn1`, `x509`, `tls_client`, `tls_server`,
- `bcrypt`, `keygen`, `speed`, and various others. As part of this
- change many obsolete, duplicated, or one-off examples were removed,
- while others were extended with new functionality. Contributions of
- new subcommands, new bling for exising ones, or documentation in any
- form is welcome.
-
-* Fix a bug in Lion, which was broken by a change in 1.11.0. The
- problem was not noticed before as Lion was also missing a test vector
- in previous releases.
diff --git a/doc/relnotes/1_11_8.rst b/doc/relnotes/1_11_8.rst
deleted file mode 100644
index 7189cff26..000000000
--- a/doc/relnotes/1_11_8.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-Version 1.11.8, 2014-02-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The `botan` command line application introduced in 1.11.7 is now
- installed along with the library.
-
-* A bug in certificate path validation introduced in 1.11.6 which
- caused all CRL signature checks to fail has been corrected.
-
-* The ChaCha20 stream cipher has been added.
-
-* The ``Transformation`` class no longer implements an interface for keying,
- this has been moved to a new subclass ``Keyed_Transformation``.
-
-* The ``Algorithm`` class, which previously acted as a global base for
- various types (ciphers, hashes, etc) has been removed.
-
-* CMAC now supports 256 and 512 bit block ciphers, which also allows
- the use of larger block ciphers with EAX mode. In particular this
- allows using Threefish in EAX mode.
-
-* The antique PBES1 private key encryption scheme (which only supports
- DES or 64-bit RC2) has been removed.
-
-* The Square, Skipjack, and Luby-Rackoff block ciphers have been removed.
-
-* The Blue Midnight Wish hash function has been removed.
-
-* Skein-512 no longer supports output lengths greater than 512 bits.
-
-* Skein did not reset its internal state properly if clear() was
- called, causing it to produce incorrect results for the following
- message. It was reset correctly in final() so most usages should not
- be affected.
-
-* A number of public key padding schemes have been renamed to match
- the most common notation; for instance EME1 is now called OAEP and
- EMSA4 is now called PSSR. Aliases are set which should allow all
- current applications to continue to work unmodified.
-
-* A bug in CFB encryption caused a few bytes past the end of the final
- block to be read. The actual output was not affected.
-
-* Fix compilation errors in the tests that occured with minimized
- builds. Contributed by Markus Wanner.
-
-* Add a new ``--destdir`` option to ``configure.py`` which controls
- where the install target will place the output. The ``--prefix``
- option continues to set the location where the library expects to be
- eventually installed.
-
-* Many class destructors which previously deleted memory have been
- removed in favor of using ``unique_ptr``.
-
-* Various portability fixes for Clang, Windows, Visual C++ 2013, OS X,
- and x86-32.
diff --git a/doc/relnotes/1_11_9.rst b/doc/relnotes/1_11_9.rst
deleted file mode 100644
index a18a0b49d..000000000
--- a/doc/relnotes/1_11_9.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-Version 1.11.9, 2014-04-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a bug in primality testing introduced in 1.8.3 which caused
- only a single random base, rather than a sequence of random bases,
- to be used in the Miller-Rabin test. This increased the probability
- that a non-prime would be accepted. Reported by Jeff Marrison.
-
-* X.509 path validation now returns a set of all errors that occurred
- during validation, rather than immediately returning the first
- detected error. This prevents a seemingly innocuous error (such as
- an expired certificate) from hiding an obviously serious error
- (such as an invalid signature). The Certificate_Status_Code enum is
- now ordered by severity, and the most severe error is returned by
- Path_Validation_Result::result(). The entire set of status codes is
- available with the new all_statuses call.
-
-* Fixed a bug in OCSP response decoding which would cause an error
- when attempting to decode responses from some widely used
- responders.
-
-* An implementation of HMAC_DRBG RNG from NIST SP800-90A has been
- added. Like the X9.31 PRNG implementation, it uses another
- underlying RNG for seeding material.
-
-* An implementation of the RFC 6979 deterministic nonce generator has
- been added.
-
-* Fix a bug in certificate path validation which prevented successful
- validation if intermediate certificates were presented out of order.
-
-* Fix a bug introduced in 1.11.5 which could cause crashes or other
- incorrect behavior when a cipher mode filter was followed in the
- pipe by another filter, and that filter had a non-empty start_msg.
-
-* The types.h header now uses stdint.h rather than cstdint to avoid
- problems with Clang on OS X.
diff --git a/doc/relnotes/1_1_0.rst b/doc/relnotes/1_1_0.rst
deleted file mode 100644
index 09a08860b..000000000
--- a/doc/relnotes/1_1_0.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-Version 1.1.0, 2002-09-14
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added entropy estimation to the RNGs
-* Improved the overall design of both Randpool and ANSI_X917_RNG
-* Added a separate RNG for nonce generation
-* Added window exponentiation support in power_mod
-* Added a get_s2k function and the PKCS #5 S2K algorithms
-* Added the TLSv1 PRF
-* Replaced BlockCipherModeIV typedef with InitializationVector class
-* Renamed PK_Key_Agreement_Scheme to PK_Key_Agreement
-* Renamed SHA1 -> SHA_160 and SHA2_x -> SHA_x
-* Added support for RIPEMD-160 PKCS#1 v1.5 signatures
-* Changed the key agreement scheme interface
-* Changed the S2K and KDF interfaces
-* Better SCAN compatibility for HAVAL, Tiger, MISTY1, SEAL, RC5, SAFER-SK
-* Added support for variable-pass Tiger
-* Major speedup for Rabin-Williams key generation
-
-
diff --git a/doc/relnotes/1_1_1.rst b/doc/relnotes/1_1_1.rst
deleted file mode 100644
index bdb13f3ff..000000000
--- a/doc/relnotes/1_1_1.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.1.1, 2002-10-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the Korean hash function HAS-160
-* Partial support for RSA and DSA X.509 public keys
-* Added a mostly functional BER encoder/decoder
-* Added support for non-deterministic MAC functions
-* Initial support for PEM encoding/decoding
-* Internal cleanups in the PK algorithms
-* Several new convenience functions in Pipe
-* Fixed two nasty bugs in Pipe
-* Messed with the entropy sources for es_unix
-* Discrete logarithm groups are checked for safety more closely now
-* For compatibility with GnuPG, ElGamal now supports DSA-style groups
-
diff --git a/doc/relnotes/1_1_10.rst b/doc/relnotes/1_1_10.rst
deleted file mode 100644
index adc295152..000000000
--- a/doc/relnotes/1_1_10.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.1.10, 2003-04-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* X509_CA can now generate new X.509 CRLs
-* Added blinding for RSA, RW, DH, and ElGamal to prevent timing attacks
-* More certificate and CRL extensions/attributes are supported
-* Better DN handling in X.509 certificates/CRLs
-* Added a DataSink hierarchy (suggested by Jim Darby)
-* Consolidated SecureAllocator and ManagedAllocator
-* Many cleanups and generalizations
-* Added a (slow) pthreads based EntropySource
-* Fixed some threading bugs
-
diff --git a/doc/relnotes/1_1_11.rst b/doc/relnotes/1_1_11.rst
deleted file mode 100644
index ef05a42a0..000000000
--- a/doc/relnotes/1_1_11.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.1.11, 2003-04-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added PKCS #10 certificate requests
-* Changed X509_Store searching interface to be more flexible
-* Added a generic Certificate_Store interface
-* Added a function for generating self-signed X.509 certs
-* Cleanups and changes to X509_CA
-* New examples for PKCS #10 and self-signed certificates
-* Some documentation updates
-
diff --git a/doc/relnotes/1_1_12.rst b/doc/relnotes/1_1_12.rst
deleted file mode 100644
index 5f652af52..000000000
--- a/doc/relnotes/1_1_12.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.1.12, 2003-04-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a ASN.1 string encoding bug
-* Fixed a pair of X509_DN encoding problems
-* Base64_Decoder and Hex_Decoder can now validate input
-* Removed support for the LibraryInitializer option 'egd_path'
-* Added tests for DSA X.509 and PKCS #8 key formats
-* Removed a long deprecated feature of DH_PrivateKey's constructor
-* Updated the RPM .spec file
-* Major documentation updates
-
diff --git a/doc/relnotes/1_1_13.rst b/doc/relnotes/1_1_13.rst
deleted file mode 100644
index b7379ceb8..000000000
--- a/doc/relnotes/1_1_13.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 1.1.13, 2003-04-22
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added OMAC
-* Added EAX authenticated cipher mode
-* Diffie-Hellman would not do blinding in some cases
-* Optimized the OFB and CTR modes
-* Corrected Skipjack's word ordering, as per NIST clarification
-* Support for all subject/issuer attribute types required by RFC 3280
-* The removeFromCRL CRL reason code is now handled correctly
-* Increased the flexibility of the allocators
-* Renamed Rijndael to AES, created aes.h, deleted rijndael.h
-* Removed support for the 'no_timer' LibraryInitializer option
-* Removed 'es_pthr' module, pending further testing
-* Cleaned up get_ciph.cpp
-
diff --git a/doc/relnotes/1_1_2.rst b/doc/relnotes/1_1_2.rst
deleted file mode 100644
index 088d66804..000000000
--- a/doc/relnotes/1_1_2.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 1.1.2, 2002-10-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Support for PKCS #8 encoded RSA, DSA, and DH private keys
-* Support for Diffie-Hellman X.509 public keys
-* Major reorganization of how X.509 keys are handled
-* Added PKCS #5 v2.0's PBES1 encryption scheme
-* Added a generic cipher lookup interface
-* Added the WiderWake4+1 stream cipher
-* Added support for sync-able stream ciphers
-* Added a 'paranoia level' option for the LibraryInitializer
-* More security for RNG output meant for long term keys
-* Added documentation for some of the new 1.1.x features
-* CFB's feedback argument is now specified in bits
-* Renamed CTR class to CTR_BE
-* Updated the RSA and DSA examples to use X.509 and PKCS #8 key formats
-
diff --git a/doc/relnotes/1_1_3.rst b/doc/relnotes/1_1_3.rst
deleted file mode 100644
index f8c7fc3fc..000000000
--- a/doc/relnotes/1_1_3.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.1.3, 2002-11-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added a generic public/private key loading interface
-* Fixed a small encoding bug in RSA, RW, and DH
-* Changed the PK encryption/decryption interface classes
-* ECB supports using padding methods
-* Added a function-based interface for library initialization
-* Added support for RIPEMD-128 and Tiger PKCS#1 v1.5 signatures
-* The cipher mode benchmarks now use 128-bit AES instead of DES
-* Removed some obsolete typedefs
-* Removed OpenCL support (opencl.h, the OPENCL_* macros, etc)
-* Added tests for PKCS #8 encoding/decoding
-* Added more tests for ECB and CBC
-
diff --git a/doc/relnotes/1_1_4.rst b/doc/relnotes/1_1_4.rst
deleted file mode 100644
index 9d74c3ae5..000000000
--- a/doc/relnotes/1_1_4.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.1.4, 2002-11-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Speedup of 15-30% for PK algorithms
-* Implemented the PBES2 encryption scheme
-* Fixed a potential bug in decoding RSA and RW private keys
-* Changed the DL_Group class interface to handle different formats better
-* Added support for PKCS #3 encoded DH parameters
-* X9.42 DH parameters use a PEM label of 'X942 DH PARAMETERS'
-* Added key pair consistency checking
-* Fixed a compatibility problem with gcc 2.96 (pointed out by Hany Greiss)
-* A botan-config script is generated at configure time
-* Documentation updates
-
diff --git a/doc/relnotes/1_1_5.rst b/doc/relnotes/1_1_5.rst
deleted file mode 100644
index 90101dedb..000000000
--- a/doc/relnotes/1_1_5.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.1.5, 2002-11-17
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the discrete logarithm integrated encryption system (DLIES)
-* Various optimizations for BigInt
-* Added support for assembler optimizations in modules
-* Added BigInt x86 optimizations module (mpi_ia32)
-
diff --git a/doc/relnotes/1_1_6.rst b/doc/relnotes/1_1_6.rst
deleted file mode 100644
index 4c638b7e3..000000000
--- a/doc/relnotes/1_1_6.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.1.6, 2002-12-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Initial support for X.509v3 certificates and CAs
-* Major redesign/rewrite of the ASN.1 encoding/decoding code
-* Added handling for DSA/NR signatures encoded as DER SEQUENCEs
-* Documented the generic cipher lookup interface
-* Added an (untested) entropy source for BeOS
-* Various cleanups and bug fixes
-
diff --git a/doc/relnotes/1_1_7.rst b/doc/relnotes/1_1_7.rst
deleted file mode 100644
index bd73607e6..000000000
--- a/doc/relnotes/1_1_7.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.1.7, 2003-01-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed an obscure but dangerous bug in SecureVector::swap
-* Consolidated SHA-384 and SHA-512 to save code space
-* Added SSL3-MAC and SSL3-PRF
-* Documentation updates, including a new tutorial
-
diff --git a/doc/relnotes/1_1_8.rst b/doc/relnotes/1_1_8.rst
deleted file mode 100644
index 2ed517ece..000000000
--- a/doc/relnotes/1_1_8.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.1.8, 2003-01-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixes for the certificate path validation algorithm in X509_Store
-* Fixed a bug affecting X509_Certificate::is_ca_cert()
-* Added a general configuration interface for policy issues
-* Cleanups and API changes in the X.509 CA, cert, and store code
-* Made various options available for X509_CA users
-* Changed X509_Time's interface to work around time_t problems
-* Fixed a theoretical weakness in Randpool's entropy mixing function
-* Fixed problems compiling with GCC 2.95.3 and GCC 2.96
-* Fixed a configure bug (reported by Jon Wilson) affecting MinGW
-
diff --git a/doc/relnotes/1_1_9.rst b/doc/relnotes/1_1_9.rst
deleted file mode 100644
index 2ed18080d..000000000
--- a/doc/relnotes/1_1_9.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.1.9, 2003-02-25
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added support for using X.509v2 CRLs
-* Fixed several bugs in the path validation algorithm
-* Certificates can be verified for a particular usage
-* Algorithm for comparing distinguished names now follows X.509
-* Cleaned up the code for the es_beos, es_ftw, es_unix modules
-* Documentation updates
-
diff --git a/doc/relnotes/1_2_0.rst b/doc/relnotes/1_2_0.rst
deleted file mode 100644
index 2372919fb..000000000
--- a/doc/relnotes/1_2_0.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.2.0, 2003-04-28
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Tweaked the Karatsuba cut-off points
-* Increased the allowed keylength of HMAC and Blowfish
-* Removed the 'mpi_ia32' module, pending rewrite
-* Workaround a GCC 2.95.x bug in eme1.cpp
-
-
diff --git a/doc/relnotes/1_2_1.rst b/doc/relnotes/1_2_1.rst
deleted file mode 100644
index 885d6a10a..000000000
--- a/doc/relnotes/1_2_1.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.2.1, 2003-05-06
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added ANSI X9.23 compatible CBC padding
-* Added an entropy source using Win32 CryptoAPI
-* Removed the Pipe I/O operators taking a FILE*
-* Moved the BigInt encoding/decoding functions into the BigInt class
-* Integrated several fixes for VC++ 7 (from Hany Greiss)
-* Fixed the configure.pl script for Windows builds
-
diff --git a/doc/relnotes/1_2_2.rst b/doc/relnotes/1_2_2.rst
deleted file mode 100644
index 6732daffb..000000000
--- a/doc/relnotes/1_2_2.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.2.2, 2003-05-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add checks to prevent any BigInt bugs from revealing an RSA or RW key
-* Changed the interface of Global_RNG::seed
-* Major improvements for the es_unix module
-* Added another Win32 entropy source, es_win32
-* The Win32 CryptoAPI entropy source can now poll multiple providers
-* Improved the BeOS entropy source
-* Renamed pipe_unixfd module to fd_unix
-* Fixed a file descriptor leak in the EGD module
-* Fixed a few locking bugs
-
diff --git a/doc/relnotes/1_2_3.rst b/doc/relnotes/1_2_3.rst
deleted file mode 100644
index fd12fc09c..000000000
--- a/doc/relnotes/1_2_3.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.2.3, 2003-05-20
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a bug that prevented DSA/NR key generation
-* Fixed a bug that prevented importing some root CA certs
-* Fixed a bug in the BER decoder when handing optional bit or byte strings
-* Fixed the encoding of authorityKeyIdentifier in X509_CA
-* Added a sanity check in PBKDF2 for zero length passphrases
-* Added versions of X509::load_key and PKCS8::load_key that take a file name
-* X509_CA generates 128 bit serial numbers now
-* Added tests to check PK key generation
-* Added a simplistic X.509 CA example
-* Cleaned up some of the examples
-
diff --git a/doc/relnotes/1_2_4.rst b/doc/relnotes/1_2_4.rst
deleted file mode 100644
index 600d030c4..000000000
--- a/doc/relnotes/1_2_4.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.2.4, 2003-05-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a bug in EMSA1 affecting NR signature verification
-* Fixed a few latent bugs in BigInt related to word size
-* Removed an unused function, mp_add2_nc, from the MPI implementation
-* Reorganized the core MPI files
-
diff --git a/doc/relnotes/1_2_5.rst b/doc/relnotes/1_2_5.rst
deleted file mode 100644
index b88c37e7e..000000000
--- a/doc/relnotes/1_2_5.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-Version 1.2.5, 2003-06-22
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a tricky and long-standing memory leak in Pipe
-* Major cleanups and fixes in the memory allocation system
-* Removed alloc_mlock, which has been superseded by the ml_unix module
-* Removed a denial of service vulnerability in X509_Store
-* Fixed compilation problems with VS .NET 2003 and Codewarrior 8
-* Added another variant of PKCS8::load_key, taking a memory buffer
-* Fixed various minor/obscure bugs which occurred when MP_WORD_BITS != 32
-* BigInt::operator%=(word) was a no-op if the input was a power of 2
-* Fixed portability problems in BigInt::to_u32bit
-* Fixed major bugs in SSL3-MAC
-* Cleaned up some messes in the PK algorithms
-* Cleanups and extensions for OMAC and EAX
-* Made changes to the entropy estimation function
-* Added a 'beos' module set for use on BeOS
-* Officially deprecated a few X509:: and PKCS8:: functions
-* Moved the contents of primes.h to numthry.h
-* Moved the contents of x509opt.h to x509self.h
-* Removed the (empty) desx.h header
-* Documentation updates
-
diff --git a/doc/relnotes/1_2_6.rst b/doc/relnotes/1_2_6.rst
deleted file mode 100644
index 9a22648d5..000000000
--- a/doc/relnotes/1_2_6.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.2.6, 2003-07-04
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major performance increase for PK algorithms on most 64-bit systems
-* Cleanups in the low-level MPI code to support asm implementations
-* Fixed build problems with some versions of Compaq's C++ compiler
-* Removed useless constructors for NR public and private keys
-* Removed support for the patch_file directive in module files
-* Removed several deprecated functions
-
diff --git a/doc/relnotes/1_2_7.rst b/doc/relnotes/1_2_7.rst
deleted file mode 100644
index 8121bbef8..000000000
--- a/doc/relnotes/1_2_7.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.2.7, 2003-10-31
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added support for reading configuration files
-* Added constructors so NR and RW keys can be imported easily
-* Fixed mp_asm64, which was completely broken in 1.2.6
-* Removed tm_hw_ia32 module; replaced by tm_hard
-* Added support for loading certain oddly formed RSA certificates
-* Fixed spelling of NON_REPUDIATION enum
-* Renamed the option default_to_ca to v1_assume_ca
-* Fixed a minor bug in X.509 certificate generation
-* Fixed a latent bug in the OID lookup code
-* Updated the RPM spec file
-* Added to the tutorial
-
diff --git a/doc/relnotes/1_2_8.rst b/doc/relnotes/1_2_8.rst
deleted file mode 100644
index e234b5ccd..000000000
--- a/doc/relnotes/1_2_8.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Version 1.2.8, 2003-11-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Merged several important bug fixes from 1.3.x
-
diff --git a/doc/relnotes/1_3_0.rst b/doc/relnotes/1_3_0.rst
deleted file mode 100644
index c1229e8d2..000000000
--- a/doc/relnotes/1_3_0.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.3.0, 2003-11-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major redesign of the PKCS #8 private key import/export system
-* Added a small amount of UI interface code for getting passphrases
-* Added heuristics that tell if a key, cert, etc is stored as PEM or BER
-* Removed CS-Cipher, SHARK, ThreeWay, MD5-MAC, and EMAC
-* Removed certain deprecated constructors of RSA, DSA, DH, RW, NR
-* Made PEM decoding more forgiving of extra text before the header
-
-
diff --git a/doc/relnotes/1_3_1.rst b/doc/relnotes/1_3_1.rst
deleted file mode 100644
index 70bc79d02..000000000
--- a/doc/relnotes/1_3_1.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Version 1.3.1, 2003-11-04
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Generalized a few pieces of the DER encoder
-* PKCS8::load_key would fail if handed an unencrypted key
-* Added a failsafe so PKCS #8 key decoding can't go into an infinite loop
-
diff --git a/doc/relnotes/1_3_10.rst b/doc/relnotes/1_3_10.rst
deleted file mode 100644
index f99d11bc2..000000000
--- a/doc/relnotes/1_3_10.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.3.10, 2004-03-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added support for OpenPGP's ASCII armor format
-* Cleaned up the RNG system; seeding is much more flexible
-* Added simple autoconfiguration abilities to configure.pl
-* Fixed a GCC 2.95.x compile problem
-* Updated the example configuration file
-* Documentation updates
-
diff --git a/doc/relnotes/1_3_11.rst b/doc/relnotes/1_3_11.rst
deleted file mode 100644
index 86c1f13a1..000000000
--- a/doc/relnotes/1_3_11.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.3.11, 2004-04-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed two show-stopping bugs in PKCS10_Request
-* Added some sanity checks in Pipe/Filter
-* The DNS and URI entries would get swapped in subjectAlternativeNames
-* MAC_Filter is now willing to not take a key at creation time
-* Setting the expiration times of certs and CRLs is more flexible
-* Fixed problems building on AIX with GCC
-* Fixed some problems in the tutorial pointed out by Dominik Vogt
-* Documentation updates
-
diff --git a/doc/relnotes/1_3_12.rst b/doc/relnotes/1_3_12.rst
deleted file mode 100644
index 0a5ef7901..000000000
--- a/doc/relnotes/1_3_12.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.3.12, 2004-05-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added ability to remove old entries from CRLs
-* Swapped the first two arguments of X509_CA::update_crl()
-* Added an < operator for MemoryRegion, so it can be used as a std::map key
-* Changed X.509 searching by DNS name from substring to full string compares
-* Renamed a few X509_Certificate and PKCS10_Request member functions
-* Fixed a problem when decoding some PKCS #10 requests
-* Hex_Decoder would not check inputs, reported by Vaclav Ovsik
-* Changed default CRL expire time from 30 days to 7 days
-* X509_CRL's default PEM header is now "X509 CRL", for OpenSSL compatibility
-* Corrected errors in the API doc, fixes from Ken Perano
-* More documentation about the Pipe/Filter code
-
diff --git a/doc/relnotes/1_3_13.rst b/doc/relnotes/1_3_13.rst
deleted file mode 100644
index 6b6726aea..000000000
--- a/doc/relnotes/1_3_13.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.3.13, 2004-05-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major fixes for Cygwin builds
-* Minor MacOS X install fixes
-* The configure script is a little better at picking the right modules
-* Removed ml_unix from the 'unix' module set for Cygwin compatibility
-* Fixed a stupid compile problem in pkcs10.h
-
diff --git a/doc/relnotes/1_3_14.rst b/doc/relnotes/1_3_14.rst
deleted file mode 100644
index 330a4690b..000000000
--- a/doc/relnotes/1_3_14.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-Version 1.3.14, 2004-06-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added support for AEP's AEP1000/AEP2000 crypto cards
-* Added a Mutex module using Qt, from Justin Karneges
-* Added support for engine loading in LibraryInitializer
-* Tweaked SecureAllocator, giving 20% better performance under heavy load
-* Added timer and memory locking modules for Win32 (tm_win32, ml_win32)
-* Renamed PK_Engine to Engine_Core
-* Improved the Karatsuba cutoff points
-* Fixes for compiling with GCC 3.4 and Sun C++ 5.5
-* Fixes for Linux/s390, OpenBSD, and Solaris
-* Added support for Linux/s390x
-* The configure script was totally broken for 'generic' OS
-* Removed Montgomery reduction due to bugs
-* Removed an unused header, pkcs8alg.h
-* check --validate returns an error code if any tests failed
-* Removed duplicate entry in Unix command list for es_unix
-* Moved the Cert_Usage enumeration into X509_Store
-* Added new timing methods for PK benchmarks, clock_gettime and RDTSC
-* Fixed a few minor bugs in the configure script
-* Removed some deprecated functions from x509cert.h and pkcs10.h
-* Removed the 'minimal' module, has to be updated for Engine support
-* Changed MP_WORD_BITS macro to BOTAN_MP_WORD_BITS to clean up namespace
-* Documentation updates
-
diff --git a/doc/relnotes/1_3_2.rst b/doc/relnotes/1_3_2.rst
deleted file mode 100644
index c4a99be88..000000000
--- a/doc/relnotes/1_3_2.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-Version 1.3.2, 2003-11-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a bug preventing DSA signatures from verifying on X.509 objects
-* Made the X509_Store search routines more efficient and flexible
-* Added a function to X509_PublicKey to do easy public/private key matching
-* Added support for decoding indefinite length BER data
-* Changed Pipe's peek() to take an offset
-* Removed Filter::set_owns in favor of the new incr_owns function
-* Removed BigInt::zero() and BigInt::one()
-* Renamed the PEM related options from base/pem_* to pem/*
-* Added an option to specify the line width when encoding PEM
-* Removed the "rng/safe_longterm" option; it's always on now
-* Changed the cipher used for RNG super-encryption from ARC4 to WiderWake4+1
-* Cleaned up the base64/hex encoders and decoders
-* Added an ASN.1/BER decoder as an example
-* AES had its internals marked 'public' in previous versions
-* Changed the value of the ASN.1 NO_OBJECT enum
-* Various new hacks in the configure script
-* Removed the already nominal support for SunOS
-
diff --git a/doc/relnotes/1_3_3.rst b/doc/relnotes/1_3_3.rst
deleted file mode 100644
index 236fbec85..000000000
--- a/doc/relnotes/1_3_3.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-Version 1.3.3, 2003-11-17
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The library can now be repeatedly initialized and shutdown without crashing
-* Fixed an off-by-one error in the CTS code
-* Fixed an error in the EMSA4 verification code
-* Fixed a memory leak in mutex.cpp (pointed out by James Widener)
-* Fixed a memory leak in Pthread_Mutex
-* Fixed several memory leaks in the testing code
-* Bulletproofed the EMSA/EME/KDF/MGF retrieval functions
-* Minor cleanups in SecureAllocator
-* Removed a needless mutex guarding the (stateless) global timer
-* Fixed a piece of bash-specific code in botan-config
-* X.509 objects report more information about decoding errors
-* Cleaned up some of the exception handling
-* Updated the example config file with new OIDSs
-* Moved the build instructions into a separate document, building.tex
-
diff --git a/doc/relnotes/1_3_4.rst b/doc/relnotes/1_3_4.rst
deleted file mode 100644
index 54a12d818..000000000
--- a/doc/relnotes/1_3_4.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.3.4, 2003-11-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added a module that does certain MPI operations using GNU MP
-* Added the X9.42 Diffie-Hellman PRF
-* The Zlib and Bzip2 objects now use custom allocators
-* Added member functions for directly hashing/MACing SecureVectors
-* Minor optimizations to the MPI addition and subtraction algorithms
-* Some cleanups in the low-level MPI code
-* Created separate AES-{128,192,256} objects
-
diff --git a/doc/relnotes/1_3_5.rst b/doc/relnotes/1_3_5.rst
deleted file mode 100644
index f94df7bd9..000000000
--- a/doc/relnotes/1_3_5.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-Version 1.3.5, 2003-11-30
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Major improvements in ASN.1 string handling
-* Added partial support for ASN.1 UTF8 STRINGs and BMP STRINGs
-* Added partial support for the X.509v3 certificate policies extension
-* Centralized the handling of character set information
-* Added FIPS 140-2 startup self tests
-* Added a module (fips140) for doing extra FIPS 140-2 tests
-* Added FIPS 186-2 RNG
-* Improved ASN.1 BIT STRING handling
-* Removed a memory leak in PKCS10_Request
-* The encoding of DirectoryString now follows PKIX guidelines
-* Fixed some of the character set dependencies
-* Fixed a DER encoding error for tags greater than 30
-* The BER decoder can now handle tags larger than 30
-* Fixed tm_hard.cpp to recognize SPARC on more systems
-* Workarounds for a GCC 2.95.x bug in x509find.cpp
-* RPM changed to install into /usr instead of /usr/local
-* Added support for QNX
-
diff --git a/doc/relnotes/1_3_6.rst b/doc/relnotes/1_3_6.rst
deleted file mode 100644
index f8310d315..000000000
--- a/doc/relnotes/1_3_6.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.3.6, 2003-12-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added a new module 'minimal', which disables most algorithms
-* SecureAllocator allocates a few blocks at startup
-* A few minor MPI cleanups
-* RPM spec file cleanups and fixes
-
diff --git a/doc/relnotes/1_3_7.rst b/doc/relnotes/1_3_7.rst
deleted file mode 100644
index 8cbb431f5..000000000
--- a/doc/relnotes/1_3_7.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.3.7, 2003-12-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a big security problem in es_unix
-* Fixed several stability problems in es_unix
-* Expanded the list of programs es_unix will try to use
-* SecureAllocator now only preallocates blocks in special cases
-* Added a special case in Global_RNG::seed for forcing a full poll
-* Removed the FIPS 186 RNG added in 1.3.5 pending further testing
-* Configure updates for PowerPC CPUs
-* Removed the (never tested) VAX support
-* Added support for S/390 Linux
-
diff --git a/doc/relnotes/1_3_8.rst b/doc/relnotes/1_3_8.rst
deleted file mode 100644
index 7fac2566a..000000000
--- a/doc/relnotes/1_3_8.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-Version 1.3.8, 2003-12-30
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Initial introduction of engine support, which separates PK keys from
- the underlying operations. An engine using GNU MP was added.
-
-* DSA, DH, NR, and ElGamal constructors accept taking just the private
- key again since the public key is easily derived from it.
-
-* Montgomery reduction support was added.
-* ElGamal keys now support being imported/exported as ASN.1 objects
-* Added Montgomery reductions
-* Added an engine that uses GNU MP (requires 4.1 or later)
-* Removed the obsolete mp_gmp module
-* Moved several initialization/shutdown functions to init.h
-* Major refactoring of the memory containers
-* New non-locking container, MemoryVector
-* Fixed 64-bit problems in BigInt::set_bit/clear_bit
-* Renamed PK_Key::check_params() to check_key()
-* Some incompatible changes to OctetString
-* Added version checking macros in version.h
-* Removed the fips140 module pending rewrite
-* Added some functions and hooks to help GUIs
-* Moved more shared code into MDx_HashFunction
-* Added a policy hook for specifying the encoding of X.509 strings
-
diff --git a/doc/relnotes/1_3_9.rst b/doc/relnotes/1_3_9.rst
deleted file mode 100644
index 1867b8231..000000000
--- a/doc/relnotes/1_3_9.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.3.9, 2004-03-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added an engine using OpenSSL (requires 0.9.7 or later)
-* X509_Certificate would lose email addresses stored in the DN
-* Fixed a missing initialization in a BigInt constructor
-* Fixed several Visual C++ compile problems
-* Fixed some BeOS build problems
-* Fixed the WiderWake benchmark
-
diff --git a/doc/relnotes/1_4_0.rst b/doc/relnotes/1_4_0.rst
deleted file mode 100644
index c1cc5ea88..000000000
--- a/doc/relnotes/1_4_0.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.4.0, 2004-06-26
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the FIPS 186 RNG back
-* Added copy_key functions for X.509 public keys and PKCS #8 private keys
-* Fixed PKCS #1 signatures with RIPEMD-128
-* Moved some code around to avoid warnings with Sun ONE compiler
-* Fixed a bug in botan-config affecting OpenBSD
-* Fixed some build problems on Tru64, HP-UX
-* Fixed compile problems with Intel C++, Compaq C++
-
-
diff --git a/doc/relnotes/1_4_1.rst b/doc/relnotes/1_4_1.rst
deleted file mode 100644
index 10f45b8b1..000000000
--- a/doc/relnotes/1_4_1.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.4.1, 2004-10-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed major errors in the X.509 and PKCS #8 copy_key functions
-* Added a LAST_MESSAGE meta-message number for Pipe
-* Added new aliases (3DES and DES-EDE) for Triple-DES
-* Added some new functions to PK_Verifier
-* Cleaned up the KDF interface
-* Disabled tm_posix on BSD due to header issues
-* Fixed a build problem on PowerPC with GNU C++ pre-3.4
-
diff --git a/doc/relnotes/1_4_10.rst b/doc/relnotes/1_4_10.rst
deleted file mode 100644
index 277245284..000000000
--- a/doc/relnotes/1_4_10.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-Version 1.4.10, 2005-12-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added an implementation of KASUMI, the block cipher used in 3G phones
-* Refactored Pipe; output queues are now managed by a distinct class
-* Made certain Filter facilities only available to subclasses of Fanout_Filter
-* There is no longer any overhead in Pipe for a message that has been read out
-* It is now possible to generate RSA keys as small as 128 bits
-* Changed some of the core classes to derive from Algorithm as a virtual base
-* Changed Randpool to use HMAC instead of a plain hash as the mixing function
-* Fixed a bug in the allocators; found and fixed by Matthew Gregan
-* Enabled the use of binary file I/O, when requested by the application
-* The OpenSSL engine's block cipher code was missing some deallocation calls
-* Disabled the es_ftw module on NetBSD, due to header problems there
-* Fixed a problem preventing tm_hard from building on MacOS X on PowerPC
-* Some cleanups for the modules that use inline assembler
-* config.h is now stored in build/ instead of build/include/botan/
-* The header util.h was split into bit_ops.h, parsing.h, and util.h
-* Cleaned up some redundant include directives
-
diff --git a/doc/relnotes/1_4_11.rst b/doc/relnotes/1_4_11.rst
deleted file mode 100644
index 1bfb5d059..000000000
--- a/doc/relnotes/1_4_11.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.4.11, 2005-12-31
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Changed Whirlpool diffusion matrix to match updated algorithm spec
-* Fixed several engine module build errors introduced in 1.4.10
-* Fixed two build problems in es_capi; reported by Matthew Gregan
-* Added a constructor to DataSource_Memory taking a std::string
-* Placing the same Filter in multiple Pipes triggers an exception
-* The configure script accepts --docdir and --libdir
-* Merged doc/rngs.txt into the main API document
-* Thanks to Joel Low for several bug reports on early tarballs of 1.4.11
-
diff --git a/doc/relnotes/1_4_12.rst b/doc/relnotes/1_4_12.rst
deleted file mode 100644
index d2c134884..000000000
--- a/doc/relnotes/1_4_12.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.4.12, 2006-01-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed an off-by-one memory read in MISTY1::key()
-* Fixed a nasty memory leak in Output_Buffers::retire()
-* Changed maximum HMAC keylength to 1024 bits
-* Fixed a build problem in the hardware timer module on 64-bit PowerPC
-
diff --git a/doc/relnotes/1_4_2.rst b/doc/relnotes/1_4_2.rst
deleted file mode 100644
index 43cc25a42..000000000
--- a/doc/relnotes/1_4_2.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.4.2, 2004-10-31
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a major CRL handling bug
-* Cipher and hash operations can be offloaded to engines
-* Added support for cipher and hash offload in OpenSSL engine
-* Improvements for 64-bit CPUs without a widening multiply instruction
-* Support for SHA2-* and Whirlpool with EMSA2
-* Fixed a long-standing build problem with conflicting include files
-* Fixed some examples that hadn't been updated for 1.4.x
-* Portability fixes for Solaris, BSD, HP-UX, and others
-* Lots of fixes and cleanups in the configure script
-* Updated the Gentoo ebuild file
-
diff --git a/doc/relnotes/1_4_3.rst b/doc/relnotes/1_4_3.rst
deleted file mode 100644
index 016221c6c..000000000
--- a/doc/relnotes/1_4_3.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.4.3, 2004-11-06
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Split up SecureAllocator into Allocator and Pooling_Allocator
-* Memory locking allocators are more likely to be used
-* Fixed the placement of includes in some modules
-* Fixed broken installation procedure
-* Fixes in configure script to support alternate install programs
-* Modules can specify the minimum version they support
-
diff --git a/doc/relnotes/1_4_4.rst b/doc/relnotes/1_4_4.rst
deleted file mode 100644
index f633751f5..000000000
--- a/doc/relnotes/1_4_4.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.4.4, 2004-12-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Further tweaks to the pooling allocator
-* Modified EMSA3 to support SSL/TLS signatures
-* Changes to support Qt/QCA, from Justin Karneges
-* Moved mux_qt module code into mod_qt
-* Fixes for HP-UX from Mike Desjardins
-
diff --git a/doc/relnotes/1_4_5.rst b/doc/relnotes/1_4_5.rst
deleted file mode 100644
index cfc8b3455..000000000
--- a/doc/relnotes/1_4_5.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.4.5, 2005-02-26
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add support for AES encryption of private keys
-* Minor fixes for PBES2 parameter decoding
-* Internal cleanups for global state variables
-* GCC 3.x version detection was broken in non-English locales
-* Work around a Sun Forte bug affecting mem_pool.h
-* Several fixes for Borland C++ 5.5, from Friedemann Kleint
-* Removed inclusion of init.h into base.h
-* Fixed a major bug in reading from certificate stores
-* Cleaned up a couple of mutex leaks
-* Removed some left-over debugging code
-* Removed SSL3_MAC, SSL3_PRF, and TLS_PRF
-
diff --git a/doc/relnotes/1_4_6.rst b/doc/relnotes/1_4_6.rst
deleted file mode 100644
index a4450928d..000000000
--- a/doc/relnotes/1_4_6.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.4.6, 2005-03-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix an error in the shutdown code introduced in 1.4.5
-* Setting base/pkcs8_tries to 0 disables the builtin fail-out
-* Support for XMPP identifiers in X.509 certificates
-* Duplicate entries in X.509 DNs are removed
-* More fixes for Borland C++, from Friedemann Kleint
-* Add a workaround for buggy iostreams
-
diff --git a/doc/relnotes/1_4_7.rst b/doc/relnotes/1_4_7.rst
deleted file mode 100644
index 1531b1cfe..000000000
--- a/doc/relnotes/1_4_7.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 1.4.7, 2005-09-25
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed major performance problems with recent versions of GNU C++
-* Added an implementation of the X9.31 PRNG
-* Removed the X9.17 and FIPS 186-2 PRNG algorithms
-* Changed defaults to use X9.31 PRNGs as global PRNG objects
-* Documentation updates to reflect the PRNG changes
-* Some cleanups related to the engine code
-* Removed two useless headers, base_eng.h and secalloc.h
-* Removed PK_Verifier::valid_signature
-* Fixed configure/build system bugs affecting MacOS X builds
-* Added support for the EKOPath x86-64 compiler
-* Added missing destructor for BlockCipherModePaddingMethod
-* Fix some build problems with Visual C++ 2005 beta
-* Fix some build problems with Visual C++ 2003 Workshop
-
diff --git a/doc/relnotes/1_4_8.rst b/doc/relnotes/1_4_8.rst
deleted file mode 100644
index 694138ecc..000000000
--- a/doc/relnotes/1_4_8.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.4.8, 2005-10-16
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Resolved a bad performance problem in the allocators; fix by Matt Johnston
-* Worked around a Visual Studio 2003 compilation problem introduced in 1.4.7
-* Renamed OMAC to CMAC to match the official NIST naming
-* Added single byte versions of update() to PK_Signer and PK_Verifier
-* Removed the unused reverse_bits and reverse_bytes functions
-
diff --git a/doc/relnotes/1_4_9.rst b/doc/relnotes/1_4_9.rst
deleted file mode 100644
index ff663a0a5..000000000
--- a/doc/relnotes/1_4_9.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 1.4.9, 2005-11-06
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the IBM-created AES candidate algorithm MARS
-* Added the South Korean block cipher SEED
-* Added the stream cipher Turing
-* Added the new hash function FORK-256
-* Deprecated the ISAAC stream cipher
-* Twofish and RC6 are significantly faster with GCC
-* Much better support for 64-bit PowerPC
-* Added support for high-resolution PowerPC timers
-* Fixed a bug in the configure script causing problems on FreeBSD
-* Changed ANSI X9.31 to support arbitrary block ciphers
-* Make the configure script a bit less noisy
-* Added more test vectors for some algorithms, including all the AES finalists
-* Various cosmetic source code cleanups
-
diff --git a/doc/relnotes/1_5_0.rst b/doc/relnotes/1_5_0.rst
deleted file mode 100644
index 6b2926510..000000000
--- a/doc/relnotes/1_5_0.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.5.0, 2006-01-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Moved all global/shared library state into a single object
-* Mutex objects are created through mutex factories instead of a global
-* Removed ::get_mutex(), ::initialize_mutex(), and Mutex::clone()
-* Removed the RNG_Quality enum entirely
-* There is now only a single global-use PRNG
-* Removed the no_aliases and no_oids options for LibraryInitializer
-* Removed the deprecated algorithms SEAL, ISAAC, and HAVAL
-* Change es_ftw to use unbuffered I/O
-
-
diff --git a/doc/relnotes/1_5_1.rst b/doc/relnotes/1_5_1.rst
deleted file mode 100644
index 69ba5c6fa..000000000
--- a/doc/relnotes/1_5_1.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.5.1, 2006-01-08
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Implemented Montgomery exponentiation
-* Implemented generalized Karatsuba multiplication and squaring
-* Implemented Comba squaring for 4, 6, and 8 word inputs
-* Added new Modular_Exponentiator and Power_Mod classes
-* Removed FixedBase_Exp and FixedExponent_Exp
-* Fixed a performance regression in get_allocator introduced in 1.5.0
-* Engines can now offer S2K algorithms and block cipher padding methods
-* Merged the remaining global 'algolist' code into Default_Engine
-* The low-level MPI code is linked as C again
-* Replaced BigInt's get_nibble with the more general get_substring
-* Some documentation updates
-
diff --git a/doc/relnotes/1_5_10.rst b/doc/relnotes/1_5_10.rst
deleted file mode 100644
index e4af64bb8..000000000
--- a/doc/relnotes/1_5_10.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.5.10, 2006-08-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add x86 assembler versions of MD4, MD5, and SHA-1
-* Expand InitializerOptions' language to support on/off switches
-* Fix definition of OID 2.5.4.8; was accidentally changed in 1.5.9
-* Fix possible resource leaks in the mmap allocator
-* Slightly optimized buffering in MDx_HashFunction
-* Initialization failures are dealt with somewhat better
-* Add an example implementing Pollard's Rho algorithm
-* Better option handling in the test/benchmark tool
-* Expand the xor_ciph example to support longer keys
-* Some updates to the documentation
-
diff --git a/doc/relnotes/1_5_11.rst b/doc/relnotes/1_5_11.rst
deleted file mode 100644
index 144d8be66..000000000
--- a/doc/relnotes/1_5_11.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.5.11, 2006-09-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Removed the Algorithm base class
-* Various cleanups in the public key inheritance hierarchy
-* Major overhaul of the configure/build setup
-* Added x86 assembler implementations of Serpent and low-level MPI code
-* Optimizations for the SHA-1 x86 assembler
-* Various improvements to the Python wrappers
-* Work around a Visual Studio compiler bug
-
diff --git a/doc/relnotes/1_5_12.rst b/doc/relnotes/1_5_12.rst
deleted file mode 100644
index 4e57fd99a..000000000
--- a/doc/relnotes/1_5_12.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.5.12, 2006-10-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Cleanups in the initialization routines
-* Add some x86-64 assembly for multiply-add
-* Fix problems generating very small (below 384 bit) RSA keys
-* Support out of tree builds
-* Bring some of the documentation up to date
-* More improvements to the Python bindings
-
diff --git a/doc/relnotes/1_5_13.rst b/doc/relnotes/1_5_13.rst
deleted file mode 100644
index b8bcf7684..000000000
--- a/doc/relnotes/1_5_13.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.5.13, 2006-12-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Compilation fixes for the bzip2, zlib, and GNU MP modules
-* Better support for Intel C++ and EKOpath C++ on x86-64
-
diff --git a/doc/relnotes/1_5_2.rst b/doc/relnotes/1_5_2.rst
deleted file mode 100644
index 5e5a68d44..000000000
--- a/doc/relnotes/1_5_2.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-Version 1.5.2, 2006-01-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed an off-by-one memory read in MISTY1::key()
-* Fixed a nasty memory leak in Output_Buffers::retire()
-* Reimplemented the memory allocator from scratch
-* Improved memory caching in Montgomery exponentiation
-* Optimizations for multiple precision addition and subtraction
-* Fixed a build problem in the hardware timer module on 64-bit PowerPC
-* Changed default Karatsuba cutoff to 12 words (was 14)
-* Removed MemoryRegion::bits(), which was unused and incorrect
-* Changed maximum HMAC keylength to 1024 bits
-* Various minor Makefile and build system changes
-* Avoid using std::min in <secmem.h> to bypass Windows libc macro pollution
-* Switched checks/clock.cpp back to using clock() by default
-* Enabled the symmetric algorithm tests, which were accidentally off in 1.5.1
-* Removed the Default_Mutex's unused clone() member function
-
diff --git a/doc/relnotes/1_5_3.rst b/doc/relnotes/1_5_3.rst
deleted file mode 100644
index 60f5f9009..000000000
--- a/doc/relnotes/1_5_3.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.5.3, 2006-01-24
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Many optimizations in the low-level multiple precision integer code
-* Added hooks for assembly implementations of the MPI code
-* Support for the X.509 issuer alternative name extension in new certs
-* Fixed a bug in the decompression modules; found and patched by Matt Johnston
-* New Windows mutex module (mux_win32), by Luca Piccarreta
-* Changed the Windows timer module to use QueryPerformanceCounter
-* mem_pool.cpp was using std::set iterators instead of std::multiset ones
-* Fixed a bug in X509_CA preventing users from disabling particular extensions
-* Fixed the mp_asm64 module, which was entirely broken in 1.5.2
-* Fixed some module build problems on FreeBSD and Tru64
-
diff --git a/doc/relnotes/1_5_4.rst b/doc/relnotes/1_5_4.rst
deleted file mode 100644
index 44eae0598..000000000
--- a/doc/relnotes/1_5_4.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 1.5.4, 2006-01-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Integrated x86 and amd64 assembly code, contributed by Luca Piccarreta
-* Fixed a memory access off-by-one in the Karatsuba code
-* Changed Pooling_Allocator's free list search to a log(N) algorithm
-* Merged ModularReducer with its only subclass, Barrett_Reducer
-* Fixed sign-handling bugs in some of the division and modulo code
-* Renamed the module description files to modinfo.txt
-* Further cleanups in the initialization code
-* Removed BigInt::add and BigInt::sub
-* Merged all the division-related functions into just divide()
-* Modified the <mp_asmi.h> functions to allow for better optimizations
-* Made the number of bits polled from an EntropySource user configurable
-* Avoid including <algorithm> in <botan/secmem.h>
-* Fixed some build problems with Sun Forte
-* Removed some dead code from bigint_modop
-* Fix the definition of same_mem
-
diff --git a/doc/relnotes/1_5_5.rst b/doc/relnotes/1_5_5.rst
deleted file mode 100644
index e4ab22fb5..000000000
--- a/doc/relnotes/1_5_5.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.5.5, 2006-02-04
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed a potential infinite loop in the memory pool code (Matt Johnston)
-* Made Pooling_Allocator::Memory_Block an actual class of sorts
-* Some small optimizations to the division and modulo computations
-* Cleaned up the implementation of some of the BigInt operators
-* Reduced use of dynamic memory allocation in low-level BigInt functions
-* A few simplifications in the Randpool mixing function
-* Removed power(), as it was not particularly useful (or fast)
-* Fixed some annoying bugs in the benchmark code
-* Added a real credits file
-
diff --git a/doc/relnotes/1_5_6.rst b/doc/relnotes/1_5_6.rst
deleted file mode 100644
index 8925a8003..000000000
--- a/doc/relnotes/1_5_6.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.5.6, 2006-03-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The low-level DER/BER coding system was redesigned and rewritten
-* Portions of the certificate code were cleaned up internally
-* Use macros to substantially clean up the GCC assembly code
-* Added 32-bit x86 assembly for Visual C++ (by Luca Piccarreta)
-* Avoid a couple of spurious warnings under Visual C++
-* Some slight cleanups in X509_PublicKey::key_id
-
diff --git a/doc/relnotes/1_5_7.rst b/doc/relnotes/1_5_7.rst
deleted file mode 100644
index 45ded103f..000000000
--- a/doc/relnotes/1_5_7.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.5.7, 2006-05-28
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Further, major changes to the BER/DER coding system
-* Updated the Qt mutex module to use Mutex_Factory
-* Moved the library global state object into an anonymous namespace
-* Drop the Visual C++ x86 assembly module due to bugs
-
diff --git a/doc/relnotes/1_5_8.rst b/doc/relnotes/1_5_8.rst
deleted file mode 100644
index c7a2c549d..000000000
--- a/doc/relnotes/1_5_8.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.5.8, 2006-06-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Many internal cleanups to the X.509 cert/CRL code
-* Allow for application code to support new X.509 extensions
-* Change the return type of X509_Certificate::{subject,issuer}_info
-* Allow for alternate character set handling mechanisms
-* Fix a bug that was slowing squaring performance somewhat
-* Fix a very hard to hit overflow bug in the C version of word3_muladd
-* Minor cleanups to the assembler modules
-* Disable es_unix module on FreeBSD due to build problem on FreeBSD 6.1
-* Support for GCC 2.95.x has been dropped in this release
-
diff --git a/doc/relnotes/1_5_9.rst b/doc/relnotes/1_5_9.rst
deleted file mode 100644
index fa7c130fa..000000000
--- a/doc/relnotes/1_5_9.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.5.9, 2006-07-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fixed bitrot in the AEP engine
-* Fix support for marking certificate/CRL extensions as critical
-* Significant cleanups in the library state / initialization code
-* LibraryInitializer takes an explicit InitializerOptions object
-* Make Mutex_Factory an abstract class, add Default_Mutex_Factory
-* Change configuration access to using global_state()
-* Add support for global named mutexes throughout the library
-* Add some STL wrappers for the delete operator
-* Change how certificates are created to be more flexible and general
-
diff --git a/doc/relnotes/1_6_0.rst b/doc/relnotes/1_6_0.rst
deleted file mode 100644
index 32b4d7ae8..000000000
--- a/doc/relnotes/1_6_0.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.6.0, 2006-12-17
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Minor cleanups versus 1.5.13
-
-
diff --git a/doc/relnotes/1_6_1.rst b/doc/relnotes/1_6_1.rst
deleted file mode 100644
index cf1de29a0..000000000
--- a/doc/relnotes/1_6_1.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.6.1, 2007-01-20
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix some base64 decoder bugs
-* Add a new option to base64 encoding, to always append a newline
-* Fix some build problems under Visual Studio with debug enabled
-* Fix a bug in BER_Decoder that was triggered under some compilers
-
diff --git a/doc/relnotes/1_6_2.rst b/doc/relnotes/1_6_2.rst
deleted file mode 100644
index 3fdea578f..000000000
--- a/doc/relnotes/1_6_2.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Version 1.6.2, 2007-03-24
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix autodection on Athlon64s running Linux
-* Fix builds on QNX and compilers using STLport
-* Remove a call to abort() that crept into production
-
diff --git a/doc/relnotes/1_6_3.rst b/doc/relnotes/1_6_3.rst
deleted file mode 100644
index c6d9f4364..000000000
--- a/doc/relnotes/1_6_3.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.6.3, 2007-07-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a race condition in the algorithm lookup cache
-* Fix problems building the memory pool on some versions of Visual C++
-
diff --git a/doc/relnotes/1_6_4.rst b/doc/relnotes/1_6_4.rst
deleted file mode 100644
index 8f5295bcc..000000000
--- a/doc/relnotes/1_6_4.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Version 1.6.4, 2008-03-08
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a compilation problem with Visual Studio C++ 2003
-
diff --git a/doc/relnotes/1_6_5.rst b/doc/relnotes/1_6_5.rst
deleted file mode 100644
index 827adff95..000000000
--- a/doc/relnotes/1_6_5.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.6.5, 2008-08-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add noexec stack marker for GNU linker in assembly code
-* Fix autoconfiguration problem on x86 with GCC 4.2 and 4.3
-
diff --git a/doc/relnotes/1_7_0.rst b/doc/relnotes/1_7_0.rst
deleted file mode 100644
index b9ad37914..000000000
--- a/doc/relnotes/1_7_0.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.0, 2007-05-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* DSA parameter generation now follows FIPS 186-3
-* Added OIDs for Rabin-Williams and Nyberg-Rueppel
-* Somewhat better support for out of tree builds
-* Minor optimizations for RC2 and Tiger
-* Documentation updates
-* Update the todo list
-
-
diff --git a/doc/relnotes/1_7_1.rst b/doc/relnotes/1_7_1.rst
deleted file mode 100644
index e53bf66d9..000000000
--- a/doc/relnotes/1_7_1.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.7.1, 2007-07-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a race condition in the algorithm object cache
-* HMAC key schedule optimization
-* The build header sets a macro defining endianness, if known
-* New word load/store abstraction allowing further optimization
-* Modify most of the library to avoid use the C-style casts
-* Use higher resolution timers in symmetric benchmarks
-
diff --git a/doc/relnotes/1_7_10.rst b/doc/relnotes/1_7_10.rst
deleted file mode 100644
index edaec7b71..000000000
--- a/doc/relnotes/1_7_10.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.7.10, 2008-09-05
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Public key benchmarks run using a selection of random keys
-* New benchmark timer options are clock_gettime, gettimeofday, times, clock
-* Including reinterpret_cast optimization for xor_buf in default header
-* Split byte swapping and word rotation functions into distinct headers
-* Add IETF modp 6144 group and 2048 and 3072 bit DSS groups
-* Optimizes BigInt right shift
-* Add aliases in DL_Group::Format enum
-* BigInt now caches the significant word count
-
diff --git a/doc/relnotes/1_7_11.rst b/doc/relnotes/1_7_11.rst
deleted file mode 100644
index be23f0d72..000000000
--- a/doc/relnotes/1_7_11.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.7.11, 2008-09-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the Salsa20 stream cipher
-* Optimized Montgomery reduction, Karatsuba squaring
-* Added 16x16->32 word Comba multiplication and squaring
-* Use a much larger Karatsuba cutoff point
-* Remove bigint_mul_add_words
-* Inlined several BigInt functions
-* Add useful information to the generated build.h
-* Rename alg_{ia32,amd64} modules to asm_{ia32,amd64}
-* Fix the Windows build
-
diff --git a/doc/relnotes/1_7_12.rst b/doc/relnotes/1_7_12.rst
deleted file mode 100644
index 21bd3da8c..000000000
--- a/doc/relnotes/1_7_12.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Version 1.7.12, 2008-09-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add x86 assembly for Visual Studio C++, by Luca Piccarreta
-* Add a Perl XS module, by Vaclav Ovsik
-* Add SWIG-based wrapper for Botan
-* Add SSE2 implementation of SHA-1, by Dean Gaudet
-* Remove the BigInt::sig_words cache due to bugs
-* Combined the 4 Blowfish sboxes, suggested by Yves Jerschow
-* Changed BigInt::grow_by and BigInt::grow_to to be non-const
-* Add private assignment operators to classes that don't support assignment
-* Benchmark RSA encryption and signatures
-* Added test programs for random_prime and ressol
-* Add high resolution timers for IA-64, HP-PA, S390x
-* Reduce use of the RNG during benchmarks
-* Fix builds on STI Cell PPU
-* Add support for IBM's XLC compiler
-* Add IETF 8192 bit MODP group
-
diff --git a/doc/relnotes/1_7_13.rst b/doc/relnotes/1_7_13.rst
deleted file mode 100644
index 66591df88..000000000
--- a/doc/relnotes/1_7_13.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.7.13, 2008-09-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add SSLv3 MAC, SSLv3 PRF, and TLS v1.0 PRF from Ajisai
-* Allow all examples to compile even if compression not enabled
-* Make CMAC's polynomial doubling operation a public class method
-* Use the -m64 flag when compiling with Sun Forte on x86-64
-* Clean up and slightly optimize CMAC::final_result
-
diff --git a/doc/relnotes/1_7_14.rst b/doc/relnotes/1_7_14.rst
deleted file mode 100644
index 6bf5c50d2..000000000
--- a/doc/relnotes/1_7_14.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.14, 2008-09-30
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Split library into parts allowing modular builds
-* Add (very preliminary) CMS support to the main library
-* Some constructors now require object pointers instead of names
-* Support multiple implementations of the same algorithm
-* Build support for Pentium-M processors, from Derek Scherger
-* Build support for MinGW/MSYS, from Zbigniew Zagorski
-* Use inline assembly for bswap on 32-bit x86
-
diff --git a/doc/relnotes/1_7_15.rst b/doc/relnotes/1_7_15.rst
deleted file mode 100644
index 9cd34ab64..000000000
--- a/doc/relnotes/1_7_15.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.15, 2008-10-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add GF(p) arithmetic from InSiTo
-* Add ECDSA and ECKAEG implementations from InSiTo
-* Minimize internal dependencies, allowing for smaller build configurations
-* Add new User Manual and Architecture Guide from FlexSecure GmbH
-* Alter configure.pl options for better autotools compatibility
-* Update build instructions for recent changes to configure.pl
-* Fix CPU detection using /proc/cpuinfo
-
diff --git a/doc/relnotes/1_7_16.rst b/doc/relnotes/1_7_16.rst
deleted file mode 100644
index 8b964da3f..000000000
--- a/doc/relnotes/1_7_16.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.7.16, 2008-10-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add several missing pieces needed for ECDSA and ECKAEG
-* Add Card Verifiable Certificates from InSiTo
-* Add SHA-224 from InSiTo
-* Add BSI variant of EMSA1 from InSiTo
-* Add GF(p) and ECDSA tests from InSiTo
-* Split ECDSA and ECKAEG into distinct modules
-* Allow OpenSSL and GNU MP engines to be built with public key algos disabled
-* Rename sha256.h to sha2_32.h and sha_64.h to sha2_64.h
-
diff --git a/doc/relnotes/1_7_17.rst b/doc/relnotes/1_7_17.rst
deleted file mode 100644
index b364d6112..000000000
--- a/doc/relnotes/1_7_17.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.7.17, 2008-10-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add missing ECDSA object identifiers
-* Fix error in x86 and x86-64 assembler affecting GF(p) math
-* Remove Boost dependency from GF(p) math
-* Modify botan-config to not print -L/usr/lib or -L/usr/local/lib
-* Add BOTAN_DLL macro to over 30 classes missing it
-* Rename the two SHA-2 base classes for consistency
-
diff --git a/doc/relnotes/1_7_18.rst b/doc/relnotes/1_7_18.rst
deleted file mode 100644
index 2bc1bf970..000000000
--- a/doc/relnotes/1_7_18.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.18, 2008-10-22
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add Doxygen comments from InSiTo
-* Add ECDSA and ECKAEG benchmarks
-* Add configure.pl switch --with-tr1-implementation
-* Fix configure.pl's --with-endian and --with-unaligned-mem options
-* Added support for pkg-config
-* Optimize byteswap with x86 inline asm for Visual C++ by Yves Jerschow
-* Use const references to avoid copying overhead in CurveGFp, GFpModulus
-
diff --git a/doc/relnotes/1_7_19.rst b/doc/relnotes/1_7_19.rst
deleted file mode 100644
index c54ce354d..000000000
--- a/doc/relnotes/1_7_19.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.7.19, 2008-11-06
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add HMAC_RNG, based on a design by Hugo Krawczyk
-* Optimized the Turing stream cipher (about 20% faster on x86-64)
-* Modify Randpool's reseeding algorithm to poll more sources
-* Add a new AutoSeeded_RNG in auto_rng.h
-* OpenPGP_S2K changed to take hash object instead of name
-* Add automatic identification for Intel's Prescott processors
-
diff --git a/doc/relnotes/1_7_2.rst b/doc/relnotes/1_7_2.rst
deleted file mode 100644
index 3b182d246..000000000
--- a/doc/relnotes/1_7_2.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.2, 2007-10-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Initialize the global library state lazily
-* Add plain CBC-MAC for backwards compatibility with old systems
-* Clean up some of the self test code
-* Throw a sensible exception if a DL_Group is not found
-* Truncate KDF2 output rather than allowing counter overflow
-* Add newly assigned OIDs for SHA-2 and DSA with SHA-224/256
-* Fix a Visual Studio compilation problem in x509stat.cpp
-
diff --git a/doc/relnotes/1_7_20.rst b/doc/relnotes/1_7_20.rst
deleted file mode 100644
index 38a4b6b1c..000000000
--- a/doc/relnotes/1_7_20.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.7.20, 2008-11-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Namespace pkg-config file by major and minor versions
-* Cache device descriptors in Device_EntropySource
-* Split base.h into {block_cipher,stream_cipher,mac,hash}.h
-* Removed get_mgf function from lookup.h
-
diff --git a/doc/relnotes/1_7_21.rst b/doc/relnotes/1_7_21.rst
deleted file mode 100644
index d3eaf48f8..000000000
--- a/doc/relnotes/1_7_21.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.7.21, 2008-11-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Make algorithm lookup much more configuable
-* Add facilities for runtime performance testing of algorithms
-* Drop use of entropy estimation in the PRNGs
-* Increase intervals between HMAC_RNG automatic reseeding
-* Drop InitializerOptions class, all options but thread safety
-
diff --git a/doc/relnotes/1_7_22.rst b/doc/relnotes/1_7_22.rst
deleted file mode 100644
index 52a286e83..000000000
--- a/doc/relnotes/1_7_22.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.7.22, 2008-11-17
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add provider preferences to Algorithm_Factory
-* Fix memory leaks in PBE_PKCS5v20 and get_pbe introduced in 1.7.21
-* Optimize AES encryption and decryption (about 10% faster)
-* Enable SSE2 optimized SHA-1 implementation on Intel Prescott CPUs
-* Fix nanoseconds overflow in benchmark code
-* Remove Engine::add_engine
-
diff --git a/doc/relnotes/1_7_23.rst b/doc/relnotes/1_7_23.rst
deleted file mode 100644
index bd30238d2..000000000
--- a/doc/relnotes/1_7_23.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.7.23, 2008-11-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Change to use TR1 (thus enabling ECDSA) with GCC and ICC
-* Optimize almost all hash functions, especially MD4 and Tiger
-* Add configure.pl options --{with,without}-{bzip2,zlib,openssl,gnump}
-* Change Timer to be pure virtual, and add ANSI_Clock_Timer
-* Cache socket descriptors in the EGD entropy source
-* Avoid bogging down startup in /proc walking entropy source
-* Remove Buffered_EntropySource helper class
-* Add a Default_Benchmark_Timer typedef in benchmark.h
-* Add examples using benchmark.h and Algorithm_Factory
-* Add ECC tests from InSiTo
-* Minor documentation updates
-
diff --git a/doc/relnotes/1_7_24.rst b/doc/relnotes/1_7_24.rst
deleted file mode 100644
index f43c752ff..000000000
--- a/doc/relnotes/1_7_24.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Version 1.7.24, 2008-12-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a compatibility problem with SHA-512/EMSA3 signature padding
-* Fix bug preventing EGD/PRNGD entropy poller from working
-* Fix integer overflow in Pooling_Allocator::get_more_core (bug id #27)
-* Add EMSA3_Raw, a variant of EMSA3 called CKM_RSA_PKCS in PKCS #11
-* Add support for SHA-224 in EMSA2 and EMSA3 PK signature padding schemes
-* Add many more test vectors for RSA with EMSA2, EMSA3, and EMSA4
-* Wrap private structs in SSE2 SHA-1 code in anonymous namespace
-* Change configure.pl's CPU autodetection output to be more consistent
-* Disable using OpenSSL's AES due to crashes of unknown cause
-* Fix warning in /proc walking entropy poller
-* Fix compilation with IBM XLC for Cell 0.9-200709
-
diff --git a/doc/relnotes/1_7_3.rst b/doc/relnotes/1_7_3.rst
deleted file mode 100644
index 8426978cd..000000000
--- a/doc/relnotes/1_7_3.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.7.3, 2008-01-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* New invocation syntax for configure.pl with several new options
-* Support for IPv4 addresses in a subject alternative name
-* New fast poll for the generic Unix entropy source (es_unix)
-* The es_file entropy source has been replaced by the es_dev module
-* The malloc allocator does not inherit from Pooling_Allocator anymore
-* The path that es_unix will search in are now fully user-configurable
-* Truncate X9.42 PRF output rather than allow counter overflow
-* PowerPC is now assumed to be big-endian
-
diff --git a/doc/relnotes/1_7_4.rst b/doc/relnotes/1_7_4.rst
deleted file mode 100644
index 608b7ffb1..000000000
--- a/doc/relnotes/1_7_4.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.7.4, 2008-03-10
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Use unaligned memory read/writes on systems that allow it, for performance
-* Assembly for x86-64 for accessing the bswap instruction
-* Use larger buffers in ARC4 and WiderWAKE for significant throughput increase
-* Unroll loops in SHA-160 for a few percent increase in performance
-* Fix compilation with GCC 3.2 in es_ftw and es_unix
-* Build fix for NetBSD systems
-* Prevent es_dev from being built except on Unix systems
-
diff --git a/doc/relnotes/1_7_5.rst b/doc/relnotes/1_7_5.rst
deleted file mode 100644
index f5ec97e14..000000000
--- a/doc/relnotes/1_7_5.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.7.5, 2008-04-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The API of X509_CA::sign_request was altered to avoid race conditions
-* New type Pipe::message_id to represent the Pipe message number
-* Remove the Named_Mutex_Holder for a small performance gain
-* Removed several unused or rarely used functions from Config
-* Ignore spaces inside of a decimal string in BigInt::decode
-* Allow using a std::istream to initialize a DataSource_Stream object
-* Fix compilation problem in zlib compression module
-* The chunk sized used by Pooling_Allocator is now a compile time setting
-* The size of random blinding factors is now a compile time setting
-* The install target no longer tries to set a particular owner/group
-
diff --git a/doc/relnotes/1_7_6.rst b/doc/relnotes/1_7_6.rst
deleted file mode 100644
index 3fb6064fd..000000000
--- a/doc/relnotes/1_7_6.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.7.6, 2008-05-05
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Initial support for Windows DLLs, from Joel Low
-* Reset the position pointer when a new block is generated in X9.32 PRNG
-* Timer objects are now treated as entropy sources
-* Moved several ASN.1-related enums from enums.h to an appropriate header
-* Removed the AEP module, due to inability to test
-* Removed Global_RNG and rng.h
-* Removed system_clock
-* Removed Library_State::UI and the pulse callback logic
-
diff --git a/doc/relnotes/1_7_7.rst b/doc/relnotes/1_7_7.rst
deleted file mode 100644
index 9934959e0..000000000
--- a/doc/relnotes/1_7_7.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.7.7, 2008-06-28
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Remove the global PRNG object
-* The PK filter objects were removed
-* Add a test suite for the ANSI X9.31 PRNG
-* Much cleaner and (mostly) thread-safe reimplementation of es_ftw
-* Remove both default arguments to ANSI_X931_RNG's constructor
-* Remove the randomizing version of OctetString::change
-* Make the cipher and MAC to use in Randpool configurable
-* Move RandomNumberGenerator declaration to rng.h
-* RSA_PrivateKey will not generate keys smaller than 1024 bits
-* Fix an error decoding BER UNIVERSAL types with special taggings
-
diff --git a/doc/relnotes/1_7_8.rst b/doc/relnotes/1_7_8.rst
deleted file mode 100644
index b02451214..000000000
--- a/doc/relnotes/1_7_8.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.7.8, 2008-07-15
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Added the block cipher Noekeon
-* Remove global deref_alias function
-* X509_Store takes timeout options as constructor arguments
-* Add Shanks-Tonelli algorithm, contributed by FlexSecure GmbH
-* Extend random_prime() for generating primes of any bit length
-* Remove Config class
-* Allow adding new entropy via base RNG interface
-* Reseeding a X9.31 PRNG also reseeds the underlying PRNG
-
diff --git a/doc/relnotes/1_7_9.rst b/doc/relnotes/1_7_9.rst
deleted file mode 100644
index 039106d71..000000000
--- a/doc/relnotes/1_7_9.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.7.9, 2008-08-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Make clear() in most algorithm base classes a pure virtual
-* Add noexec stack marker for GNU linker in assembly code
-* Avoid string operations in ressol
-* Compilation fixes for MinGW and Visual Studio C++ 2008
-* Some autoconfiguration fixes for Windows
-
diff --git a/doc/relnotes/1_8_0.rst b/doc/relnotes/1_8_0.rst
deleted file mode 100644
index e9ebbe43f..000000000
--- a/doc/relnotes/1_8_0.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.8.0, 2008-12-08
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix compilation on Solaris with GCC
-
-
diff --git a/doc/relnotes/1_8_1.rst b/doc/relnotes/1_8_1.rst
deleted file mode 100644
index 532842fba..000000000
--- a/doc/relnotes/1_8_1.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.8.1, 2009-01-20
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Avoid a valgrind warning in es_unix.cpp on 32-bit Linux
-* Fix memory leak in PKCS8 load_key and encrypt_key
-* Relicense api.tex from CC-By-SA 2.5 to BSD
-* Fix botan-config on MacOS X, Solaris
-
diff --git a/doc/relnotes/1_8_10.rst b/doc/relnotes/1_8_10.rst
deleted file mode 100644
index 3c4f62b09..000000000
--- a/doc/relnotes/1_8_10.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.8.10, 2010-08-31
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Switch default PKCS #8 encryption algorithm from 3DES to AES-256
-* Increase default hash iterations from 2048 to 10000 in PBES1 and PBES2
-* Use small tables in the first round of AES
-* Add PBKDF typedef and get_pbkdf for better compatability with 1.9
-* Add version of S2K::derive_key taking salt and iteration count
-* Enable the /proc-walking entropy source on NetBSD
-* Fix the doxygen makefile target
-
diff --git a/doc/relnotes/1_8_11.rst b/doc/relnotes/1_8_11.rst
deleted file mode 100644
index 688023ab4..000000000
--- a/doc/relnotes/1_8_11.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.8.11, 2010-11-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a number of CRL encoding and decoding bugs
-* When building a debug library under VC++, use the debug runtime
-* Fix compilation under Sun Studio on Linux and Solaris
-* Add several functions for compatability with 1.9
-* In the examples, read most input files as binary
-* The Perl build script has been removed in this release
-
diff --git a/doc/relnotes/1_8_12.rst b/doc/relnotes/1_8_12.rst
deleted file mode 100644
index 14d29325e..000000000
--- a/doc/relnotes/1_8_12.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.8.12, 2011-06-20
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-* If EMSA3(Raw) was used for more than one signature, it would produce
- incorrect output.
-
-* Fix the --enable-debug option to configure.py
-
-* Improve OS detection on Cygwin
-
-* Fix compilation under Sun Studio 12 on Solaris
-
-* Fix a memory leak in the constructors of DataSource_Stream and
- DataSink_Stream which would occur if opening the file failed (:pr:`144`)
-
diff --git a/doc/relnotes/1_8_13.rst b/doc/relnotes/1_8_13.rst
deleted file mode 100644
index e96f6e449..000000000
--- a/doc/relnotes/1_8_13.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Version 1.8.13, 2011-07-02
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* A race condition in `Algorithm_Factory` could cause crashes in
- multithreaded code. See :botan-devel:`this thread on botan-devel
- <2011-July/001455>` for details and workarounds.
-
diff --git a/doc/relnotes/1_8_14.rst b/doc/relnotes/1_8_14.rst
deleted file mode 100644
index cf48e3cc7..000000000
--- a/doc/relnotes/1_8_14.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Version 1.8.14, 2012-07-18
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The malloc allocator would return null instead of throwing in the
- event of an allocation failure, which could cause an application
- crash due to null pointer dereference where normally an exception
- would occur.
-
-* Recent versions of OpenSSL include extra information in ECC private
- keys, the presence of which caused an exception when such a key was
- loaded by botan. The decoding of ECC private keys has been changed to
- ignore these fields if they are set.
-
-* AutoSeeded_RNG has been changed to prefer ``/dev/random`` over
- ``/dev/urandom``
-
-* Fix detection of s390x (Debian bug 638347)
diff --git a/doc/relnotes/1_8_2.rst b/doc/relnotes/1_8_2.rst
deleted file mode 100644
index 8ba19973b..000000000
--- a/doc/relnotes/1_8_2.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.8.2, 2009-04-07
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Make entropy polling more flexible and in most cases faster
-* GOST 28147 now supports multiple sbox parameters
-* Added the GOST 34.11 hash function
-* Fix botan-config problems on MacOS X
-
diff --git a/doc/relnotes/1_8_3.rst b/doc/relnotes/1_8_3.rst
deleted file mode 100644
index 3bfe7bde0..000000000
--- a/doc/relnotes/1_8_3.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.8.3, 2009-07-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add a new Python configuration script
-* Add the Skein-512 SHA-3 candidate hash function
-* Add the XTS block cipher mode from IEEE P1619
-* Fix random_prime when generating a prime of less than 7 bits
-* Improve handling of low-entropy situations during PRNG seeding
-* Change random device polling to prefer /dev/urandom over /dev/random
-* Use an input insensitive implementation of same_mem instead of memcmp
-* Correct DataSource::discard_next to return the number of discarded bytes
-* Provide a default value for AutoSeeded_RNG::reseed
-* Fix Gentoo bug 272242
-
diff --git a/doc/relnotes/1_8_4.rst b/doc/relnotes/1_8_4.rst
deleted file mode 100644
index b103db11f..000000000
--- a/doc/relnotes/1_8_4.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Version 1.8.4, 2009-07-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix a bug in nonce generation in the Miller-Rabin test
-
diff --git a/doc/relnotes/1_8_5.rst b/doc/relnotes/1_8_5.rst
deleted file mode 100644
index f2675de99..000000000
--- a/doc/relnotes/1_8_5.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.8.5, 2009-07-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Change configure.py to work on stock Python 2.4
-* Avoid a crash in Skein_512::add_data processing a zero-length input
-* Small build fixes for SPARC, ARM, and HP-PA processors
-* The test suite now returns an error code from main() if any tests failed
-
diff --git a/doc/relnotes/1_8_6.rst b/doc/relnotes/1_8_6.rst
deleted file mode 100644
index 6e4fa8c56..000000000
--- a/doc/relnotes/1_8_6.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.8.6, 2009-08-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add Cryptobox, a set of simple password-based encryption routines
-* Only read world-readable files when walking /proc for entropy
-* Fix building with TR1 disabled
-* Fix x86 bswap support for Visual C++
-* Fixes for compilation under Sun C++
-* Add support for Dragonfly BSD (contributed by Patrick Georgi)
-* Add support for the Open64 C++ compiler
-* Build fixes for MIPS systems running Linux
-* Minor changes to license, now equivalent to the FreeBSD/NetBSD license
-
diff --git a/doc/relnotes/1_8_7.rst b/doc/relnotes/1_8_7.rst
deleted file mode 100644
index e5bf54649..000000000
--- a/doc/relnotes/1_8_7.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Version 1.8.7, 2009-09-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fix processing multiple messages in XTS mode
-* Add --no-autoload option to configure.py, for minimized builds
-
diff --git a/doc/relnotes/1_8_8.rst b/doc/relnotes/1_8_8.rst
deleted file mode 100644
index a46032c20..000000000
--- a/doc/relnotes/1_8_8.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Version 1.8.8, 2009-11-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Alter Skein-512 to match the tweaked 1.2 specification
-* Fix use of inline asm for access to x86 bswap function
-* Allow building the library without AES enabled
-* Add 'powerpc64' alias to ppc64 arch for Gentoo ebuild
-
diff --git a/doc/relnotes/1_8_9.rst b/doc/relnotes/1_8_9.rst
deleted file mode 100644
index c66198364..000000000
--- a/doc/relnotes/1_8_9.rst
+++ /dev/null
@@ -1,27 +0,0 @@
-Version 1.8.9, 2010-06-16
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Use constant time multiplication in IDEA
-
-* Avoid possible timing attack against OAEP decoding
-
-* Add new X509::BER_encode and PKCS8::BER_encode
-
-* Enable DLL builds under Windows
-
-* Add Win32 installer support
-
-* Add support for the Clang compiler
-
-* Fix problem in semcem.h preventing build under Clang or GCC 3.4
-
-* Fix bug that prevented creation of DSA groups under 1024 bits
-
-* Fix crash in GMP_Engine if library is shutdown and reinitialized and
- a PK algorithm was used after the second init
-
-* Work around problem with recent binutils in x86-64 SHA-1
-
-* The Perl build script is no longer supported and refuses to run by
- default. If you really want to use it, pass
- ``--i-know-this-is-broken`` to the script.
diff --git a/doc/relnotes/1_9_0.rst b/doc/relnotes/1_9_0.rst
deleted file mode 100644
index 3e0407887..000000000
--- a/doc/relnotes/1_9_0.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-Version 1.9.0, 2009-09-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add support for parallel invocation of block ciphers where possible
-* Add SSE2 implementation of Serpent
-* Add Rivest's package transform (an all or nothing transform)
-* Minor speedups to the Turing key schedule
-* Fix processing multiple messages in XTS mode
-* Add --no-autoload option to configure.py, for minimized builds
-* The previously used configure.pl script is no longer supported
-
-
diff --git a/doc/relnotes/1_9_1.rst b/doc/relnotes/1_9_1.rst
deleted file mode 100644
index e044f1d3c..000000000
--- a/doc/relnotes/1_9_1.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-Version 1.9.1, 2009-10-23
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Better support for Python and Perl wrappers
-* Add an implementation of Blue Midnight Wish (Round 2 tweak version)
-* Modify Skein-512 to match the tweaked 1.2 specification
-* Add threshold secret sharing (draft-mcgrew-tss-02)
-* Add runtime cpu feature detection for x86/x86-64
-* Add code for general runtime self testing for hashes, MACs, and ciphers
-* Optimize XTEA; twice as fast as before on Core2 and Opteron
-* Convert CTR_BE and OFB from filters to stream ciphers
-* New parsing code for SCAN algorithm names
-* Enable SSE2 optimizations under Visual C++
-* Remove all use of C++ exception specifications
-* Add support for GNU/Hurd and Clang/LLVM
-
diff --git a/doc/relnotes/1_9_10.rst b/doc/relnotes/1_9_10.rst
deleted file mode 100644
index 296c34ca3..000000000
--- a/doc/relnotes/1_9_10.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-Version 1.9.10, 2010-08-12
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add a constant-time AES implementation using SSSE3. This code is
- based on public domain assembly written by `Mike Hamburg
- <http://crypto.stanford.edu/vpaes/>`_, and described in his CHES
- 2009 paper "Accelerating AES with Vector Permute Instructions". In
- addition to being constant time, it is also significantly faster
- than the table-based implementation on some processors. The current
- code has been tested with GCC 4.5, Visual C++ 2008, and Clang 2.8.
-
-
-* Support for dynamically loading Engine objects at runtime was also
- added. Currently only system that use ``dlopen``-style dynamic
- linking are supported.
-
-* On GCC 4.3 and later, use the byteswap intrinsic functions.
-
-* Drop support for building with Python 2.4
-
-* Fix benchmarking of block ciphers in ECB mode
-
-* Consolidate the two x86 assembly engines
-
-* Rename S2K to PBKDF
-
diff --git a/doc/relnotes/1_9_11.rst b/doc/relnotes/1_9_11.rst
deleted file mode 100644
index ea48fb9e5..000000000
--- a/doc/relnotes/1_9_11.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-Version 1.9.11, 2010-11-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* The TLS API has changed substantially and now relies heavily on
- TR1's ``std::function`` is now required. Additionally, it is
- required that all callers derive a subclass of TLS_Policy and pass
- it to a client or server object. Please remember that the TLS
- interface/API is currently unstable and will very likely change
- further before TLS is included in a stable release. A handshake
- failure that occured when RC4 was negotiated has also been fixed.
-
-* Some possible timing channels in the implementations of Montgomery
- reduction and the IDEA key schedule were removed. The table-based
- AES implementation uses smaller tables in the first round to help
- make some timing/cache attacks harder.
-
-* The library now uses size_t instead of u32bit to represent
- lengths. Also the interfaces for the memory containers have changed
- substantially to better match STL container interfaces;
- MemoryRegion::append, MemoryRegion::destroy, and MemoryRegion::set
- were all removed, and several other functions, like clear and
- resize, have changed meaning.
-
-* Update Skein-512 to match the v1.3 specification
-* Fix a number of CRL encoding and decoding bugs
-* Counter mode now always encrypts 256 blocks in parallel
-* Use small tables in the first round of AES
-* Removed AES class: app must choose AES-128, AES-192, or AES-256
-* Add hex encoding/decoding functions that can be used without a Pipe
-* Add base64 encoding functions that can be used without a Pipe
-* Add to_string function to X509_Certificate
-* Add support for dynamic engine loading on Windows
-* Replace BlockCipher::BLOCK_SIZE attribute with function block_size()
-* Replace HashFunction::HASH_BLOCK_SIZE attribute with hash_block_size()
-* Move PBKDF lookup to engine system
-* The IDEA key schedule has been changed to run in constant time
-* Add Algorithm and Key_Length_Specification classes
-* Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
-* Allow using PBKDF2 with empty passphrases
-* Add compile-time deprecation warnings for GCC, Clang, and MSVC
-* Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
-* Improve support for Intel Atom processors
-* Fix compilation problems under Sun Studio and Clang
-
diff --git a/doc/relnotes/1_9_12.rst b/doc/relnotes/1_9_12.rst
deleted file mode 100644
index 21ad561d5..000000000
--- a/doc/relnotes/1_9_12.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-Version 1.9.12, 2010-12-13
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add the Keccak hash function
-* Fix compilation problems in Python wrappers
-* Fix compilation problem in OpenSSL engine
-* Update SQLite3 database encryption codec
diff --git a/doc/relnotes/1_9_13.rst b/doc/relnotes/1_9_13.rst
deleted file mode 100644
index 701b6e5f0..000000000
--- a/doc/relnotes/1_9_13.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-Version 1.9.13, 2011-02-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-GOST 34.10 signatures were being formatted in a way that was not
-compatible with other implemenations, and specifically how GOST is
-used in DNSSEC.
-
-The Keccak hash function was updated to the tweaked variant proposed
-for round 3 of the NIST hash competition. This version is not
-compatible with the previous algorithm.
-
-A new option ``--distribution-info`` was added to the configure
-script. It allows the user building the library to set any
-distribution-specific notes on the build, which are available as a
-macro ``BOTAN_DISTRIBUTION_INFO``. The default value is
-'unspecified'. If you are building an unmodified version of botan
-(especially for distribution), and want to indicate to applications
-that this is the case, consider using
-``--distribution-info=pristine``. If you are making any patches or
-modifications, it is recommended to use
-``--distribution-info=[Distribution Name] [Version]``, for instance
-'FooNix 1.9.13-r3'.
-
-Some bugs preventing compilation under Clang 2.9 and Sun Studio 12
-were fixed.
-
-The DER/BER codecs use ``size_t`` instead of ``u32bit`` for small
-integers
-
-
diff --git a/doc/relnotes/1_9_14.rst b/doc/relnotes/1_9_14.rst
deleted file mode 100644
index 318d7b53d..000000000
--- a/doc/relnotes/1_9_14.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-Version 1.9.14, 2011-03-01
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add support for bcrypt, OpenBSD's password hashing scheme.
-
-* Add support for NIST's AES key wrapping algorithm, as described in
- :rfc:`3394`. It is available by including ``rfc3394.h``.
-
-* Fix an infinite loop in zlib filters introduced in 1.9.11 (:pr:`142`)
-
diff --git a/doc/relnotes/1_9_15.rst b/doc/relnotes/1_9_15.rst
deleted file mode 100644
index 77b8dbde9..000000000
--- a/doc/relnotes/1_9_15.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-Version 1.9.15, 2011-03-21
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* First release candidate for 1.10.0
-
-* Modify how message expansion is done in SHA-256 and SHA-512.
- Instead of expanding the entire message at the start, compute them
- in the minimum number of registers. Values are computed 15 rounds
- before they are needed. On a Core i7-860, GCC 4.5.2, went from 143
- to 157 MiB/s in SHA-256, and 211 to 256 MiB/s in SHA-512.
-
-* Pipe will delete empty output queues as soon as they are no longer
- needed, even if earlier messages still have data unread. However an
- (empty) entry in a deque of pointers will remain until all prior
- messages are completely emptied.
-
-* Avoid reading the SPARC ``%tick`` register on OpenBSD as unlike the
- Linux and NetBSD kernels, it will not trap and emulate it for us,
- causing a illegal instruction crash.
-
-* Improve detection and autoconfiguration for ARM processors. Thanks
- go out to the the `Tahoe-LAFS Software Foundation
- <http://tahoe-lafs.org>`_, who donated a Sheevaplug that I'll be
- using to figure out how to make the cryptographic primitives
- Tahoe-LAFS relies on faster, particularly targeting the ARMv5TE.
diff --git a/doc/relnotes/1_9_16.rst b/doc/relnotes/1_9_16.rst
deleted file mode 100644
index fe7441be8..000000000
--- a/doc/relnotes/1_9_16.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-Version 1.9.16, 2011-04-11
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Second release candidate for 1.10.0
-
-* The documentation, previously written in LaTeX, is now in
- reStructuredText suitable for processing by `Sphinx
- <http://sphinx.pocoo.org>`_, which can generate nicely formatted
- HTML and PDFs. The documentation has also been greatly updated and
- expanded.
-
-* The class ``EC_Domain_Params`` has been renamed ``EC_Group``, with a
- typedef for backwards compatability.
-
-* ``EC_Group``'s string constructor didn't understand the standard
- names like "secp160r1", forcing use of the OIDs.
-
-* Two constructors for ECDSA private keys, the one that creates a new
- random key, and the one that provides a preset private key as a
- ``BigInt``, have been merged. This matches the existing interface
- for DSA and DH keys. If you previously used the version taking a
- ``BigInt`` private key, you'll have to additionally pass in a
- ``RandomNumberGenerator`` object starting in this release.
-
-* It is now possible to create ECDH keys with a preset ``BigInt``
- private key; previously no method for this was available.
-
-* The overload of ``generate_passhash9`` that takes an explicit
- algorithm identifier has been merged with the one that does not.
- The algorithm identifier code has been moved from the second
- parameter to the fourth.
-
-* Change shared library versioning to match the normal Unix
- conventions. Instead of ``libbotan-X.Y.Z.so``, the shared lib is
- named ``libbotan-X.Y.so.Z``; this allows the runtime linker to do
- its runtime linky magic. It can be safely presumed that any change
- in the major or minor version indicates ABI incompatability.
-
-* Remove the socket wrapper code; it was not actually used by anything
- in the library, only in the examples, and you can use whatever kind
- of (blocking) socket interface you like with the SSL/TLS code. It's
- available as socket.h in the examples directory if you want to use
- it.
-
-* Disable the by-default 'strong' checking of private keys that are
- loaded from storage. You can always request key material sanity
- checking using Private_Key::check_key.
-
-* Bring back removed functions ``min_keylength_of``,
- ``max_keylength_of``, ``keylength_multiple_of`` in ``lookup.h`` to
- avoid breaking applications written against 1.8
-
diff --git a/doc/relnotes/1_9_17.rst b/doc/relnotes/1_9_17.rst
deleted file mode 100644
index 794120be3..000000000
--- a/doc/relnotes/1_9_17.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-Version 1.9.17, 2011-04-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Third release candidate for 1.10.0
-
-* The format preserving encryption method currently available was
- presented in the header ``fpe.h`` and the functions ``fpe_encrypt``
- and ``fpe_decrypt``. These were renamed as it is likely that other
- FPE schemes will be included in the future. The header is now
- ``fpe_fe1.h``, and the functions are named ``fe1_encrypt`` and
- ``fe1_decrypt``.
-
-* New options to ``configure.py`` control what tools are used for
- documentation generation. The ``--with-sphinx`` option enables using
- Sphinx to convert ReST into HTML; otherwise the ReST sources are
- installed directly. If ``--with-doxygen`` is used, Doxygen will run
- as well. Documentation generation can be triggered via the ``docs``
- target in the makefile; it will also be installed by the install
- target on Unix.
-
-* A bug in 1.9.16 effectively disabled support for runtime CPU feature
- detection on x86 under GCC in that release.
-
-* A mostly internal change, all references to "ia32" and "amd64" have
- been changed to the vendor neutral and probably easier to understand
- "x86-32" and "x86-64". For instance, the "mp_amd64" module has been
- renamed "mp_x86_64", and the macro indicating x86-32 has changed
- from ``BOTAN_TARGET_ARCH_IS_IA32`` to
- ``BOTAN_TARGET_ARCH_IS_X86_32``. The classes calling assembly have
- also been renamed.
-
-* Similiarly to the above change, the AES implemenations using the
- AES-NI instruction set have been renamed from AES_XXX_Intel to
- AES_XXX_NI.
-
-* Systems that are identified as `sun4u` will default to compiling for
- 32-bit SPARCv9 code rather than 64-bit. This matches the still
- common convention for 32-bit SPARC userspaces. If you want 64-bit
- code on such as system, use ``--cpu=sparc64``.
-
-* Some minor fixes for compiling botan under the BeOS
- clone/continuation `Haiku <http://haiku-os.org>`_.
-
-* Further updates to the documentation
-
diff --git a/doc/relnotes/1_9_18.rst b/doc/relnotes/1_9_18.rst
deleted file mode 100644
index b82167bdf..000000000
--- a/doc/relnotes/1_9_18.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-Version 1.9.18, 2011-06-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Fourth release candidate for 1.10.0
-
-* The GOST 34.10 verification operation was not ensuring that s and r
- were both greater than zero. This could potentially have meant it
- would have accepted an invalid all-zero signature as valid for any
- message. Due to how ECC points are internally represented it instead
- resulted in an exception being thrown.
-
-* A simple multiexponentation algorithm is now used in ECDSA and
- GOST-34.10 signature verification, leading to 20 to 25% improvements
- in ECDSA and 25% to 40% improvements in GOST-34.10 verification
- performance.
-
-* The internal representation of elliptic curve points has been
- modified to use Montgomery representation exclusively, resulting in
- reduced memory usage and a 10 to 20% performance improvement for
- ECDSA and ECDH.
-
-* In OAEP decoding, scan for the delimiter bytes using a loop that is
- written without conditionals so as to help avoid timing analysis.
- Unfortunately GCC at least is 'smart' enough to compile it to
- jumps anyway.
-
-* The SSE2 implementation of IDEA did not work correctly when compiled
- by Clang, because the trick it used to emulate a 16 bit unsigned
- compare in SSE (which doesn't contain one natively) relied on signed
- overflow working in the 'usual' way. A different method that doesn't
- rely on signed overflow is now used.
-
-* Add support for compiling SSL using Visual C++ 2010's TR1
- implementation.
-
-* Fix a bug under Visual C++ 2010 which would cause ``hex_encode`` to
- crash if given a zero-sized input to encode.
-
-* A new build option ``--via-amalgamation`` will first generate the
- single-file amalgamation, then build the library from that single
- file. This option requires a lot of memory and does not parallelize,
- but the resulting library is smaller and may be faster.
-
-* On Unix, the library and header paths have been changed to allow
- parallel installation of different versions of the library. Headers
- are installed into ``<prefix>/include/botan-1.9/botan``, libraries
- are named ``libbotan-1.9``, and ``botan-config`` is now namespaced
- (so in this release ``botan-config-1.9``). All of these embedded
- versions will be 1.10 in the upcoming stable release.
-
-* The soname system has been modified. In this release the library
- soname is ``libbotan-1.9.so.0``, with the full library being named
- ``libbotan-1.9.so.0.18``. The ``0`` is the ABI version, and will be
- incremented whenever a breaking ABI change is made.
-
-* TR1 support is not longer automatically assumed under older versions
- of GCC
-
-* Functions for base64 decoding that work standalone (without needing
- to use a pipe) have been added to ``base64.h``
-
-* The function ``BigInt::to_u32bit`` was inadvertently removed in 1.9.11
- and has been added back.
-
-* The function ``BigInt::get_substring`` did not work correctly with a
- *length* argument of 32.
-
-* The implementation of ``FD_ZERO`` on Solaris uses ``memset`` and
- assumes the caller included ``string.h`` on its behalf. Do so to
- fix compilation in the ``dev_random`` and ``unix_procs`` entropy
- sources. Patch from Jeremy C. Reed.
-
-* Add two different configuration targets for Atom, since some are
- 32-bit and some are 64-bit. The 'atom' target now refers to the
- 64-bit implementations, use 'atom32' to target the 32-bit
- processors.
-
-* The (incomplete) support for CMS and card verifiable certificates
- are disabled by default; add ``--enable-modules=cms`` or
- ``--enable-modules=cvc`` during configuration to turn them back on.
-
diff --git a/doc/relnotes/1_9_2.rst b/doc/relnotes/1_9_2.rst
deleted file mode 100644
index e3a46b770..000000000
--- a/doc/relnotes/1_9_2.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.9.2, 2009-11-03
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add SIMD version of XTEA
-* Support both SSE2 and AltiVec SIMD for Serpent and XTEA
-* Optimizations for SHA-1 and SHA-2
-* Add AltiVec runtime detection
-* Fix x86 CPU identification with Intel C++ and Visual C++
-
diff --git a/doc/relnotes/1_9_3.rst b/doc/relnotes/1_9_3.rst
deleted file mode 100644
index 7e7b27efc..000000000
--- a/doc/relnotes/1_9_3.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.9.3, 2009-11-19
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add new AES implementation using Intel's AES instruction intrinsics
-* Add an implementation of format preserving encryption
-* Allow use of any hash function in X.509 certificate creation
-* Optimizations for MARS, Skipjack, and AES
-* Set macros for available SIMD instructions in build.h
-* Add support for using InnoSetup to package Windows builds
-* By default build a DLL on Windows
-
diff --git a/doc/relnotes/1_9_4.rst b/doc/relnotes/1_9_4.rst
deleted file mode 100644
index 60e02ffd6..000000000
--- a/doc/relnotes/1_9_4.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-Version 1.9.4, 2010-03-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add the Ajisai SSLv3/TLSv1.0 implementation
-
-* Add GOST 34.10-2001 public key signature scheme
-* Add SIMD implementation of Noekeon
-
-* Add SSE2 implementation of IDEA
-
-* Extend Salsa20 to support longer IVs (XSalsa20)
-
-* Perform XTS encryption and decryption in parallel where possible
-
-* Perform CBC decryption in parallel where possible
-
-* Add SQLite3 db encryption codec, contributed by Olivier de Gaalon
-
-* Add a block cipher cascade construction
-
-* Add support for password hashing for authentication (passhash9.h)
-
-* Add support for Win32 high resolution system timers
-
-* Major refactoring and API changes in the public key code
-
-* PK_Signer class now verifies all signatures before releasing them to
- the caller; this should help prevent a wide variety of fault
- attacks, though it does have the downside of hurting signature
- performance, particularly for DSA/ECDSA.
-
-* Changed S2K interface: derive_key now takes salt, iteration count
-
-* Remove dependency on TR1 shared_ptr in ECC and CVC code
-
-* Renamed ECKAEG to its more usual name, ECDH
-
-* Fix crash in GMP_Engine if library is shutdown and reinitialized
-
-* Fix an invalid memory read in MD4
-
-* Fix Visual C++ static builds
-
-* Remove Timer class entirely
-
-* Switch default PKCS #8 encryption algorithm from 3DES to AES-128
-
-* New configuration option, ``--gen-amalgamation``, creates a pair of
- files (``botan_all.cpp`` and ``botan_all.h``) which contain the
- contents of the library as it would have normally been compiled
- based on the set configuration.
-
-* Many headers are now explicitly internal-use-only and are not installed
-
-* Greatly improve the Win32 installer
-
-* Several fixes for Visual C++ debug builds
diff --git a/doc/relnotes/1_9_5.rst b/doc/relnotes/1_9_5.rst
deleted file mode 100644
index cdcd8db4b..000000000
--- a/doc/relnotes/1_9_5.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-Version 1.9.5, 2010-03-29
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Numerous ECC optimizations
-* Fix GOST 34.10-2001 X.509 key loading
-* Allow PK_Signer's fault protection checks to be toggled off
-* Avoid using pool-based locking allocator if we can't mlock
-* Remove all runtime options
-* New BER_Decoder::{decode_and_check, decode_octet_string_bigint}
-* Remove SecureBuffer in favor of SecureVector length parameter
-* HMAC_RNG: Perform a poll along with user-supplied entropy
-* Fix crash in MemoryRegion if Allocator::get failed
-* Fix small compilation problem on FreeBSD
-
diff --git a/doc/relnotes/1_9_6.rst b/doc/relnotes/1_9_6.rst
deleted file mode 100644
index 971da7bca..000000000
--- a/doc/relnotes/1_9_6.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-Version 1.9.6, 2010-04-09
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* TLS: Add support for TLS v1.1
-* TLS: Support server name indicator extension
-* TLS: Fix server handshake
-* TLS: Fix server using DSA certificates
-* TLS: Avoid timing channel between CBC padding check and MAC verification
-
diff --git a/doc/relnotes/1_9_7.rst b/doc/relnotes/1_9_7.rst
deleted file mode 100644
index 4c6e2c21d..000000000
--- a/doc/relnotes/1_9_7.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-Version 1.9.7, 2010-04-27
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* TLS: Support reading SSLv2 client hellos
-* TLS: Add support for SEED ciphersuites (RFC 4162)
-* Add Comb4P hash combiner function
-
-* Fix checking of EMSA_Raw signatures with leading 0 bytes, valid
- signatures could be rejected in certain scenarios.
-
-
diff --git a/doc/relnotes/1_9_8.rst b/doc/relnotes/1_9_8.rst
deleted file mode 100644
index a671d946c..000000000
--- a/doc/relnotes/1_9_8.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-Version 1.9.8, 2010-06-14
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* Add support for wide multiplications on 64-bit Windows
-* Use constant time multiplication in IDEA
-* Avoid possible timing attack against OAEP decoding
-* Removed FORK-256; rarely used and it has been broken
-* Rename ``--use-boost-python`` to ``--with-boost-python``
-* Skip building shared libraries on MinGW/Cygwin
-* Fix creation of 512 and 768 bit DL groups using the DSA kosherizer
-* Fix compilation on GCC versions before 4.3 (missing cpuid.h)
-* Fix compilation under the Clang compiler
-
diff --git a/doc/relnotes/1_9_9.rst b/doc/relnotes/1_9_9.rst
deleted file mode 100644
index 4ff1a9c0c..000000000
--- a/doc/relnotes/1_9_9.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-Version 1.9.9, 2010-06-28
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A new pure virtual function has been added to ``Filter``, ``name``
-which simply returns some useful identifier for the object. Any
-out-of-tree ``Filter`` implementations will need to be updated.
-
-Add ``Keyed_Filter::valid_iv_length`` which makes it possible to query
-as to what IV length(s) a particular filter allows. Previously,
-partially because there was no such query mechanism, if a filter did
-not support IVs at all, then calls to ``set_iv`` would be silently
-ignored. Now an exception about the invalid IV length will be thrown.
-
-The default iteration count for the password based encryption schemes
-has been increased from 2048 to 10000. This should make
-password-guessing attacks against private keys encrypted with versions
-after this release somewhat harder.
-
-New functions for encoding public and private keys to binary,
-``X509::BER_encode`` and ``PKCS8::BER_encode`` have been added.
-
-Problems compiling under Apple's version of GCC 4.2.1 and on 64-bit
-MIPS systems using GCC 4.4 or later were fixed.
-
-The coverage of Doxygen documentation comments has significantly
-improved in this release.
diff --git a/doc/relnotes/contents.rst b/doc/relnotes/contents.rst
deleted file mode 100644
index 406fc4133..000000000
--- a/doc/relnotes/contents.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-
-Release Notes
-========================================
-
-.. toctree::
- :maxdepth: 2
-
- index
diff --git a/doc/relnotes/index.rst b/doc/relnotes/index.rst
deleted file mode 100644
index f94a0bfea..000000000
--- a/doc/relnotes/index.rst
+++ /dev/null
@@ -1,277 +0,0 @@
-
-Release Notes
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Series 1.11
-----------------------------------------
-
-.. toctree::
- :maxdepth: 1
-
- 1_11_17
- 1_11_16
- 1_11_15
- 1_11_14
- 1_11_13
- 1_11_12
- 1_11_11
- 1_11_10
- 1_11_9
- 1_11_8
- 1_11_7
- 1_11_6
- 1_11_5
- 1_11_4
- 1_11_3
- 1_11_2
- 1_11_1
- 1_11_0
-
-Series 1.10
-----------------------------------------
-
-.. toctree::
-
- 1_10_9
- 1_10_8
- 1_10_7
- 1_10_6
- 1_10_5
- 1_10_4
- 1_10_3
- 1_10_2
- 1_10_1
- 1_10_0
-
-Series 1.9
-----------------------------------------
-
-.. toctree::
-
- 1_9_18
- 1_9_17
- 1_9_16
- 1_9_15
- 1_9_14
- 1_9_13
- 1_9_12
- 1_9_11
- 1_9_10
- 1_9_9
- 1_9_8
- 1_9_7
- 1_9_6
- 1_9_5
- 1_9_4
- 1_9_3
- 1_9_2
- 1_9_1
- 1_9_0
-
-Series 1.8
-----------------------------------------
-
-.. toctree::
-
- 1_8_14
- 1_8_13
- 1_8_12
- 1_8_11
- 1_8_10
- 1_8_9
- 1_8_8
- 1_8_7
- 1_8_6
- 1_8_5
- 1_8_4
- 1_8_3
- 1_8_2
- 1_8_1
- 1_8_0
-
-Series 1.7
-----------------------------------------
-
-.. toctree::
-
- 1_7_24
- 1_7_23
- 1_7_22
- 1_7_21
- 1_7_20
- 1_7_19
- 1_7_18
- 1_7_17
- 1_7_16
- 1_7_15
- 1_7_14
- 1_7_13
- 1_7_12
- 1_7_11
- 1_7_10
- 1_7_9
- 1_7_8
- 1_7_7
- 1_7_6
- 1_7_5
- 1_7_4
- 1_7_3
- 1_7_2
- 1_7_1
- 1_7_0
-
-Series 1.6
-----------------------------------------
-
-.. toctree::
-
- 1_6_5
- 1_6_4
- 1_6_3
- 1_6_2
- 1_6_1
- 1_6_0
-
-Series 1.5
-----------------------------------------
-
-.. toctree::
-
- 1_5_13
- 1_5_12
- 1_5_11
- 1_5_10
- 1_5_9
- 1_5_8
- 1_5_7
- 1_5_6
- 1_5_5
- 1_5_4
- 1_5_3
- 1_5_2
- 1_5_1
- 1_5_0
-
-Series 1.4
-----------------------------------------
-
-.. toctree::
-
- 1_4_12
- 1_4_11
- 1_4_10
- 1_4_9
- 1_4_8
- 1_4_7
- 1_4_6
- 1_4_5
- 1_4_4
- 1_4_3
- 1_4_2
- 1_4_1
- 1_4_0
-
-Series 1.3
-----------------------------------------
-
-.. toctree::
-
- 1_3_14
- 1_3_13
- 1_3_12
- 1_3_11
- 1_3_10
- 1_3_9
- 1_3_8
- 1_3_7
- 1_3_6
- 1_3_5
- 1_3_4
- 1_3_3
- 1_3_2
- 1_3_1
- 1_3_0
-
-Series 1.2
-----------------------------------------
-
-.. toctree::
-
- 1_2_8
- 1_2_7
- 1_2_6
- 1_2_5
- 1_2_4
- 1_2_3
- 1_2_2
- 1_2_1
- 1_2_0
-
-Series 1.1
-----------------------------------------
-
-.. toctree::
-
- 1_1_13
- 1_1_12
- 1_1_11
- 1_1_10
- 1_1_9
- 1_1_8
- 1_1_7
- 1_1_6
- 1_1_5
- 1_1_4
- 1_1_3
- 1_1_2
- 1_1_1
- 1_1_0
-
-Series 1.0
-----------------------------------------
-
-.. toctree::
-
- 1_0_2
- 1_0_1
- 1_0_0
-
-Series 0.9
-----------------------------------------
-
-.. toctree::
-
- 0_9_2
- 0_9_1
- 0_9_0
-
-Series 0.8
-----------------------------------------
-
-.. toctree::
-
- 0_8_7
- 0_8_6
- 0_8_5
- 0_8_4
- 0_8_3
- 0_8_2
- 0_8_1
- 0_8_0
-
-Series 0.7
-----------------------------------------
-
-.. toctree::
-
- 0_7_10
- 0_7_9
- 0_7_8
- 0_7_7
- 0_7_6
- 0_7_5
- 0_7_4
- 0_7_3
- 0_7_2
- 0_7_1
- 0_7_0
diff --git a/doc/dev/roadmap.rst b/doc/roadmap.rst
index 9c30130e1..76ab81f07 100644
--- a/doc/dev/roadmap.rst
+++ b/doc/roadmap.rst
@@ -11,13 +11,13 @@ snapshots are made directly from it. Every once in a while a new even-numbered
branch is forked. All development continues on the main trunk, with fixes and
occasionally small features backported to the stable branch. Stability of API
and ABI is very important in the stable branches, whereas in trunk ABI changes
-happen with no warning and API changes are made whenever it would serve the
+happen with no warning, and API changes are made whenever it would serve the
ends of justice.
Current Status
----------------------------------------
-Currently (as of 2015-01-08) trunk is numbered 1.11 and is written in C++11,
+Currently (as of 2015-07-03) trunk is numbered 1.11 and is written in C++11,
unlike earlier versions which used C++98. In due time a new stable 2.0 branch
will be made off of trunk and afterwards trunk will be renumbered as 2.1. The
2.0 releases will be maintained with security and bug fixes at least until a
@@ -40,18 +40,17 @@ released.
Supported Targets
----------------------------------------
-The primary supported target (ie, what the main developer uses and tests with
-regularly) is a recent GCC or Clang on Linux with an x86-64 CPU. Occasionally
-Linux systems using POWER, MIPS, and ARM processors are also checked. Testing
-and fixes for Windows, MinGW, OS X, OpenBSD, Visual C++, iOS, etc comes
-primarily from users.
+The primary supported targets, which are tested with every commit by
+continous integration, are GCC and Clang on Linux, Clang on OS X, and
+MSVC 2013 on Windows, all on some form of x86.
+
+Other processors, like ARM, MIPS, and POWER processors, and OSes, such
+as OpenBSD, MinGW, or iOS are occasionally tested on an ad-hoc basis,
+but breakage is somewhat more likely.
Ongoing Issues
----------------------------------------
-Currently sources are kept in :doc:`Monotone <vcs>`, which likely discourages
-some would-be developers. The github mirror may be helping somewhat here.
-
Some infrastructure, scripts and such still exists only on the machines of the
primary developer.
diff --git a/doc/dev/todo.rst b/doc/todo.rst
index 6845e0e68..2d82615ea 100644
--- a/doc/dev/todo.rst
+++ b/doc/todo.rst
@@ -5,8 +5,7 @@ These are features either requested by users or that seem like
potentially useful things to have. Several are quite self-contained
and could make a quick project.
-Request a new feature by sending a patch to this file or by writing to
-the mailing list.
+Request a new feature by opening a pull request to update this file.
Symmetric Algorithms, Hashes, ...
----------------------------------------
@@ -14,6 +13,9 @@ Symmetric Algorithms, Hashes, ...
* Bitsliced AES or Camellia
* Camellia with AES-NI
* Serpent using AVX2
+* Serpent using SSSE3 pshufb for sboxes
+* ChaCha20 using SSE2 or AVX2
+* SHA-512 using SSE2 (to access 64-bit math on x86-32)
* scrypt
* BLAKE2b
* Skein-MAC
@@ -25,9 +27,15 @@ Public Key Crypto, Math
* EdDSA
* Ed448-Goldilocks
-* Add specialized reductions for other NIST primes
+* FHMQV
+* Support mixed hashes and non-empty param strings in OAEP
* Fast new implementations/algorithms for ECC point operations,
Montgomery multiplication, multi-exponentiation, ...
+* Some PK operations, especially RSA, have extensive computations per
+ operation setup but many of the computed values depend only on the
+ key and could be shared across operation objects.
+* Have BigInt '%' and '/' operators compute and cache the Barrett
+ reduction value on the BigInt.
TLS
----------------------------------------
@@ -44,6 +52,9 @@ TLS
PKIX
----------------------------------------
+* Support multiple DNS names in certificates
+* X.509 name constraints
+* X.509 policy constraints
* OCSP responder logic
* X.509 attribute certificates (RFC 5755)
@@ -55,17 +66,23 @@ New Protocols
* SSHv2 client and/or server
* Cash schemes (such as Lucre, credlib, bitcoin?)
+Library Infrastructure
+----------------------------------------
+* Add logging callbacks
+* Add latency tracing framework
+* Compute cycles/byte estimates for benchmark output
+
Accelerators / backends
----------------------------------------
-* Improve OpenSSL provider (add cipher modes, RSA, etc)
+* Extend OpenSSL provider (cipher modes, ECDH, ECDSA, HMAC)
* /dev/crypto
* Windows CryptoAPI
* Apple CommonCrypto
* ARMv8 crypto extensions
* Intel Skylake SHA-1/SHA-2
-Python/FFI
+FFI (Python, OCaml)
----------------------------------------
* Expose TLS
diff --git a/doc/website/algos.rst b/doc/website/algos.rst
deleted file mode 100644
index fcf51c91f..000000000
--- a/doc/website/algos.rst
+++ /dev/null
@@ -1,104 +0,0 @@
-
-Supported Algorithms
-========================================
-
-Botan supports a range of cryptographic algorithms and protocols,
-including:
-
-TLS/Public Key Infrastructure
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * TLS/DTLS (v1.0 to v1.2), including using preshared keys (TLS-PSK) or
- passwords (TLS-SRP) and most important extensions.
- * X.509 certificates (including generating new self-signed and CA
- certs) and CRLs
- * Certificate path validation and OCSP
- * PKCS #10 certificate requests (creation and certificate issue)
-
-Public Key Cryptography
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * Encryption algorithms RSA, ElGamal, DLIES
- (padding schemes OAEP or PKCS #1 v1.5)
- * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001, Nyberg-Rueppel,
- Rabin-Williams (padding schemes PSS, PKCS #1 v1.5, X9.31)
- * Diffie-Hellman, ECDH using NIST/Brainpool prime groups, Curve25519
- * McEliece code based encryption providing a KEM scheme
-
-Block ciphers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, and ChaCha20Poly1305
- * Unauthenticated cipher modes CTR, CBC, XTS, CFB, OFB, and ECB
- * AES (including constant time SSSE3 and AES-NI versions)
- * AES candidates Serpent, Twofish, MARS, CAST-256, RC6
- * DES, 3DES and DESX
- * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147
- * Other block ciphers including Threefish-512, Blowfish, CAST-128, IDEA,
- Noekeon, TEA, XTEA, RC2, RC5, SAFER-SK
- * Large block cipher construction Lion
-
-Stream Ciphers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * RC4
- * Salsa20/XSalsa20
- * ChaCha20
-
-Hash functions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
- * RIPEMD-160, RIPEMD-128, Tiger, Whirlpool
- * SHA-3 winner Keccak-1600
- * SHA-3 candidate Skein-512
- * Hash function combiners (Parallel and Comb4P)
- * National standard hashes HAS-160 and GOST 34.11
- * Obsolete or insecure hashes MD5, MD4, MD2
- * Non-cryptographic checksums Adler32, CRC24, CRC32
-
-Authentication Codes and PRFs
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * HMAC
- * CMAC (aka OMAC1)
- * Poly1305
- * SipHash
- * Obsolete designs CBC-MAC and ANSI X9.19 DES-MAC
-
-Other Useful Things
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- * Key derivation functions for passwords, including PBKDF2
- * Password hashing functions, including bcrypt
- * General key derivation functions KDF1 and KDF2 from IEEE 1363
-
-Recommended Algorithms
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This section is by no means the last word on selecting which algorithms to
-use. However, botan includes a sometimes bewildering array of possible
-algorithms, and unless you're familiar with the latest developments in the
-field, it can be hard to know what is secure and what is not. The following
-attributes of the algorithms were evaluated when making this list: security,
-support by other implementations, patent/IP status, and efficiency (in
-roughly that order).
-
-If your data is in motion, strongly consider using TLS v1.2 as a pre built,
-already standard and well studied protocol.
-
-Otherwise, if you simply *must* do something custom, use:
-
-* Message encryption: AES or Serpent in EAX or GCM mode
-
-* General hash functions: SHA-256 or SHA-512
-
-* Message authentication: HMAC with SHA-256
-
-* Public Key Encryption: RSA, 2048+ bit keys, with OAEP and SHA-256
- ("EME1(SHA-256)")
-
-* Public Key Signatures: RSA, 2048+ bit keys with PSS and SHA-512
- ("EMSA4(SHA-512)"), or ECDSA with SHA-256 or SHA-512
-
-* Key Agreement: Diffie-Hellman or ECDH, with "KDF2(SHA-256)"
diff --git a/doc/website/contents.rst b/doc/website/contents.rst
deleted file mode 100644
index afe5c5d01..000000000
--- a/doc/website/contents.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-
-Contents
-========================================
-
-.. toctree::
-
- index
- download
- vcs
- license
- manual
- pgpkey
- credits
- users
- algos
- news.rst
-
diff --git a/doc/website/download.rst b/doc/website/download.rst
deleted file mode 100644
index b605bddfc..000000000
--- a/doc/website/download.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-
-Download
-========================================
-
-All releases are signed with a :doc:`PGP key <pgpkey>`.
-
-.. note::
-
- All users, especially for new applications, are encouraged to use
- the latest 1.11 release instead of 1.10, though some API changes
- are still likely to occur before a new stable release based on 1.11.
-
-Current Development Series (1.11)
-----------------------------------------
-
-The latest development release is :doc:`relnotes/1_11_17`:
-:tgz:`1.11.17` (:tgz_sig:`sig <1.11.17>`)
-
-.. note::
-
- Botan 1.11 requires a working C++11 compiler; GCC 4.8 and later,
- Clang 3.4 and later, and MSVC 2013 are regularly tested.
-
-Current Stable Series (1.10)
-----------------------------------------
-
-The latest stable branch release is :doc:`relnotes/1_10_9`:
-:tgz:`1.10.9` (:tgz_sig:`sig <1.10.9>`)
-
-From Your Favorite Distribution
-----------------------------------------
-
-Botan is already included in many package distributions though often
-the included version lags behind the latest release. Distributions
-providing botan include
-`Fedora <https://admin.fedoraproject.org/pkgdb/acls/name/botan>`_,
-`EPEL <http://dl.fedoraproject.org/pub/epel/6/SRPMS/repoview/botan.html>`_ (for RHEL/CentOS),
-`Debian <http://packages.debian.org/search?keywords=libbotan>`_,
-`Ubuntu <http://packages.ubuntu.com/search?keywords=botan>`_,
-`Gentoo <http://packages.gentoo.org/package/botan>`_,
-`Arch <http://www.archlinux.org/packages/community/x86_64/botan/>`_,
-`Slackbuild <http://slackbuilds.org/result/?search=Botan>`_,
-`FreeBSD <http://www.freshports.org/security/botan110>`_,
-`NetBSD <ftp://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/security/botan/README.html>`_,
-`Cygwin <http://cygwin.com/packages/x86/botan/>`_,
-`MacPorts <http://www.macports.org/ports.php?by=name&substr=botan>`_,
-`OpenPKG <http://www.openpkg.org/product/packages/?package=botan>`_, and
-`T2 SDE <http://www.t2-project.org/packages/botan.html>`_
diff --git a/doc/website/index.rst b/doc/website/index.rst
deleted file mode 100644
index f96b13daa..000000000
--- a/doc/website/index.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-
-Botan: Crypto and TLS for C++11
-========================================
-
-Botan is a crypto library for C++ released under the permissive
-:doc:`BSD-2 license <license>`.
-
-It provides useful things like TLS, X.509 PKIX (certs, CRLs, OCSP,
-etc), ECDSA, AES, GCM, and bcrypt, plus a :doc:`kitchen sink <algos>`
-of other crypto algorithms of various utility. A third party open source
-implementation of `SSHv2 <https://github.com/cdesjardins/ne7ssh>`_
-that uses botan is also available. In addition to C++ you can use
-(parts of) botan from Python or Perl (both included in tree), or with
-`Node.js <https://github.com/justinfreitag/node-botan>`_.
-
-See :doc:`download` for information about getting the latest release,
-and :doc:`manual` for the documentation.
-
-If you need help or have questions, send a mail to the `development
-mailing list
-<http://lists.randombit.net/mailman/listinfo/botan-devel/>`_.
-
-You can browse the source online via the
-`GitHub mirror <https://github.com/randombit/botan>`_.
-
-To report a bug use
-`Bugzilla <http://bugs.randombit.net/>`_ or
-`GitHub Issues <https://github.com/randombit/botan/issues>`_.
-
diff --git a/doc/website/license.rst b/doc/website/license.rst
deleted file mode 100644
index d07a34e9a..000000000
--- a/doc/website/license.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-
-.. _license:
-.. highlight:: none
-
-License
-========================================
-
-.. literalinclude:: license.txt
diff --git a/doc/website/manual.rst b/doc/website/manual.rst
deleted file mode 100644
index bda6ef09c..000000000
--- a/doc/website/manual.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-
-Reference Manual
-========================================
-
-The documentation is all under ``doc`` in your source tree, stored as
-``.rst`` (`RestructedText <http://docutils.sourceforge.net/rst.html>`_) files.
-They can be processed by `Sphinx <http://sphinx-doc.org>`_ to produce
-HTML or PDF output.
-
-The `manual </manual/>`_ and `Doxygen reference </doxygen/>`_ for the
-latest development release is available online.
diff --git a/doc/website/pgpkey.rst b/doc/website/pgpkey.rst
deleted file mode 100644
index 1f0e83a44..000000000
--- a/doc/website/pgpkey.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-
-Code Signing Key
-========================================
-
-.. highlight:: none
-
-The following PGP key is used to sign all releases::
-
- pub 2048R/EFBADFBC 2004-10-30
- Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
- uid Botan Distribution Key
-
- -----BEGIN PGP PUBLIC KEY BLOCK-----
- Version: GnuPG v2.0.17 (GNU/Linux)
-
- mQELBEGD1j0BCADHxPJkPcjJE+4Dlisx2hVc0Dj6JI1MSLrkM8R+2bOhVUSferxP
- T1EMPhfrAdOHTAloyvRThJztnZsNKqfLL49GGcBLdEGAVNks1pG37Teze5Lx1XIu
- zJFrozL2sqBy5C6nHpFgd1tcD68Rah2wp0u2cR9owXf1IqKdEfuo661+MTv7wTB1
- 4hKV75nB7ZO6676SEZRILYM+7RJwKAKEmEPJc6hEf94VXn9ecNzaTlHgYkjhz9db
- LOd3od9XvuUw+LMR1dwBqMxbvR90MiXjbedDEkbArcZB9YOAIvEX/lC3qaW4XJt4
- iwHWl/YVZEfALcvQywe2CDrH5hO794wd9MpBAAYptBZCb3RhbiBEaXN0cmlidXRp
- b24gS2V5iQEqBBMBAgAUAhsDAh4BAheABQJKfFpnBBUKCQgACgkQYhHr8e+637xk
- PQf/aOi78XenwwvFrwXOVIVTdZIf8rK1zJksf26h09UD8uVV6z5iiTcpn86+eN9p
- 6Ar8IH3tD+JuFnPSwZ/r9MNC2XZwenYo4Gb14jqM6/9hBe328vmeM4Y1G7bD4HrL
- kgV5WEyokqm3zbp3FBLr3Vh68TAC5JB9aHevra+cCA2u3vBNI3YUM5z4TdO150P3
- J00whkqImQEUni8bgxvllBLFM+uhucsX3HZWkoDEpotbg8yd0bqMkiPEyMr1OnJq
- eDVDMrB5wnyLgLFfRAAw3mopM0C1PNOAHr/BIYiaDHX2OwnOfep8rMDoRVf2Ge0D
- DBgsJJ6LduQHLeg403SHWL2F6YkCHAQTAQIABgUCQYPWUgAKCRBcD5boTsFta+r9
- EACWVis7YcaGkKKgRB/5ox8rM36XVhMXdh/hnnGHt5rapbbRRkRHRcWU8WIcFO1A
- 59+TfwNNd8gN1MEt/5aX5KHWVKHBDexJgIxm6Dm1pisYHf/dnYQPM18hmqqwNlKY
- 97hFkPpHd7enrtc/SvGbQhhLXYlpwBrdMl76e9xJLnnrRQksxegGPo8cr+C9HTs1
- Lwa8zzBxyBwYBYX+0moDkDShEhuXx6mEOXrGvQanJuIvpoIwGH+62E65MbJGlwWp
- w/MAtm2jFhBIhGV0bqJCFp9zIgdNgfskBaPr0oilbuJQZqP0Iqe/6CCt4XkS51yW
- ZqxjLAFpEpvDec4PGw3witKf/koGon9X8C035+nEjLBrWy18Q91vw2USyLI+mm9d
- iMAS8pY2gomfxBO2VwYHJryZykjCYQkccRA1tHteRj4gqTObo0Ak47y5MnplTWwi
- 40oP7K2cfhCRBmMioxmYES4xsHEupfRBo3xr1Jq9q0t688WTT1NXHPMPoueF9mKZ
- Cf2pa9aHsqBmWTm3sCaNQKGubCDBEUmJUyndmSatJyYM7NVYoUp6EfqMACFuTNdB
- sjKMh7aWVikQpbJDfA1BIU3lZeqgjgrghVAWkEOBfhG0IVZj+RVCJpsqoTJ8asY2
- VreArSCyr/VnLEnfuH/QpgvCiCbepo3E34DJt4SaAOO2ZohGBBARAgAGBQJMGVc1
- AAoJEKY/LL36AvvMgsoAn2G7kXd09BF7ffk1Sfh174SVrvM9AKC7+R7x0+yV3SCd
- JkkUOo3xR5cOxw==
- =1QuR
- -----END PGP PUBLIC KEY BLOCK-----
diff --git a/doc/website/users.rst b/doc/website/users.rst
deleted file mode 100644
index 7cb0d924a..000000000
--- a/doc/website/users.rst
+++ /dev/null
@@ -1,118 +0,0 @@
-
-Users
-========================================
-
-This is a list of some of the known users of botan. The open source
-projects might be helpful as an additional reference for library
-usage.
-
-If you'd like to be added to the list, email the development list.
-
-Open Source Software
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* `BIND 10 <http://www.isc.org/bind10>`_ the new version of the BIND
- DNS server uses botan for various crypto operations.
-
-* `SoftHSM <http://trac.opendnssec.org/wiki/SoftHSM>`_ an open sourced
- software PKCS #11 implementation, which is used as part of the
- `OpenDNSSEC <http://www.opendnssec.org>`_ project.
-
-* `Qt Creator <http://qt.nokia.com/products/developer-tools>`_, an
- IDE for building Qt applications.
-
-* `NetSieben's <http://netsieben.com/products/ssh/>`_
- SSH library provides SSHv2 client connections for C++
- applications, using botan for the crypto. (GPL or commercial)
-
-* `InSiTo <http://www.flexsecure.eu/insito/index.html>`_ is a library
- for ePassports based on botan which was commissioned by the German
- Federal Office for Information Security.
-
-* `QCA <http://delta.affinix.com/qca/>`_, the Qt Cryptographic
- Architecture (part of KDE4) uses parts of botan as an `embedded
- crypto provider
- <http://quickgit.kde.org/?p=qca.git&a=tree&hb=master&f=src%2Fbotantools%2Fbotan>`_
- and also has a `qca-botan plugin <http://quickgit.kde.org/?p=qca.git&a=tree&hb=master&f=plugins%2Fqca-botan>`_.
-
-* `TCHead <http://16s.us/TCHead/>`_ is a utility for analyzing
- TrueCrypt volume headers.
-
-* `Octopod <http://code.google.com/p/octopod/>`_ is a
- file sharing system.
-
-* `Silverlock <http://www.petroules.com/products/silverlock/>`_
- is a GPL password management tool for Windows, OS X, and Linux.</p>
-
-* `Monotone <http://monotone.ca/>`_, a free distributed
- version control system, uses botan for RSA authentication,
- content hashing, and message authentication.
-
-* `Publimark <http://www.gleguelv.org/soft/publimark/index.html>`_
- is a tool for hiding messages in an audio file.
-
-* `KeySafe <http://therning.org/magnus/computer/keysafe>`_,
- a password application for GNOME
-
-* `SuSE <http://gcc.opensuse.org>`_ uses botan as part
- of a test suite for the GCC optimizer.
-
-* `Openbench <http://www.exactcode.de/site/open_source/openbench/>`_,
- an open source benchmark suite, uses botan as a component.
-
-* `VNCcrack <http://www.randombit.net/code/vnccrack/>`_
- is a password cracker for the VNC authentication/response protocol.
-
-Commercial Software
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* `Hulu Desktop <http://www.hulu.com/labs/hulu-desktop>`_ uses botan
- on Windows `(ref)
- <http://download.hulu.com/HuluDesktop_ThirdPartyLicenses.txt>`_.
-
-* `Hitman Pro <http://www.surfright.nl/en>`_ is a malware
- scanner for Windows.
-
-* `Flying Lab Software <http://www.burningsea.com>`_, a Seattle based
- game developer, uses botan as a part of their user authentication
- process.
-
-* `CryptoTE <http://idlebox.net/2009/cryptote/>`_ is a text editor
- with integrated strong cryptography.
-
-* `TextEgg <http://www.textegg.com/>`_ is an encrypted document editor.
-
-* `Seagate <http://www.seagate.com/www/en-us/support/downloads/>`_
- uses botan for the drive encryption in the Maxtor OneTouch III Mini
- Edition hard drive.
-
-* `E.V.E. Paradox <http://www.entropicsoftware.com/eve/eve.html>`_, a
- suite of games for Windows.
-
-Research Projects
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-* `A Unified Approach to Intra-Domain Security
- <http://www.csiir.ornl.gov/shue/research/securecom09.pdf>`_
- describes a system by researches from Oak Ridge National Lab and
- Indiana University that uses botan to secure ARP and DHCP.
-
-* `CLL: A Cryptographic Link Layer for Local Area Networks
- <http://www.springerlink.com/content/c4681m76808l4621/>`_ describes
- a network encryption system using botan. (One of the coauthors, Yves
- Jerschow, also contributed a number of optimizations to the
- library).
-
-* The system described in `Enabling Intrusion Detection in IPsec
- Protected IPv6 Networks Through Secret-key Sharing
- <http://www.dtic.mil/dtic/tr/fulltext/u2/a431510.pdf>`_.
-
-* `An experimental tamper detection system
- <http://www.cis.udel.edu/~hiper/passages/papers/jochenMILCOM03.pdf>`_
- designed by researchers from the University of Delaware and the US
- Army Research Laboratory.
-
-* A prototype implementation of a telephony signal security system,
- described in `Prototyping and evaluation of TCAPsec
- <http://www.cs.kau.se/cs/education/courses/davddiss/Uppsatser_2007/D2007-04.pdf>`_
- by Kang Chung and Mathilda Gustafsson.
diff --git a/doc/website/vcs.rst b/doc/website/vcs.rst
deleted file mode 100644
index e2353ee53..000000000
--- a/doc/website/vcs.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-
-Accessing Version Control
-========================================
-
-Botan's development occurs using a distributed version control system
-called `Monotone <http://www.monotone.ca>`_ (though there is also a
-mirror on `github <https://github.com/randombit/botan>`_). The main
-branch of development occurs on the branch named
-``net.randombit.botan``. To download that branch and set up a new
-workspace, run::
-
- $ mtn db init --db=botan.mtn
- $ mtn pull --db=botan.mtn mtn.randombit.net 'net.randombit.botan'
- [...]
- $ mtn checkout --db=botan.mtn --branch=net.randombit.botan
- [...]
-
-By default the ``checkout`` command will place the workspace in a
-directory with the same name as the branch you are checking out. If
-you want a different directory name, just include it after the
-``--branch`` option (you can also rename this directory at any time).
-
-If this is the first time you've connected to the server, Monotone
-will print::
-
- mtn: first time connecting to server mtn.randombit.net
- mtn: I'll assume it's really them, but you might want to double-check
- mtn: their key's fingerprint: 8c0b868f2247215c63c96983b1c8ca0f0f0cfd9a
-
-The fingerprint shown above was the correct one as of March 21, 2013.
-
-To pull further changes, from anywhere in the workspace run these
-commands::
-
- $ mtn pull
- [...]
- $ mtn update
- [summary of changes]
-
-The ``mtn update`` command will give you a summary of which files
-changed; to view the full changelog, run ``mtn log``.
diff --git a/readme.rst b/readme.rst
index 08672111d..ac1014188 100644
--- a/readme.rst
+++ b/readme.rst
@@ -1,30 +1,47 @@
-Botan Crypto Library
+Botan: Crypto and TLS for C++11
========================================
-Botan is a C++11 library for crypto and TLS released under the permissive
-2-clause BSD license (see ``doc/license.txt`` for the specifics).
+Botan (Japanese for peony) is a C++ cryptography library
+released under the permissive
+`Simplified BSD <http://botan.randombit.net/license.txt>`_ license.
+It provides useful things like TLS, X.509 certificates, ECDSA, AES,
+GCM, ChaCha20Poly1305, and bcrypt, plus a kitchen sink of other crypto
+algorithms of various utility; see the full list below.
-For all the details on building the library read ``doc/manual/building.rst``,
-but basically::
+Development is coordinated on `GitHub <https://github.com/randombit/botan>`_
+and contributions are welcome.
+
+.. highlight:: none
+
+For all the details on building the library, read the
+`users manual <http://botan.randombit.net/manual>`_, but basically::
$ ./configure.py --help
$ ./configure.py [probably some options]
$ make
$ ./botan-test
- # test output
+ # lots of output...
+ Tests all ok
$ ./botan
# shows available commands
$ make install
-You can file bugs at https://github.com/randombit/botan/issues/
-or by sending a report to the `botan-devel mailing list
-<http://lists.randombit.net/mailman/listinfo/botan-devel/>`_
+If you need help or have questions, send a mail to the
+`mailing list <http://lists.randombit.net/mailman/listinfo/botan-devel/>`_
+or open a ticket on
+`GitHub Issues <https://github.com/randombit/botan/issues>`_.
-The `github wiki <https://github.com/randombit/botan/wiki>`_
-is also available as a resource.
+The `GitHub wiki <https://github.com/randombit/botan/wiki>`_
+and `Doxygen docs <https://botan.randombit.net/doxygen>`_
+may also prove useful resources.
-CI Status
-----------------------------------------
+In addition to C++ there are (partial, in-progress) bindings for C89,
+Python and OCaml included along with the library, and
+`Node.js <https://github.com/justinfreitag/node-botan>`_ wrapper also
+exists.
+
+There is also a third party open source implementation of
+`SSHv2 <https://github.com/cdesjardins/cppssh>`_ using the library.
.. image:: https://travis-ci.org/randombit/botan.svg?branch=master
:target: https://travis-ci.org/randombit/botan
@@ -32,11 +49,169 @@ CI Status
.. image:: https://ci.appveyor.com/api/projects/status/n9f94dljd03j2lce?svg=true
:target: https://ci.appveyor.com/project/randombit/botan/branch/master
-.. image:: https://botan-ci.kullo.net/badge/build
- :target: https://botan-ci.kullo.net/
+.. image:: https://circleci.com/gh/randombit/botan.svg?style=shield
+ :target: https://circleci.com/gh/randombit/botan
-.. image:: https://botan-ci.kullo.net/badge/tests
+.. image:: https://botan-ci.kullo.net/badge
:target: https://botan-ci.kullo.net/
+.. image:: https://scan.coverity.com/projects/624/badge.svg
+ :target: https://scan.coverity.com/projects/624
+
.. image:: https://coveralls.io/repos/randombit/botan/badge.svg?branch=master
:target: https://coveralls.io/r/randombit/botan?branch=master
+
+Download
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The 1.11 branch is highly recommended, especially for new development.
+But be warned the API is still subject to some change before the 2.0
+stable release.
+
+All releases are signed with a
+`PGP key <http://botan.randombit.net/pgpkey.txt>`_::
+
+ pub 2048R/EFBADFBC 2004-10-30
+ Key fingerprint = 621D AF64 11E1 851C 4CF9 A2E1 6211 EBF1 EFBA DFBC
+ uid Botan Distribution Key
+
+Botan may already be included in your favorite distribution, such as
+`Fedora <https://admin.fedoraproject.org/pkgdb/packages/botan>`_,
+`EPEL <http://dl.fedoraproject.org/pub/epel/7/SRPMS/repoview/botan.html>`_ (for RHEL/CentOS),
+`Debian <http://packages.debian.org/search?keywords=libbotan>`_,
+`Ubuntu <http://packages.ubuntu.com/search?keywords=botan>`_,
+`Gentoo <http://packages.gentoo.org/package/botan>`_,
+`Arch <http://www.archlinux.org/packages/community/x86_64/botan/>`_,
+`Slackbuild <http://slackbuilds.org/result/?search=Botan>`_,
+`FreeBSD ports <http://www.freshports.org/security/botan110>`_, or
+`MacPorts <http://www.macports.org/ports.php?by=name&substr=botan>`_.
+
+Current Development Series (1.11)
+----------------------------------------
+
+A new development release is made on the first Monday of every month.
+
+The latest development release is
+`1.11.19 <http://botan.randombit.net/releases/Botan-1.11.19.tgz>`_
+`(sig) <http://botan.randombit.net/releases/Botan-1.11.19.tgz.asc>`_
+released 2015-08-03
+
+Botan 1.11 requires a working C++11 compiler; GCC 4.8 and later,
+Clang 3.4 and later, and MSVC 2013 are regularly tested.
+
+Current Stable Series (1.10)
+----------------------------------------
+
+The latest stable branch release is
+`1.10.10 <http://botan.randombit.net/releases/Botan-1.10.10.tgz>`_
+`(sig) <http://botan.randombit.net/releases/Botan-1.10.10.tgz.asc>`_
+released 2015-08-03
+
+Botan 1.10 is the last version written in C++98.
+
+Books and other resources
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You should have some knowledge of cryptography *before* trying to use
+the library. This is an area where it is very easy to make mistakes,
+and where things are often subtle and/or counterintuitive. Obviously
+the library tries to provide things at a high level precisely to
+minimize the number of ways things can go wrong, but naive use will
+almost certainly not result in a secure system.
+
+Especially recommended are:
+
+- *Cryptography Engineering*
+ by Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
+
+- *Security Engineering -- A Guide to Building Dependable Distributed Systems*
+ by Ross Anderson
+
+- *Handbook of Applied Cryptography*
+ by Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
+ (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_)
+
+If you're doing something non-trivial or unique, you might want to at
+the very least ask for review/input on a mailing list such as the
+`metzdowd <http://www.metzdowd.com/mailman/listinfo/cryptography>`_ or
+`randombit <http://lists.randombit.net/mailman/listinfo/cryptography>`_
+crypto lists. And (if possible) pay a professional cryptographer or
+security company to review your design and code.
+
+Supported Algorithms/Protocols/RFCs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+TLS/Public Key Infrastructure
+----------------------------------------
+
+* TLS/DTLS (v1.0 to v1.2), including using preshared keys (TLS-PSK)
+ or passwords (TLS-SRP) and most important extensions (including
+ secure renegotiation, session tickets, SNI, and ALPN)
+* X.509 certificates (including generating new self-signed and CA
+ certs) and CRLs
+* PKIX certificate path validation, OCSP requests, PKCS #10 CSRs
+
+Public Key Cryptography
+----------------------------------------
+
+* Encryption algorithms RSA and ElGamal (with OAEP or PKCS #1 v1.5)
+* Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001, Nyberg-Rueppel,
+ Rabin-Williams (with PSS, PKCS #1 v1.5, or X9.31)
+* Diffie-Hellman, ECDH using NIST/Brainpool prime groups, Curve25519
+* McEliece code based encryption providing a KEM scheme
+
+Ciphers and cipher modes
+----------------------------------------
+
+* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, and ChaCha20Poly1305
+* Unauthenticated cipher modes CTR, CBC, XTS, CFB, OFB, and ECB
+* AES (including constant time SSSE3 and AES-NI versions)
+* AES candidates Serpent, Twofish, MARS, CAST-256, RC6
+* Stream ciphers Salsa20/XSalsa20, ChaCha20, and RC4
+* DES, 3DES and DESX
+* National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147
+* Other block ciphers including Threefish-512, Blowfish, CAST-128, IDEA,
+ Noekeon, TEA, XTEA, RC2, RC5, SAFER-SK
+* Large block cipher construction Lion
+
+Hash functions and MACs
+----------------------------------------
+
+* SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
+* SHA-3 winner Keccak-1600
+* SHA-3 candidate Skein-512
+* Authentication codes HMAC, CMAC, Poly1305, SipHash
+* RIPEMD-160, RIPEMD-128, Tiger, Whirlpool
+* Hash function combiners (Parallel and Comb4P)
+* National standard hashes HAS-160 and GOST 34.11
+* Non-cryptographic checksums Adler32, CRC24, CRC32
+* Obsolete algorithms MD5, MD4, MD2, CBC-MAC, X9.19 DES-MAC
+
+Other Useful Things
+----------------------------------------
+
+* Key derivation functions for passwords, including PBKDF2
+* Password hashing functions, including bcrypt
+* General key derivation functions KDF1 and KDF2 from IEEE 1363
+
+Recommended Algorithms
+----------------------------------------
+
+If your application is protecting network traffic, seriously consider
+using TLS v1.2 as a pre built, standard and well studied protocol.
+
+Otherwise, if you simply *must* do something custom, the developers
+currently recommend using:
+
+* Message encryption: AES or Serpent in GCM mode, or ChaCha20Poly1305
+
+* General hash functions: SHA-256 or SHA-384
+
+* Message authentication: HMAC with SHA-256
+
+* Public Key Encryption: RSA, 2048+ bit keys, with OAEP and SHA-256
+
+* Public Key Signatures: RSA, 2048+ bit keys with PSS and SHA-512,
+ or ECDSA with P-256/SHA-256 or P-384/SHA-384
+
+* Key Agreement: ECDH P-256 or Curve25519, with KDF2(SHA-256)
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index c83e3fcd1..5db2ce566 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -1,4 +1,3 @@
-
#ifndef BOTAN_BUILD_CONFIG_H__
#define BOTAN_BUILD_CONFIG_H__
@@ -7,7 +6,7 @@
* %{user}@%{hostname} running '%{command_line}'
*
* Target
-* - Compiler: %{cc} %{lib_opt}
+* - Compiler: %{cxx} %{lib_opt}
* - Arch: %{submodel}/%{arch}
* - OS: %{os}
*/
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt
index 195318291..0fbc67ce9 100644
--- a/src/build-data/cc/clang.txt
+++ b/src/build-data/cc/clang.txt
@@ -2,7 +2,6 @@ macro_name CLANG
binary_name clang++
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
@@ -13,24 +12,34 @@ lang_flags "-std=c++11 -D_REENTRANT -fstack-protector"
warning_flags "-Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wunreachable-code"
maintainer_warning_flags "-Qunused-arguments -Werror -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=unreachable-code"
-makefile_style gmake
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-O3"
+app_opt_flags_release "-O2"
-lib_opt_flags "-O3"
-app_opt_flags "-O2"
shared_flags "-fPIC"
-debug_flags "-g"
-no_debug_flags ""
coverage_flags "--coverage"
visibility_build_flags "-fvisibility=hidden"
visibility_attribute '__attribute__((visibility("default")))'
-<so_link_flags>
+makefile_style gmake
+
+<so_link_commands>
+darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)"
+darwin-debug -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)"
+
# The default works for GNU ld and several other Unix linkers
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
+default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+</so_link_commands>
-darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)"
-</so_link_flags>
+<binary_link_commands>
+linux -> "$(LINKER) -Wl,-rpath=\$$ORIGIN"
+linux-debug -> "$(LINKER) -Wl,-rpath=\$$ORIGIN"
+default -> "$(LINKER)"
+default-debug -> "$(LINKER)"
+</binary_link_commands>
<isa_flags>
sse2 -> "-msse2"
diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt
index b93a67171..a41abc7c4 100644
--- a/src/build-data/cc/ekopath.txt
+++ b/src/build-data/cc/ekopath.txt
@@ -2,27 +2,28 @@ macro_name PATHSCALE
binary_name pathCC
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "-O3 -OPT:Ofast:alias=disjoint"
-app_opt_flags "-O2"
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-O3 -OPT:Ofast:alias=disjoint"
+app_opt_flags_release "-O2"
+
lang_flags "-D_REENTRANT -ansi -Wno-long-long"
warning_flags "-W -Wall"
ar_command "pathCC -ar -o"
shared_flags "-fPIC"
-debug_flags -g
makefile_style gmake
-<so_link_flags>
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
-</so_link_flags>
+<so_link_commands>
+default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+</so_link_commands>
<mach_opt>
athlon -> "-mcpu=athlon"
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index 1e1eb2fb9..877ce4d58 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -2,7 +2,6 @@ macro_name GCC
binary_name g++
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
@@ -12,30 +11,44 @@ lang_flags "-std=c++11 -D_REENTRANT"
maintainer_warning_flags "-Wold-style-cast -Werror -Wno-error=old-style-cast -Wno-error=zero-as-null-pointer-constant -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=strict-overflow"
warning_flags "-Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wzero-as-null-pointer-constant"
-lib_opt_flags "-O2"
-app_opt_flags "-O2"
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-O2"
+lib_opt_flags_debug "-O0"
+app_opt_flags_release "-O2"
+app_opt_flags_debug "-O0"
+
shared_flags "-fPIC"
-debug_flags "-g"
coverage_flags "--coverage"
+#sanitizer_flags "-D_GLIBCXX_DEBUG -fsanitize=address -fsanitize=undefined"
+sanitizer_flags "-D_GLIBCXX_DEBUG -fsanitize=address"
visibility_build_flags "-fvisibility=hidden"
visibility_attribute '__attribute__((visibility("default")))'
makefile_style gmake
-<so_link_flags>
+<so_link_commands>
# The default works for GNU ld and several other Unix linkers
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
+default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+default-debug -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
# Darwin, HP-UX and Solaris linkers use different syntax
-darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)"
-hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)"
-solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)"
+darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)"
+hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME_ABI)"
+solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME_ABI)"
# AIX and OpenBSD don't use sonames at all
aix -> "$(CXX) -shared -fPIC"
openbsd -> "$(CXX) -shared -fPIC"
-</so_link_flags>
+</so_link_commands>
+
+<binary_link_commands>
+linux -> "$(LINKER) -Wl,-rpath=\$$ORIGIN"
+linux-debug -> "$(LINKER) -Wl,-rpath=\$$ORIGIN"
+default -> "$(LINKER)"
+default-debug -> "$(LINKER)"
+</binary_link_commands>
<isa_flags>
sse2 -> "-msse2"
diff --git a/src/build-data/cc/hpcc.txt b/src/build-data/cc/hpcc.txt
index e6008abad..2e30995f6 100644
--- a/src/build-data/cc/hpcc.txt
+++ b/src/build-data/cc/hpcc.txt
@@ -2,16 +2,16 @@ macro_name HP_ACC
binary_name aCC
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "+O2"
-app_opt_flags "+O2"
-debug_flags -g
-no_debug_flags ""
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "+O2"
+app_opt_flags_release "+O2"
+
lang_flags "-AA -ext +eh -z"
warning_flags "" # +w
shared_flags "+Z"
@@ -24,6 +24,6 @@ hppa1.1 -> "+DA1.1"
hppa2.0 -> "+DA2.0W"
</mach_abi_linking>
-<so_link_flags>
-default -> "$(CXX) +Z -b -Wl,+h,$(SONAME)" # Documented in cc(1), but not CC(1) (?)
-</so_link_flags>
+<so_link_commands>
+default -> "$(CXX) +Z -b -Wl,+h,$(SONAME_ABI)" # Documented in cc(1), but not CC(1) (?)
+</so_link_commands>
diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt
index df447967c..f7fdf72be 100644
--- a/src/build-data/cc/icc.txt
+++ b/src/build-data/cc/icc.txt
@@ -2,16 +2,16 @@ macro_name INTEL
binary_name icpc
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "-O2 -ip -unroll"
-app_opt_flags "-O2"
-debug_flags -g
-no_debug_flags "-fomit-frame-pointer"
+compile_flags_release "-c -fomit-frame-pointer"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-O2 -ip -unroll"
+app_opt_flags_release "-O2"
+
lang_flags "-std=c++0x"
warning_flags "-w1"
shared_flags "-fPIC"
@@ -29,6 +29,6 @@ nehalem -> "-march=core2"
westmere -> "-march=core2"
</mach_opt>
-<so_link_flags>
-default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME)"
-</so_link_flags>
+<so_link_commands>
+default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME_ABI)"
+</so_link_commands>
diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt
index 4529893ac..7a35f9648 100644
--- a/src/build-data/cc/msvc.txt
+++ b/src/build-data/cc/msvc.txt
@@ -1,16 +1,18 @@
macro_name MSVC
binary_name cl
+linker_name link
-compile_option "/nologo /c "
output_to_option "/Fo"
add_include_dir_option "/I"
add_lib_dir_option -L
add_lib_option ""
-no_debug_flags "/O2"
-debug_flags "/Od /Zi /DDEBUG"
-app_opt_flags "/D_CONSOLE"
+compile_flags_release "/nologo /c /bigobj /O2"
+compile_flags_debug "/nologo /c /bigobj /Od /Zi /FS /DEBUG"
+app_opt_flags_release "/D_CONSOLE"
+app_opt_flags_debug "/D_CONSOLE"
+
lang_flags "/EHs /GR"
warning_flags "/W3 /wd4275 /wd4267"
@@ -33,9 +35,15 @@ clmul -> ""
rdrand -> ""
</isa_flags>
-<so_link_flags>
-default -> "$(CXX) /LD"
-</so_link_flags>
+<so_link_commands>
+default -> "$(LINKER) /DLL"
+default-debug -> "$(LINKER) /DLL /DEBUG"
+</so_link_commands>
+
+<binary_link_commands>
+default -> "$(LINKER)"
+default-debug -> "$(LINKER) /DEBUG"
+</binary_link_commands>
<mach_abi_linking>
all -> "/MD"
diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt
index 032bbe72f..ca4b49cd9 100644
--- a/src/build-data/cc/pgi.txt
+++ b/src/build-data/cc/pgi.txt
@@ -2,22 +2,23 @@ macro_name PORTLAND_GROUP
binary_name pgCC
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "-fast -Minline"
-app_opt_flags "-fast"
+compile_flags_release "-c"
+compile_flags_debug "-c"
+lib_opt_flags_release "-fast -Minline"
+app_opt_flags_release "-fast"
shared_flags "-fPIC"
makefile_style gmake
-<so_link_flags>
-linux -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
-solaris -> "$(CXX) -G -fPIC -Wl,-h,$(SONAME)"
-</so_link_flags>
+<so_link_commands>
+linux -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+solaris -> "$(CXX) -G -fPIC -Wl,-h,$(SONAME_ABI)"
+</so_link_commands>
<mach_opt>
i586 -> "-tp p5"
diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt
index cf29b9687..964c878ff 100644
--- a/src/build-data/cc/sunstudio.txt
+++ b/src/build-data/cc/sunstudio.txt
@@ -2,16 +2,16 @@ macro_name SUN_STUDIO
binary_name CC
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "-xO5"
-app_opt_flags "-xO2"
-debug_flags -g
-no_debug_flags ""
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-xO5"
+app_opt_flags_release "-xO2"
+
shared_flags "-KPIC"
warning_flags "+w -erroff=truncwarn,wnoretvalue"
lang_flags "+p -features=extensions -D__FUNCTION__=__func__"
@@ -20,9 +20,9 @@ ar_command "CC -xar -o"
makefile_style gmake
-<so_link_flags>
-default -> "$(CXX) -G -h$(SONAME)"
-</so_link_flags>
+<so_link_commands>
+default -> "$(CXX) -G -h$(SONAME_ABI)"
+</so_link_commands>
<mach_opt>
i386 -> "-xtarget=486"
diff --git a/src/build-data/cc/xlc.txt b/src/build-data/cc/xlc.txt
index bfa67f40f..68dc62582 100644
--- a/src/build-data/cc/xlc.txt
+++ b/src/build-data/cc/xlc.txt
@@ -2,17 +2,17 @@ macro_name IBM_XLC
binary_name xlC
-compile_option "-c "
output_to_option "-o "
add_include_dir_option -I
add_lib_dir_option -L
add_lib_option -l
-lib_opt_flags "-O2"
-app_opt_flags "-O2"
+compile_flags_release "-c"
+compile_flags_debug "-c -g"
+lib_opt_flags_release "-O2"
+app_opt_flags_release "-O2"
+
lang_flags ""
-debug_flags -g
-no_debug_flags ""
makefile_style gmake
@@ -23,6 +23,6 @@ power4 -> "-qarch=pwr4"
power5 -> "-qarch=pwr5"
</mach_opt>
-<so_link_flags>
+<so_link_commands>
default -> "$(CXX) -qmkshrobj"
-</so_link_flags>
+</so_link_commands>
diff --git a/src/build-data/makefile/gmake.in b/src/build-data/makefile/gmake.in
index 6b22a26f3..c6ef73854 100644
--- a/src/build-data/makefile/gmake.in
+++ b/src/build-data/makefile/gmake.in
@@ -47,16 +47,13 @@ $(STATIC_LIB): $(LIBOBJS)
$(RANLIB) $(STATIC_LIB)
# Fake targets
-.PHONY = clean distclean docs website install valgrind lcov
+.PHONY = clean distclean docs install valgrind lcov
%{gmake_coverage_in}
SPHINX_CONFIG = %{sphinx_config_dir}
SPHINX_OPTS = -b html
-WEBSITE_DIR=%{doc_output_dir}/website
-WEBSITE_SRC_DIR=%{doc_output_dir}/website-src
-
clean:
-$(RM) %{libobj_dir}/*
-$(RM) %{testobj_dir}/*
@@ -77,17 +74,3 @@ docs:
install: $(APP) docs
$(SCRIPTS_DIR)/install.py --destdir=%{destdir} --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}
-
-website:
- rm -rf $(WEBSITE_SRC_DIR) $(WEBSITE_DIR)
- mkdir -p $(WEBSITE_SRC_DIR)
- cp -r %{doc_dir}/*.txt %{doc_dir}/*.rst %{doc_dir}/relnotes %{doc_dir}/website/*.rst $(WEBSITE_SRC_DIR)
- ./src/scripts/combine_relnotes.py %{doc_dir}/relnotes > $(WEBSITE_SRC_DIR)/news.rst
- sphinx-build -c $(SPHINX_CONFIG) -b html $(WEBSITE_SRC_DIR) $(WEBSITE_DIR)
- sphinx-build -c $(SPHINX_CONFIG) -b html %{doc_dir}/manual $(WEBSITE_DIR)/manual
- rm -rf $(WEBSITE_DIR)/.doctrees
- rm -rf $(WEBSITE_DIR)/manual/.doctrees
- rm -f $(WEBSITE_DIR)/.buildinfo
- rm -f $(WEBSITE_DIR)/manual/.buildinfo
- doxygen %{build_dir}/botan.doxy
- mv %{doc_output_dir}/doxygen $(WEBSITE_DIR)/doxygen
diff --git a/src/build-data/makefile/gmake_dso.in b/src/build-data/makefile/gmake_dso.in
index 0e7974791..fa167b780 100644
--- a/src/build-data/makefile/gmake_dso.in
+++ b/src/build-data/makefile/gmake_dso.in
@@ -1,12 +1,12 @@
-SHARED_LIB_NAME = $(LIB_BASENAME).%{so_suffix}.%{so_abi_rev}.%{version_patch}
-SONAME = $(LIB_BASENAME).%{so_suffix}.%{so_abi_rev}
-SYMLINK = $(LIB_BASENAME).%{so_suffix}
+SONAME_PATCH = %{soname_patch}
+SONAME_ABI = %{soname_abi}
+SONAME_BASE = %{soname_base}
-SHARED_LIB = %{out_dir}/$(SHARED_LIB_NAME)
+SHARED_LIB = %{out_dir}/$(SONAME_PATCH)
$(SHARED_LIB): $(LIBOBJS)
$(LIB_LINK_CMD) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) -o $(SHARED_LIB)
- $(LN) $(SHARED_LIB_NAME) %{out_dir}/$(SONAME)
- $(LN) $(SHARED_LIB_NAME) %{out_dir}/$(SYMLINK)
+ $(LN) $(SONAME_PATCH) %{out_dir}/$(SONAME_ABI)
+ $(LN) $(SONAME_PATCH) %{out_dir}/$(SONAME_BASE)
LIBRARIES += $(SHARED_LIB)
diff --git a/src/build-data/makefile/header.in b/src/build-data/makefile/header.in
index b0e248ebe..a83184bb8 100644
--- a/src/build-data/makefile/header.in
+++ b/src/build-data/makefile/header.in
@@ -1,5 +1,6 @@
# Compiler Options
-CXX = %{cc}
+CXX = %{cxx}
+LINKER = %{linker}
LIB_OPT = %{lib_opt}
APP_OPT = %{app_opt}
LANG_FLAGS = %{lang_flags}
diff --git a/src/build-data/makefile/nmake.in b/src/build-data/makefile/nmake.in
index 9445063d9..88188071b 100644
--- a/src/build-data/makefile/nmake.in
+++ b/src/build-data/makefile/nmake.in
@@ -18,10 +18,21 @@ APP = %{out_dir}\botan%{program_suffix}
TEST = %{out_dir}\botan-test%{program_suffix}
# Library targets
-# LIB_FILENAME is either a static lib or the DLL
+#
+# LIB_FILENAME is always the .lib file, that is either a static lib or a
+# by-product of the DLL creation used to link the DLL into applications
LIB_BASENAME = %{libname}
-LIB_FILENAME = %{out_dir}\$(LIB_BASENAME).%{static_suffix}
+LIB_FILENAME = %{out_dir}\$(LIB_BASENAME).lib
+
+!If "$(SO_OBJ_FLAGS)" == ""
+# static lib
LIBRARIES = $(LIB_FILENAME)
+!Else
+# shared lib
+SO_FILENAME = %{out_dir}\$(LIB_BASENAME).dll
+LIBRARIES = $(SO_FILENAME)
+!Endif
+
# File Lists
LIBOBJS = %{lib_objs}
@@ -42,18 +53,22 @@ all: $(APP) $(TEST)
# Link Commands
$(APP): $(LIBRARIES) $(APPOBJS)
- $(APP_LINK_CMD) /Fe$@ $(APPOBJS) $(LIB_FILENAME) $(APP_LINKS_TO)
+ $(APP_LINK_CMD) /OUT:$@ $(APPOBJS) $(LIB_FILENAME) $(APP_LINKS_TO)
$(APP_POST_LINK_CMD)
$(TEST): $(LIBRARIES) $(TESTOBJS)
- $(TEST_LINK_CMD) /Fe$@ $(TESTOBJS) $(LIB_FILENAME) $(TEST_LINKS_TO)
+ $(TEST_LINK_CMD) /OUT:$@ $(TESTOBJS) $(LIB_FILENAME) $(TEST_LINKS_TO)
$(TEST_POST_LINK_CMD)
-$(LIB_FILENAME): $(LIBOBJS)
!If "$(SO_OBJ_FLAGS)" == ""
- $(AR) /OUT:$(LIB_FILENAME) $(LIBOBJS)
+# static lib
+$(LIB_FILENAME): $(LIBOBJS)
+ $(AR) /OUT:$@ $(LIBOBJS)
!Else
- $(LIB_LINK_CMD) /Fe%{out_dir}\$(LIB_BASENAME) $(LIBOBJS) $(LIB_LINKS_TO)
+# shared lib
+# Creates the DLL $(SO_FILENAME) and the .lib $(LIB_FILENAME)
+$(SO_FILENAME): $(LIBOBJS)
+ $(LIB_LINK_CMD) /OUT:$@ $(LIBOBJS) $(LIB_LINKS_TO)
!Endif
# Fake Targets
diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in
deleted file mode 100644
index f6e49ee75..000000000
--- a/src/build-data/makefile/python.in
+++ /dev/null
@@ -1,26 +0,0 @@
-
-# Build commands for Python wrapper
-PYTHON_ROOT = /usr/lib/python%{python_version}/config
-PYTHON_INC = -I/usr/include/python%{python_version}
-PYTHON_SITE_PACKAGE_DIR = /usr/lib/python%{python_version}/site-packages/
-
-PYTHON_FLAGS = -I%{python_dir} -fPIC -ftemplate-depth-255 $(WARN_FLAGS) $(PYTHON_INC) $(CFLAGS)
-
-BOTAN_PYTHON_MODDIR = %{python_obj_dir}
-
-PYTHON_OBJS = %{python_objs}
-
-python: $(BOTAN_PYTHON_MODDIR)/_botan.so
-
-PYTHON_FLAGS = $(LANG_FLAGS) $(WARN_FLAGS) $(SO_OBJ_FLAGS) -Os -ftemplate-depth=255 $(PYTHON_INC) -Wno-error
-
-%{python_build_cmds}
-
-$(BOTAN_PYTHON_MODDIR)/_botan.so: $(PYTHON_OBJS)
- cp %{python_dir}/*.py $(BOTAN_PYTHON_MODDIR)
- $(CXX) -shared -Wl,-soname,$@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) $(LDFLAGS) -lbotan-$(BRANCH) -lboost_python-%{python_version} -o $@
-
-install_python:
- mkdir -p $(PYTHON_SITE_PACKAGE_DIR)/botan
- cp $(BOTAN_PYTHON_MODDIR)/_botan.so $(BOTAN_PYTHON_MODDIR)/*.py $(PYTHON_SITE_PACKAGE_DIR)/botan
- chmod -R u=rwX,go=rX $(PYTHON_SITE_PACKAGE_DIR)/botan
diff --git a/src/build-data/os/aix.txt b/src/build-data/os/aix.txt
index 369b720c4..546fbf9ad 100644
--- a/src/build-data/os/aix.txt
+++ b/src/build-data/os/aix.txt
@@ -2,4 +2,5 @@ os_type unix
<target_features>
gettimeofday
+getsid
</target_features>
diff --git a/src/build-data/os/android.txt b/src/build-data/os/android.txt
new file mode 100644
index 000000000..43e5fdc44
--- /dev/null
+++ b/src/build-data/os/android.txt
@@ -0,0 +1,14 @@
+os_type unix
+
+soname_pattern_base "libbotan-{version_major}.{version_minor}.so"
+soname_pattern_abi "libbotan-{version_major}.{version_minor}.so.{abi_rev}"
+soname_pattern_patch "libbotan-{version_major}.{version_minor}.so.{abi_rev}.{version_patch}"
+
+<target_features>
+clock_gettime
+gettimeofday
+posix_mlock
+gmtime_r
+dlopen
+readdir
+</target_features>
diff --git a/src/build-data/os/cygwin.txt b/src/build-data/os/cygwin.txt
index bedb10732..be67e2607 100644
--- a/src/build-data/os/cygwin.txt
+++ b/src/build-data/os/cygwin.txt
@@ -12,4 +12,6 @@ doc_dir docs
<target_features>
gettimeofday
+getsid
+timegm
</target_features>
diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt
index b33548e1a..56285ccf7 100644
--- a/src/build-data/os/darwin.txt
+++ b/src/build-data/os/darwin.txt
@@ -1,6 +1,8 @@
os_type unix
-so_suffix dylib
+soname_pattern_base "libbotan-{version_major}.{version_minor}.dylib"
+soname_pattern_abi "libbotan-{version_major}.{version_minor}.{abi_rev}.dylib"
+soname_pattern_patch "libbotan-{version_major}.{version_minor}.{abi_rev}.{version_patch}.dylib"
# It doesn't have the 's' option; you need to use needs ranlib
ar_command "ar cr"
@@ -14,6 +16,8 @@ gettimeofday
gmtime_r
memset_s
readdir
+getsid
+timegm
</target_features>
<aliases>
diff --git a/src/build-data/os/freebsd.txt b/src/build-data/os/freebsd.txt
index 5df133c8e..32767cb1f 100644
--- a/src/build-data/os/freebsd.txt
+++ b/src/build-data/os/freebsd.txt
@@ -7,4 +7,6 @@ posix_mlock
gmtime_r
dlopen
readdir
+getsid
+timegm
</target_features>
diff --git a/src/build-data/os/haiku.txt b/src/build-data/os/haiku.txt
index 8e35e76eb..981ce6795 100644
--- a/src/build-data/os/haiku.txt
+++ b/src/build-data/os/haiku.txt
@@ -8,6 +8,7 @@ doc_dir system/documentation
<target_features>
gettimeofday
gmtime_r
+getsid
</target_features>
<aliases>
diff --git a/src/build-data/os/hpux.txt b/src/build-data/os/hpux.txt
index 19c230d77..726b0b960 100644
--- a/src/build-data/os/hpux.txt
+++ b/src/build-data/os/hpux.txt
@@ -1,9 +1,8 @@
os_type unix
-so_suffix sl
-
<target_features>
gettimeofday
+getsid
</target_features>
<aliases>
diff --git a/src/build-data/os/irix.txt b/src/build-data/os/irix.txt
index 369b720c4..546fbf9ad 100644
--- a/src/build-data/os/irix.txt
+++ b/src/build-data/os/irix.txt
@@ -2,4 +2,5 @@ os_type unix
<target_features>
gettimeofday
+getsid
</target_features>
diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt
index 9061b31d8..c83e57afa 100644
--- a/src/build-data/os/linux.txt
+++ b/src/build-data/os/linux.txt
@@ -1,5 +1,9 @@
os_type unix
+soname_pattern_base "libbotan-{version_major}.{version_minor}.so"
+soname_pattern_abi "libbotan-{version_major}.{version_minor}.so.{abi_rev}"
+soname_pattern_patch "libbotan-{version_major}.{version_minor}.so.{abi_rev}.{version_patch}"
+
<target_features>
clock_gettime
gettimeofday
@@ -7,6 +11,8 @@ posix_mlock
gmtime_r
dlopen
readdir
+getsid
+timegm
</target_features>
<aliases>
diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt
index 4f3e7f08b..a2ba363f2 100644
--- a/src/build-data/os/mingw.txt
+++ b/src/build-data/os/mingw.txt
@@ -2,9 +2,12 @@ os_type windows
program_suffix .exe
obj_suffix o
-so_suffix dll
static_suffix a
+soname_pattern_base "libbotan-{version_major}.{version_minor}.dll"
+soname_pattern_abi "libbotan-{version_major}.{version_minor}.dll.{abi_rev}"
+soname_pattern_patch "libbotan-{version_major}.{version_minor}.dll.{abi_rev}.{version_patch}"
+
build_shared no
ar_command "ar crs"
@@ -23,6 +26,7 @@ mingw32
<target_features>
cryptgenrandom
loadlibrary
+mkgmtime
win32_virtual_lock
win32_get_systemtime
</target_features>
diff --git a/src/build-data/os/netbsd.txt b/src/build-data/os/netbsd.txt
index 5df133c8e..32767cb1f 100644
--- a/src/build-data/os/netbsd.txt
+++ b/src/build-data/os/netbsd.txt
@@ -7,4 +7,6 @@ posix_mlock
gmtime_r
dlopen
readdir
+getsid
+timegm
</target_features>
diff --git a/src/build-data/os/openbsd.txt b/src/build-data/os/openbsd.txt
index 5df133c8e..510a7accd 100644
--- a/src/build-data/os/openbsd.txt
+++ b/src/build-data/os/openbsd.txt
@@ -7,4 +7,5 @@ posix_mlock
gmtime_r
dlopen
readdir
+timegm
</target_features>
diff --git a/src/build-data/os/qnx.txt b/src/build-data/os/qnx.txt
index 4c0965764..71c85eb3c 100644
--- a/src/build-data/os/qnx.txt
+++ b/src/build-data/os/qnx.txt
@@ -6,4 +6,5 @@ gettimeofday
posix_mlock
gmtime_r
dlopen
+getsid
</target_features>
diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt
index 0ed785036..52749e397 100644
--- a/src/build-data/os/solaris.txt
+++ b/src/build-data/os/solaris.txt
@@ -6,6 +6,7 @@ install_cmd_exec '/usr/ucb/install -m 755'
<target_features>
posix_mlock
gettimeofday
+getsid
</target_features>
<aliases>
diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt
index b72ef0768..32236e00b 100644
--- a/src/build-data/os/windows.txt
+++ b/src/build-data/os/windows.txt
@@ -2,9 +2,10 @@ os_type windows
program_suffix .exe
obj_suffix obj
-so_suffix dll
static_suffix lib
+soname_pattern_base "botan.dll"
+
install_root c:\\Botan
doc_dir docs
@@ -15,9 +16,11 @@ install_cmd_exec "copy"
cryptgenrandom
gmtime_s
loadlibrary
+mkgmtime
query_perf_counter
virtual_lock
rtlsecurezeromemory
+stl_filesystem_msvc
</target_features>
<aliases>
diff --git a/src/build-data/sphinx/conf.py b/src/build-data/sphinx/conf.py
index 29a1c1fe7..f506b461a 100644
--- a/src/build-data/sphinx/conf.py
+++ b/src/build-data/sphinx/conf.py
@@ -35,7 +35,6 @@ if is_website_build and use_disqus:
files_dir = 'http://botan.randombit.net/releases'
extlinks = {
- 'pr': ('http://bugs.randombit.net/show_bug.cgi?id=%s', 'PR '),
'wikipedia': ('https://en.wikipedia.org/wiki/%s', ''),
'botan-devel': ('http://lists.randombit.net/pipermail/botan-devel/%s.html', None),
@@ -113,8 +112,8 @@ html_theme_options = {
'headercolor1': 'darkblue',
'headercolor2': 'darkblue',
'textalign': 'left',
- 'pagewidth': '80em',
- 'documentwidth': '60em'
+ 'pagewidth': '70em',
+ 'documentwidth': '50em'
}
# Add any paths that contain custom themes here, relative to this directory.
diff --git a/src/cmd/apps.h b/src/cmd/apps.h
index 8e8e48742..bcb860fb4 100644
--- a/src/cmd/apps.h
+++ b/src/cmd/apps.h
@@ -8,6 +8,7 @@
#include <functional>
#include <string>
#include <set>
+#include <botan/build.h>
#include <botan/hex.h>
#include <botan/auto_rng.h>
#include "getopt.h"
diff --git a/src/cmd/asn1.cpp b/src/cmd/asn1.cpp
index f5b6b6b4e..7264c1a6d 100644
--- a/src/cmd/asn1.cpp
+++ b/src/cmd/asn1.cpp
@@ -6,6 +6,8 @@
#include "apps.h"
+#if defined(BOTAN_HAS_ASN1) && defined(BOTAN_HAS_PEM_CODEC)
+
#include <botan/bigint.h>
#include <botan/hex.h>
#include <botan/der_enc.h>
@@ -350,3 +352,5 @@ int asn1(int argc, char* argv[])
REGISTER_APP(asn1);
}
+
+#endif // BOTAN_HAS_ASN1 && BOTAN_HAS_PEM_CODEC
diff --git a/src/cmd/base64.cpp b/src/cmd/base64.cpp
index 84a30e8ea..d9b2ffa3d 100644
--- a/src/cmd/base64.cpp
+++ b/src/cmd/base64.cpp
@@ -6,6 +6,9 @@
*/
#include "apps.h"
+
+#if defined(BOTAN_HAS_CODEC_FILTERS)
+
#include <fstream>
#include <iostream>
#include <string>
@@ -88,3 +91,4 @@ int base64(int argc, char* argv[])
REGISTER_APP(base64);
}
+#endif // BOTAN_HAS_CODEC_FILTERS
diff --git a/src/cmd/bcrypt.cpp b/src/cmd/bcrypt.cpp
index 498e8f8fd..3cf5f7516 100644
--- a/src/cmd/bcrypt.cpp
+++ b/src/cmd/bcrypt.cpp
@@ -7,6 +7,7 @@
#include "apps.h"
#if defined(BOTAN_HAS_BCRYPT)
+
#include <botan/bcrypt.h>
namespace {
diff --git a/src/cmd/ca.cpp b/src/cmd/ca.cpp
index b32f07f51..3b67d40fb 100644
--- a/src/cmd/ca.cpp
+++ b/src/cmd/ca.cpp
@@ -7,7 +7,9 @@
#include "apps.h"
#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
#include <botan/x509_ca.h>
+#include <botan/pkcs8.h>
namespace {
diff --git a/src/cmd/cert_verify.cpp b/src/cmd/cert_verify.cpp
index feff40141..15cd5b8f8 100644
--- a/src/cmd/cert_verify.cpp
+++ b/src/cmd/cert_verify.cpp
@@ -45,8 +45,8 @@ int cert_verify(int argc, char* argv[])
return 0;
}
-}
-
REGISTER_APP(cert_verify);
-#endif
+}
+
+#endif // BOTAN_HAS_X509_CERTIFICATES
diff --git a/src/cmd/compress.cpp b/src/cmd/compress.cpp
index 35f74f8af..c9168f3df 100644
--- a/src/cmd/compress.cpp
+++ b/src/cmd/compress.cpp
@@ -6,6 +6,8 @@
#include "apps.h"
+#if defined(BOTAN_HAS_COMPRESSION)
+
#include <botan/compression.h>
#include <fstream>
@@ -120,3 +122,5 @@ REGISTER_APP(compress);
REGISTER_APP(uncompress);
}
+
+#endif // BOTAN_HAS_COMPRESSION
diff --git a/src/cmd/credentials.h b/src/cmd/credentials.h
index afd83420b..f7109e1a3 100644
--- a/src/cmd/credentials.h
+++ b/src/cmd/credentials.h
@@ -7,6 +7,7 @@
#ifndef EXAMPLE_CREDENTIALS_MANAGER_H__
#define EXAMPLE_CREDENTIALS_MANAGER_H__
+#include <botan/pkcs8.h>
#include <botan/credentials_manager.h>
#include <botan/x509self.h>
#include <botan/rsa.h>
@@ -82,7 +83,7 @@ class Basic_Credentials_Manager : public Credentials_Manager
std::vector<Botan::Certificate_Store*>
trusted_certificate_authorities(const std::string& type,
- const std::string& /*hostname*/)
+ const std::string& /*hostname*/) override
{
std::vector<Botan::Certificate_Store*> v;
@@ -99,7 +100,7 @@ class Basic_Credentials_Manager : public Credentials_Manager
void verify_certificate_chain(
const std::string& type,
const std::string& purported_hostname,
- const std::vector<X509_Certificate>& cert_chain)
+ const std::vector<X509_Certificate>& cert_chain) override
{
try
{
@@ -117,7 +118,7 @@ class Basic_Credentials_Manager : public Credentials_Manager
std::vector<X509_Certificate> cert_chain(
const std::vector<std::string>& algos,
const std::string& type,
- const std::string& hostname)
+ const std::string& hostname) override
{
BOTAN_UNUSED(type);
@@ -137,7 +138,7 @@ class Basic_Credentials_Manager : public Credentials_Manager
Private_Key* private_key_for(const X509_Certificate& cert,
const std::string& /*type*/,
- const std::string& /*context*/)
+ const std::string& /*context*/) override
{
for(auto&& i : m_creds)
{
diff --git a/src/cmd/dsa_sign.cpp b/src/cmd/dsa_sign.cpp
index 8a7365329..25ad6f9de 100644
--- a/src/cmd/dsa_sign.cpp
+++ b/src/cmd/dsa_sign.cpp
@@ -10,6 +10,7 @@
#include <botan/dsa.h>
#include <botan/pubkey.h>
+#include <botan/pkcs8.h>
#include <botan/base64.h>
#include <fstream>
diff --git a/src/cmd/factor.cpp b/src/cmd/factor.cpp
index e4e20f5b7..5ea53478d 100644
--- a/src/cmd/factor.cpp
+++ b/src/cmd/factor.cpp
@@ -9,6 +9,8 @@
#include "apps.h"
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
#include <botan/reducer.h>
#include <botan/numthry.h>
@@ -154,3 +156,5 @@ int factor(int argc, char* argv[])
REGISTER_APP(factor);
}
+
+#endif // BOTAN_HAS_NUMBERTHEORY
diff --git a/src/cmd/fpe.cpp b/src/cmd/fpe.cpp
index 579586eaf..a9da9dcb7 100644
--- a/src/cmd/fpe.cpp
+++ b/src/cmd/fpe.cpp
@@ -6,7 +6,7 @@
#include "apps.h"
-#if defined(BOTAN_HAS_FPE_FE1)
+#if defined(BOTAN_HAS_FPE_FE1) && defined(BOTAN_HAS_SHA1)
#include <botan/fpe_fe1.h>
#include <botan/sha160.h>
@@ -151,5 +151,4 @@ REGISTER_APP(fpe);
}
-#endif
-
+#endif // BOTAN_HAS_FPE_FE1 && BOTAN_HAS_SHA1
diff --git a/src/cmd/fuzzer.cpp b/src/cmd/fuzzer.cpp
new file mode 100644
index 000000000..3174c76b8
--- /dev/null
+++ b/src/cmd/fuzzer.cpp
@@ -0,0 +1,141 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "apps.h"
+#include <fstream>
+#include <botan/auto_rng.h>
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+#include <botan/x509cert.h>
+#include <botan/x509_crl.h>
+#include <botan/pkcs8.h>
+#endif
+
+#if defined(BOTAN_HAS_TLS)
+#include <botan/tls_client.h>
+#endif
+
+namespace {
+
+#if defined(BOTAN_HAS_TLS)
+
+class Fuzzer_Creds : public Credentials_Manager
+ {
+ public:
+ void verify_certificate_chain(const std::string& type,
+ const std::string& purported_hostname,
+ const std::vector<X509_Certificate>& cert_chain) override
+ {
+ try
+ {
+ Credentials_Manager::verify_certificate_chain(type,
+ purported_hostname,
+ cert_chain);
+ }
+ catch(std::exception& e) {}
+ }
+
+ std::string psk_identity_hint(const std::string&, const std::string&) override { return "psk_hint"; }
+ std::string psk_identity(const std::string&, const std::string&, const std::string&) override { return "psk_id"; }
+ SymmetricKey psk(const std::string&, const std::string&, const std::string&) override
+ {
+ return SymmetricKey("AABBCCDDEEFF00112233445566778899");
+ }
+ };
+
+#endif
+
+int fuzzer(int argc, char* argv[])
+ {
+ if(argc != 3)
+ {
+ std::cout << "Usage: " << argv[0] << " [type] [input_file]\n";
+ std::cout << "Hook for fuzzers such as afl (produces no output)\n";
+ std::cout << "Types: cert crl privkey tls_client\n";
+ return 1;
+ }
+
+ const std::string type = argv[1];
+ const std::string input = argv[2];
+
+ AutoSeeded_RNG rng;
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+ if(type == "cert")
+ {
+ X509_Certificate cert(input);
+ return 0;
+ }
+
+ if(type == "crl")
+ {
+ X509_CRL crl(input);
+ return 0;
+ }
+
+ if(type == "privkey")
+ {
+ std::unique_ptr<Private_Key>(PKCS8::load_key(input, rng));
+ return 0;
+ }
+
+#endif
+
+#if defined(BOTAN_HAS_TLS)
+ if(type == "tls_client")
+ {
+ auto dev_null = [](const byte[], size_t) {};
+
+ auto ignore_alerts = [](TLS::Alert, const byte[], size_t) {};
+ auto ignore_hs = [](const TLS::Session&) { return true; };
+
+ TLS::Session_Manager_In_Memory session_manager(rng);
+ TLS::Policy policy;
+ TLS::Protocol_Version client_offer = TLS::Protocol_Version::TLS_V12;
+ TLS::Server_Information info("server.name", 443);
+ const std::vector<std::string> protocols_to_offer = { "fuzz/1.0", "http/1.1", "bunny/1.21.3" };
+ Fuzzer_Creds creds;
+
+ TLS::Client client(dev_null,
+ dev_null,
+ ignore_alerts,
+ ignore_hs,
+ session_manager,
+ creds,
+ policy,
+ rng,
+ info,
+ client_offer,
+ protocols_to_offer);
+
+ std::ifstream in(input.c_str());
+
+ std::vector<byte> buf(1024);
+
+ try
+ {
+ while(in.good())
+ {
+ in.read((char*)&buf[0], buf.size());
+ size_t got = in.gcount();
+ client.received_data(&buf[0], got);
+ }
+ }
+ catch(std::exception& e)
+ {
+ return 0;
+ }
+ return 0;
+ }
+#endif
+
+ std::cout << "Unknown type '" << type << "'\n";
+ return 1;
+ }
+
+REGISTER_APP(fuzzer);
+
+}
diff --git a/src/cmd/hash.cpp b/src/cmd/hash.cpp
index dd5bc1e82..fdeaa465d 100644
--- a/src/cmd/hash.cpp
+++ b/src/cmd/hash.cpp
@@ -5,6 +5,9 @@
*/
#include "apps.h"
+
+#if defined(BOTAN_HAS_CODEC_FILTERS)
+
#include <botan/lookup.h>
#include <botan/filters.h>
#include <iostream>
@@ -57,3 +60,5 @@ int hash(int argc, char* argv[])
REGISTER_APP(hash);
}
+
+#endif // BOTAN_HAS_CODEC_FILTERS
diff --git a/src/cmd/implementation/speed.h b/src/cmd/implementation/speed.h
new file mode 100644
index 000000000..1f082eb52
--- /dev/null
+++ b/src/cmd/implementation/speed.h
@@ -0,0 +1,28 @@
+/*
+* (C) 2014 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_CHECK_BENCHMARK_H__
+#define BOTAN_CHECK_BENCHMARK_H__
+
+#include <botan/rng.h>
+#include <string>
+#include <chrono>
+
+void benchmark_public_key(Botan::RandomNumberGenerator& rng,
+ const std::string& algo, double seconds);
+
+std::map<std::string, double> benchmark_is_prime(Botan::RandomNumberGenerator &rng,
+ const std::chrono::milliseconds runtime);
+
+std::map<std::string, double> benchmark_random_prime(Botan::RandomNumberGenerator &rng,
+ const std::chrono::milliseconds runtime);
+
+bool benchmark_transform(Botan::RandomNumberGenerator& rng, const std::string& algo_name,
+ const std::chrono::milliseconds runtime);
+
+
+#endif
diff --git a/src/cmd/implementation/speed_prime.cpp b/src/cmd/implementation/speed_prime.cpp
new file mode 100644
index 000000000..a7a344bef
--- /dev/null
+++ b/src/cmd/implementation/speed_prime.cpp
@@ -0,0 +1,96 @@
+/*
+* (C) 2015 Simon Warta (Kullo GmbH)
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "speed.h"
+
+using namespace Botan;
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
+#include <botan/numthry.h>
+#include <chrono>
+
+namespace {
+const size_t RSA_EXP = 65537;
+const size_t RSA_BITS = 2048;
+
+const auto SAMPLE_DATA = std::vector<BigInt>{
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895363"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895377"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895381"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895389"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895399"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895401"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895431"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895441"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895461"),
+ BigInt("147572674850319649408425528388978190129147580193826207917614581140087181349813950149403694089438460074197915858493514824951402666113125007396293585089750170962882245605820159076002066981429137353341175732273168874025070408827561035943771554301600092787967626039381375658829078877390735440179859333066156895471"),
+ };
+}
+
+#endif // BOTAN_HAS_NUMBERTHEORY
+
+std::map<std::string, double> benchmark_is_prime(RandomNumberGenerator& rng,
+ const std::chrono::milliseconds runtime)
+ {
+ std::map<std::string, double> speeds;
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
+ std::chrono::nanoseconds time_used(0);
+ size_t reps = 0;
+
+ auto start = std::chrono::high_resolution_clock::now();
+
+ while(time_used < runtime)
+ {
+ // main work
+ for (const BigInt &p : SAMPLE_DATA)
+ {
+ is_prime(p, rng, 64, true);
+ }
+
+ ++reps;
+ time_used = std::chrono::high_resolution_clock::now() - start;
+ }
+
+ const double seconds_used = static_cast<double>(time_used.count()) / 1000000000;
+ speeds["base"] = reps / seconds_used; // ie, return ops per second
+
+#endif // BOTAN_HAS_NUMBERTHEORY
+
+ return speeds;
+ }
+
+std::map<std::string, double> benchmark_random_prime(RandomNumberGenerator& rng,
+ const std::chrono::milliseconds runtime)
+ {
+ std::map<std::string, double> speeds;
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
+ std::chrono::nanoseconds time_used(0);
+ size_t reps = 0;
+
+ auto start = std::chrono::high_resolution_clock::now();
+
+ while(time_used < runtime)
+ {
+ // main work
+ random_prime(rng, (RSA_BITS + 1) / 2, RSA_EXP);
+
+ ++reps;
+ time_used = std::chrono::high_resolution_clock::now() - start;
+ }
+
+ const double seconds_used = static_cast<double>(time_used.count()) / 1000000000;
+ speeds["base"] = reps / seconds_used; // ie, return ops per second
+
+#endif // BOTAN_HAS_NUMBERTHEORY
+
+ return speeds;
+ }
+
diff --git a/src/cmd/speed_pk.cpp b/src/cmd/implementation/speed_public_key.cpp
index 63395e624..1e14f7eca 100644
--- a/src/cmd/speed_pk.cpp
+++ b/src/cmd/implementation/speed_public_key.cpp
@@ -4,21 +4,20 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include "../apps.h"
+
+#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
+
#include "speed.h"
#include "timer.h"
-#include <botan/pkcs8.h>
-#include <botan/mem_ops.h>
-#include <botan/parsing.h>
-#include <botan/oids.h>
#include <map>
#include <sstream>
-
-#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
- #include <botan/x509_key.h>
- #include <botan/pkcs8.h>
- #include <botan/pubkey.h>
-#endif
+#include <botan/mem_ops.h>
+#include <botan/parsing.h>
+#include <botan/pkcs8.h>
+#include <botan/pubkey.h>
+#include <botan/x509_key.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -48,7 +47,7 @@
#include <botan/elgamal.h>
#endif
-#if defined(BOTAN_HAS_DLIES)
+#if defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2)
#include <botan/dlies.h>
#include <botan/kdf2.h>
#include <botan/hmac.h>
@@ -615,7 +614,7 @@ void benchmark_dh(RandomNumberGenerator& rng,
}
#endif
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES)
+#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2)
void benchmark_dlies(RandomNumberGenerator& rng,
double seconds,
Benchmark_Report& report)
@@ -785,8 +784,8 @@ void benchmark_mce(RandomNumberGenerator& rng,
}
-void bench_pk(RandomNumberGenerator& rng,
- const std::string& algo, double seconds)
+void benchmark_public_key(RandomNumberGenerator& rng,
+ const std::string& algo, double seconds)
{
/*
There is some strangeness going on here. It looks like algorithms
@@ -851,7 +850,7 @@ void bench_pk(RandomNumberGenerator& rng,
benchmark_dh(rng, seconds, report);
#endif
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES)
+#if defined(BOTAN_HAS_DIFFIE_HELLMAN) && defined(BOTAN_HAS_DLIES) && defined(BOTAN_HAS_KDF2)
if(algo == "All" || algo == "DLIES")
benchmark_dlies(rng, seconds, report);
#endif
@@ -876,3 +875,4 @@ void bench_pk(RandomNumberGenerator& rng,
benchmark_mce(rng, seconds, report);
#endif
}
+#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO
diff --git a/src/cmd/implementation/speed_transform.cpp b/src/cmd/implementation/speed_transform.cpp
new file mode 100644
index 000000000..2db5cdd70
--- /dev/null
+++ b/src/cmd/implementation/speed_transform.cpp
@@ -0,0 +1,67 @@
+/*
+* (C) 2009 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "speed.h"
+
+#include <iostream>
+#include <iomanip>
+
+#include <botan/cipher_mode.h>
+#include <botan/transform.h>
+
+using namespace Botan;
+
+namespace {
+void benchmark_transform(std::unique_ptr<Transform> tf,
+ RandomNumberGenerator& rng,
+ const std::chrono::milliseconds runtime)
+ {
+ for(size_t buf_size : { 16, 64, 256, 1024, 8192 })
+ {
+ secure_vector<byte> buffer(buf_size);
+
+ std::chrono::nanoseconds time_used(0);
+
+ tf->start(rng.random_vec(tf->default_nonce_length()));
+
+ auto start = std::chrono::high_resolution_clock::now();
+
+ secure_vector<byte> buf(buf_size);
+ size_t reps = 0;
+ while(time_used < runtime)
+ {
+ tf->update(buf);
+ buf.resize(buf_size);
+ ++reps;
+ time_used = std::chrono::high_resolution_clock::now() - start;
+ }
+
+ const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count();
+
+ const double seconds_used = static_cast<double>(nsec_used) / 1000000000;
+
+ const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024;
+
+ std::cout << tf->name() << " " << std::setprecision(4) << Mbps
+ << " MiB / sec with " << buf_size << " byte blocks" << std::endl;
+ }
+ }
+}
+
+bool benchmark_transform(RandomNumberGenerator& rng, const std::string& algo_name,
+ const std::chrono::milliseconds runtime)
+ {
+ std::unique_ptr<Transform> tf;
+ tf.reset(get_cipher_mode(algo_name, ENCRYPTION));
+ if(!tf)
+ return false;
+
+ if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get()))
+ keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength()));
+
+ benchmark_transform(std::move(tf), rng, runtime);
+ return true;
+ }
diff --git a/src/cmd/timer.cpp b/src/cmd/implementation/timer.cpp
index 14e55316b..14e55316b 100644
--- a/src/cmd/timer.cpp
+++ b/src/cmd/implementation/timer.cpp
diff --git a/src/cmd/timer.h b/src/cmd/implementation/timer.h
index ac5bd5cef..ac5bd5cef 100644
--- a/src/cmd/timer.h
+++ b/src/cmd/implementation/timer.h
diff --git a/src/cmd/is_prime.cpp b/src/cmd/is_prime.cpp
index c3bf8970e..703772477 100644
--- a/src/cmd/is_prime.cpp
+++ b/src/cmd/is_prime.cpp
@@ -5,6 +5,9 @@
*/
#include "apps.h"
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
#include <botan/numthry.h>
namespace {
@@ -43,3 +46,5 @@ int is_prime(int argc, char* argv[])
REGISTER_APP(is_prime);
}
+
+#endif // BOTAN_HAS_NUMBERTHEORY
diff --git a/src/cmd/keygen.cpp b/src/cmd/keygen.cpp
index 75ba3ed42..ead7dd39d 100644
--- a/src/cmd/keygen.cpp
+++ b/src/cmd/keygen.cpp
@@ -5,11 +5,16 @@
*/
#include "apps.h"
+
+#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO) && defined(BOTAN_HAS_X509_CERTIFICATES)
+
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <memory>
+#include <botan/pk_keys.h>
+#include <botan/pkcs8.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -120,3 +125,5 @@ int keygen(int argc, char* argv[])
REGISTER_APP(keygen);
}
+
+#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO && BOTAN_HAS_X509_CERTIFICATES
diff --git a/src/cmd/pkcs10.cpp b/src/cmd/pkcs10.cpp
index ff5fa7bf9..18fdea9bf 100644
--- a/src/cmd/pkcs10.cpp
+++ b/src/cmd/pkcs10.cpp
@@ -6,15 +6,16 @@
#include "apps.h"
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
+#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_HAS_RSA)
+
+#include <botan/pkcs8.h>
#include <botan/x509self.h>
#include <botan/rsa.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
#include <fstream>
#include <memory>
+using namespace Botan;
+
namespace {
int pkcs10(int argc, char* argv[])
@@ -60,4 +61,4 @@ REGISTER_APP(pkcs10);
}
-#endif
+#endif // BOTAN_HAS_X509_CERTIFICATES && BOTAN_HAS_RSA
diff --git a/src/cmd/self_sig.cpp b/src/cmd/self_sig.cpp
index 0a6c59d87..6916420ca 100644
--- a/src/cmd/self_sig.cpp
+++ b/src/cmd/self_sig.cpp
@@ -6,15 +6,16 @@
#include "apps.h"
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
+#if defined(BOTAN_HAS_X509_CERTIFICATES) && defined(BOTAN_HAS_RSA)
+
+#include <botan/pkcs8.h>
#include <botan/x509self.h>
#include <botan/rsa.h>
-#include <botan/dsa.h>
-using namespace Botan;
-
#include <fstream>
#include <memory>
+using namespace Botan;
+
namespace {
int self_sig(int argc, char* argv[])
@@ -45,7 +46,6 @@ int self_sig(int argc, char* argv[])
RSA_PrivateKey key(rng, 2048);
//DL_Group group(rng, DL_Group::DSA_Kosherizer, 2048, 256);
- //DSA_PrivateKey key(rng, group);
std::ofstream priv_key("private.pem");
priv_key << PKCS8::PEM_encode(key, rng, argv[1]);
@@ -82,4 +82,4 @@ REGISTER_APP(self_sig);
}
-#endif
+#endif // BOTAN_HAS_X509_CERTIFICATES && BOTAN_HAS_RSA
diff --git a/src/cmd/speed.cpp b/src/cmd/speed.cpp
index 5e12ff3bc..91b2f4fbd 100644
--- a/src/cmd/speed.cpp
+++ b/src/cmd/speed.cpp
@@ -4,27 +4,21 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include "speed.h"
#include "apps.h"
+
+#if defined(BOTAN_HAS_RUNTIME_BENCHMARKING)
+
+#include "implementation/speed.h"
+
#include <iostream>
#include <iomanip>
#include <botan/benchmark.h>
-#include <botan/aead.h>
#include <botan/auto_rng.h>
-#include <botan/parsing.h>
-#include <botan/symkey.h>
-#include <botan/hex.h>
-
-#include <chrono>
-
-typedef std::chrono::high_resolution_clock benchmark_clock;
-
using namespace Botan;
namespace {
-
const std::vector<std::string> default_benchmark_list = {
/* Block ciphers */
"AES-128",
@@ -86,7 +80,11 @@ const std::vector<std::string> default_benchmark_list = {
/* MACs */
"CMAC(AES-128)",
- "HMAC(SHA-1)"
+ "HMAC(SHA-1)",
+
+ /* Misc */
+ "is_prime",
+ "random_prime"
};
void report_results(const std::string& algo,
@@ -119,76 +117,43 @@ void report_results(const std::string& algo,
std::cout.flags(flags);
}
-void time_transform(std::unique_ptr<Transform> tf,
- RandomNumberGenerator& rng)
+void bench_algo(const std::string& algo,
+ RandomNumberGenerator& rng,
+ double seconds,
+ size_t buf_size)
{
- const std::chrono::seconds runtime(2);
-
- for(size_t buf_size : { 16, 64, 256, 1024, 8192 })
- {
- secure_vector<byte> buffer(buf_size);
-
- std::chrono::nanoseconds time_used(0);
-
- tf->start(rng.random_vec(tf->default_nonce_length()));
-
- auto start = std::chrono::high_resolution_clock::now();
-
- secure_vector<byte> buf(buf_size);
- size_t reps = 0;
- while(time_used < runtime)
- {
- tf->update(buf);
- buf.resize(buf_size);
- ++reps;
- time_used = std::chrono::high_resolution_clock::now() - start;
- }
-
- const u64bit nsec_used = std::chrono::duration_cast<std::chrono::nanoseconds>(time_used).count();
-
- const double seconds_used = static_cast<double>(nsec_used) / 1000000000;
-
- const double Mbps = ((reps / seconds_used) * buf_size) / 1024 / 1024;
-
- std::cout << tf->name() << " " << std::setprecision(4) << Mbps
- << " MiB / sec with " << buf_size << " byte blocks" << std::endl;
- }
- }
+ std::chrono::milliseconds runtime(
+ static_cast<std::chrono::milliseconds::rep>(seconds * 1000));
-bool time_transform(const std::string& algo, RandomNumberGenerator& rng)
+ if (algo == "random_prime")
{
- std::unique_ptr<Transform> tf;
- tf.reset(get_cipher_mode(algo, ENCRYPTION));
- if(!tf)
- return false;
-
- if(Keyed_Transform* keyed = dynamic_cast<Keyed_Transform*>(tf.get()))
- keyed->set_key(rng.random_vec(keyed->key_spec().maximum_keylength()));
-
- time_transform(std::move(tf), rng);
- return true;
+ auto speeds = benchmark_random_prime(rng, runtime);
+ report_results(algo, speeds);
+ return;
}
-void bench_algo(const std::string& algo,
- RandomNumberGenerator& rng,
- double seconds,
- size_t buf_size)
+ if (algo == "is_prime")
{
- std::chrono::milliseconds ms(
- static_cast<std::chrono::milliseconds::rep>(seconds * 1000));
+ auto speeds = benchmark_is_prime(rng, runtime);
+ report_results(algo, speeds);
+ return;
+ }
- if(time_transform(algo, rng))
+ // This does report itself
+ if (benchmark_transform(rng, algo, runtime))
return;
- std::map<std::string, double> speeds = algorithm_benchmark(algo, rng, ms, buf_size);
-
- if(!speeds.empty())
+ try
{
+ auto speeds = algorithm_benchmark(algo, rng, runtime, buf_size);
report_results(algo, speeds);
- return;
}
-
- bench_pk(rng, algo, seconds);
+ catch (No_Provider_Found)
+ {
+ #if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
+ benchmark_public_key(rng, algo, seconds);
+ #endif
+ }
}
int speed(int argc, char* argv[])
@@ -242,3 +207,4 @@ int speed(int argc, char* argv[])
REGISTER_APP(speed);
}
+#endif // BOTAN_HAS_RUNTIME_BENCHMARKING
diff --git a/src/cmd/speed.h b/src/cmd/speed.h
deleted file mode 100644
index 5f3918a3f..000000000
--- a/src/cmd/speed.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-* (C) 2014 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_CHECK_BENCHMARK_H__
-#define BOTAN_CHECK_BENCHMARK_H__
-
-#include <botan/rng.h>
-#include <string>
-
-void bench_pk(Botan::RandomNumberGenerator& rng,
- const std::string& algo, double seconds);
-
-#endif
diff --git a/src/cmd/tls_client.cpp b/src/cmd/tls_client.cpp
index e052c6842..a5da299c6 100644
--- a/src/cmd/tls_client.cpp
+++ b/src/cmd/tls_client.cpp
@@ -6,7 +6,11 @@
#include "apps.h"
-#if defined(BOTAN_HAS_TLS) && !defined(BOTAN_TARGET_OS_IS_WINDOWS) && !defined(BOTAN_TARGET_OS_IS_MINGW)
+#if defined(BOTAN_HAS_TLS) \
+ && defined(BOTAN_HAS_DSA) \
+ && !defined(BOTAN_TARGET_OS_IS_WINDOWS) \
+ && !defined(BOTAN_TARGET_OS_IS_MINGW)
+
#include <botan/tls_client.h>
#include <botan/pkcs8.h>
#include <botan/hex.h>
@@ -289,4 +293,5 @@ int tls_client(int argc, char* argv[])
REGISTER_APP(tls_client);
}
+
#endif
diff --git a/src/cmd/tls_server.cpp b/src/cmd/tls_server.cpp
index b7fbfa2c8..744ab5544 100644
--- a/src/cmd/tls_server.cpp
+++ b/src/cmd/tls_server.cpp
@@ -7,7 +7,10 @@
#include "apps.h"
-#if defined(BOTAN_HAS_TLS) && !defined(BOTAN_TARGET_OS_IS_WINDOWS)
+#if defined(BOTAN_HAS_TLS) && defined(BOTAN_HAS_DSA) \
+ && !defined(BOTAN_TARGET_OS_IS_WINDOWS) \
+ && !defined(BOTAN_TARGET_OS_IS_MINGW)
+
#include <botan/tls_server.h>
#include <botan/hex.h>
diff --git a/src/lib/alloc/locking_allocator/info.txt b/src/lib/alloc/locking_allocator/info.txt
index 09b59406c..d3b5e86f8 100644
--- a/src/lib/alloc/locking_allocator/info.txt
+++ b/src/lib/alloc/locking_allocator/info.txt
@@ -1,6 +1,7 @@
define LOCKING_ALLOCATOR 20131128
<os>
+android
linux
freebsd
netbsd
diff --git a/src/lib/alloc/locking_allocator/locking_allocator.cpp b/src/lib/alloc/locking_allocator/locking_allocator.cpp
index 6a9cc2579..ec294d8f0 100644
--- a/src/lib/alloc/locking_allocator/locking_allocator.cpp
+++ b/src/lib/alloc/locking_allocator/locking_allocator.cpp
@@ -26,7 +26,9 @@ const size_t ALIGNMENT_MULTIPLE = 2;
size_t reset_mlock_limit(size_t max_req)
{
+#if defined(RLIMIT_MEMLOCK)
struct rlimit limits;
+
::getrlimit(RLIMIT_MEMLOCK, &limits);
if(limits.rlim_cur < limits.rlim_max)
@@ -37,6 +39,9 @@ size_t reset_mlock_limit(size_t max_req)
}
return std::min<size_t>(limits.rlim_cur, max_req);
+#endif
+
+ return 0;
}
size_t mlock_limit()
diff --git a/src/lib/asn1/alg_id.h b/src/lib/asn1/alg_id.h
index 5083274f1..9e36fd120 100644
--- a/src/lib/asn1/alg_id.h
+++ b/src/lib/asn1/alg_id.h
@@ -22,8 +22,8 @@ class BOTAN_DLL AlgorithmIdentifier : public ASN1_Object
public:
enum Encoding_Option { USE_NULL_PARAM };
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
AlgorithmIdentifier() {}
AlgorithmIdentifier(const OID&, Encoding_Option);
diff --git a/src/lib/asn1/asn1_alt_name.h b/src/lib/asn1/asn1_alt_name.h
index daf62d464..91ba2bcf1 100644
--- a/src/lib/asn1/asn1_alt_name.h
+++ b/src/lib/asn1/asn1_alt_name.h
@@ -22,8 +22,8 @@ namespace Botan {
class BOTAN_DLL AlternativeName : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
std::multimap<std::string, std::string> contents() const;
diff --git a/src/lib/asn1/asn1_attribute.h b/src/lib/asn1/asn1_attribute.h
index e094bd3aa..371b0f99a 100644
--- a/src/lib/asn1/asn1_attribute.h
+++ b/src/lib/asn1/asn1_attribute.h
@@ -20,8 +20,8 @@ namespace Botan {
class BOTAN_DLL Attribute : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder& to) const;
- void decode_from(class BER_Decoder& from);
+ void encode_into(class DER_Encoder& to) const override;
+ void decode_from(class BER_Decoder& from) override;
OID oid;
std::vector<byte> parameters;
diff --git a/src/lib/asn1/asn1_obj.cpp b/src/lib/asn1/asn1_obj.cpp
index 265668d83..20555e3dd 100644
--- a/src/lib/asn1/asn1_obj.cpp
+++ b/src/lib/asn1/asn1_obj.cpp
@@ -10,6 +10,7 @@
#include <botan/ber_dec.h>
#include <botan/data_src.h>
#include <botan/parsing.h>
+#include <botan/internal/stl_util.h>
namespace Botan {
@@ -45,8 +46,7 @@ std::vector<byte> put_in_sequence(const std::vector<byte>& contents)
*/
std::string to_string(const BER_Object& obj)
{
- return std::string(reinterpret_cast<const char*>(&obj.value[0]),
- obj.value.size());
+ return to_string(obj.value);
}
/*
diff --git a/src/lib/asn1/asn1_obj.h b/src/lib/asn1/asn1_obj.h
index d208ec78e..f68ef675e 100644
--- a/src/lib/asn1/asn1_obj.h
+++ b/src/lib/asn1/asn1_obj.h
@@ -13,6 +13,9 @@
namespace Botan {
+class BER_Decoder;
+class DER_Encoder;
+
/**
* ASN.1 Type and Class Tags
*/
@@ -44,8 +47,9 @@ enum ASN1_Tag {
VISIBLE_STRING = 0x1A,
BMP_STRING = 0x1E,
- UTC_TIME = 0x17,
- GENERALIZED_TIME = 0x18,
+ UTC_TIME = 0x17,
+ GENERALIZED_TIME = 0x18,
+ UTC_OR_GENERALIZED_TIME = 0x19,
NO_OBJECT = 0xFF00,
DIRECTORY_STRING = 0xFF01
@@ -61,13 +65,13 @@ class BOTAN_DLL ASN1_Object
* Encode whatever this object is into to
* @param to the DER_Encoder that will be written to
*/
- virtual void encode_into(class DER_Encoder& to) const = 0;
+ virtual void encode_into(DER_Encoder& to) const = 0;
/**
* Decode whatever this object is from from
* @param from the BER_Decoder that will be read from
*/
- virtual void decode_from(class BER_Decoder& from) = 0;
+ virtual void decode_from(BER_Decoder& from) = 0;
virtual ~ASN1_Object() {}
};
diff --git a/src/lib/asn1/asn1_oid.h b/src/lib/asn1/asn1_oid.h
index cf4fd9f54..7cdb9f58f 100644
--- a/src/lib/asn1/asn1_oid.h
+++ b/src/lib/asn1/asn1_oid.h
@@ -20,8 +20,8 @@ namespace Botan {
class BOTAN_DLL OID : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
/**
* Find out whether this OID is empty
diff --git a/src/lib/asn1/asn1_str.h b/src/lib/asn1/asn1_str.h
index 911331c9c..84458e517 100644
--- a/src/lib/asn1/asn1_str.h
+++ b/src/lib/asn1/asn1_str.h
@@ -18,8 +18,8 @@ namespace Botan {
class BOTAN_DLL ASN1_String : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
std::string value() const;
std::string iso_8859() const;
diff --git a/src/lib/asn1/asn1_time.cpp b/src/lib/asn1/asn1_time.cpp
index 72bf87df9..a9dffa95c 100644
--- a/src/lib/asn1/asn1_time.cpp
+++ b/src/lib/asn1/asn1_time.cpp
@@ -9,6 +9,7 @@
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
#include <botan/charset.h>
+#include <botan/exceptn.h>
#include <botan/parsing.h>
#include <botan/calendar.h>
#include <sstream>
@@ -16,162 +17,36 @@
namespace Botan {
-/*
-* Create an X509_Time
-*/
-X509_Time::X509_Time(const std::string& time_str)
- {
- set_to(time_str);
- }
-
-/*
-* Create a X509_Time from a time point
-*/
X509_Time::X509_Time(const std::chrono::system_clock::time_point& time)
{
calendar_point cal = calendar_value(time);
- year = cal.year;
- month = cal.month;
- day = cal.day;
- hour = cal.hour;
- minute = cal.minutes;
- second = cal.seconds;
+ m_year = cal.year;
+ m_month = cal.month;
+ m_day = cal.day;
+ m_hour = cal.hour;
+ m_minute = cal.minutes;
+ m_second = cal.seconds;
- tag = (year >= 2050) ? GENERALIZED_TIME : UTC_TIME;
+ m_tag = (m_year >= 2050) ? GENERALIZED_TIME : UTC_TIME;
}
-/*
-* Create an X509_Time
-*/
-X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag t) : tag(t)
+X509_Time::X509_Time(const std::string& t_spec, ASN1_Tag tag)
{
set_to(t_spec, tag);
}
-/*
-* Set the time with a human readable string
-*/
-void X509_Time::set_to(const std::string& time_str)
- {
- if(time_str == "")
- {
- year = month = day = hour = minute = second = 0;
- tag = NO_OBJECT;
- return;
- }
-
- std::vector<std::string> params;
- std::string current;
-
- for(size_t j = 0; j != time_str.size(); ++j)
- {
- if(Charset::is_digit(time_str[j]))
- current += time_str[j];
- else
- {
- if(current != "")
- params.push_back(current);
- current.clear();
- }
- }
- if(current != "")
- params.push_back(current);
-
- if(params.size() < 3 || params.size() > 6)
- throw Invalid_Argument("Invalid time specification " + time_str);
-
- year = to_u32bit(params[0]);
- month = to_u32bit(params[1]);
- day = to_u32bit(params[2]);
- hour = (params.size() >= 4) ? to_u32bit(params[3]) : 0;
- minute = (params.size() >= 5) ? to_u32bit(params[4]) : 0;
- second = (params.size() == 6) ? to_u32bit(params[5]) : 0;
-
- tag = (year >= 2050) ? GENERALIZED_TIME : UTC_TIME;
-
- if(!passes_sanity_check())
- throw Invalid_Argument("Invalid time specification " + time_str);
- }
-
-/*
-* Set the time with an ISO time format string
-*/
-void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag)
- {
- if(spec_tag == GENERALIZED_TIME)
- {
- if(t_spec.size() != 13 && t_spec.size() != 15)
- throw Invalid_Argument("Invalid GeneralizedTime: " + t_spec);
- }
- else if(spec_tag == UTC_TIME)
- {
- if(t_spec.size() != 11 && t_spec.size() != 13)
- throw Invalid_Argument("Invalid UTCTime: " + t_spec);
- }
- else
- {
- throw Invalid_Argument("Invalid time tag " + std::to_string(spec_tag) + " val " + t_spec);
- }
-
- if(t_spec[t_spec.size()-1] != 'Z')
- throw Invalid_Argument("Invalid time encoding: " + t_spec);
-
- const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4;
-
- std::vector<std::string> params;
- std::string current;
-
- for(size_t j = 0; j != YEAR_SIZE; ++j)
- current += t_spec[j];
- params.push_back(current);
- current.clear();
-
- for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j)
- {
- current += t_spec[j];
- if(current.size() == 2)
- {
- params.push_back(current);
- current.clear();
- }
- }
-
- year = to_u32bit(params[0]);
- month = to_u32bit(params[1]);
- day = to_u32bit(params[2]);
- hour = to_u32bit(params[3]);
- minute = to_u32bit(params[4]);
- second = (params.size() == 6) ? to_u32bit(params[5]) : 0;
- tag = spec_tag;
-
- if(spec_tag == UTC_TIME)
- {
- if(year >= 50) year += 1900;
- else year += 2000;
- }
-
- if(!passes_sanity_check())
- throw Invalid_Argument("Invalid time specification " + t_spec);
- }
-
-/*
-* DER encode a X509_Time
-*/
void X509_Time::encode_into(DER_Encoder& der) const
{
- if(tag != GENERALIZED_TIME && tag != UTC_TIME)
+ if(m_tag != GENERALIZED_TIME && m_tag != UTC_TIME)
throw Invalid_Argument("X509_Time: Bad encoding tag");
- der.add_object(tag, UNIVERSAL,
- Charset::transcode(as_string(),
+ der.add_object(m_tag, UNIVERSAL,
+ Charset::transcode(to_string(),
LOCAL_CHARSET,
LATIN1_CHARSET));
}
-/*
-* Decode a BER encoded X509_Time
-*/
void X509_Time::decode_from(BER_Decoder& source)
{
BER_Object ber_time = source.get_next_object();
@@ -182,33 +57,36 @@ void X509_Time::decode_from(BER_Decoder& source)
ber_time.type_tag);
}
-/*
-* Return a string representation of the time
-*/
-std::string X509_Time::as_string() const
+std::string X509_Time::to_string() const
{
if(time_is_set() == false)
throw Invalid_State("X509_Time::as_string: No time set");
- u32bit full_year = year;
+ u32bit full_year = m_year;
- if(tag == UTC_TIME)
+ if(m_tag == UTC_TIME)
{
- if(year < 1950 || year >= 2050)
+ if(m_year < 1950 || m_year >= 2050)
throw Encoding_Error("X509_Time: The time " + readable_string() +
" cannot be encoded as a UTCTime");
- full_year = (year >= 2000) ? (year - 2000) : (year - 1900);
+ full_year = (m_year >= 2000) ? (m_year - 2000) : (m_year - 1900);
}
- std::string repr = std::to_string(full_year*10000000000 +
- month*100000000 +
- day*1000000 +
- hour*10000 +
- minute*100 +
- second) + "Z";
+ const auto factor_y = uint64_t{10000000000ull}; // literal exceeds 32bit int range
+ const auto factor_m = uint64_t{100000000ull};
+ const auto factor_d = uint64_t{1000000ull};
+ const auto factor_h = uint64_t{10000ull};
+ const auto factor_i = uint64_t{100ull};
- u32bit desired_size = (tag == UTC_TIME) ? 13 : 15;
+ std::string repr = std::to_string(factor_y * full_year +
+ factor_m * m_month +
+ factor_d * m_day +
+ factor_h * m_hour +
+ factor_i * m_minute +
+ m_second) + "Z";
+
+ u32bit desired_size = (m_tag == UTC_TIME) ? 13 : 15;
while(repr.size() < desired_size)
repr = "0" + repr;
@@ -216,17 +94,6 @@ std::string X509_Time::as_string() const
return repr;
}
-/*
-* Return if the time has been set somehow
-*/
-bool X509_Time::time_is_set() const
- {
- return (year != 0);
- }
-
-/*
-* Return a human readable string representation
-*/
std::string X509_Time::readable_string() const
{
if(time_is_set() == false)
@@ -237,33 +104,19 @@ std::string X509_Time::readable_string() const
{
using namespace std;
output << setfill('0')
- << setw(4) << year << "/" << setw(2) << month << "/" << setw(2) << day
+ << setw(4) << m_year << "/" << setw(2) << m_month << "/" << setw(2) << m_day
<< " "
- << setw(2) << hour << ":" << setw(2) << minute << ":" << setw(2) << second
+ << setw(2) << m_hour << ":" << setw(2) << m_minute << ":" << setw(2) << m_second
<< " UTC";
}
return output.str();
}
-/*
-* Do a general sanity check on the time
-*/
-bool X509_Time::passes_sanity_check() const
+bool X509_Time::time_is_set() const
{
- if(year < 1950 || year > 2100)
- return false;
- if(month == 0 || month > 12)
- return false;
- if(day == 0 || day > 31)
- return false;
- if(hour >= 24 || minute > 60 || second > 60)
- return false;
- return true;
+ return (m_year != 0);
}
-/*
-* Compare this time against another
-*/
s32bit X509_Time::cmp(const X509_Time& other) const
{
if(time_is_set() == false)
@@ -271,22 +124,132 @@ s32bit X509_Time::cmp(const X509_Time& other) const
const s32bit EARLIER = -1, LATER = 1, SAME_TIME = 0;
- if(year < other.year) return EARLIER;
- if(year > other.year) return LATER;
- if(month < other.month) return EARLIER;
- if(month > other.month) return LATER;
- if(day < other.day) return EARLIER;
- if(day > other.day) return LATER;
- if(hour < other.hour) return EARLIER;
- if(hour > other.hour) return LATER;
- if(minute < other.minute) return EARLIER;
- if(minute > other.minute) return LATER;
- if(second < other.second) return EARLIER;
- if(second > other.second) return LATER;
+ if(m_year < other.m_year) return EARLIER;
+ if(m_year > other.m_year) return LATER;
+ if(m_month < other.m_month) return EARLIER;
+ if(m_month > other.m_month) return LATER;
+ if(m_day < other.m_day) return EARLIER;
+ if(m_day > other.m_day) return LATER;
+ if(m_hour < other.m_hour) return EARLIER;
+ if(m_hour > other.m_hour) return LATER;
+ if(m_minute < other.m_minute) return EARLIER;
+ if(m_minute > other.m_minute) return LATER;
+ if(m_second < other.m_second) return EARLIER;
+ if(m_second > other.m_second) return LATER;
return SAME_TIME;
}
+void X509_Time::set_to(const std::string& t_spec, ASN1_Tag spec_tag)
+ {
+ if(spec_tag == UTC_OR_GENERALIZED_TIME)
+ {
+ try
+ {
+ set_to(t_spec, GENERALIZED_TIME);
+ return;
+ }
+ catch(Invalid_Argument) {} // Not a generalized time. Continue
+
+ try
+ {
+ set_to(t_spec, UTC_TIME);
+ return;
+ }
+ catch(Invalid_Argument) {} // Not a UTC time. Continue
+
+ throw Invalid_Argument("Time string could not be parsed as GeneralizedTime or UTCTime.");
+ }
+
+ BOTAN_ASSERT(spec_tag == UTC_TIME || spec_tag == GENERALIZED_TIME, "Invalid tag.");
+
+ if(t_spec.empty())
+ throw Invalid_Argument("Time string must not be empty.");
+
+ if(t_spec.back() != 'Z')
+ throw Unsupported_Argument("Botan does not support times with timezones other than Z: " + t_spec);
+
+ if(spec_tag == GENERALIZED_TIME)
+ {
+ if(t_spec.size() != 13 && t_spec.size() != 15)
+ throw Invalid_Argument("Invalid GeneralizedTime string: '" + t_spec + "'");
+ }
+ else if(spec_tag == UTC_TIME)
+ {
+ if(t_spec.size() != 11 && t_spec.size() != 13)
+ throw Invalid_Argument("Invalid UTCTime string: '" + t_spec + "'");
+ }
+
+ const size_t YEAR_SIZE = (spec_tag == UTC_TIME) ? 2 : 4;
+
+ std::vector<std::string> params;
+ std::string current;
+
+ for(size_t j = 0; j != YEAR_SIZE; ++j)
+ current += t_spec[j];
+ params.push_back(current);
+ current.clear();
+
+ for(size_t j = YEAR_SIZE; j != t_spec.size() - 1; ++j)
+ {
+ current += t_spec[j];
+ if(current.size() == 2)
+ {
+ params.push_back(current);
+ current.clear();
+ }
+ }
+
+ m_year = to_u32bit(params[0]);
+ m_month = to_u32bit(params[1]);
+ m_day = to_u32bit(params[2]);
+ m_hour = to_u32bit(params[3]);
+ m_minute = to_u32bit(params[4]);
+ m_second = (params.size() == 6) ? to_u32bit(params[5]) : 0;
+ m_tag = spec_tag;
+
+ if(spec_tag == UTC_TIME)
+ {
+ if(m_year >= 50) m_year += 1900;
+ else m_year += 2000;
+ }
+
+ if(!passes_sanity_check())
+ throw Invalid_Argument("Time did not pass sanity check: " + t_spec);
+ }
+
+/*
+* Do a general sanity check on the time
+*/
+bool X509_Time::passes_sanity_check() const
+ {
+ if(m_year < 1950 || m_year > 2100)
+ return false;
+ if(m_month == 0 || m_month > 12)
+ return false;
+ if(m_day == 0 || m_day > 31)
+ return false;
+ if(m_hour >= 24 || m_minute > 60 || m_second > 60)
+ return false;
+
+ if (m_tag == UTC_TIME)
+ {
+ /*
+ UTCTime limits the value of components such that leap seconds
+ are not covered. See "UNIVERSAL 23" in "Information technology
+ Abstract Syntax Notation One (ASN.1): Specification of basic notation"
+
+ http://www.itu.int/ITU-T/studygroups/com17/languages/
+ */
+ if (m_hour > 23 || m_minute > 59 || m_second > 59)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/*
* Compare two X509_Times for in various ways
*/
diff --git a/src/lib/asn1/asn1_time.h b/src/lib/asn1/asn1_time.h
index 6650f2fd4..313b26b06 100644
--- a/src/lib/asn1/asn1_time.h
+++ b/src/lib/asn1/asn1_time.h
@@ -19,27 +19,44 @@ namespace Botan {
class BOTAN_DLL X509_Time : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ /// DER encode a X509_Time
+ void encode_into(DER_Encoder&) const override;
- std::string as_string() const;
+ // Decode a BER encoded X509_Time
+ void decode_from(BER_Decoder&) override;
+
+ /// Return an internal string representation of the time
+ std::string to_string() const;
+
+ /// Returns a human friendly string replesentation of no particular formatting
std::string readable_string() const;
- bool time_is_set() const;
- std::string to_string() const { return readable_string(); }
+ /// Return if the time has been set somehow
+ bool time_is_set() const;
- s32bit cmp(const X509_Time&) const;
+ /// Compare this time against another
+ s32bit cmp(const X509_Time& other) const;
- void set_to(const std::string&);
- void set_to(const std::string&, ASN1_Tag);
+ /// Create an invalid X509_Time
+ X509_Time() {}
+ /// Create a X509_Time from a time point
X509_Time(const std::chrono::system_clock::time_point& time);
- X509_Time(const std::string& = "");
- X509_Time(const std::string&, ASN1_Tag);
+
+ /// Create an X509_Time from string
+ X509_Time(const std::string& t_spec, ASN1_Tag tag);
+
private:
+ void set_to(const std::string& t_spec, ASN1_Tag);
bool passes_sanity_check() const;
- u32bit year, month, day, hour, minute, second;
- ASN1_Tag tag;
+
+ u32bit m_year = 0;
+ u32bit m_month = 0;
+ u32bit m_day = 0;
+ u32bit m_hour = 0;
+ u32bit m_minute = 0;
+ u32bit m_second = 0;
+ ASN1_Tag m_tag = NO_OBJECT;
};
/*
diff --git a/src/lib/asn1/ber_dec.cpp b/src/lib/asn1/ber_dec.cpp
index 06543d9e7..4267d79dc 100644
--- a/src/lib/asn1/ber_dec.cpp
+++ b/src/lib/asn1/ber_dec.cpp
@@ -1,6 +1,7 @@
+
/*
* BER Decoder
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2008,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -218,7 +219,10 @@ BER_Object BER_Decoder::get_next_object()
if(next.type_tag == NO_OBJECT)
return next;
- size_t length = decode_length(source);
+ const size_t length = decode_length(source);
+ if(!source->check_available(length))
+ throw BER_Decoding_Error("Value truncated");
+
next.value.resize(length);
if(source->read(next.value.data(), length) != length)
throw BER_Decoding_Error("Value truncated");
@@ -526,6 +530,8 @@ BER_Decoder& BER_Decoder::decode(secure_vector<byte>& buffer,
buffer = obj.value;
else
{
+ if(obj.value.empty())
+ throw BER_Decoding_Error("Invalid BIT STRING");
if(obj.value[0] >= 8)
throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
@@ -549,6 +555,8 @@ BER_Decoder& BER_Decoder::decode(std::vector<byte>& buffer,
buffer = unlock(obj.value);
else
{
+ if(obj.value.empty())
+ throw BER_Decoding_Error("Invalid BIT STRING");
if(obj.value[0] >= 8)
throw BER_Decoding_Error("Bad number of unused bits in BIT STRING");
diff --git a/src/lib/asn1/x509_dn.h b/src/lib/asn1/x509_dn.h
index 43e0103bd..cf1fbc03b 100644
--- a/src/lib/asn1/x509_dn.h
+++ b/src/lib/asn1/x509_dn.h
@@ -22,8 +22,8 @@ namespace Botan {
class BOTAN_DLL X509_DN : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
std::multimap<OID, std::string> get_attributes() const;
std::vector<std::string> get_attribute(const std::string&) const;
diff --git a/src/lib/base/algo_registry.h b/src/lib/base/algo_registry.h
index 0ae91c218..918206577 100644
--- a/src/lib/base/algo_registry.h
+++ b/src/lib/base/algo_registry.h
@@ -212,11 +212,17 @@ make_new_T_1X(const typename Algo_Registry<T>::Spec& spec)
return new T(x.release());
}
+// Append to macros living outside of functions, so that invocations must end with a semicolon.
+// The struct is only declared to force the semicolon, it is never defined.
+#define BOTAN_FORCE_SEMICOLON struct BOTAN_DUMMY_STRUCT
+
#define BOTAN_REGISTER_TYPE(T, type, name, maker, provider, pref) \
- namespace { Algo_Registry<T>::Add g_ ## type ## _reg(name, maker, provider, pref); }
+ namespace { Algo_Registry<T>::Add g_ ## type ## _reg(name, maker, provider, pref); } \
+ BOTAN_FORCE_SEMICOLON
#define BOTAN_REGISTER_TYPE_COND(cond, T, type, name, maker, provider, pref) \
- namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, maker, provider, pref); }
+ namespace { Algo_Registry<T>::Add g_ ## type ## _reg(cond, name, maker, provider, pref); } \
+ BOTAN_FORCE_SEMICOLON
#define BOTAN_REGISTER_NAMED_T(T, name, type, maker) \
BOTAN_REGISTER_TYPE(T, type, name, maker, "base", 128)
diff --git a/src/lib/base/init.h b/src/lib/base/init.h
index b73355628..0c61eba6f 100644
--- a/src/lib/base/init.h
+++ b/src/lib/base/init.h
@@ -17,7 +17,7 @@ namespace Botan {
* Previously botan had state whose lifetime had to be explicitly
* managed by the application. As of 1.11.14 this is no longer the
* case, and this class is no longer needed and kept only for backwards
-* compatability.
+* compatibility.
*/
class BOTAN_DLL LibraryInitializer
{
diff --git a/src/lib/base/transform.h b/src/lib/base/transform.h
index b5916a3a4..cd4ee9880 100644
--- a/src/lib/base/transform.h
+++ b/src/lib/base/transform.h
@@ -69,7 +69,7 @@ class BOTAN_DLL Transform
/**
* Process some data. Input must be in size update_granularity() byte blocks.
- * @param blocks in/out paramter which will possibly be resized
+ * @param blocks in/out parameter which will possibly be resized
* @param offset an offset into blocks to begin processing
*/
virtual void update(secure_vector<byte>& blocks, size_t offset = 0) = 0;
diff --git a/src/lib/block/aes/aes.h b/src/lib/block/aes/aes.h
index b57d4ce65..f8b8d2938 100644
--- a/src/lib/block/aes/aes.h
+++ b/src/lib/block/aes/aes.h
@@ -18,15 +18,15 @@ namespace Botan {
class BOTAN_DLL AES_128 : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
+ void clear() override;
- std::string name() const { return "AES-128"; }
- BlockCipher* clone() const { return new AES_128; }
+ std::string name() const override { return "AES-128"; }
+ BlockCipher* clone() const override { return new AES_128; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u32bit> EK, DK;
secure_vector<byte> ME, MD;
@@ -38,15 +38,15 @@ class BOTAN_DLL AES_128 : public Block_Cipher_Fixed_Params<16, 16>
class BOTAN_DLL AES_192 : public Block_Cipher_Fixed_Params<16, 24>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
+ void clear() override;
- std::string name() const { return "AES-192"; }
- BlockCipher* clone() const { return new AES_192; }
+ std::string name() const override { return "AES-192"; }
+ BlockCipher* clone() const override { return new AES_192; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u32bit> EK, DK;
secure_vector<byte> ME, MD;
@@ -58,15 +58,15 @@ class BOTAN_DLL AES_192 : public Block_Cipher_Fixed_Params<16, 24>
class BOTAN_DLL AES_256 : public Block_Cipher_Fixed_Params<16, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
+ void clear() override;
- std::string name() const { return "AES-256"; }
- BlockCipher* clone() const { return new AES_256; }
+ std::string name() const override { return "AES-256"; }
+ BlockCipher* clone() const override { return new AES_256; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u32bit> EK, DK;
secure_vector<byte> ME, MD;
diff --git a/src/lib/block/aes_ni/aes_ni.h b/src/lib/block/aes_ni/aes_ni.h
index f329b409e..0f85c3482 100644
--- a/src/lib/block/aes_ni/aes_ni.h
+++ b/src/lib/block/aes_ni/aes_ni.h
@@ -18,16 +18,16 @@ namespace Botan {
class BOTAN_DLL AES_128_NI : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- size_t parallelism() const { return 4; }
+ size_t parallelism() const override { return 4; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-128"; }
- BlockCipher* clone() const { return new AES_128_NI; }
+ void clear() override;
+ std::string name() const override { return "AES-128"; }
+ BlockCipher* clone() const override { return new AES_128_NI; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
@@ -38,16 +38,16 @@ class BOTAN_DLL AES_128_NI : public Block_Cipher_Fixed_Params<16, 16>
class BOTAN_DLL AES_192_NI : public Block_Cipher_Fixed_Params<16, 24>
{
public:
- size_t parallelism() const { return 4; }
+ size_t parallelism() const override { return 4; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-192"; }
- BlockCipher* clone() const { return new AES_192_NI; }
+ void clear() override;
+ std::string name() const override { return "AES-192"; }
+ BlockCipher* clone() const override { return new AES_192_NI; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
@@ -58,16 +58,16 @@ class BOTAN_DLL AES_192_NI : public Block_Cipher_Fixed_Params<16, 24>
class BOTAN_DLL AES_256_NI : public Block_Cipher_Fixed_Params<16, 32>
{
public:
- size_t parallelism() const { return 4; }
+ size_t parallelism() const override { return 4; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-256"; }
- BlockCipher* clone() const { return new AES_256_NI; }
+ void clear() override;
+ std::string name() const override { return "AES-256"; }
+ BlockCipher* clone() const override { return new AES_256_NI; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
diff --git a/src/lib/block/aes_ssse3/aes_ssse3.h b/src/lib/block/aes_ssse3/aes_ssse3.h
index 4e3df39e9..49e0346e4 100644
--- a/src/lib/block/aes_ssse3/aes_ssse3.h
+++ b/src/lib/block/aes_ssse3/aes_ssse3.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL AES_128_SSSE3 : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-128"; }
- BlockCipher* clone() const { return new AES_128_SSSE3; }
+ void clear() override;
+ std::string name() const override { return "AES-128"; }
+ BlockCipher* clone() const override { return new AES_128_SSSE3; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
@@ -36,14 +36,14 @@ class BOTAN_DLL AES_128_SSSE3 : public Block_Cipher_Fixed_Params<16, 16>
class BOTAN_DLL AES_192_SSSE3 : public Block_Cipher_Fixed_Params<16, 24>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-192"; }
- BlockCipher* clone() const { return new AES_192_SSSE3; }
+ void clear() override;
+ std::string name() const override { return "AES-192"; }
+ BlockCipher* clone() const override { return new AES_192_SSSE3; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
@@ -54,14 +54,14 @@ class BOTAN_DLL AES_192_SSSE3 : public Block_Cipher_Fixed_Params<16, 24>
class BOTAN_DLL AES_256_SSSE3 : public Block_Cipher_Fixed_Params<16, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "AES-256"; }
- BlockCipher* clone() const { return new AES_256_SSSE3; }
+ void clear() override;
+ std::string name() const override { return "AES-256"; }
+ BlockCipher* clone() const override { return new AES_256_SSSE3; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h
index 060dbb29b..08bf18fd3 100644
--- a/src/lib/block/block_cipher.h
+++ b/src/lib/block/block_cipher.h
@@ -151,9 +151,9 @@ class Block_Cipher_Fixed_Params : public BlockCipher
{
public:
enum { BLOCK_SIZE = BS };
- size_t block_size() const { return BS; }
+ size_t block_size() const override { return BS; }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(KMIN, KMAX, KMOD);
}
diff --git a/src/lib/block/block_utils.h b/src/lib/block/block_utils.h
index dacc79a45..89f8a3dd3 100644
--- a/src/lib/block/block_utils.h
+++ b/src/lib/block/block_utils.h
@@ -23,11 +23,12 @@ namespace Botan {
#define BOTAN_REGISTER_BLOCK_CIPHER_1LEN(name, def) BOTAN_REGISTER_T_1LEN(BlockCipher, name, def)
-#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(type, name) BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, make_new_T<type>)
+#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(type, name) \
+ BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, make_new_T<type>)
#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1LEN(type, name, def) \
BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, (make_new_T_1len<type,def>))
#define BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(type, name, def) \
- BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str<type>, std::placeholders::_1, def));
+ BOTAN_REGISTER_NAMED_T(BlockCipher, name, type, std::bind(make_new_T_1str<type>, std::placeholders::_1, def))
#define BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(cond, type, name, provider, pref) \
BOTAN_COND_REGISTER_NAMED_T_NOARGS(cond, BlockCipher, type, name, provider, pref)
diff --git a/src/lib/block/blowfish/blowfish.cpp b/src/lib/block/blowfish/blowfish.cpp
index ece1a31fd..63838929d 100644
--- a/src/lib/block/blowfish/blowfish.cpp
+++ b/src/lib/block/blowfish/blowfish.cpp
@@ -88,10 +88,10 @@ void Blowfish::decrypt_n(const byte in[], byte out[], size_t blocks) const
void Blowfish::key_schedule(const byte key[], size_t length)
{
P.resize(18);
- std::copy(P_INIT, P_INIT + 18, P.begin());
+ copy_mem(P.data(), P_INIT, 18);
S.resize(1024);
- std::copy(S_INIT, S_INIT + 1024, S.begin());
+ copy_mem(S.data(), S_INIT, 1024);
const byte null_salt[16] = { 0 };
@@ -133,10 +133,10 @@ void Blowfish::eks_key_schedule(const byte key[], size_t length,
std::to_string(workfactor) + " too large");
P.resize(18);
- std::copy(P_INIT, P_INIT + 18, P.begin());
+ copy_mem(P.data(), P_INIT, 18);
S.resize(1024);
- std::copy(S_INIT, S_INIT + 1024, S.begin());
+ copy_mem(S.data(), S_INIT, 1024);
key_expansion(key, length, salt);
diff --git a/src/lib/block/blowfish/blowfish.h b/src/lib/block/blowfish/blowfish.h
index 8653bb7d6..e1042465f 100644
--- a/src/lib/block/blowfish/blowfish.h
+++ b/src/lib/block/blowfish/blowfish.h
@@ -18,8 +18,8 @@ namespace Botan {
class BOTAN_DLL Blowfish : public Block_Cipher_Fixed_Params<8, 1, 56>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
/**
* Modified EKSBlowfish key schedule, used for bcrypt password hashing
@@ -27,11 +27,11 @@ class BOTAN_DLL Blowfish : public Block_Cipher_Fixed_Params<8, 1, 56>
void eks_key_schedule(const byte key[], size_t key_length,
const byte salt[16], size_t workfactor);
- void clear();
- std::string name() const { return "Blowfish"; }
- BlockCipher* clone() const { return new Blowfish; }
+ void clear() override;
+ std::string name() const override { return "Blowfish"; }
+ BlockCipher* clone() const override { return new Blowfish; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
void key_expansion(const byte key[],
size_t key_length,
diff --git a/src/lib/block/camellia/camellia.h b/src/lib/block/camellia/camellia.h
index ea08ce2a2..884cb2bd7 100644
--- a/src/lib/block/camellia/camellia.h
+++ b/src/lib/block/camellia/camellia.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL Camellia_128 : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Camellia-128"; }
- BlockCipher* clone() const { return new Camellia_128; }
+ void clear() override;
+ std::string name() const override { return "Camellia-128"; }
+ BlockCipher* clone() const override { return new Camellia_128; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u64bit> SK;
};
@@ -36,14 +36,14 @@ class BOTAN_DLL Camellia_128 : public Block_Cipher_Fixed_Params<16, 16>
class BOTAN_DLL Camellia_192 : public Block_Cipher_Fixed_Params<16, 24>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Camellia-192"; }
- BlockCipher* clone() const { return new Camellia_192; }
+ void clear() override;
+ std::string name() const override { return "Camellia-192"; }
+ BlockCipher* clone() const override { return new Camellia_192; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u64bit> SK;
};
@@ -54,14 +54,14 @@ class BOTAN_DLL Camellia_192 : public Block_Cipher_Fixed_Params<16, 24>
class BOTAN_DLL Camellia_256 : public Block_Cipher_Fixed_Params<16, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Camellia-256"; }
- BlockCipher* clone() const { return new Camellia_256; }
+ void clear() override;
+ std::string name() const override { return "Camellia-256"; }
+ BlockCipher* clone() const override { return new Camellia_256; }
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u64bit> SK;
};
diff --git a/src/lib/block/cascade/cascade.h b/src/lib/block/cascade/cascade.h
index e96c34549..386f1bd21 100644
--- a/src/lib/block/cascade/cascade.h
+++ b/src/lib/block/cascade/cascade.h
@@ -18,20 +18,20 @@ namespace Botan {
class BOTAN_DLL Cascade_Cipher : public BlockCipher
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- size_t block_size() const { return m_block; }
+ size_t block_size() const override { return m_block; }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(m_cipher1->maximum_keylength() +
m_cipher2->maximum_keylength());
}
- void clear();
- std::string name() const;
- BlockCipher* clone() const;
+ void clear() override;
+ std::string name() const override;
+ BlockCipher* clone() const override;
static Cascade_Cipher* make(const Spec& spec);
@@ -45,7 +45,7 @@ class BOTAN_DLL Cascade_Cipher : public BlockCipher
Cascade_Cipher(const Cascade_Cipher&) = delete;
Cascade_Cipher& operator=(const Cascade_Cipher&) = delete;
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
size_t m_block;
std::unique_ptr<BlockCipher> m_cipher1, m_cipher2;
diff --git a/src/lib/block/cast/cast128.h b/src/lib/block/cast/cast128.h
index ed28d6a71..2a0f4462a 100644
--- a/src/lib/block/cast/cast128.h
+++ b/src/lib/block/cast/cast128.h
@@ -18,15 +18,15 @@ namespace Botan {
class BOTAN_DLL CAST_128 : public Block_Cipher_Fixed_Params<8, 11, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "CAST-128"; }
- BlockCipher* clone() const { return new CAST_128; }
+ void clear() override;
+ std::string name() const override { return "CAST-128"; }
+ BlockCipher* clone() const override { return new CAST_128; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
static void cast_ks(secure_vector<u32bit>& ks,
secure_vector<u32bit>& user_key);
diff --git a/src/lib/block/cast/cast256.h b/src/lib/block/cast/cast256.h
index 206b4d83e..9f7546711 100644
--- a/src/lib/block/cast/cast256.h
+++ b/src/lib/block/cast/cast256.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL CAST_256 : public Block_Cipher_Fixed_Params<16, 4, 32, 4>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "CAST-256"; }
- BlockCipher* clone() const { return new CAST_256; }
+ void clear() override;
+ std::string name() const override { return "CAST-256"; }
+ BlockCipher* clone() const override { return new CAST_256; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> MK;
secure_vector<byte> RK;
diff --git a/src/lib/block/des/des.h b/src/lib/block/des/des.h
index aa201e560..1a2fdc5c9 100644
--- a/src/lib/block/des/des.h
+++ b/src/lib/block/des/des.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL DES : public Block_Cipher_Fixed_Params<8, 8>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "DES"; }
- BlockCipher* clone() const { return new DES; }
+ void clear() override;
+ std::string name() const override { return "DES"; }
+ BlockCipher* clone() const override { return new DES; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> round_key;
};
@@ -36,14 +36,14 @@ class BOTAN_DLL DES : public Block_Cipher_Fixed_Params<8, 8>
class BOTAN_DLL TripleDES : public Block_Cipher_Fixed_Params<8, 16, 24, 8>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "TripleDES"; }
- BlockCipher* clone() const { return new TripleDES; }
+ void clear() override;
+ std::string name() const override { return "TripleDES"; }
+ BlockCipher* clone() const override { return new TripleDES; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> round_key;
};
diff --git a/src/lib/block/des/desx.h b/src/lib/block/des/desx.h
index f324ed7d5..0f155b241 100644
--- a/src/lib/block/des/desx.h
+++ b/src/lib/block/des/desx.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL DESX : public Block_Cipher_Fixed_Params<8, 24>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "DESX"; }
- BlockCipher* clone() const { return new DESX; }
+ void clear() override;
+ std::string name() const override { return "DESX"; }
+ BlockCipher* clone() const override { return new DESX; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<byte> K1, K2;
DES des;
};
diff --git a/src/lib/block/gost_28147/gost_28147.h b/src/lib/block/gost_28147/gost_28147.h
index 6d6e546f2..3cf1c4578 100644
--- a/src/lib/block/gost_28147/gost_28147.h
+++ b/src/lib/block/gost_28147/gost_28147.h
@@ -52,13 +52,13 @@ class BOTAN_DLL GOST_28147_89_Params
class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
+ void clear() override;
- std::string name() const;
- BlockCipher* clone() const { return new GOST_28147_89(SBOX); }
+ std::string name() const override;
+ BlockCipher* clone() const override { return new GOST_28147_89(SBOX); }
/**
* @param params the sbox parameters to use
@@ -68,7 +68,7 @@ class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32>
GOST_28147_89(const std::vector<u32bit>& other_SBOX) :
SBOX(other_SBOX), EK(8) {}
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
/*
* The sbox is not secret, this is just a larger expansion of it
diff --git a/src/lib/block/idea/idea.h b/src/lib/block/idea/idea.h
index 3c01ad873..68d4d61b0 100644
--- a/src/lib/block/idea/idea.h
+++ b/src/lib/block/idea/idea.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "IDEA"; }
- BlockCipher* clone() const { return new IDEA; }
+ void clear() override;
+ std::string name() const override { return "IDEA"; }
+ BlockCipher* clone() const override { return new IDEA; }
protected:
/**
* @return const reference to encryption subkeys
@@ -36,7 +36,7 @@ class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16>
const secure_vector<u16bit>& get_DK() const { return DK; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u16bit> EK, DK;
};
diff --git a/src/lib/block/idea_sse2/idea_sse2.h b/src/lib/block/idea_sse2/idea_sse2.h
index 10d19688e..18ea7c74d 100644
--- a/src/lib/block/idea_sse2/idea_sse2.h
+++ b/src/lib/block/idea_sse2/idea_sse2.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL IDEA_SSE2 : public IDEA
{
public:
- size_t parallelism() const { return 8; }
+ size_t parallelism() const override { return 8; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- BlockCipher* clone() const { return new IDEA_SSE2; }
+ BlockCipher* clone() const override { return new IDEA_SSE2; }
};
}
diff --git a/src/lib/block/kasumi/kasumi.h b/src/lib/block/kasumi/kasumi.h
index 97e8dbb31..9f86279af 100644
--- a/src/lib/block/kasumi/kasumi.h
+++ b/src/lib/block/kasumi/kasumi.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL KASUMI : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "KASUMI"; }
- BlockCipher* clone() const { return new KASUMI; }
+ void clear() override;
+ std::string name() const override { return "KASUMI"; }
+ BlockCipher* clone() const override { return new KASUMI; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u16bit> EK;
};
diff --git a/src/lib/block/lion/lion.h b/src/lib/block/lion/lion.h
index 451ee9f88..d03d1d1a0 100644
--- a/src/lib/block/lion/lion.h
+++ b/src/lib/block/lion/lion.h
@@ -48,7 +48,7 @@ class BOTAN_DLL Lion : public BlockCipher
StreamCipher* cipher,
size_t block_size);
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
size_t left_size() const { return m_hash->output_length(); }
size_t right_size() const { return m_block_size - left_size(); }
diff --git a/src/lib/block/mars/mars.h b/src/lib/block/mars/mars.h
index 90de963ce..250fd2731 100644
--- a/src/lib/block/mars/mars.h
+++ b/src/lib/block/mars/mars.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL MARS : public Block_Cipher_Fixed_Params<16, 16, 32, 4>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "MARS"; }
- BlockCipher* clone() const { return new MARS; }
+ void clear() override;
+ std::string name() const override { return "MARS"; }
+ BlockCipher* clone() const override { return new MARS; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK;
};
diff --git a/src/lib/block/misty1/misty1.h b/src/lib/block/misty1/misty1.h
index 177c2c0b5..56153f929 100644
--- a/src/lib/block/misty1/misty1.h
+++ b/src/lib/block/misty1/misty1.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL MISTY1 : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "MISTY1"; }
- BlockCipher* clone() const { return new MISTY1; }
+ void clear() override;
+ std::string name() const override { return "MISTY1"; }
+ BlockCipher* clone() const override { return new MISTY1; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u16bit> EK, DK;
};
diff --git a/src/lib/block/noekeon/noekeon.h b/src/lib/block/noekeon/noekeon.h
index 36be5903c..7b5b6d11b 100644
--- a/src/lib/block/noekeon/noekeon.h
+++ b/src/lib/block/noekeon/noekeon.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Noekeon"; }
- BlockCipher* clone() const { return new Noekeon; }
+ void clear() override;
+ std::string name() const override { return "Noekeon"; }
+ BlockCipher* clone() const override { return new Noekeon; }
protected:
/**
* The Noekeon round constants
@@ -41,7 +41,7 @@ class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16>
const secure_vector<u32bit>& get_DK() const { return DK; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK, DK;
};
diff --git a/src/lib/block/noekeon_simd/noekeon_simd.h b/src/lib/block/noekeon_simd/noekeon_simd.h
index eaf48a364..8d40d13dd 100644
--- a/src/lib/block/noekeon_simd/noekeon_simd.h
+++ b/src/lib/block/noekeon_simd/noekeon_simd.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL Noekeon_SIMD : public Noekeon
{
public:
- size_t parallelism() const { return 4; }
+ size_t parallelism() const override { return 4; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- BlockCipher* clone() const { return new Noekeon_SIMD; }
+ BlockCipher* clone() const override { return new Noekeon_SIMD; }
};
}
diff --git a/src/lib/block/rc2/rc2.h b/src/lib/block/rc2/rc2.h
index 1ae58e186..11956f408 100644
--- a/src/lib/block/rc2/rc2.h
+++ b/src/lib/block/rc2/rc2.h
@@ -18,8 +18,8 @@ namespace Botan {
class BOTAN_DLL RC2 : public Block_Cipher_Fixed_Params<8, 1, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
/**
* Return the code of the effective key bits
@@ -28,11 +28,11 @@ class BOTAN_DLL RC2 : public Block_Cipher_Fixed_Params<8, 1, 32>
*/
static byte EKB_code(size_t bits);
- void clear();
- std::string name() const { return "RC2"; }
- BlockCipher* clone() const { return new RC2; }
+ void clear() override;
+ std::string name() const override { return "RC2"; }
+ BlockCipher* clone() const override { return new RC2; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u16bit> K;
};
diff --git a/src/lib/block/rc5/rc5.h b/src/lib/block/rc5/rc5.h
index 782d0592c..b8ff1c3f7 100644
--- a/src/lib/block/rc5/rc5.h
+++ b/src/lib/block/rc5/rc5.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL RC5 : public Block_Cipher_Fixed_Params<8, 1, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const;
- BlockCipher* clone() const { return new RC5(rounds); }
+ void clear() override;
+ std::string name() const override;
+ BlockCipher* clone() const override { return new RC5(rounds); }
/**
* @param rounds the number of RC5 rounds to run. Must be between
@@ -31,7 +31,7 @@ class BOTAN_DLL RC5 : public Block_Cipher_Fixed_Params<8, 1, 32>
*/
RC5(size_t rounds);
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
size_t rounds;
secure_vector<u32bit> S;
diff --git a/src/lib/block/rc6/rc6.h b/src/lib/block/rc6/rc6.h
index 282d56639..1ff7304ed 100644
--- a/src/lib/block/rc6/rc6.h
+++ b/src/lib/block/rc6/rc6.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL RC6 : public Block_Cipher_Fixed_Params<16, 1, 32>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "RC6"; }
- BlockCipher* clone() const { return new RC6; }
+ void clear() override;
+ std::string name() const override { return "RC6"; }
+ BlockCipher* clone() const override { return new RC6; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> S;
};
diff --git a/src/lib/block/safer/safer_sk.h b/src/lib/block/safer/safer_sk.h
index d346c739e..74241d4e6 100644
--- a/src/lib/block/safer/safer_sk.h
+++ b/src/lib/block/safer/safer_sk.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL SAFER_SK : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const;
- BlockCipher* clone() const;
+ void clear() override;
+ std::string name() const override;
+ BlockCipher* clone() const override;
/**
* @param rounds the number of rounds to use - must be between 1
@@ -31,7 +31,7 @@ class BOTAN_DLL SAFER_SK : public Block_Cipher_Fixed_Params<8, 16>
*/
SAFER_SK(size_t rounds);
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
size_t rounds;
secure_vector<byte> EK;
diff --git a/src/lib/block/seed/seed.h b/src/lib/block/seed/seed.h
index d98d6e798..431af7309 100644
--- a/src/lib/block/seed/seed.h
+++ b/src/lib/block/seed/seed.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL SEED : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "SEED"; }
- BlockCipher* clone() const { return new SEED; }
+ void clear() override;
+ std::string name() const override { return "SEED"; }
+ BlockCipher* clone() const override { return new SEED; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
class G_FUNC
{
diff --git a/src/lib/block/serpent/serpent.h b/src/lib/block/serpent/serpent.h
index a3f5d0817..7fdf4600d 100644
--- a/src/lib/block/serpent/serpent.h
+++ b/src/lib/block/serpent/serpent.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Serpent"; }
- BlockCipher* clone() const { return new Serpent; }
+ void clear() override;
+ std::string name() const override { return "Serpent"; }
+ BlockCipher* clone() const override { return new Serpent; }
protected:
/**
* For use by subclasses using SIMD, asm, etc
@@ -42,7 +42,7 @@ class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
}
private:
- void key_schedule(const byte key[], size_t length);
+ void key_schedule(const byte key[], size_t length) override;
secure_vector<u32bit> round_key;
};
diff --git a/src/lib/block/serpent_simd/serp_simd.h b/src/lib/block/serpent_simd/serp_simd.h
index cde5bf112..373d47fa1 100644
--- a/src/lib/block/serpent_simd/serp_simd.h
+++ b/src/lib/block/serpent_simd/serp_simd.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL Serpent_SIMD : public Serpent
{
public:
- size_t parallelism() const { return 4; }
+ size_t parallelism() const override { return 4; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- BlockCipher* clone() const { return new Serpent_SIMD; }
+ BlockCipher* clone() const override { return new Serpent_SIMD; }
};
}
diff --git a/src/lib/block/serpent_x86_32/info.txt b/src/lib/block/serpent_x86_32/info.txt
deleted file mode 100644
index 370213e87..000000000
--- a/src/lib/block/serpent_x86_32/info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-define SERPENT_X86_32 20131128
-
-load_on asm_ok
-
-<arch>
-x86_32
-</arch>
-
-<requires>
-asm_x86_32
-serpent
-</requires>
diff --git a/src/lib/block/serpent_x86_32/serp_x86_32.cpp b/src/lib/block/serpent_x86_32/serp_x86_32.cpp
deleted file mode 100644
index f055880b3..000000000
--- a/src/lib/block/serpent_x86_32/serp_x86_32.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-* Serpent in x86-32
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/block_utils.h>
-#include <botan/serp_x86_32.h>
-
-namespace Botan {
-
-BOTAN_REGISTER_NAMED_T_NOARGS(BlockCipher, Serpent_X86_32, "Serpent", "x86-32");
-
-extern "C" {
-
-/**
-* Entry point for Serpent encryption in x86 asm
-* @param in the input block
-* @param out the output block
-* @param ks the key schedule
-*/
-void botan_serpent_x86_32_encrypt(const byte in[16],
- byte out[16],
- const u32bit ks[132]);
-
-/**
-* Entry point for Serpent decryption in x86 asm
-* @param in the input block
-* @param out the output block
-* @param ks the key schedule
-*/
-void botan_serpent_x86_32_decrypt(const byte in[16],
- byte out[16],
- const u32bit ks[132]);
-
-/**
-* Entry point for Serpent key schedule in x86 asm
-* @param ks holds the initial working key (padded), and is set to the
- final key schedule
-*/
-void botan_serpent_x86_32_key_schedule(u32bit ks[140]);
-
-}
-
-/*
-* Serpent Encryption
-*/
-void Serpent_X86_32::encrypt_n(const byte in[], byte out[], size_t blocks) const
- {
- auto keys = this->get_round_keys();
-
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_serpent_x86_32_encrypt(in, out, keys.data());
- in += BLOCK_SIZE;
- out += BLOCK_SIZE;
- }
- }
-
-/*
-* Serpent Decryption
-*/
-void Serpent_X86_32::decrypt_n(const byte in[], byte out[], size_t blocks) const
- {
- auto keys = this->get_round_keys();
-
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_serpent_x86_32_decrypt(in, out, keys.data());
- in += BLOCK_SIZE;
- out += BLOCK_SIZE;
- }
- }
-
-/*
-* Serpent Key Schedule
-*/
-void Serpent_X86_32::key_schedule(const byte key[], size_t length)
- {
- secure_vector<u32bit> W(140);
- for(size_t i = 0; i != length / 4; ++i)
- W[i] = load_le<u32bit>(key, i);
- W[length / 4] |= u32bit(1) << ((length%4)*8);
-
- botan_serpent_x86_32_key_schedule(W.data());
- this->set_round_keys(&W[8]);
- }
-
-}
diff --git a/src/lib/block/serpent_x86_32/serp_x86_32.h b/src/lib/block/serpent_x86_32/serp_x86_32.h
deleted file mode 100644
index 89fb1a8fe..000000000
--- a/src/lib/block/serpent_x86_32/serp_x86_32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Serpent in x86-32 asm
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SERPENT_X86_32_H__
-#define BOTAN_SERPENT_X86_32_H__
-
-#include <botan/serpent.h>
-
-namespace Botan {
-
-/**
-* Serpent implementation in x86-32 assembly
-*/
-class BOTAN_DLL Serpent_X86_32 : public Serpent
- {
- public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
-
- BlockCipher* clone() const { return new Serpent_X86_32; }
- private:
- void key_schedule(const byte[], size_t);
- };
-
-}
-
-#endif
diff --git a/src/lib/block/serpent_x86_32/serp_x86_32_imp.S b/src/lib/block/serpent_x86_32/serp_x86_32_imp.S
deleted file mode 100644
index 807c3fc54..000000000
--- a/src/lib/block/serpent_x86_32/serp_x86_32_imp.S
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
-* Serpent in x86-32 assembler
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/asm_x86_32.h>
-
-START_LISTING(serp_x86_32.S)
-
-#define SBOX_E1(A, B, C, D, T) \
- XOR(D, A) ; \
- ASSIGN(T, B) ; \
- AND(B, D) ; \
- XOR(T, C) ; \
- XOR(B, A) ; \
- OR(A, D) ; \
- XOR(A, T) ; \
- XOR(T, D) ; \
- XOR(D, C) ; \
- OR(C, B) ; \
- XOR(C, T) ; \
- NOT(T) ; \
- OR(T, B) ; \
- XOR(B, D) ; \
- XOR(B, T) ; \
- OR(D, A) ; \
- XOR(B, D) ; \
- XOR(T, D) ; \
- ASSIGN(D, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, T) ;
-
-#define SBOX_E2(A, B, C, D, T) \
- NOT(A) ; \
- NOT(C) ; \
- ASSIGN(T, A) ; \
- AND(A, B) ; \
- XOR(C, A) ; \
- OR(A, D) ; \
- XOR(D, C) ; \
- XOR(B, A) ; \
- XOR(A, T) ; \
- OR(T, B) ; \
- XOR(B, D) ; \
- OR(C, A) ; \
- AND(C, T) ; \
- XOR(A, B) ; \
- AND(B, C) ; \
- XOR(B, A) ; \
- AND(A, C) ; \
- XOR(T, A) ; \
- ASSIGN(A, C) ; \
- ASSIGN(C, D) ; \
- ASSIGN(D, B) ; \
- ASSIGN(B, T) ;
-
-#define SBOX_E3(A, B, C, D, T) \
- ASSIGN(T, A) ; \
- AND(A, C) ; \
- XOR(A, D) ; \
- XOR(C, B) ; \
- XOR(C, A) ; \
- OR(D, T) ; \
- XOR(D, B) ; \
- XOR(T, C) ; \
- ASSIGN(B, D) ; \
- OR(D, T) ; \
- XOR(D, A) ; \
- AND(A, B) ; \
- XOR(T, A) ; \
- XOR(B, D) ; \
- XOR(B, T) ; \
- NOT(T) ; \
- ASSIGN(A, C) ; \
- ASSIGN(C, B) ; \
- ASSIGN(B, D) ; \
- ASSIGN(D, T) ;
-
-#define SBOX_E4(A, B, C, D, T) \
- ASSIGN(T, A) ; \
- OR(A, D) ; \
- XOR(D, B) ; \
- AND(B, T) ; \
- XOR(T, C) ; \
- XOR(C, D) ; \
- AND(D, A) ; \
- OR(T, B) ; \
- XOR(D, T) ; \
- XOR(A, B) ; \
- AND(T, A) ; \
- XOR(B, D) ; \
- XOR(T, C) ; \
- OR(B, A) ; \
- XOR(B, C) ; \
- XOR(A, D) ; \
- ASSIGN(C, B) ; \
- OR(B, D) ; \
- XOR(B, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, C) ; \
- ASSIGN(C, D) ; \
- ASSIGN(D, T) ;
-
-#define SBOX_E5(A, B, C, D, T) \
- XOR(B, D) ; \
- NOT(D) ; \
- XOR(C, D) ; \
- XOR(D, A) ; \
- ASSIGN(T, B) ; \
- AND(B, D) ; \
- XOR(B, C) ; \
- XOR(T, D) ; \
- XOR(A, T) ; \
- AND(C, T) ; \
- XOR(C, A) ; \
- AND(A, B) ; \
- XOR(D, A) ; \
- OR(T, B) ; \
- XOR(T, A) ; \
- OR(A, D) ; \
- XOR(A, C) ; \
- AND(C, D) ; \
- NOT(A) ; \
- XOR(T, C) ; \
- ASSIGN(C, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, T) ;
-
-#define SBOX_E6(A, B, C, D, T) \
- XOR(A, B) ; \
- XOR(B, D) ; \
- NOT(D) ; \
- ASSIGN(T, B) ; \
- AND(B, A) ; \
- XOR(C, D) ; \
- XOR(B, C) ; \
- OR(C, T) ; \
- XOR(T, D) ; \
- AND(D, B) ; \
- XOR(D, A) ; \
- XOR(T, B) ; \
- XOR(T, C) ; \
- XOR(C, A) ; \
- AND(A, D) ; \
- NOT(C) ; \
- XOR(A, T) ; \
- OR(T, D) ; \
- XOR(T, C) ; \
- ASSIGN(C, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, D) ; \
- ASSIGN(D, T) ;
-
-#define SBOX_E7(A, B, C, D, T) \
- NOT(C) ; \
- ASSIGN(T, D) ; \
- AND(D, A) ; \
- XOR(A, T) ; \
- XOR(D, C) ; \
- OR(C, T) ; \
- XOR(B, D) ; \
- XOR(C, A) ; \
- OR(A, B) ; \
- XOR(C, B) ; \
- XOR(T, A) ; \
- OR(A, D) ; \
- XOR(A, C) ; \
- XOR(T, D) ; \
- XOR(T, A) ; \
- NOT(D) ; \
- AND(C, T) ; \
- XOR(C, D) ; \
- ASSIGN(D, C) ; \
- ASSIGN(C, T) ;
-
-#define SBOX_E8(A, B, C, D, T) \
- ASSIGN(T, B) ; \
- OR(B, C) ; \
- XOR(B, D) ; \
- XOR(T, C) ; \
- XOR(C, B) ; \
- OR(D, T) ; \
- AND(D, A) ; \
- XOR(T, C) ; \
- XOR(D, B) ; \
- OR(B, T) ; \
- XOR(B, A) ; \
- OR(A, T) ; \
- XOR(A, C) ; \
- XOR(B, T) ; \
- XOR(C, B) ; \
- AND(B, A) ; \
- XOR(B, T) ; \
- NOT(C) ; \
- OR(C, A) ; \
- XOR(T, C) ; \
- ASSIGN(C, B) ; \
- ASSIGN(B, D) ; \
- ASSIGN(D, A) ; \
- ASSIGN(A, T) ;
-
-#define SBOX_D1(A, B, C, D, T) \
- NOT(C) ; \
- ASSIGN(T, B) ; \
- OR(B, A) ; \
- NOT(T) ; \
- XOR(B, C) ; \
- OR(C, T) ; \
- XOR(B, D) ; \
- XOR(A, T) ; \
- XOR(C, A) ; \
- AND(A, D) ; \
- XOR(T, A) ; \
- OR(A, B) ; \
- XOR(A, C) ; \
- XOR(D, T) ; \
- XOR(C, B) ; \
- XOR(D, A) ; \
- XOR(D, B) ; \
- AND(C, D) ; \
- XOR(T, C) ; \
- ASSIGN(C, B) ; \
- ASSIGN(B, T) ;
-
-#define SBOX_D2(A, B, C, D, T) \
- ASSIGN(T, B) ; \
- XOR(B, D) ; \
- AND(D, B) ; \
- XOR(T, C) ; \
- XOR(D, A) ; \
- OR(A, B) ; \
- XOR(C, D) ; \
- XOR(A, T) ; \
- OR(A, C) ; \
- XOR(B, D) ; \
- XOR(A, B) ; \
- OR(B, D) ; \
- XOR(B, A) ; \
- NOT(T) ; \
- XOR(T, B) ; \
- OR(B, A) ; \
- XOR(B, A) ; \
- OR(B, T) ; \
- XOR(D, B) ; \
- ASSIGN(B, A) ; \
- ASSIGN(A, T) ; \
- ASSIGN(T, D) ; \
- ASSIGN(D, C) ; \
- ASSIGN(C, T) ;
-
-#define SBOX_D3(A, B, C, D, T) \
- XOR(C, D) ; \
- XOR(D, A) ; \
- ASSIGN(T, D) ; \
- AND(D, C) ; \
- XOR(D, B) ; \
- OR(B, C) ; \
- XOR(B, T) ; \
- AND(T, D) ; \
- XOR(C, D) ; \
- AND(T, A) ; \
- XOR(T, C) ; \
- AND(C, B) ; \
- OR(C, A) ; \
- NOT(D) ; \
- XOR(C, D) ; \
- XOR(A, D) ; \
- AND(A, B) ; \
- XOR(D, T) ; \
- XOR(D, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, T) ;
-
-#define SBOX_D4(A, B, C, D, T) \
- ASSIGN(T, C) ; \
- XOR(C, B) ; \
- XOR(A, C) ; \
- AND(T, C) ; \
- XOR(T, A) ; \
- AND(A, B) ; \
- XOR(B, D) ; \
- OR(D, T) ; \
- XOR(C, D) ; \
- XOR(A, D) ; \
- XOR(B, T) ; \
- AND(D, C) ; \
- XOR(D, B) ; \
- XOR(B, A) ; \
- OR(B, C) ; \
- XOR(A, D) ; \
- XOR(B, T) ; \
- XOR(A, B) ; \
- ASSIGN(T, A) ; \
- ASSIGN(A, C) ; \
- ASSIGN(C, D) ; \
- ASSIGN(D, T) ;
-
-#define SBOX_D5(A, B, C, D, T) \
- ASSIGN(T, C) ; \
- AND(C, D) ; \
- XOR(C, B) ; \
- OR(B, D) ; \
- AND(B, A) ; \
- XOR(T, C) ; \
- XOR(T, B) ; \
- AND(B, C) ; \
- NOT(A) ; \
- XOR(D, T) ; \
- XOR(B, D) ; \
- AND(D, A) ; \
- XOR(D, C) ; \
- XOR(A, B) ; \
- AND(C, A) ; \
- XOR(D, A) ; \
- XOR(C, T) ; \
- OR(C, D) ; \
- XOR(D, A) ; \
- XOR(C, B) ; \
- ASSIGN(B, D) ; \
- ASSIGN(D, T) ;
-
-#define SBOX_D6(A, B, C, D, T) \
- NOT(B) ; \
- ASSIGN(T, D) ; \
- XOR(C, B) ; \
- OR(D, A) ; \
- XOR(D, C) ; \
- OR(C, B) ; \
- AND(C, A) ; \
- XOR(T, D) ; \
- XOR(C, T) ; \
- OR(T, A) ; \
- XOR(T, B) ; \
- AND(B, C) ; \
- XOR(B, D) ; \
- XOR(T, C) ; \
- AND(D, T) ; \
- XOR(T, B) ; \
- XOR(D, T) ; \
- NOT(T) ; \
- XOR(D, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, T) ; \
- ASSIGN(T, D) ; \
- ASSIGN(D, C) ; \
- ASSIGN(C, T) ;
-
-#define SBOX_D7(A, B, C, D, T) \
- XOR(A, C) ; \
- ASSIGN(T, C) ; \
- AND(C, A) ; \
- XOR(T, D) ; \
- NOT(C) ; \
- XOR(D, B) ; \
- XOR(C, D) ; \
- OR(T, A) ; \
- XOR(A, C) ; \
- XOR(D, T) ; \
- XOR(T, B) ; \
- AND(B, D) ; \
- XOR(B, A) ; \
- XOR(A, D) ; \
- OR(A, C) ; \
- XOR(D, B) ; \
- XOR(T, A) ; \
- ASSIGN(A, B) ; \
- ASSIGN(B, C) ; \
- ASSIGN(C, T) ;
-
-#define SBOX_D8(A, B, C, D, T) \
- ASSIGN(T, C) ; \
- XOR(C, A) ; \
- AND(A, D) ; \
- OR(T, D) ; \
- NOT(C) ; \
- XOR(D, B) ; \
- OR(B, A) ; \
- XOR(A, C) ; \
- AND(C, T) ; \
- AND(D, T) ; \
- XOR(B, C) ; \
- XOR(C, A) ; \
- OR(A, C) ; \
- XOR(T, B) ; \
- XOR(A, D) ; \
- XOR(D, T) ; \
- OR(T, A) ; \
- XOR(D, C) ; \
- XOR(T, C) ; \
- ASSIGN(C, B) ; \
- ASSIGN(B, A) ; \
- ASSIGN(A, D) ; \
- ASSIGN(D, T) ;
-
-#define TRANSFORM(A, B, C, D, T) \
- ROTL_IMM(A, 13) ; \
- ROTL_IMM(C, 3) ; \
- SHL2_3(T, A) ; \
- XOR(B, A) ; \
- XOR(D, C) ; \
- XOR(B, C) ; \
- XOR(D, T) ; \
- ROTL_IMM(B, 1) ; \
- ROTL_IMM(D, 7) ; \
- ASSIGN(T, B) ; \
- SHL_IMM(T, 7) ; \
- XOR(A, B) ; \
- XOR(C, D) ; \
- XOR(A, D) ; \
- XOR(C, T) ; \
- ROTL_IMM(A, 5) ; \
- ROTL_IMM(C, 22) ;
-
-#define I_TRANSFORM(A, B, C, D, T) \
- ROTR_IMM(C, 22) ; \
- ROTR_IMM(A, 5) ; \
- ASSIGN(T, B) ; \
- SHL_IMM(T, 7) ; \
- XOR(A, B) ; \
- XOR(C, D) ; \
- XOR(A, D) ; \
- XOR(C, T) ; \
- ROTR_IMM(D, 7) ; \
- ROTR_IMM(B, 1) ; \
- SHL2_3(T, A) ; \
- XOR(B, C) ; \
- XOR(D, C) ; \
- XOR(B, A) ; \
- XOR(D, T) ; \
- ROTR_IMM(C, 3) ; \
- ROTR_IMM(A, 13) ;
-
-#define KEY_XOR(A, B, C, D, N) \
- XOR(A, ARRAY4(EDI, (4*N ))) ; \
- XOR(B, ARRAY4(EDI, (4*N+1))) ; \
- XOR(C, ARRAY4(EDI, (4*N+2))) ; \
- XOR(D, ARRAY4(EDI, (4*N+3))) ;
-
-/*
-* Serpent Encryption
-*/
-START_FUNCTION(botan_serpent_x86_32_encrypt)
- SPILL_REGS()
-#define PUSHED 4
-
- ASSIGN(EBP, ARG(1)) /* input block */
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
- ASSIGN(EDI, ARG(3)) /* round keys */
- ZEROIZE(EBP)
-
-#define E_ROUND(A, B, C, D, T, N, SBOX) \
- KEY_XOR(A, B, C, D, N) \
- SBOX(A, B, C, D, T) \
- TRANSFORM(A, B, C, D, T)
-
-
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_E1)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_E2)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_E3)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_E4)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_E5)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_E6)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_E7)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_E8)
-
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_E1)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_E2)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_E3)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_E4)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_E5)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_E6)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_E7)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_E8)
-
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_E1)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_E2)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_E3)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_E4)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_E5)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_E6)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_E7)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_E8)
-
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_E1)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_E2)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_E3)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_E4)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_E5)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_E6)
- E_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_E7)
-
- KEY_XOR(EAX, EBX, ECX, EDX, 31)
- SBOX_E8(EAX, EBX, ECX, EDX, EBP)
- KEY_XOR(EAX, EBX, ECX, EDX, 32)
-
- ASSIGN(EBP, ARG(2)) /* output block */
- ASSIGN(ARRAY4(EBP, 0), EAX)
- ASSIGN(ARRAY4(EBP, 1), EBX)
- ASSIGN(ARRAY4(EBP, 2), ECX)
- ASSIGN(ARRAY4(EBP, 3), EDX)
-
- RESTORE_REGS()
-#undef PUSHED
-END_FUNCTION(botan_serpent_x86_32_encrypt)
-
-/*
-* Serpent Decryption
-*/
-START_FUNCTION(botan_serpent_x86_32_decrypt)
- SPILL_REGS()
-#define PUSHED 4
-
- ASSIGN(EBP, ARG(1)) /* input block */
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
- ASSIGN(EDI, ARG(3)) /* round keys */
-
- ZEROIZE(EBP)
-
-#define D_ROUND(A, B, C, D, T, N, SBOX) \
- I_TRANSFORM(A, B, C, D, T) \
- SBOX(A, B, C, D, T) \
- KEY_XOR(A, B, C, D, N) \
-
- KEY_XOR(EAX, EBX, ECX, EDX, 32)
- SBOX_D8(EAX, EBX, ECX, EDX, EBP)
- KEY_XOR(EAX, EBX, ECX, EDX, 31)
-
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 30, SBOX_D7)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 29, SBOX_D6)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 28, SBOX_D5)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 27, SBOX_D4)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 26, SBOX_D3)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 25, SBOX_D2)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 24, SBOX_D1)
-
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 23, SBOX_D8)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 22, SBOX_D7)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 21, SBOX_D6)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 20, SBOX_D5)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 19, SBOX_D4)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 18, SBOX_D3)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 17, SBOX_D2)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 16, SBOX_D1)
-
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 15, SBOX_D8)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 14, SBOX_D7)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 13, SBOX_D6)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 12, SBOX_D5)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 11, SBOX_D4)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 10, SBOX_D3)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 9, SBOX_D2)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 8, SBOX_D1)
-
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 7, SBOX_D8)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 6, SBOX_D7)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 5, SBOX_D6)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 4, SBOX_D5)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 3, SBOX_D4)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 2, SBOX_D3)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 1, SBOX_D2)
- D_ROUND(EAX, EBX, ECX, EDX, EBP, 0, SBOX_D1)
-
- ASSIGN(EBP, ARG(2)) /* output block */
- ASSIGN(ARRAY4(EBP, 0), EAX)
- ASSIGN(ARRAY4(EBP, 1), EBX)
- ASSIGN(ARRAY4(EBP, 2), ECX)
- ASSIGN(ARRAY4(EBP, 3), EDX)
-
- RESTORE_REGS()
-#undef PUSHED
-END_FUNCTION(botan_serpent_x86_32_decrypt)
-
-/*
-* Serpent Key Schedule
-*/
-START_FUNCTION(botan_serpent_x86_32_key_schedule)
- SPILL_REGS()
-#define PUSHED 4
-
- ASSIGN(EDI, ARG(1)) /* round keys */
- ASSIGN(ESI, IMM(8))
- ADD_IMM(EDI, 32)
-
-START_LOOP(.L_SERP_EXPANSION)
- ASSIGN(EAX, ARRAY4(EDI, -1))
- ASSIGN(EBX, ARRAY4(EDI, -3))
- ASSIGN(ECX, ARRAY4(EDI, -5))
- ASSIGN(EDX, ARRAY4(EDI, -8))
-
- ASSIGN(EBP, ESI)
- SUB_IMM(EBP, 8)
- XOR(EBP, IMM(0x9E3779B9))
- XOR(EAX, EBX)
- XOR(ECX, EDX)
- XOR(EAX, EBP)
- XOR(EAX, ECX)
-
- ROTL_IMM(EAX, 11)
-
- ASSIGN(ARRAY4(EDI, 0), EAX)
-
- ADD_IMM(ESI, 1)
- ADD_IMM(EDI, 4)
-LOOP_UNTIL_EQ(ESI, 140, .L_SERP_EXPANSION)
-
- ASSIGN(EDI, ARG(1)) /* round keys */
-
-#define LOAD_AND_SBOX(MSG, SBOX) \
- ASSIGN(EAX, ARRAY4(EDI, (4*MSG+ 8))) ; \
- ASSIGN(EBX, ARRAY4(EDI, (4*MSG+ 9))) ; \
- ASSIGN(ECX, ARRAY4(EDI, (4*MSG+10))) ; \
- ASSIGN(EDX, ARRAY4(EDI, (4*MSG+11))) ; \
- SBOX(EAX, EBX, ECX, EDX, EBP) ; \
- ASSIGN(ARRAY4(EDI, (4*MSG+ 8)), EAX) ; \
- ASSIGN(ARRAY4(EDI, (4*MSG+ 9)), EBX) ; \
- ASSIGN(ARRAY4(EDI, (4*MSG+10)), ECX) ; \
- ASSIGN(ARRAY4(EDI, (4*MSG+11)), EDX)
-
- LOAD_AND_SBOX( 0, SBOX_E4)
- LOAD_AND_SBOX( 1, SBOX_E3)
- LOAD_AND_SBOX( 2, SBOX_E2)
- LOAD_AND_SBOX( 3, SBOX_E1)
-
- LOAD_AND_SBOX( 4, SBOX_E8)
- LOAD_AND_SBOX( 5, SBOX_E7)
- LOAD_AND_SBOX( 6, SBOX_E6)
- LOAD_AND_SBOX( 7, SBOX_E5)
- LOAD_AND_SBOX( 8, SBOX_E4)
- LOAD_AND_SBOX( 9, SBOX_E3)
- LOAD_AND_SBOX(10, SBOX_E2)
- LOAD_AND_SBOX(11, SBOX_E1)
-
- LOAD_AND_SBOX(12, SBOX_E8)
- LOAD_AND_SBOX(13, SBOX_E7)
- LOAD_AND_SBOX(14, SBOX_E6)
- LOAD_AND_SBOX(15, SBOX_E5)
- LOAD_AND_SBOX(16, SBOX_E4)
- LOAD_AND_SBOX(17, SBOX_E3)
- LOAD_AND_SBOX(18, SBOX_E2)
- LOAD_AND_SBOX(19, SBOX_E1)
-
- LOAD_AND_SBOX(20, SBOX_E8)
- LOAD_AND_SBOX(21, SBOX_E7)
- LOAD_AND_SBOX(22, SBOX_E6)
- LOAD_AND_SBOX(23, SBOX_E5)
- LOAD_AND_SBOX(24, SBOX_E4)
- LOAD_AND_SBOX(25, SBOX_E3)
- LOAD_AND_SBOX(26, SBOX_E2)
- LOAD_AND_SBOX(27, SBOX_E1)
-
- LOAD_AND_SBOX(28, SBOX_E8)
- LOAD_AND_SBOX(29, SBOX_E7)
- LOAD_AND_SBOX(30, SBOX_E6)
- LOAD_AND_SBOX(31, SBOX_E5)
- LOAD_AND_SBOX(32, SBOX_E4)
-
- RESTORE_REGS()
-#undef PUSHED
-END_FUNCTION(botan_serpent_x86_32_key_schedule)
diff --git a/src/lib/block/tea/tea.h b/src/lib/block/tea/tea.h
index 55e6d8309..3c5b4773e 100644
--- a/src/lib/block/tea/tea.h
+++ b/src/lib/block/tea/tea.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL TEA : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "TEA"; }
- BlockCipher* clone() const { return new TEA; }
+ void clear() override;
+ std::string name() const override { return "TEA"; }
+ BlockCipher* clone() const override { return new TEA; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> K;
};
diff --git a/src/lib/block/threefish_avx2/info.txt b/src/lib/block/threefish_avx2/info.txt
index 3f62629b9..4a3275092 100644
--- a/src/lib/block/threefish_avx2/info.txt
+++ b/src/lib/block/threefish_avx2/info.txt
@@ -1,3 +1,7 @@
define THREEFISH_512_AVX2 20131224
need_isa avx2
+
+<requires>
+threefish
+</requires>
diff --git a/src/lib/block/twofish/twofish.h b/src/lib/block/twofish/twofish.h
index f6e030df2..c6af1a030 100644
--- a/src/lib/block/twofish/twofish.h
+++ b/src/lib/block/twofish/twofish.h
@@ -18,14 +18,14 @@ namespace Botan {
class BOTAN_DLL Twofish : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "Twofish"; }
- BlockCipher* clone() const { return new Twofish; }
+ void clear() override;
+ std::string name() const override { return "Twofish"; }
+ BlockCipher* clone() const override { return new Twofish; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
static void rs_mul(byte[4], byte, size_t);
diff --git a/src/lib/block/xtea/xtea.h b/src/lib/block/xtea/xtea.h
index 4de0bea72..ea5c39418 100644
--- a/src/lib/block/xtea/xtea.h
+++ b/src/lib/block/xtea/xtea.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL XTEA : public Block_Cipher_Fixed_Params<8, 16>
{
public:
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
- void clear();
- std::string name() const { return "XTEA"; }
- BlockCipher* clone() const { return new XTEA; }
+ void clear() override;
+ std::string name() const override { return "XTEA"; }
+ BlockCipher* clone() const override { return new XTEA; }
protected:
/**
* @return const reference to the key schedule
@@ -31,7 +31,7 @@ class BOTAN_DLL XTEA : public Block_Cipher_Fixed_Params<8, 16>
const secure_vector<u32bit>& get_EK() const { return EK; }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
secure_vector<u32bit> EK;
};
diff --git a/src/lib/block/xtea_simd/xtea_simd.h b/src/lib/block/xtea_simd/xtea_simd.h
index 451dc8c8d..04280f1ae 100644
--- a/src/lib/block/xtea_simd/xtea_simd.h
+++ b/src/lib/block/xtea_simd/xtea_simd.h
@@ -18,11 +18,11 @@ namespace Botan {
class BOTAN_DLL XTEA_SIMD : public XTEA
{
public:
- size_t parallelism() const { return 8; }
+ size_t parallelism() const override { return 8; }
- void encrypt_n(const byte in[], byte out[], size_t blocks) const;
- void decrypt_n(const byte in[], byte out[], size_t blocks) const;
- BlockCipher* clone() const { return new XTEA_SIMD; }
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
+ BlockCipher* clone() const override { return new XTEA_SIMD; }
};
}
diff --git a/src/lib/cert/cvc/cvc_self.h b/src/lib/cert/cvc/cvc_self.h
index b29164a7f..005703636 100644
--- a/src/lib/cert/cvc/cvc_self.h
+++ b/src/lib/cert/cvc/cvc_self.h
@@ -9,7 +9,6 @@
#ifndef BOTAN_CVC_EAC_SELF_H__
#define BOTAN_CVC_EAC_SELF_H__
-#include <botan/pkcs8.h>
#include <botan/cvc_cert.h>
#include <botan/ecdsa.h>
#include <botan/asn1_obj.h>
diff --git a/src/lib/cert/cvc/signed_obj.h b/src/lib/cert/cvc/signed_obj.h
index a6b49c55b..aa6ace4b7 100644
--- a/src/lib/cert/cvc/signed_obj.h
+++ b/src/lib/cert/cvc/signed_obj.h
@@ -10,7 +10,6 @@
#define BOTAN_EAC_SIGNED_OBJECT_H__
#include <botan/asn1_obj.h>
-#include <botan/key_constraint.h>
#include <botan/x509_key.h>
#include <botan/pipe.h>
#include <vector>
diff --git a/src/lib/cert/x509/certstor.cpp b/src/lib/cert/x509/certstor.cpp
index d075fe706..e3498f602 100644
--- a/src/lib/cert/x509/certstor.cpp
+++ b/src/lib/cert/x509/certstor.cpp
@@ -6,7 +6,7 @@
*/
#include <botan/certstor.h>
-#include <botan/fs.h>
+#include <botan/internal/filesystem.h>
namespace Botan {
@@ -118,7 +118,7 @@ Certificate_Store_In_Memory::Certificate_Store_In_Memory(const std::string& dir)
if(dir == "")
return;
- std::vector<std::string> maybe_certs = list_all_readable_files_in_or_under(dir);
+ std::vector<std::string> maybe_certs = get_files_recursive(dir);
for(auto&& cert_file : maybe_certs)
{
try
diff --git a/src/lib/cert/x509/crl_ent.h b/src/lib/cert/x509/crl_ent.h
index 7cf148fd9..42cb25fe3 100644
--- a/src/lib/cert/x509/crl_ent.h
+++ b/src/lib/cert/x509/crl_ent.h
@@ -39,8 +39,8 @@ enum CRL_Code {
class BOTAN_DLL CRL_Entry : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
/**
* Get the serial number of the certificate associated with this entry.
diff --git a/src/lib/cert/x509/pkcs10.h b/src/lib/cert/x509/pkcs10.h
index 0d73466bd..6aa66fbfd 100644
--- a/src/lib/cert/x509/pkcs10.h
+++ b/src/lib/cert/x509/pkcs10.h
@@ -10,7 +10,6 @@
#include <botan/x509_obj.h>
#include <botan/x509_dn.h>
-#include <botan/pkcs8.h>
#include <botan/datastor.h>
#include <botan/key_constraint.h>
#include <botan/asn1_attribute.h>
@@ -100,7 +99,7 @@ class BOTAN_DLL PKCS10_Request : public X509_Object
*/
PKCS10_Request(const std::vector<byte>& vec);
private:
- void force_decode();
+ void force_decode() override;
void handle_attribute(const Attribute&);
Data_Store info;
diff --git a/src/lib/cert/x509/x509_ca.h b/src/lib/cert/x509/x509_ca.h
index 6dc65493e..2e05258e3 100644
--- a/src/lib/cert/x509/x509_ca.h
+++ b/src/lib/cert/x509/x509_ca.h
@@ -11,7 +11,6 @@
#include <botan/x509cert.h>
#include <botan/x509_crl.h>
#include <botan/x509_ext.h>
-#include <botan/pkcs8.h>
#include <botan/pkcs10.h>
#include <botan/pubkey.h>
diff --git a/src/lib/cert/x509/x509_crl.cpp b/src/lib/cert/x509/x509_crl.cpp
index e3dfb787e..8b6d1522b 100644
--- a/src/lib/cert/x509/x509_crl.cpp
+++ b/src/lib/cert/x509/x509_crl.cpp
@@ -102,8 +102,8 @@ void X509_CRL::force_decode()
X509_Time start, end;
tbs_crl.decode(start).decode(end);
- info.add("X509.CRL.start", start.readable_string());
- info.add("X509.CRL.end", end.readable_string());
+ info.add("X509.CRL.start", start.to_string());
+ info.add("X509.CRL.end", end.to_string());
BER_Object next = tbs_crl.get_next_object();
@@ -177,7 +177,7 @@ u32bit X509_CRL::crl_number() const
*/
X509_Time X509_CRL::this_update() const
{
- return info.get1("X509.CRL.start");
+ return X509_Time(info.get1("X509.CRL.start"), ASN1_Tag::UTC_OR_GENERALIZED_TIME);
}
/*
@@ -185,7 +185,7 @@ X509_Time X509_CRL::this_update() const
*/
X509_Time X509_CRL::next_update() const
{
- return info.get1("X509.CRL.end");
+ return X509_Time(info.get1("X509.CRL.end"), ASN1_Tag::UTC_OR_GENERALIZED_TIME);
}
}
diff --git a/src/lib/cert/x509/x509_crl.h b/src/lib/cert/x509/x509_crl.h
index 1897d8d59..a9a8e80cf 100644
--- a/src/lib/cert/x509/x509_crl.h
+++ b/src/lib/cert/x509/x509_crl.h
@@ -99,7 +99,7 @@ class BOTAN_DLL X509_CRL : public X509_Object
bool throw_on_unknown_critical = false);
private:
- void force_decode();
+ void force_decode() override;
bool throw_on_unknown_critical;
std::vector<CRL_Entry> revoked;
diff --git a/src/lib/cert/x509/x509_ext.cpp b/src/lib/cert/x509/x509_ext.cpp
index 78c9ceec6..4da7467c3 100644
--- a/src/lib/cert/x509/x509_ext.cpp
+++ b/src/lib/cert/x509/x509_ext.cpp
@@ -449,14 +449,14 @@ class Policy_Information : public ASN1_Object
Policy_Information() {}
Policy_Information(const OID& oid) : oid(oid) {}
- void encode_into(DER_Encoder& codec) const
+ void encode_into(DER_Encoder& codec) const override
{
codec.start_cons(SEQUENCE)
.encode(oid)
.end_cons();
}
- void decode_from(BER_Decoder& codec)
+ void decode_from(BER_Decoder& codec) override
{
codec.start_cons(SEQUENCE)
.decode(oid)
diff --git a/src/lib/cert/x509/x509_ext.h b/src/lib/cert/x509/x509_ext.h
index 352a61d88..2ed892055 100644
--- a/src/lib/cert/x509/x509_ext.h
+++ b/src/lib/cert/x509/x509_ext.h
@@ -60,8 +60,8 @@ class BOTAN_DLL Certificate_Extension
class BOTAN_DLL Extensions : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
void contents_to(Data_Store&, Data_Store&) const;
@@ -89,7 +89,7 @@ static const size_t NO_CERT_PATH_LIMIT = 0xFFFFFFF0;
class BOTAN_DLL Basic_Constraints : public Certificate_Extension
{
public:
- Basic_Constraints* copy() const
+ Basic_Constraints* copy() const override
{ return new Basic_Constraints(is_ca, path_limit); }
Basic_Constraints(bool ca = false, size_t limit = 0) :
@@ -98,11 +98,12 @@ class BOTAN_DLL Basic_Constraints : public Certificate_Extension
bool get_is_ca() const { return is_ca; }
size_t get_path_limit() const;
private:
- std::string oid_name() const { return "X509v3.BasicConstraints"; }
+ std::string oid_name() const override
+ { return "X509v3.BasicConstraints"; }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
bool is_ca;
size_t path_limit;
@@ -114,18 +115,19 @@ class BOTAN_DLL Basic_Constraints : public Certificate_Extension
class BOTAN_DLL Key_Usage : public Certificate_Extension
{
public:
- Key_Usage* copy() const { return new Key_Usage(constraints); }
+ Key_Usage* copy() const override { return new Key_Usage(constraints); }
Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : constraints(c) {}
Key_Constraints get_constraints() const { return constraints; }
private:
- std::string oid_name() const { return "X509v3.KeyUsage"; }
+ std::string oid_name() const override { return "X509v3.KeyUsage"; }
- bool should_encode() const { return (constraints != NO_CONSTRAINTS); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override
+ { return (constraints != NO_CONSTRAINTS); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
Key_Constraints constraints;
};
@@ -136,19 +138,21 @@ class BOTAN_DLL Key_Usage : public Certificate_Extension
class BOTAN_DLL Subject_Key_ID : public Certificate_Extension
{
public:
- Subject_Key_ID* copy() const { return new Subject_Key_ID(key_id); }
+ Subject_Key_ID* copy() const override
+ { return new Subject_Key_ID(key_id); }
Subject_Key_ID() {}
Subject_Key_ID(const std::vector<byte>&);
std::vector<byte> get_key_id() const { return key_id; }
private:
- std::string oid_name() const { return "X509v3.SubjectKeyIdentifier"; }
+ std::string oid_name() const override
+ { return "X509v3.SubjectKeyIdentifier"; }
- bool should_encode() const { return (key_id.size() > 0); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return (key_id.size() > 0); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::vector<byte> key_id;
};
@@ -159,19 +163,21 @@ class BOTAN_DLL Subject_Key_ID : public Certificate_Extension
class BOTAN_DLL Authority_Key_ID : public Certificate_Extension
{
public:
- Authority_Key_ID* copy() const { return new Authority_Key_ID(key_id); }
+ Authority_Key_ID* copy() const override
+ { return new Authority_Key_ID(key_id); }
Authority_Key_ID() {}
Authority_Key_ID(const std::vector<byte>& k) : key_id(k) {}
std::vector<byte> get_key_id() const { return key_id; }
private:
- std::string oid_name() const { return "X509v3.AuthorityKeyIdentifier"; }
+ std::string oid_name() const override
+ { return "X509v3.AuthorityKeyIdentifier"; }
- bool should_encode() const { return (key_id.size() > 0); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return (key_id.size() > 0); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::vector<byte> key_id;
};
@@ -189,12 +195,12 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension
Alternative_Name(const std::string&, const std::string&);
private:
- std::string oid_name() const { return oid_name_str; }
+ std::string oid_name() const override { return oid_name_str; }
- bool should_encode() const { return alt_name.has_items(); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return alt_name.has_items(); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::string oid_name_str;
AlternativeName alt_name;
@@ -206,7 +212,7 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension
class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name
{
public:
- Subject_Alternative_Name* copy() const
+ Subject_Alternative_Name* copy() const override
{ return new Subject_Alternative_Name(get_alt_name()); }
Subject_Alternative_Name(const AlternativeName& = AlternativeName());
@@ -218,7 +224,7 @@ class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name
class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name
{
public:
- Issuer_Alternative_Name* copy() const
+ Issuer_Alternative_Name* copy() const override
{ return new Issuer_Alternative_Name(get_alt_name()); }
Issuer_Alternative_Name(const AlternativeName& = AlternativeName());
@@ -230,19 +236,21 @@ class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name
class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension
{
public:
- Extended_Key_Usage* copy() const { return new Extended_Key_Usage(oids); }
+ Extended_Key_Usage* copy() const override
+ { return new Extended_Key_Usage(oids); }
Extended_Key_Usage() {}
Extended_Key_Usage(const std::vector<OID>& o) : oids(o) {}
std::vector<OID> get_oids() const { return oids; }
private:
- std::string oid_name() const { return "X509v3.ExtendedKeyUsage"; }
+ std::string oid_name() const override
+ { return "X509v3.ExtendedKeyUsage"; }
- bool should_encode() const { return (oids.size() > 0); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return (oids.size() > 0); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::vector<OID> oids;
};
@@ -253,7 +261,7 @@ class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension
class BOTAN_DLL Certificate_Policies : public Certificate_Extension
{
public:
- Certificate_Policies* copy() const
+ Certificate_Policies* copy() const override
{ return new Certificate_Policies(oids); }
Certificate_Policies() {}
@@ -261,12 +269,13 @@ class BOTAN_DLL Certificate_Policies : public Certificate_Extension
std::vector<OID> get_oids() const { return oids; }
private:
- std::string oid_name() const { return "X509v3.CertificatePolicies"; }
+ std::string oid_name() const override
+ { return "X509v3.CertificatePolicies"; }
- bool should_encode() const { return (oids.size() > 0); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return (oids.size() > 0); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::vector<OID> oids;
};
@@ -274,7 +283,7 @@ class BOTAN_DLL Certificate_Policies : public Certificate_Extension
class BOTAN_DLL Authority_Information_Access : public Certificate_Extension
{
public:
- Authority_Information_Access* copy() const
+ Authority_Information_Access* copy() const override
{ return new Authority_Information_Access(m_ocsp_responder); }
Authority_Information_Access() {}
@@ -283,14 +292,15 @@ class BOTAN_DLL Authority_Information_Access : public Certificate_Extension
m_ocsp_responder(ocsp) {}
private:
- std::string oid_name() const { return "PKIX.AuthorityInformationAccess"; }
+ std::string oid_name() const override
+ { return "PKIX.AuthorityInformationAccess"; }
- bool should_encode() const { return (m_ocsp_responder != ""); }
+ bool should_encode() const override { return (m_ocsp_responder != ""); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
- void contents_to(Data_Store&, Data_Store&) const;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::string m_ocsp_responder;
};
@@ -301,19 +311,19 @@ class BOTAN_DLL Authority_Information_Access : public Certificate_Extension
class BOTAN_DLL CRL_Number : public Certificate_Extension
{
public:
- CRL_Number* copy() const;
+ CRL_Number* copy() const override;
CRL_Number() : has_value(false), crl_number(0) {}
CRL_Number(size_t n) : has_value(true), crl_number(n) {}
size_t get_crl_number() const;
private:
- std::string oid_name() const { return "X509v3.CRLNumber"; }
+ std::string oid_name() const override { return "X509v3.CRLNumber"; }
- bool should_encode() const { return has_value; }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return has_value; }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
bool has_value;
size_t crl_number;
@@ -325,18 +335,19 @@ class BOTAN_DLL CRL_Number : public Certificate_Extension
class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension
{
public:
- CRL_ReasonCode* copy() const { return new CRL_ReasonCode(reason); }
+ CRL_ReasonCode* copy() const override
+ { return new CRL_ReasonCode(reason); }
CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : reason(r) {}
CRL_Code get_reason() const { return reason; }
private:
- std::string oid_name() const { return "X509v3.ReasonCode"; }
+ std::string oid_name() const override { return "X509v3.ReasonCode"; }
- bool should_encode() const { return (reason != UNSPECIFIED); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ bool should_encode() const override { return (reason != UNSPECIFIED); }
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
CRL_Code reason;
};
@@ -350,15 +361,15 @@ class BOTAN_DLL CRL_Distribution_Points : public Certificate_Extension
class BOTAN_DLL Distribution_Point : public ASN1_Object
{
public:
- void encode_into(class DER_Encoder&) const;
- void decode_from(class BER_Decoder&);
+ void encode_into(class DER_Encoder&) const override;
+ void decode_from(class BER_Decoder&) override;
const AlternativeName& point() const { return m_point; }
private:
AlternativeName m_point;
};
- CRL_Distribution_Points* copy() const
+ CRL_Distribution_Points* copy() const override
{ return new CRL_Distribution_Points(m_distribution_points); }
CRL_Distribution_Points() {}
@@ -370,13 +381,15 @@ class BOTAN_DLL CRL_Distribution_Points : public Certificate_Extension
{ return m_distribution_points; }
private:
- std::string oid_name() const { return "X509v3.CRLDistributionPoints"; }
+ std::string oid_name() const override
+ { return "X509v3.CRLDistributionPoints"; }
- bool should_encode() const { return !m_distribution_points.empty(); }
+ bool should_encode() const override
+ { return !m_distribution_points.empty(); }
- std::vector<byte> encode_inner() const;
- void decode_inner(const std::vector<byte>&);
- void contents_to(Data_Store&, Data_Store&) const;
+ std::vector<byte> encode_inner() const override;
+ void decode_inner(const std::vector<byte>&) override;
+ void contents_to(Data_Store&, Data_Store&) const override;
std::vector<Distribution_Point> m_distribution_points;
};
diff --git a/src/lib/cert/x509/x509cert.cpp b/src/lib/cert/x509/x509cert.cpp
index 195af7730..f6f87bbf4 100644
--- a/src/lib/cert/x509/x509cert.cpp
+++ b/src/lib/cert/x509/x509cert.cpp
@@ -136,8 +136,8 @@ void X509_Certificate::force_decode()
subject.add("X509.Certificate.version", version);
subject.add("X509.Certificate.serial", BigInt::encode(serial_bn));
- subject.add("X509.Certificate.start", start.readable_string());
- subject.add("X509.Certificate.end", end.readable_string());
+ subject.add("X509.Certificate.start", start.to_string());
+ subject.add("X509.Certificate.end", end.to_string());
issuer.add("X509.Certificate.v2.key_id", v2_issuer_key_id);
subject.add("X509.Certificate.v2.key_id", v2_subject_key_id);
diff --git a/src/lib/cert/x509/x509cert.h b/src/lib/cert/x509/x509cert.h
index 563b900f2..9fd3e660a 100644
--- a/src/lib/cert/x509/x509cert.h
+++ b/src/lib/cert/x509/x509cert.h
@@ -50,7 +50,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object
/**
* Get a value for a specific subject_info parameter name.
- * @param name the name of the paramter to look up. Possible names are
+ * @param name the name of the parameter to look up. Possible names are
* "X509.Certificate.version", "X509.Certificate.serial",
* "X509.Certificate.start", "X509.Certificate.end",
* "X509.Certificate.v2.key_id", "X509.Certificate.public_key",
@@ -64,7 +64,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object
/**
* Get a value for a specific subject_info parameter name.
- * @param name the name of the paramter to look up. Possible names are
+ * @param name the name of the parameter to look up. Possible names are
* "X509.Certificate.v2.key_id" or "X509v3.AuthorityKeyIdentifier".
* @return value(s) of the specified parameter
*/
@@ -221,7 +221,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object
X509_Certificate(const std::vector<byte>& in);
private:
- void force_decode();
+ void force_decode() override;
friend class X509_CA;
friend class BER_Decoder;
diff --git a/src/lib/cert/x509/x509opt.cpp b/src/lib/cert/x509/x509opt.cpp
index c620ab25b..52845658f 100644
--- a/src/lib/cert/x509/x509opt.cpp
+++ b/src/lib/cert/x509/x509opt.cpp
@@ -17,7 +17,7 @@ namespace Botan {
*/
void X509_Cert_Options::not_before(const std::string& time_string)
{
- start = X509_Time(time_string);
+ start = X509_Time(time_string, ASN1_Tag::UTC_OR_GENERALIZED_TIME);
}
/*
@@ -25,7 +25,7 @@ void X509_Cert_Options::not_before(const std::string& time_string)
*/
void X509_Cert_Options::not_after(const std::string& time_string)
{
- end = X509_Time(time_string);
+ end = X509_Time(time_string, ASN1_Tag::UTC_OR_GENERALIZED_TIME);
}
/*
diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp
index fa6d34a2d..09cabcb65 100644
--- a/src/lib/cert/x509/x509path.cpp
+++ b/src/lib/cert/x509/x509path.cpp
@@ -107,10 +107,10 @@ check_chain(const std::vector<X509_Certificate>& cert_path,
}
// Check all certs for valid time range
- if(current_time < X509_Time(subject.start_time()))
+ if(current_time < X509_Time(subject.start_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
status.insert(Certificate_Status_Code::CERT_NOT_YET_VALID);
- if(current_time > X509_Time(subject.end_time()))
+ if(current_time > X509_Time(subject.end_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
status.insert(Certificate_Status_Code::CERT_HAS_EXPIRED);
// Check issuer constraints
diff --git a/src/lib/cert/x509/x509path.h b/src/lib/cert/x509/x509path.h
index 6f3ab115f..f400641be 100644
--- a/src/lib/cert/x509/x509path.h
+++ b/src/lib/cert/x509/x509path.h
@@ -94,7 +94,7 @@ class BOTAN_DLL Path_Validation_Result
const std::vector<X509_Certificate>& cert_path() const { return m_cert_path; }
/**
- * @return true iff the validation was succesful
+ * @return true iff the validation was successful
*/
bool successful_validation() const;
diff --git a/src/lib/cert/x509/x509self.h b/src/lib/cert/x509/x509self.h
index d15aabc59..a4bbad214 100644
--- a/src/lib/cert/x509/x509self.h
+++ b/src/lib/cert/x509/x509self.h
@@ -9,7 +9,6 @@
#define BOTAN_X509_SELF_H__
#include <botan/x509cert.h>
-#include <botan/pkcs8.h>
#include <botan/pkcs10.h>
#include <botan/asn1_time.h>
diff --git a/src/lib/codec/base64/base64.cpp b/src/lib/codec/base64/base64.cpp
index 1b1767aa1..a63d2b373 100644
--- a/src/lib/codec/base64/base64.cpp
+++ b/src/lib/codec/base64/base64.cpp
@@ -78,9 +78,7 @@ size_t base64_encode(char out[],
std::string base64_encode(const byte input[],
size_t input_length)
{
- const size_t output_length = (input_length == 0)
- ? 0
- : (round_up<size_t>(input_length, 3) / 3) * 4;
+ const size_t output_length = (round_up(input_length, 3) / 3) * 4;
std::string output(output_length, 0);
size_t consumed = 0;
@@ -231,10 +229,8 @@ size_t base64_decode(byte output[],
secure_vector<byte> base64_decode(const char input[],
size_t input_length,
bool ignore_ws)
- {
- const size_t output_length = (input_length == 0)
- ? 0
- : (round_up<size_t>(input_length, 4) * 3) / 4;
+ {
+ const size_t output_length = (round_up(input_length, 4) * 3) / 4;
secure_vector<byte> bin(output_length);
size_t written = base64_decode(bin.data(),
diff --git a/src/lib/compression/compress_utils.h b/src/lib/compression/compress_utils.h
index d06971751..2a830ac4e 100644
--- a/src/lib/compression/compress_utils.h
+++ b/src/lib/compression/compress_utils.h
@@ -86,7 +86,7 @@ class Zlib_Style_Stream : public Compression_Stream
};
#define BOTAN_REGISTER_COMPRESSION(C, D) \
- BOTAN_REGISTER_T_1LEN(Transform, C, 9) \
+ BOTAN_REGISTER_T_1LEN(Transform, C, 9); \
BOTAN_REGISTER_T_NOARGS(Transform, D)
}
diff --git a/src/lib/credentials/credentials_manager.h b/src/lib/credentials/credentials_manager.h
index af0021393..96e840d13 100644
--- a/src/lib/credentials/credentials_manager.h
+++ b/src/lib/credentials/credentials_manager.h
@@ -21,7 +21,7 @@ class BigInt;
* Interface for a credentials manager.
*
* A type is a fairly static value that represents the general nature
-* of the transaction occuring. Currently used values are "tls-client"
+* of the transaction occurring. Currently used values are "tls-client"
* and "tls-server". Context represents a hostname, email address,
* username, or other identifier.
*/
@@ -34,7 +34,7 @@ class BOTAN_DLL Credentials_Manager
* Return a list of the certificates of CAs that we trust in this
* type/context.
*
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type. For instance
* for type "tls-client", context specifies the servers name.
@@ -52,7 +52,7 @@ class BOTAN_DLL Credentials_Manager
* std::exception with an informative what() result if the
* certificate chain cannot be verified.
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param hostname specifies the purported hostname
* @param cert_chain specifies a certificate chain leading to a
* trusted root CA certificate.
@@ -73,7 +73,7 @@ class BOTAN_DLL Credentials_Manager
* "DSA", "ECDSA", etc), or empty if there
* is no preference by the caller.
*
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type.
*/
@@ -92,7 +92,7 @@ class BOTAN_DLL Credentials_Manager
* @param cert_key_type specifies the type of key requested
* ("RSA", "DSA", "ECDSA", etc)
*
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
*
* @param context specifies a context relative to type.
*/
@@ -112,7 +112,7 @@ class BOTAN_DLL Credentials_Manager
const std::string& context);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return true if we should attempt SRP authentication
*/
@@ -120,7 +120,7 @@ class BOTAN_DLL Credentials_Manager
const std::string& context);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return identifier for client-side SRP auth, if available
for this type/context. Should return empty string
@@ -130,7 +130,7 @@ class BOTAN_DLL Credentials_Manager
const std::string& context);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identifier specifies what identifier we want the
* password for. This will be a value previously returned
@@ -154,7 +154,7 @@ class BOTAN_DLL Credentials_Manager
bool generate_fake_on_unknown);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @return the PSK identity hint for this type/context
*/
@@ -162,7 +162,7 @@ class BOTAN_DLL Credentials_Manager
const std::string& context);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identity_hint was passed by the server (but may be empty)
* @return the PSK identity we want to use
@@ -172,7 +172,7 @@ class BOTAN_DLL Credentials_Manager
const std::string& identity_hint);
/**
- * @param type specifies the type of operation occuring
+ * @param type specifies the type of operation occurring
* @param context specifies a context relative to type.
* @param identity is a PSK identity previously returned by
psk_identity for the same type and context.
diff --git a/src/lib/entropy/beos_stats/es_beos.h b/src/lib/entropy/beos_stats/es_beos.h
index 331ae3bc0..2565b9180 100644
--- a/src/lib/entropy/beos_stats/es_beos.h
+++ b/src/lib/entropy/beos_stats/es_beos.h
@@ -18,9 +18,9 @@ namespace Botan {
class BeOS_EntropySource : public EntropySource
{
private:
- std::string name() const { return "BeOS Statistics"; }
+ std::string name() const override { return "BeOS Statistics"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
};
}
diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.h b/src/lib/entropy/cryptoapi_rng/es_capi.h
index 34ab2e22d..81a5003b2 100644
--- a/src/lib/entropy/cryptoapi_rng/es_capi.h
+++ b/src/lib/entropy/cryptoapi_rng/es_capi.h
@@ -19,9 +19,9 @@ namespace Botan {
class Win32_CAPI_EntropySource : public EntropySource
{
public:
- std::string name() const { return "Win32 CryptoGenRandom"; }
+ std::string name() const override { return "Win32 CryptoGenRandom"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
/**
* Win32_Capi_Entropysource Constructor
diff --git a/src/lib/entropy/dev_random/dev_random.h b/src/lib/entropy/dev_random/dev_random.h
index 1df616d56..0d0c2df60 100644
--- a/src/lib/entropy/dev_random/dev_random.h
+++ b/src/lib/entropy/dev_random/dev_random.h
@@ -20,9 +20,9 @@ namespace Botan {
class Device_EntropySource : public EntropySource
{
public:
- std::string name() const { return "RNG Device Reader"; }
+ std::string name() const override { return "RNG Device Reader"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
Device_EntropySource(const std::vector<std::string>& fsnames);
~Device_EntropySource();
diff --git a/src/lib/entropy/dev_random/info.txt b/src/lib/entropy/dev_random/info.txt
index 98a6a7e61..d8b7df134 100644
--- a/src/lib/entropy/dev_random/info.txt
+++ b/src/lib/entropy/dev_random/info.txt
@@ -10,6 +10,7 @@ dev_random.h
<os>
aix
+android
cygwin
darwin
dragonfly
@@ -23,5 +24,4 @@ netbsd
openbsd
qnx
solaris
-tru64
</os>
diff --git a/src/lib/entropy/egd/es_egd.h b/src/lib/entropy/egd/es_egd.h
index 0c9caec66..7f7df1133 100644
--- a/src/lib/entropy/egd/es_egd.h
+++ b/src/lib/entropy/egd/es_egd.h
@@ -21,9 +21,9 @@ namespace Botan {
class EGD_EntropySource : public EntropySource
{
public:
- std::string name() const { return "EGD/PRNGD"; }
+ std::string name() const override { return "EGD/PRNGD"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
EGD_EntropySource(const std::vector<std::string>&);
~EGD_EntropySource();
diff --git a/src/lib/entropy/egd/info.txt b/src/lib/entropy/egd/info.txt
index fdf5c4959..b7b951c2b 100644
--- a/src/lib/entropy/egd/info.txt
+++ b/src/lib/entropy/egd/info.txt
@@ -16,6 +16,7 @@ qnx -> socket
</libs>
<os>
+android
aix
cygwin
darwin
@@ -28,5 +29,4 @@ netbsd
openbsd
qnx
solaris
-tru64
</os>
diff --git a/src/lib/entropy/hres_timer/hres_timer.h b/src/lib/entropy/hres_timer/hres_timer.h
index 762acadbf..b5b92fd97 100644
--- a/src/lib/entropy/hres_timer/hres_timer.h
+++ b/src/lib/entropy/hres_timer/hres_timer.h
@@ -21,8 +21,8 @@ namespace Botan {
class High_Resolution_Timestamp : public EntropySource
{
public:
- std::string name() const { return "High Resolution Timestamp"; }
- void poll(Entropy_Accumulator& accum);
+ std::string name() const override { return "High Resolution Timestamp"; }
+ void poll(Entropy_Accumulator& accum) override;
};
}
diff --git a/src/lib/entropy/proc_walk/info.txt b/src/lib/entropy/proc_walk/info.txt
index 2a53a7ed8..c713d3b8e 100644
--- a/src/lib/entropy/proc_walk/info.txt
+++ b/src/lib/entropy/proc_walk/info.txt
@@ -9,6 +9,7 @@ proc_walk.h
</header:internal>
<os>
+android
aix
cygwin
darwin
@@ -22,7 +23,6 @@ netbsd
openbsd
qnx
solaris
-tru64
</os>
<requires>
diff --git a/src/lib/entropy/proc_walk/proc_walk.cpp b/src/lib/entropy/proc_walk/proc_walk.cpp
index 217ed5a52..7fbea678e 100644
--- a/src/lib/entropy/proc_walk/proc_walk.cpp
+++ b/src/lib/entropy/proc_walk/proc_walk.cpp
@@ -41,7 +41,7 @@ class Directory_Walker : public File_Descriptor_Source
::closedir(m_cur_dir.first);
}
- int next_fd();
+ int next_fd() override;
private:
std::pair<struct dirent*, std::string> get_next_dirent();
diff --git a/src/lib/entropy/proc_walk/proc_walk.h b/src/lib/entropy/proc_walk/proc_walk.h
index 939feb112..ec56f9e2d 100644
--- a/src/lib/entropy/proc_walk/proc_walk.h
+++ b/src/lib/entropy/proc_walk/proc_walk.h
@@ -26,9 +26,9 @@ class File_Descriptor_Source
class ProcWalking_EntropySource : public EntropySource
{
public:
- std::string name() const { return "Proc Walker"; }
+ std::string name() const override { return "Proc Walker"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
ProcWalking_EntropySource(const std::string& root_dir) :
m_path(root_dir), m_dir(nullptr) {}
diff --git a/src/lib/entropy/rdrand/rdrand.cpp b/src/lib/entropy/rdrand/rdrand.cpp
index 74876e203..178c52798 100644
--- a/src/lib/entropy/rdrand/rdrand.cpp
+++ b/src/lib/entropy/rdrand/rdrand.cpp
@@ -29,7 +29,7 @@ void Intel_Rdrand::poll(Entropy_Accumulator& accum)
Even if backdoored, rdrand cannot harm us because the HMAC_RNG poll process
is designed to handle arbitrarily large amounts of attacker known/chosen
input (or even a reseed where every bit we reseeded with was attacker chosen),
- as long as at least one seed occured with enough unknown-to-attacker entropy.
+ as long as at least one seed occurred with enough unknown-to-attacker entropy.
*/
const double ENTROPY_ESTIMATE = 0.0;
const size_t RDRAND_POLLS = 32;
diff --git a/src/lib/entropy/rdrand/rdrand.h b/src/lib/entropy/rdrand/rdrand.h
index bc02ef93e..9ff6e557f 100644
--- a/src/lib/entropy/rdrand/rdrand.h
+++ b/src/lib/entropy/rdrand/rdrand.h
@@ -19,8 +19,8 @@ namespace Botan {
class Intel_Rdrand : public EntropySource
{
public:
- std::string name() const { return "Intel Rdrand"; }
- void poll(Entropy_Accumulator& accum);
+ std::string name() const override { return "Intel Rdrand"; }
+ void poll(Entropy_Accumulator& accum) override;
};
}
diff --git a/src/lib/entropy/unix_procs/info.txt b/src/lib/entropy/unix_procs/info.txt
index 755d2565d..ee382d8da 100644
--- a/src/lib/entropy/unix_procs/info.txt
+++ b/src/lib/entropy/unix_procs/info.txt
@@ -10,6 +10,7 @@ unix_procs.h
</header:internal>
<os>
+android
aix
cygwin
darwin
@@ -21,5 +22,4 @@ linux
netbsd
qnx
solaris
-tru64
</os>
diff --git a/src/lib/entropy/unix_procs/unix_procs.cpp b/src/lib/entropy/unix_procs/unix_procs.cpp
index 3c641da70..c6ad6a700 100644
--- a/src/lib/entropy/unix_procs/unix_procs.cpp
+++ b/src/lib/entropy/unix_procs/unix_procs.cpp
@@ -72,7 +72,9 @@ void UnixProcessInfo_EntropySource::poll(Entropy_Accumulator& accum)
accum.add(::getppid(), 0.0);
accum.add(::getuid(), 0.0);
accum.add(::getgid(), 0.0);
+#if defined(BOTAN_TARGET_OS_HAS_GETSID)
accum.add(::getsid(0), 0.0);
+#endif
accum.add(::getpgrp(), 0.0);
struct ::rusage usage;
diff --git a/src/lib/entropy/unix_procs/unix_procs.h b/src/lib/entropy/unix_procs/unix_procs.h
index cf6a8bb7d..808d34221 100644
--- a/src/lib/entropy/unix_procs/unix_procs.h
+++ b/src/lib/entropy/unix_procs/unix_procs.h
@@ -23,7 +23,7 @@ namespace Botan {
class Unix_EntropySource : public EntropySource
{
public:
- std::string name() const { return "Unix Process Runner"; }
+ std::string name() const override { return "Unix Process Runner"; }
void poll(Entropy_Accumulator& accum) override;
@@ -81,9 +81,9 @@ class Unix_EntropySource : public EntropySource
class UnixProcessInfo_EntropySource : public EntropySource
{
public:
- std::string name() const { return "Unix Process Info"; }
+ std::string name() const override { return "Unix Process Info"; }
- void poll(Entropy_Accumulator& accum);
+ void poll(Entropy_Accumulator& accum) override;
};
}
diff --git a/src/lib/entropy/win32_stats/es_win32.h b/src/lib/entropy/win32_stats/es_win32.h
index 4809abeee..98bfb0e36 100644
--- a/src/lib/entropy/win32_stats/es_win32.h
+++ b/src/lib/entropy/win32_stats/es_win32.h
@@ -18,8 +18,8 @@ namespace Botan {
class Win32_EntropySource : public EntropySource
{
public:
- std::string name() const { return "Win32 Statistics"; }
- void poll(Entropy_Accumulator& accum);
+ std::string name() const override { return "Win32 Statistics"; }
+ void poll(Entropy_Accumulator& accum) override;
};
}
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 91acde2bc..8d96a0fc7 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -13,10 +13,12 @@
#include <botan/mac.h>
#include <botan/pbkdf.h>
#include <botan/version.h>
+#include <botan/pkcs8.h>
#include <botan/pubkey.h>
#include <botan/data_src.h>
#include <botan/hex.h>
#include <botan/mem_ops.h>
+#include <botan/x509_key.h>
#include <cstring>
#include <memory>
@@ -56,7 +58,7 @@ struct botan_struct
{
if(m_magic != MAGIC)
throw std::runtime_error("Bad magic " + std::to_string(m_magic) +
- " in ffi object expected" + std::to_string(MAGIC));
+ " in ffi object expected " + std::to_string(MAGIC));
return m_obj.get();
}
private:
@@ -209,9 +211,9 @@ int botan_rng_init(botan_rng_t* rng_out, const char* rng_type)
void randomize(Botan::byte out[], size_t len) override { m_rng.randomize(out, len); }
bool is_seeded() const override { return m_rng.is_seeded(); }
void clear() override { m_rng.clear(); }
- std::string name() const { return m_rng.name(); }
- void reseed(size_t poll_bits = 256) { m_rng.reseed(poll_bits); }
- void add_entropy(const Botan::byte in[], size_t len) { m_rng.add_entropy(in, len); }
+ std::string name() const override { return m_rng.name(); }
+ void reseed(size_t poll_bits = 256) override { m_rng.reseed(poll_bits); }
+ void add_entropy(const Botan::byte in[], size_t len) override { m_rng.add_entropy(in, len); }
private:
Botan::RandomNumberGenerator& m_rng;
};
@@ -581,6 +583,7 @@ int botan_pbkdf(const char* pbkdf_algo, uint8_t out[], size_t out_len,
{
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_iterations(out, out_len, pass, salt, salt_len, iterations);
+ return 0;
}
catch(std::exception& e)
{
@@ -603,6 +606,7 @@ int botan_pbkdf_timed(const char* pbkdf_algo,
pbkdf->pbkdf_timed(out, out_len, password, salt, salt_len,
std::chrono::milliseconds(ms_to_run),
*iterations_used);
+ return 0;
}
catch(std::exception& e)
{
@@ -621,6 +625,7 @@ int botan_kdf(const char* kdf_algo,
{
std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_algo));
kdf->kdf(out, out_len, secret, secret_len, salt, salt_len);
+ return 0;
}
catch(std::exception& e)
{
diff --git a/src/lib/filters/basefilt.h b/src/lib/filters/basefilt.h
index f87ac66e7..36c5201a1 100644
--- a/src/lib/filters/basefilt.h
+++ b/src/lib/filters/basefilt.h
@@ -19,9 +19,9 @@ namespace Botan {
*/
struct BOTAN_DLL BitBucket : public Filter
{
- void write(const byte[], size_t) {}
+ void write(const byte[], size_t) override {}
- std::string name() const { return "BitBucket"; }
+ std::string name() const override { return "BitBucket"; }
};
/**
@@ -33,9 +33,9 @@ struct BOTAN_DLL BitBucket : public Filter
class BOTAN_DLL Chain : public Fanout_Filter
{
public:
- void write(const byte input[], size_t length) { send(input, length); }
+ void write(const byte input[], size_t length) override { send(input, length); }
- std::string name() const;
+ std::string name() const override;
/**
* Construct a chain of up to four filters. The filters are set
@@ -60,10 +60,10 @@ class BOTAN_DLL Chain : public Fanout_Filter
class BOTAN_DLL Fork : public Fanout_Filter
{
public:
- void write(const byte input[], size_t length) { send(input, length); }
+ void write(const byte input[], size_t length) override { send(input, length); }
void set_port(size_t n) { Fanout_Filter::set_port(n); }
- std::string name() const;
+ std::string name() const override;
/**
* Construct a Fork filter with up to four forks.
@@ -86,7 +86,7 @@ class BOTAN_DLL Fork : public Fanout_Filter
class BOTAN_DLL Threaded_Fork : public Fork
{
public:
- std::string name() const;
+ std::string name() const override;
/**
* Construct a Threaded_Fork filter with up to four forks.
@@ -104,7 +104,7 @@ class BOTAN_DLL Threaded_Fork : public Fork
protected:
void set_next(Filter* f[], size_t n);
- void send(const byte in[], size_t length);
+ void send(const byte in[], size_t length) override;
private:
void thread_delegate_work(const byte input[], size_t length);
diff --git a/src/lib/filters/codec_filt/b64_filt.cpp b/src/lib/filters/codec_filt/b64_filt.cpp
index d9e4a5f8a..df3cad6a4 100644
--- a/src/lib/filters/codec_filt/b64_filt.cpp
+++ b/src/lib/filters/codec_filt/b64_filt.cpp
@@ -126,6 +126,11 @@ void Base64_Decoder::write(const byte input[], size_t length)
while(length)
{
size_t to_copy = std::min<size_t>(length, in.size() - position);
+ if(to_copy == 0)
+ {
+ in.resize(in.size()*2);
+ out.resize(out.size()*2);
+ }
copy_mem(&in[position], input, to_copy);
position += to_copy;
diff --git a/src/lib/filters/codec_filt/b64_filt.h b/src/lib/filters/codec_filt/b64_filt.h
index b73cca3b2..8ab428076 100644
--- a/src/lib/filters/codec_filt/b64_filt.h
+++ b/src/lib/filters/codec_filt/b64_filt.h
@@ -18,19 +18,19 @@ namespace Botan {
class BOTAN_DLL Base64_Encoder : public Filter
{
public:
- std::string name() const { return "Base64_Encoder"; }
+ std::string name() const override { return "Base64_Encoder"; }
/**
* Input a part of a message to the encoder.
* @param input the message to input as a byte array
* @param length the length of the byte array input
*/
- void write(const byte input[], size_t length);
+ void write(const byte input[], size_t length) override;
/**
* Inform the Encoder that the current message shall be closed.
*/
- void end_msg();
+ void end_msg() override;
/**
* Create a base64 encoder.
@@ -57,19 +57,19 @@ class BOTAN_DLL Base64_Encoder : public Filter
class BOTAN_DLL Base64_Decoder : public Filter
{
public:
- std::string name() const { return "Base64_Decoder"; }
+ std::string name() const override { return "Base64_Decoder"; }
/**
* Input a part of a message to the decoder.
* @param input the message to input as a byte array
* @param length the length of the byte array input
*/
- void write(const byte input[], size_t length);
+ void write(const byte input[], size_t length) override;
/**
* Finish up the current message
*/
- void end_msg();
+ void end_msg() override;
/**
* Create a base64 decoder.
diff --git a/src/lib/filters/codec_filt/hex_filt.h b/src/lib/filters/codec_filt/hex_filt.h
index 008fd6799..6130e729c 100644
--- a/src/lib/filters/codec_filt/hex_filt.h
+++ b/src/lib/filters/codec_filt/hex_filt.h
@@ -24,10 +24,10 @@ class BOTAN_DLL Hex_Encoder : public Filter
*/
enum Case { Uppercase, Lowercase };
- std::string name() const { return "Hex_Encoder"; }
+ std::string name() const override { return "Hex_Encoder"; }
- void write(const byte in[], size_t length);
- void end_msg();
+ void write(const byte in[], size_t length) override;
+ void end_msg() override;
/**
* Create a hex encoder.
@@ -59,10 +59,10 @@ class BOTAN_DLL Hex_Encoder : public Filter
class BOTAN_DLL Hex_Decoder : public Filter
{
public:
- std::string name() const { return "Hex_Decoder"; }
+ std::string name() const override { return "Hex_Decoder"; }
- void write(const byte[], size_t);
- void end_msg();
+ void write(const byte[], size_t) override;
+ void end_msg() override;
/**
* Construct a Hex Decoder using the specified
diff --git a/src/lib/filters/data_snk.h b/src/lib/filters/data_snk.h
index 8c5826285..15e2de6ef 100644
--- a/src/lib/filters/data_snk.h
+++ b/src/lib/filters/data_snk.h
@@ -19,7 +19,7 @@ namespace Botan {
class BOTAN_DLL DataSink : public Filter
{
public:
- bool attachable() { return false; }
+ bool attachable() override { return false; }
DataSink() {}
virtual ~DataSink() {}
@@ -33,9 +33,9 @@ class BOTAN_DLL DataSink : public Filter
class BOTAN_DLL DataSink_Stream : public DataSink
{
public:
- std::string name() const { return identifier; }
+ std::string name() const override { return identifier; }
- void write(const byte[], size_t);
+ void write(const byte[], size_t) override;
/**
* Construct a DataSink_Stream from a stream.
diff --git a/src/lib/filters/data_src.cpp b/src/lib/filters/data_src.cpp
index 7551b0037..4e0725943 100644
--- a/src/lib/filters/data_src.cpp
+++ b/src/lib/filters/data_src.cpp
@@ -34,10 +34,18 @@ size_t DataSource::peek_byte(byte& out) const
*/
size_t DataSource::discard_next(size_t n)
{
+ byte buf[64] = { 0 };
size_t discarded = 0;
- byte dummy;
- for(size_t j = 0; j != n; ++j)
- discarded += read_byte(dummy);
+
+ while(n)
+ {
+ const size_t got = this->read(buf, std::min(n, sizeof(buf)));
+ discarded += got;
+
+ if(got == 0)
+ break;
+ }
+
return discarded;
}
@@ -52,6 +60,11 @@ size_t DataSource_Memory::read(byte out[], size_t length)
return got;
}
+bool DataSource_Memory::check_available(size_t n)
+ {
+ return (n <= (source.size() - offset));
+ }
+
/*
* Peek into a memory buffer
*/
@@ -99,6 +112,15 @@ size_t DataSource_Stream::read(byte out[], size_t length)
return got;
}
+bool DataSource_Stream::check_available(size_t n)
+ {
+ const std::streampos orig_pos = source.tellg();
+ source.seekg(0, std::ios::end);
+ const size_t avail = source.tellg() - orig_pos;
+ source.seekg(orig_pos);
+ return (avail >= n);
+ }
+
/*
* Peek into a stream
*/
diff --git a/src/lib/filters/data_src.h b/src/lib/filters/data_src.h
index e6b7b9573..2b6998448 100644
--- a/src/lib/filters/data_src.h
+++ b/src/lib/filters/data_src.h
@@ -32,6 +32,8 @@ class BOTAN_DLL DataSource
*/
virtual size_t read(byte out[], size_t length) = 0;
+ virtual bool check_available(size_t n) = 0;
+
/**
* Read from the source but do not modify the internal
* offset. Consecutive calls to peek() will return portions of
@@ -97,9 +99,10 @@ class BOTAN_DLL DataSource
class BOTAN_DLL DataSource_Memory : public DataSource
{
public:
- size_t read(byte[], size_t);
- size_t peek(byte[], size_t, size_t) const;
- bool end_of_data() const;
+ size_t read(byte[], size_t) override;
+ size_t peek(byte[], size_t, size_t) const override;
+ bool check_available(size_t n) override;
+ bool end_of_data() const override;
/**
* Construct a memory source that reads from a string
@@ -129,7 +132,7 @@ class BOTAN_DLL DataSource_Memory : public DataSource
DataSource_Memory(const std::vector<byte>& in) :
source(in.begin(), in.end()), offset(0) {}
- virtual size_t get_bytes_read() const { return offset; }
+ size_t get_bytes_read() const override { return offset; }
private:
secure_vector<byte> source;
size_t offset;
@@ -141,10 +144,11 @@ class BOTAN_DLL DataSource_Memory : public DataSource
class BOTAN_DLL DataSource_Stream : public DataSource
{
public:
- size_t read(byte[], size_t);
- size_t peek(byte[], size_t, size_t) const;
- bool end_of_data() const;
- std::string id() const;
+ size_t read(byte[], size_t) override;
+ size_t peek(byte[], size_t, size_t) const override;
+ bool check_available(size_t n) override;
+ bool end_of_data() const override;
+ std::string id() const override;
DataSource_Stream(std::istream&,
const std::string& id = "<std::istream>");
@@ -162,7 +166,7 @@ class BOTAN_DLL DataSource_Stream : public DataSource
~DataSource_Stream();
- virtual size_t get_bytes_read() const { return total_read; }
+ size_t get_bytes_read() const override { return total_read; }
private:
const std::string identifier;
diff --git a/src/lib/filters/fd_unix/info.txt b/src/lib/filters/fd_unix/info.txt
index 84d6e4775..ea76d0dd7 100644
--- a/src/lib/filters/fd_unix/info.txt
+++ b/src/lib/filters/fd_unix/info.txt
@@ -3,6 +3,7 @@ define PIPE_UNIXFD_IO 20131128
load_on auto
<os>
+android
aix
cygwin
darwin
@@ -17,5 +18,4 @@ netbsd
openbsd
qnx
solaris
-tru64
</os>
diff --git a/src/lib/filters/filters.h b/src/lib/filters/filters.h
index 1a9597de3..7a527dde0 100644
--- a/src/lib/filters/filters.h
+++ b/src/lib/filters/filters.h
@@ -34,23 +34,23 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter
{
public:
- std::string name() const { return m_cipher->name(); }
+ std::string name() const override { return m_cipher->name(); }
/**
* Write input data
* @param input data
* @param input_len length of input in bytes
*/
- void write(const byte input[], size_t input_len);
+ void write(const byte input[], size_t input_len) override;
- bool valid_iv_length(size_t iv_len) const
+ bool valid_iv_length(size_t iv_len) const override
{ return m_cipher->valid_iv_length(iv_len); }
/**
* Set the initialization vector for this filter.
* @param iv the initialization vector to set
*/
- void set_iv(const InitializationVector& iv)
+ void set_iv(const InitializationVector& iv) override
{
m_cipher->set_iv(iv.begin(), iv.length());
}
@@ -59,7 +59,7 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter
* Set the key of this filter.
* @param key the key to set
*/
- void set_key(const SymmetricKey& key) { m_cipher->set_key(key); }
+ void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); }
Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
@@ -99,10 +99,10 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter
class BOTAN_DLL Hash_Filter : public Filter
{
public:
- void write(const byte input[], size_t len) { m_hash->update(input, len); }
- void end_msg();
+ void write(const byte input[], size_t len) override { m_hash->update(input, len); }
+ void end_msg() override;
- std::string name() const { return m_hash->name(); }
+ std::string name() const override { return m_hash->name(); }
/**
* Construct a hash filter.
@@ -136,16 +136,16 @@ class BOTAN_DLL Hash_Filter : public Filter
class BOTAN_DLL MAC_Filter : public Keyed_Filter
{
public:
- void write(const byte input[], size_t len) { m_mac->update(input, len); }
- void end_msg();
+ void write(const byte input[], size_t len) override { m_mac->update(input, len); }
+ void end_msg() override;
- std::string name() const { return m_mac->name(); }
+ std::string name() const override { return m_mac->name(); }
/**
* Set the key of this filter.
* @param key the key to set
*/
- void set_key(const SymmetricKey& key) { m_mac->set_key(key); }
+ void set_key(const SymmetricKey& key) override { m_mac->set_key(key); }
Key_Length_Specification key_spec() const override { return m_mac->key_spec(); }
diff --git a/src/lib/filters/pipe.cpp b/src/lib/filters/pipe.cpp
index b3bbe501f..15ace9ffc 100644
--- a/src/lib/filters/pipe.cpp
+++ b/src/lib/filters/pipe.cpp
@@ -20,10 +20,10 @@ namespace {
class Null_Filter : public Filter
{
public:
- void write(const byte input[], size_t length)
+ void write(const byte input[], size_t length) override
{ send(input, length); }
- std::string name() const { return "Null"; }
+ std::string name() const override { return "Null"; }
};
}
diff --git a/src/lib/filters/pipe.h b/src/lib/filters/pipe.h
index ce91e9e82..3f8d4d04c 100644
--- a/src/lib/filters/pipe.h
+++ b/src/lib/filters/pipe.h
@@ -39,7 +39,7 @@ class BOTAN_DLL Pipe : public DataSource
struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument
{
/**
- * @param where the error occured
+ * @param where the error occurred
* @param msg the invalid message id that was used
*/
Invalid_Message_Number(const std::string& where, message_id msg) :
@@ -145,7 +145,7 @@ class BOTAN_DLL Pipe : public DataSource
* @param length the length of the byte array output
* @return number of bytes actually read into output
*/
- size_t read(byte output[], size_t length);
+ size_t read(byte output[], size_t length) override;
/**
* Read a specified message from the pipe. Moves the internal
@@ -191,7 +191,7 @@ class BOTAN_DLL Pipe : public DataSource
* @param offset the offset from the current position in message
* @return number of bytes actually peeked and written into output
*/
- size_t peek(byte output[], size_t length, size_t offset) const;
+ size_t peek(byte output[], size_t length, size_t offset) const override;
/** Read from the specified message but do not modify the
* internal offset. Consecutive calls to peek() will return
@@ -219,12 +219,15 @@ class BOTAN_DLL Pipe : public DataSource
/**
* @return the number of bytes read from the default message.
*/
- size_t get_bytes_read() const;
+ size_t get_bytes_read() const override;
/**
* @return the number of bytes read from the specified message.
*/
- size_t get_bytes_read(message_id msg = DEFAULT_MESSAGE) const;
+ size_t get_bytes_read(message_id msg) const;
+
+ bool check_available(size_t n) override;
+ bool check_available_msg(size_t n, message_id msg);
/**
* @return currently set default message
@@ -248,7 +251,7 @@ class BOTAN_DLL Pipe : public DataSource
* Test whether this pipe has any data that can be read from.
* @return true if there is more data to read, false otherwise
*/
- bool end_of_data() const;
+ bool end_of_data() const override;
/**
* Start a new message in the pipe. A potential other message in this pipe
diff --git a/src/lib/filters/pipe_rw.cpp b/src/lib/filters/pipe_rw.cpp
index 077bd93bb..796f9100e 100644
--- a/src/lib/filters/pipe_rw.cpp
+++ b/src/lib/filters/pipe_rw.cpp
@@ -168,4 +168,14 @@ size_t Pipe::get_bytes_read(message_id msg) const
return outputs->get_bytes_read(msg);
}
+bool Pipe::check_available(size_t n)
+ {
+ return (n <= remaining(DEFAULT_MESSAGE));
+ }
+
+bool Pipe::check_available_msg(size_t n, message_id msg)
+ {
+ return (n <= remaining(msg));
+ }
+
}
diff --git a/src/lib/filters/secqueue.cpp b/src/lib/filters/secqueue.cpp
index 718223876..120e8dd0d 100644
--- a/src/lib/filters/secqueue.cpp
+++ b/src/lib/filters/secqueue.cpp
@@ -60,9 +60,9 @@ class SecureQueueNode
*/
SecureQueue::SecureQueue()
{
- bytes_read = 0;
+ m_bytes_read = 0;
set_next(nullptr, 0);
- head = tail = new SecureQueueNode;
+ m_head = m_tail = new SecureQueueNode;
}
/*
@@ -71,11 +71,11 @@ SecureQueue::SecureQueue()
SecureQueue::SecureQueue(const SecureQueue& input) :
Fanout_Filter(), DataSource()
{
- bytes_read = 0;
+ m_bytes_read = 0;
set_next(nullptr, 0);
- head = tail = new SecureQueueNode;
- SecureQueueNode* temp = input.head;
+ m_head = m_tail = new SecureQueueNode;
+ SecureQueueNode* temp = input.m_head;
while(temp)
{
write(&temp->buffer[temp->start], temp->end - temp->start);
@@ -88,14 +88,14 @@ SecureQueue::SecureQueue(const SecureQueue& input) :
*/
void SecureQueue::destroy()
{
- SecureQueueNode* temp = head;
+ SecureQueueNode* temp = m_head;
while(temp)
{
SecureQueueNode* holder = temp->next;
delete temp;
temp = holder;
}
- head = tail = nullptr;
+ m_head = m_tail = nullptr;
}
/*
@@ -104,8 +104,8 @@ void SecureQueue::destroy()
SecureQueue& SecureQueue::operator=(const SecureQueue& input)
{
destroy();
- head = tail = new SecureQueueNode;
- SecureQueueNode* temp = input.head;
+ m_head = m_tail = new SecureQueueNode;
+ SecureQueueNode* temp = input.m_head;
while(temp)
{
write(&temp->buffer[temp->start], temp->end - temp->start);
@@ -119,17 +119,17 @@ SecureQueue& SecureQueue::operator=(const SecureQueue& input)
*/
void SecureQueue::write(const byte input[], size_t length)
{
- if(!head)
- head = tail = new SecureQueueNode;
+ if(!m_head)
+ m_head = m_tail = new SecureQueueNode;
while(length)
{
- const size_t n = tail->write(input, length);
+ const size_t n = m_tail->write(input, length);
input += n;
length -= n;
if(length)
{
- tail->next = new SecureQueueNode;
- tail = tail->next;
+ m_tail->next = new SecureQueueNode;
+ m_tail = m_tail->next;
}
}
}
@@ -140,20 +140,20 @@ void SecureQueue::write(const byte input[], size_t length)
size_t SecureQueue::read(byte output[], size_t length)
{
size_t got = 0;
- while(length && head)
+ while(length && m_head)
{
- const size_t n = head->read(output, length);
+ const size_t n = m_head->read(output, length);
output += n;
got += n;
length -= n;
- if(head->size() == 0)
+ if(m_head->size() == 0)
{
- SecureQueueNode* holder = head->next;
- delete head;
- head = holder;
+ SecureQueueNode* holder = m_head->next;
+ delete m_head;
+ m_head = holder;
}
}
- bytes_read += got;
+ m_bytes_read += got;
return got;
}
@@ -162,7 +162,7 @@ size_t SecureQueue::read(byte output[], size_t length)
*/
size_t SecureQueue::peek(byte output[], size_t length, size_t offset) const
{
- SecureQueueNode* current = head;
+ SecureQueueNode* current = m_head;
while(offset && current)
{
@@ -193,7 +193,7 @@ size_t SecureQueue::peek(byte output[], size_t length, size_t offset) const
*/
size_t SecureQueue::get_bytes_read() const
{
- return bytes_read;
+ return m_bytes_read;
}
/*
@@ -201,7 +201,7 @@ size_t SecureQueue::get_bytes_read() const
*/
size_t SecureQueue::size() const
{
- SecureQueueNode* current = head;
+ SecureQueueNode* current = m_head;
size_t count = 0;
while(current)
diff --git a/src/lib/filters/secqueue.h b/src/lib/filters/secqueue.h
index 7eb8ffc17..33afd478a 100644
--- a/src/lib/filters/secqueue.h
+++ b/src/lib/filters/secqueue.h
@@ -20,24 +20,26 @@ namespace Botan {
class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource
{
public:
- std::string name() const { return "Queue"; }
+ std::string name() const override { return "Queue"; }
- void write(const byte[], size_t);
+ void write(const byte[], size_t) override;
- size_t read(byte[], size_t);
- size_t peek(byte[], size_t, size_t = 0) const;
- size_t get_bytes_read() const;
+ size_t read(byte[], size_t) override;
+ size_t peek(byte[], size_t, size_t = 0) const override;
+ size_t get_bytes_read() const override;
- bool end_of_data() const;
+ bool end_of_data() const override;
bool empty() const;
+ bool check_available(size_t n) override { return n <= size(); }
+
/**
* @return number of bytes available in the queue
*/
size_t size() const;
- bool attachable() { return false; }
+ bool attachable() override { return false; }
/**
* SecureQueue assignment
@@ -57,11 +59,12 @@ class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource
SecureQueue(const SecureQueue& other);
~SecureQueue() { destroy(); }
+
private:
- size_t bytes_read;
void destroy();
- class SecureQueueNode* head;
- class SecureQueueNode* tail;
+ size_t m_bytes_read;
+ class SecureQueueNode* m_head;
+ class SecureQueueNode* m_tail;
};
}
diff --git a/src/lib/hash/checksum/adler32/adler32.h b/src/lib/hash/checksum/adler32/adler32.h
index f3767b786..307236d6d 100644
--- a/src/lib/hash/checksum/adler32/adler32.h
+++ b/src/lib/hash/checksum/adler32/adler32.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL Adler32 : public HashFunction
{
public:
- std::string name() const { return "Adler32"; }
- size_t output_length() const { return 4; }
- HashFunction* clone() const { return new Adler32; }
+ std::string name() const override { return "Adler32"; }
+ size_t output_length() const override { return 4; }
+ HashFunction* clone() const override { return new Adler32; }
- void clear() { S1 = 1; S2 = 0; }
+ void clear() override { S1 = 1; S2 = 0; }
Adler32() { clear(); }
~Adler32() { clear(); }
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
u16bit S1, S2;
};
diff --git a/src/lib/hash/checksum/crc24/crc24.h b/src/lib/hash/checksum/crc24/crc24.h
index a5cc090ad..8df8bd727 100644
--- a/src/lib/hash/checksum/crc24/crc24.h
+++ b/src/lib/hash/checksum/crc24/crc24.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL CRC24 : public HashFunction
{
public:
- std::string name() const { return "CRC24"; }
- size_t output_length() const { return 3; }
- HashFunction* clone() const { return new CRC24; }
+ std::string name() const override { return "CRC24"; }
+ size_t output_length() const override { return 3; }
+ HashFunction* clone() const override { return new CRC24; }
- void clear() { crc = 0xB704CE; }
+ void clear() override { crc = 0xB704CE; }
CRC24() { clear(); }
~CRC24() { clear(); }
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
u32bit crc;
};
diff --git a/src/lib/hash/checksum/crc32/crc32.h b/src/lib/hash/checksum/crc32/crc32.h
index 503b18b7a..8ae95d42a 100644
--- a/src/lib/hash/checksum/crc32/crc32.h
+++ b/src/lib/hash/checksum/crc32/crc32.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL CRC32 : public HashFunction
{
public:
- std::string name() const { return "CRC32"; }
- size_t output_length() const { return 4; }
- HashFunction* clone() const { return new CRC32; }
+ std::string name() const override { return "CRC32"; }
+ size_t output_length() const override { return 4; }
+ HashFunction* clone() const override { return new CRC32; }
- void clear() { crc = 0xFFFFFFFF; }
+ void clear() override { crc = 0xFFFFFFFF; }
CRC32() { clear(); }
~CRC32() { clear(); }
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
u32bit crc;
};
diff --git a/src/lib/hash/comb4p/comb4p.h b/src/lib/hash/comb4p/comb4p.h
index d2e9587c2..1a99934a2 100644
--- a/src/lib/hash/comb4p/comb4p.h
+++ b/src/lib/hash/comb4p/comb4p.h
@@ -25,29 +25,29 @@ class BOTAN_DLL Comb4P : public HashFunction
*/
Comb4P(HashFunction* h1, HashFunction* h2);
- size_t hash_block_size() const;
+ size_t hash_block_size() const override;
- size_t output_length() const
+ size_t output_length() const override
{
return m_hash1->output_length() + m_hash2->output_length();
}
static Comb4P* make(const Spec& spec);
- HashFunction* clone() const
+ HashFunction* clone() const override
{
return new Comb4P(m_hash1->clone(), m_hash2->clone());
}
- std::string name() const
+ std::string name() const override
{
return "Comb4P(" + m_hash1->name() + "," + m_hash2->name() + ")";
}
- void clear();
+ void clear() override;
private:
- void add_data(const byte input[], size_t length);
- void final_result(byte out[]);
+ void add_data(const byte input[], size_t length) override;
+ void final_result(byte out[]) override;
std::unique_ptr<HashFunction> m_hash1, m_hash2;
};
diff --git a/src/lib/hash/gost_3411/gost_3411.h b/src/lib/hash/gost_3411/gost_3411.h
index fb636e30e..2ad96dbdb 100644
--- a/src/lib/hash/gost_3411/gost_3411.h
+++ b/src/lib/hash/gost_3411/gost_3411.h
@@ -19,19 +19,19 @@ namespace Botan {
class BOTAN_DLL GOST_34_11 : public HashFunction
{
public:
- std::string name() const { return "GOST-R-34.11-94" ; }
- size_t output_length() const { return 32; }
- size_t hash_block_size() const { return 32; }
- HashFunction* clone() const { return new GOST_34_11; }
+ std::string name() const override { return "GOST-R-34.11-94" ; }
+ size_t output_length() const override { return 32; }
+ size_t hash_block_size() const override { return 32; }
+ HashFunction* clone() const override { return new GOST_34_11; }
- void clear();
+ void clear() override;
GOST_34_11();
private:
void compress_n(const byte input[], size_t blocks);
- void add_data(const byte[], size_t);
- void final_result(byte[]);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
GOST_28147_89 cipher;
secure_vector<byte> buffer, sum, hash;
diff --git a/src/lib/hash/has160/has160.h b/src/lib/hash/has160/has160.h
index 795b244c3..75d0bda90 100644
--- a/src/lib/hash/has160/has160.h
+++ b/src/lib/hash/has160/has160.h
@@ -14,22 +14,22 @@ namespace Botan {
/**
* HAS-160, a Korean hash function standardized in
-* TTAS.KO-12.0011/R1. Used in conjuction with KCDSA
+* TTAS.KO-12.0011/R1. Used in conjunction with KCDSA
*/
class BOTAN_DLL HAS_160 : public MDx_HashFunction
{
public:
- std::string name() const { return "HAS-160"; }
- size_t output_length() const { return 20; }
- HashFunction* clone() const { return new HAS_160; }
+ std::string name() const override { return "HAS-160"; }
+ size_t output_length() const override { return 20; }
+ HashFunction* clone() const override { return new HAS_160; }
- void clear();
+ void clear() override;
HAS_160() : MDx_HashFunction(64, false, true), X(20), digest(5)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u32bit> X, digest;
};
diff --git a/src/lib/hash/keccak/keccak.h b/src/lib/hash/keccak/keccak.h
index a115d8f7f..0e7d3d5d1 100644
--- a/src/lib/hash/keccak/keccak.h
+++ b/src/lib/hash/keccak/keccak.h
@@ -27,15 +27,15 @@ class BOTAN_DLL Keccak_1600 : public HashFunction
*/
Keccak_1600(size_t output_bits = 512);
- size_t hash_block_size() const { return bitrate / 8; }
- size_t output_length() const { return output_bits / 8; }
+ size_t hash_block_size() const override { return bitrate / 8; }
+ size_t output_length() const override { return output_bits / 8; }
- HashFunction* clone() const;
- std::string name() const;
- void clear();
+ HashFunction* clone() const override;
+ std::string name() const override;
+ void clear() override;
private:
- void add_data(const byte input[], size_t length);
- void final_result(byte out[]);
+ void add_data(const byte input[], size_t length) override;
+ void final_result(byte out[]) override;
size_t output_bits, bitrate;
secure_vector<u64bit> S;
diff --git a/src/lib/hash/md2/md2.h b/src/lib/hash/md2/md2.h
index bde390385..62f1b8a9f 100644
--- a/src/lib/hash/md2/md2.h
+++ b/src/lib/hash/md2/md2.h
@@ -18,19 +18,19 @@ namespace Botan {
class BOTAN_DLL MD2 : public HashFunction
{
public:
- std::string name() const { return "MD2"; }
- size_t output_length() const { return 16; }
- size_t hash_block_size() const { return 16; }
- HashFunction* clone() const { return new MD2; }
+ std::string name() const override { return "MD2"; }
+ size_t output_length() const override { return 16; }
+ size_t hash_block_size() const override { return 16; }
+ HashFunction* clone() const override { return new MD2; }
- void clear();
+ void clear() override;
MD2() : X(48), checksum(16), buffer(16)
{ clear(); }
private:
- void add_data(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
void hash(const byte[]);
- void final_result(byte[]);
+ void final_result(byte[]) override;
secure_vector<byte> X, checksum, buffer;
size_t position;
diff --git a/src/lib/hash/md4/md4.h b/src/lib/hash/md4/md4.h
index 3d38550c2..182da4ab2 100644
--- a/src/lib/hash/md4/md4.h
+++ b/src/lib/hash/md4/md4.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL MD4 : public MDx_HashFunction
{
public:
- std::string name() const { return "MD4"; }
- size_t output_length() const { return 16; }
- HashFunction* clone() const { return new MD4; }
+ std::string name() const override { return "MD4"; }
+ size_t output_length() const override { return 16; }
+ HashFunction* clone() const override { return new MD4; }
- void clear();
+ void clear() override;
MD4() : MDx_HashFunction(64, false, true), M(16), digest(4)
{ clear(); }
protected:
- void compress_n(const byte input[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte input[], size_t blocks) override;
+ void copy_out(byte[]) override;
/**
* The message buffer, exposed for use by subclasses (x86 asm)
diff --git a/src/lib/hash/md4_x86_32/info.txt b/src/lib/hash/md4_x86_32/info.txt
deleted file mode 100644
index fa7eef6cb..000000000
--- a/src/lib/hash/md4_x86_32/info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-define MD4_X86_32 20131128
-
-load_on asm_ok
-
-<arch>
-x86_32
-</arch>
-
-<requires>
-asm_x86_32
-md4
-</requires>
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32.cpp b/src/lib/hash/md4_x86_32/md4_x86_32.cpp
deleted file mode 100644
index 28860a369..000000000
--- a/src/lib/hash/md4_x86_32/md4_x86_32.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* MD4 (x86-32)
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/hash_utils.h>
-#include <botan/md4_x86_32.h>
-
-namespace Botan {
-
-BOTAN_REGISTER_NAMED_T_NOARGS(HashFunction, MD4_X86_32, "MD4", "x86-32");
-
-/**
-* MD4 compression function in x86-32 asm
-* @param digest the current digest
-* @param input the input block
-* @param M the message buffer
-*/
-extern "C" void botan_md4_x86_32_compress(u32bit digest[4],
- const byte input[64],
- u32bit M[16]);
-
-/*
-* MD4 Compression Function
-*/
-void MD4_X86_32::compress_n(const byte input[], size_t blocks)
- {
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_md4_x86_32_compress(digest.data(), input, M.data());
- input += hash_block_size();
- }
- }
-
-}
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32.h b/src/lib/hash/md4_x86_32/md4_x86_32.h
deleted file mode 100644
index 1cb6c779d..000000000
--- a/src/lib/hash/md4_x86_32/md4_x86_32.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* MD4 (x86-32)
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_MD4_X86_32_H__
-#define BOTAN_MD4_X86_32_H__
-
-#include <botan/md4.h>
-
-namespace Botan {
-
-/**
-* MD4 using x86 assembly
-*/
-class BOTAN_DLL MD4_X86_32 : public MD4
- {
- public:
- HashFunction* clone() const { return new MD4_X86_32; }
- private:
- void compress_n(const byte[], size_t blocks);
- };
-
-}
-
-#endif
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32_imp.S b/src/lib/hash/md4_x86_32/md4_x86_32_imp.S
deleted file mode 100644
index 035b30801..000000000
--- a/src/lib/hash/md4_x86_32/md4_x86_32_imp.S
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-* MD4 in x86-32 assembler
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/asm_x86_32.h>
-
-START_LISTING(md4_x86_32_imp.S)
-
-START_FUNCTION(botan_md4_x86_32_compress)
- SPILL_REGS()
-
-#define PUSHED 4
-
- ASSIGN(EBP, ARG(2)) /* input block */
- ASSIGN(EDI, ARG(3)) /* expanded words */
-
- ZEROIZE(ESI)
-
-START_LOOP(.LOAD_INPUT)
- ADD_IMM(ESI, 4)
-
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
- ADD_IMM(EBP, 16)
-
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-4), EAX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-3), EBX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-2), ECX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-1), EDX)
-LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
-
- ASSIGN(EBP, ARG(1))
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
-#define MSG EDI
-#define T1 ESI
-#define T2 EBP
-
-#define FF(A, B, C, D, N, S) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, C) ; \
- XOR(T2, D) ; \
- AND(T2, B) ; \
- XOR(T2, D) ; \
- ADD(A, T1) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ;
-
-#define GG(A, B, C, D, N, S) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, B) ; \
- OR(T2, C) ; \
- AND(T2, D) ; \
- ADD3_IMM(A, T1, 0x5A827999) ; \
- ASSIGN(T1, B) ; \
- AND(T1, C) ; \
- OR(T2, T1) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ;
-
-#define HH(A, B, C, D, N, S) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, B) ; \
- XOR(T2, C) ; \
- XOR(T2, D) ; \
- ADD3_IMM(A, T1, 0x6ED9EBA1) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ;
-
- FF(EAX,EBX,ECX,EDX, 0, 3);
- FF(EDX,EAX,EBX,ECX, 1, 7);
- FF(ECX,EDX,EAX,EBX, 2,11);
- FF(EBX,ECX,EDX,EAX, 3,19);
- FF(EAX,EBX,ECX,EDX, 4, 3);
- FF(EDX,EAX,EBX,ECX, 5, 7);
- FF(ECX,EDX,EAX,EBX, 6,11);
- FF(EBX,ECX,EDX,EAX, 7,19);
- FF(EAX,EBX,ECX,EDX, 8, 3);
- FF(EDX,EAX,EBX,ECX, 9, 7);
- FF(ECX,EDX,EAX,EBX,10,11);
- FF(EBX,ECX,EDX,EAX,11,19);
- FF(EAX,EBX,ECX,EDX,12, 3);
- FF(EDX,EAX,EBX,ECX,13, 7);
- FF(ECX,EDX,EAX,EBX,14,11);
- FF(EBX,ECX,EDX,EAX,15,19);
-
- GG(EAX,EBX,ECX,EDX, 0, 3);
- GG(EDX,EAX,EBX,ECX, 4, 5);
- GG(ECX,EDX,EAX,EBX, 8, 9);
- GG(EBX,ECX,EDX,EAX,12,13);
- GG(EAX,EBX,ECX,EDX, 1, 3);
- GG(EDX,EAX,EBX,ECX, 5, 5);
- GG(ECX,EDX,EAX,EBX, 9, 9);
- GG(EBX,ECX,EDX,EAX,13,13);
- GG(EAX,EBX,ECX,EDX, 2, 3);
- GG(EDX,EAX,EBX,ECX, 6, 5);
- GG(ECX,EDX,EAX,EBX,10, 9);
- GG(EBX,ECX,EDX,EAX,14,13);
- GG(EAX,EBX,ECX,EDX, 3, 3);
- GG(EDX,EAX,EBX,ECX, 7, 5);
- GG(ECX,EDX,EAX,EBX,11, 9);
- GG(EBX,ECX,EDX,EAX,15,13);
-
- HH(EAX,EBX,ECX,EDX, 0, 3);
- HH(EDX,EAX,EBX,ECX, 8, 9);
- HH(ECX,EDX,EAX,EBX, 4,11);
- HH(EBX,ECX,EDX,EAX,12,15);
- HH(EAX,EBX,ECX,EDX, 2, 3);
- HH(EDX,EAX,EBX,ECX,10, 9);
- HH(ECX,EDX,EAX,EBX, 6,11);
- HH(EBX,ECX,EDX,EAX,14,15);
- HH(EAX,EBX,ECX,EDX, 1, 3);
- HH(EDX,EAX,EBX,ECX, 9, 9);
- HH(ECX,EDX,EAX,EBX, 5,11);
- HH(EBX,ECX,EDX,EAX,13,15);
- HH(EAX,EBX,ECX,EDX, 3, 3);
- HH(EDX,EAX,EBX,ECX,11, 9);
- HH(ECX,EDX,EAX,EBX, 7,11);
- HH(EBX,ECX,EDX,EAX,15,15);
-
- ASSIGN(EBP, ARG(1))
- ADD(ARRAY4(EBP, 0), EAX)
- ADD(ARRAY4(EBP, 1), EBX)
- ADD(ARRAY4(EBP, 2), ECX)
- ADD(ARRAY4(EBP, 3), EDX)
-
- RESTORE_REGS()
-END_FUNCTION(botan_md4_x86_32_compress)
diff --git a/src/lib/hash/md5/md5.h b/src/lib/hash/md5/md5.h
index bbdc11aa6..9c5e548c0 100644
--- a/src/lib/hash/md5/md5.h
+++ b/src/lib/hash/md5/md5.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL MD5 : public MDx_HashFunction
{
public:
- std::string name() const { return "MD5"; }
- size_t output_length() const { return 16; }
- HashFunction* clone() const { return new MD5; }
+ std::string name() const override { return "MD5"; }
+ size_t output_length() const override { return 16; }
+ HashFunction* clone() const override { return new MD5; }
- void clear();
+ void clear() override;
MD5() : MDx_HashFunction(64, false, true), M(16), digest(4)
{ clear(); }
protected:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
/**
* The message buffer, exposed for use by subclasses (x86 asm)
diff --git a/src/lib/hash/md5_x86_32/info.txt b/src/lib/hash/md5_x86_32/info.txt
deleted file mode 100644
index 769ee8389..000000000
--- a/src/lib/hash/md5_x86_32/info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-define MD5_X86_32 20131128
-
-load_on asm_ok
-
-<arch>
-x86_32
-</arch>
-
-<requires>
-asm_x86_32
-md5
-</requires>
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32.cpp b/src/lib/hash/md5_x86_32/md5_x86_32.cpp
deleted file mode 100644
index 083e90900..000000000
--- a/src/lib/hash/md5_x86_32/md5_x86_32.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* MD5 (x86-32)
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/hash_utils.h>
-#include <botan/md5_x86_32.h>
-
-namespace Botan {
-
-BOTAN_REGISTER_NAMED_T_NOARGS(HashFunction, MD5_X86_32, "MD5", "x86-32");
-
-namespace {
-
-extern "C"
-void botan_md5_x86_32_compress(u32bit[4], const byte[64], u32bit[16]);
-
-}
-
-/*
-* MD5 Compression Function
-*/
-void MD5_X86_32::compress_n(const byte input[], size_t blocks)
- {
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_md5_x86_32_compress(digest.data(), input, M.data());
- input += hash_block_size();
- }
- }
-
-}
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32.h b/src/lib/hash/md5_x86_32/md5_x86_32.h
deleted file mode 100644
index 2f8873a2a..000000000
--- a/src/lib/hash/md5_x86_32/md5_x86_32.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* MD5 (x86-32)
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_MD5_X86_32_H__
-#define BOTAN_MD5_X86_32_H__
-
-#include <botan/md5.h>
-
-namespace Botan {
-
-/**
-* MD5 in x86 assembly
-*/
-class BOTAN_DLL MD5_X86_32 : public MD5
- {
- public:
- HashFunction* clone() const { return new MD5_X86_32; }
- private:
- void compress_n(const byte[], size_t blocks);
- };
-
-}
-
-#endif
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32_imp.S b/src/lib/hash/md5_x86_32/md5_x86_32_imp.S
deleted file mode 100644
index 23606e93a..000000000
--- a/src/lib/hash/md5_x86_32/md5_x86_32_imp.S
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-* MD5 in x86-32 assembler
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/asm_x86_32.h>
-
-START_LISTING(md5_x86_32.S)
-
-START_FUNCTION(botan_md5_x86_32_compress)
- SPILL_REGS()
-
-#define PUSHED 4
-
- ASSIGN(EBP, ARG(2)) /* input block */
- ASSIGN(EDI, ARG(3)) /* expanded words */
-
- ZEROIZE(ESI)
-
-START_LOOP(.LOAD_INPUT)
- ADD_IMM(ESI, 4)
-
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
- ADD_IMM(EBP, 16)
-
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-4), EAX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-3), EBX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-2), ECX)
- ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-1), EDX)
-LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
-
- ASSIGN(EBP, ARG(1))
- ASSIGN(EAX, ARRAY4(EBP, 0))
- ASSIGN(EBX, ARRAY4(EBP, 1))
- ASSIGN(ECX, ARRAY4(EBP, 2))
- ASSIGN(EDX, ARRAY4(EBP, 3))
-
-#define MSG EDI
-#define T1 ESI
-#define T2 EBP
-
-#define FF(A, B, C, D, N, S, MAGIC) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, C) ; \
- XOR(T2, D) ; \
- AND(T2, B) ; \
- XOR(T2, D) ; \
- ADD3_IMM(A, T1, MAGIC) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ; \
- ADD(A, B) ;
-
-#define GG(A, B, C, D, N, S, MAGIC) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, B) ; \
- XOR(T2, C) ; \
- AND(T2, D) ; \
- XOR(T2, C) ; \
- ADD3_IMM(A, T1, MAGIC) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ; \
- ADD(A, B) ;
-
-#define HH(A, B, C, D, N, S, MAGIC) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, B) ; \
- XOR(T2, C) ; \
- XOR(T2, D) ; \
- ADD3_IMM(A, T1, MAGIC) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ; \
- ADD(A, B) ;
-
-#define II(A, B, C, D, N, S, MAGIC) \
- ASSIGN(T1, ARRAY4(MSG, N)) ; \
- ASSIGN(T2, D) ; \
- NOT(T2) ; \
- OR(T2, B) ; \
- XOR(T2, C) ; \
- ADD3_IMM(A, T1, MAGIC) ; \
- ADD(A, T2) ; \
- ROTL_IMM(A, S) ; \
- ADD(A, B) ;
-
- FF(EAX,EBX,ECX,EDX, 0, 7,0xD76AA478);
- FF(EDX,EAX,EBX,ECX, 1,12,0xE8C7B756);
- FF(ECX,EDX,EAX,EBX, 2,17,0x242070DB);
- FF(EBX,ECX,EDX,EAX, 3,22,0xC1BDCEEE);
- FF(EAX,EBX,ECX,EDX, 4, 7,0xF57C0FAF);
- FF(EDX,EAX,EBX,ECX, 5,12,0x4787C62A);
- FF(ECX,EDX,EAX,EBX, 6,17,0xA8304613);
- FF(EBX,ECX,EDX,EAX, 7,22,0xFD469501);
- FF(EAX,EBX,ECX,EDX, 8, 7,0x698098D8);
- FF(EDX,EAX,EBX,ECX, 9,12,0x8B44F7AF);
- FF(ECX,EDX,EAX,EBX,10,17,0xFFFF5BB1);
- FF(EBX,ECX,EDX,EAX,11,22,0x895CD7BE);
- FF(EAX,EBX,ECX,EDX,12, 7,0x6B901122);
- FF(EDX,EAX,EBX,ECX,13,12,0xFD987193);
- FF(ECX,EDX,EAX,EBX,14,17,0xA679438E);
- FF(EBX,ECX,EDX,EAX,15,22,0x49B40821);
-
- GG(EAX,EBX,ECX,EDX, 1, 5,0xF61E2562);
- GG(EDX,EAX,EBX,ECX, 6, 9,0xC040B340);
- GG(ECX,EDX,EAX,EBX,11,14,0x265E5A51);
- GG(EBX,ECX,EDX,EAX, 0,20,0xE9B6C7AA);
- GG(EAX,EBX,ECX,EDX, 5, 5,0xD62F105D);
- GG(EDX,EAX,EBX,ECX,10, 9,0x02441453);
- GG(ECX,EDX,EAX,EBX,15,14,0xD8A1E681);
- GG(EBX,ECX,EDX,EAX, 4,20,0xE7D3FBC8);
- GG(EAX,EBX,ECX,EDX, 9, 5,0x21E1CDE6);
- GG(EDX,EAX,EBX,ECX,14, 9,0xC33707D6);
- GG(ECX,EDX,EAX,EBX, 3,14,0xF4D50D87);
- GG(EBX,ECX,EDX,EAX, 8,20,0x455A14ED);
- GG(EAX,EBX,ECX,EDX,13, 5,0xA9E3E905);
- GG(EDX,EAX,EBX,ECX, 2, 9,0xFCEFA3F8);
- GG(ECX,EDX,EAX,EBX, 7,14,0x676F02D9);
- GG(EBX,ECX,EDX,EAX,12,20,0x8D2A4C8A);
-
- HH(EAX,EBX,ECX,EDX, 5, 4,0xFFFA3942);
- HH(EDX,EAX,EBX,ECX, 8,11,0x8771F681);
- HH(ECX,EDX,EAX,EBX,11,16,0x6D9D6122);
- HH(EBX,ECX,EDX,EAX,14,23,0xFDE5380C);
- HH(EAX,EBX,ECX,EDX, 1, 4,0xA4BEEA44);
- HH(EDX,EAX,EBX,ECX, 4,11,0x4BDECFA9);
- HH(ECX,EDX,EAX,EBX, 7,16,0xF6BB4B60);
- HH(EBX,ECX,EDX,EAX,10,23,0xBEBFBC70);
- HH(EAX,EBX,ECX,EDX,13, 4,0x289B7EC6);
- HH(EDX,EAX,EBX,ECX, 0,11,0xEAA127FA);
- HH(ECX,EDX,EAX,EBX, 3,16,0xD4EF3085);
- HH(EBX,ECX,EDX,EAX, 6,23,0x04881D05);
- HH(EAX,EBX,ECX,EDX, 9, 4,0xD9D4D039);
- HH(EDX,EAX,EBX,ECX,12,11,0xE6DB99E5);
- HH(ECX,EDX,EAX,EBX,15,16,0x1FA27CF8);
- HH(EBX,ECX,EDX,EAX, 2,23,0xC4AC5665);
-
- II(EAX,EBX,ECX,EDX, 0, 6,0xF4292244);
- II(EDX,EAX,EBX,ECX, 7,10,0x432AFF97);
- II(ECX,EDX,EAX,EBX,14,15,0xAB9423A7);
- II(EBX,ECX,EDX,EAX, 5,21,0xFC93A039);
- II(EAX,EBX,ECX,EDX,12, 6,0x655B59C3);
- II(EDX,EAX,EBX,ECX, 3,10,0x8F0CCC92);
- II(ECX,EDX,EAX,EBX,10,15,0xFFEFF47D);
- II(EBX,ECX,EDX,EAX, 1,21,0x85845DD1);
- II(EAX,EBX,ECX,EDX, 8, 6,0x6FA87E4F);
- II(EDX,EAX,EBX,ECX,15,10,0xFE2CE6E0);
- II(ECX,EDX,EAX,EBX, 6,15,0xA3014314);
- II(EBX,ECX,EDX,EAX,13,21,0x4E0811A1);
- II(EAX,EBX,ECX,EDX, 4, 6,0xF7537E82);
- II(EDX,EAX,EBX,ECX,11,10,0xBD3AF235);
- II(ECX,EDX,EAX,EBX, 2,15,0x2AD7D2BB);
- II(EBX,ECX,EDX,EAX, 9,21,0xEB86D391);
-
- ASSIGN(EBP, ARG(1))
- ADD(ARRAY4(EBP, 0), EAX)
- ADD(ARRAY4(EBP, 1), EBX)
- ADD(ARRAY4(EBP, 2), ECX)
- ADD(ARRAY4(EBP, 3), EDX)
-
- RESTORE_REGS()
-END_FUNCTION(botan_md5_x86_32_compress)
diff --git a/src/lib/hash/mdx_hash/mdx_hash.h b/src/lib/hash/mdx_hash/mdx_hash.h
index 9671cbe81..2652d9ea6 100644
--- a/src/lib/hash/mdx_hash/mdx_hash.h
+++ b/src/lib/hash/mdx_hash/mdx_hash.h
@@ -29,10 +29,10 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction
bool big_bit_endian,
size_t counter_size = 8);
- size_t hash_block_size() const { return buffer.size(); }
+ size_t hash_block_size() const override { return buffer.size(); }
protected:
- void add_data(const byte input[], size_t length);
- void final_result(byte output[]);
+ void add_data(const byte input[], size_t length) override;
+ void final_result(byte output[]) override;
/**
* Run the hash's compression function over a set of blocks
@@ -41,7 +41,7 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction
*/
virtual void compress_n(const byte blocks[], size_t block_n) = 0;
- void clear();
+ void clear() override;
/**
* Copy the output to the buffer
diff --git a/src/lib/hash/par_hash/par_hash.h b/src/lib/hash/par_hash/par_hash.h
index 58900043a..0410e6826 100644
--- a/src/lib/hash/par_hash/par_hash.h
+++ b/src/lib/hash/par_hash/par_hash.h
@@ -19,11 +19,11 @@ namespace Botan {
class BOTAN_DLL Parallel : public HashFunction
{
public:
- void clear();
- std::string name() const;
- HashFunction* clone() const;
+ void clear() override;
+ std::string name() const override;
+ HashFunction* clone() const override;
- size_t output_length() const;
+ size_t output_length() const override;
/**
* @param hashes a set of hashes to compute in parallel
@@ -37,8 +37,8 @@ class BOTAN_DLL Parallel : public HashFunction
private:
Parallel() {}
- void add_data(const byte[], size_t);
- void final_result(byte[]);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
std::vector<std::unique_ptr<HashFunction>> hashes;
};
diff --git a/src/lib/hash/rmd128/rmd128.h b/src/lib/hash/rmd128/rmd128.h
index a91122c79..ea1eb2286 100644
--- a/src/lib/hash/rmd128/rmd128.h
+++ b/src/lib/hash/rmd128/rmd128.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction
{
public:
- std::string name() const { return "RIPEMD-128"; }
- size_t output_length() const { return 16; }
- HashFunction* clone() const { return new RIPEMD_128; }
+ std::string name() const override { return "RIPEMD-128"; }
+ size_t output_length() const override { return 16; }
+ HashFunction* clone() const override { return new RIPEMD_128; }
- void clear();
+ void clear() override;
RIPEMD_128() : MDx_HashFunction(64, false, true), M(16), digest(4)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u32bit> M, digest;
};
diff --git a/src/lib/hash/rmd160/rmd160.h b/src/lib/hash/rmd160/rmd160.h
index a4f428c37..ad7182404 100644
--- a/src/lib/hash/rmd160/rmd160.h
+++ b/src/lib/hash/rmd160/rmd160.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction
{
public:
- std::string name() const { return "RIPEMD-160"; }
- size_t output_length() const { return 20; }
- HashFunction* clone() const { return new RIPEMD_160; }
+ std::string name() const override { return "RIPEMD-160"; }
+ size_t output_length() const override { return 20; }
+ HashFunction* clone() const override { return new RIPEMD_160; }
- void clear();
+ void clear() override;
RIPEMD_160() : MDx_HashFunction(64, false, true), M(16), digest(5)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u32bit> M, digest;
};
diff --git a/src/lib/hash/sha1/sha160.h b/src/lib/hash/sha1/sha160.h
index fbafb5c7d..6328d74c4 100644
--- a/src/lib/hash/sha1/sha160.h
+++ b/src/lib/hash/sha1/sha160.h
@@ -18,11 +18,11 @@ namespace Botan {
class BOTAN_DLL SHA_160 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-160"; }
- size_t output_length() const { return 20; }
- HashFunction* clone() const { return new SHA_160; }
+ std::string name() const override { return "SHA-160"; }
+ size_t output_length() const override { return 20; }
+ HashFunction* clone() const override { return new SHA_160; }
- void clear();
+ void clear() override;
SHA_160() : MDx_HashFunction(64, true, true), digest(5), W(80)
{
@@ -41,8 +41,8 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction
clear();
}
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
/**
* The digest value, exposed for use by subclasses (asm, SSE2)
diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.h b/src/lib/hash/sha1_sse2/sha1_sse2.h
index fc74c41b7..20bb63727 100644
--- a/src/lib/hash/sha1_sse2/sha1_sse2.h
+++ b/src/lib/hash/sha1_sse2/sha1_sse2.h
@@ -18,10 +18,10 @@ namespace Botan {
class BOTAN_DLL SHA_160_SSE2 : public SHA_160
{
public:
- HashFunction* clone() const { return new SHA_160_SSE2; }
+ HashFunction* clone() const override { return new SHA_160_SSE2; }
SHA_160_SSE2() : SHA_160(0) {} // no W needed
private:
- void compress_n(const byte[], size_t blocks);
+ void compress_n(const byte[], size_t blocks) override;
};
}
diff --git a/src/lib/hash/sha1_x86_32/info.txt b/src/lib/hash/sha1_x86_32/info.txt
deleted file mode 100644
index 51e3f6587..000000000
--- a/src/lib/hash/sha1_x86_32/info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-define SHA1_X86_32 20131128
-
-load_on asm_ok
-
-<arch>
-x86_32
-</arch>
-
-<requires>
-asm_x86_32
-sha1
-</requires>
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp b/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp
deleted file mode 100644
index c5986221e..000000000
--- a/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* SHA-160 in x86-32
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/hash_utils.h>
-#include <botan/sha1_x86_32.h>
-
-namespace Botan {
-
-BOTAN_REGISTER_NAMED_T_NOARGS(HashFunction, SHA_160_X86_32, "SHA-160", "x86-32");
-
-namespace {
-
-extern "C"
-void botan_sha160_x86_32_compress(u32bit[5], const byte[64], u32bit[81]);
-
-}
-
-/*
-* SHA-160 Compression Function
-*/
-void SHA_160_X86_32::compress_n(const byte input[], size_t blocks)
- {
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_sha160_x86_32_compress(digest.data(), input, W.data());
- input += hash_block_size();
- }
- }
-
-}
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32.h b/src/lib/hash/sha1_x86_32/sha1_x86_32.h
deleted file mode 100644
index 738000744..000000000
--- a/src/lib/hash/sha1_x86_32/sha1_x86_32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* SHA-160 in x86-32 asm
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SHA_160_X86_32_H__
-#define BOTAN_SHA_160_X86_32_H__
-
-#include <botan/sha160.h>
-
-namespace Botan {
-
-/**
-* SHA-160 in x86 assembly
-*/
-class BOTAN_DLL SHA_160_X86_32 : public SHA_160
- {
- public:
- HashFunction* clone() const { return new SHA_160_X86_32; }
-
- // Note 81 instead of normal 80: x86-32 asm needs an extra temp
- SHA_160_X86_32() : SHA_160(81) {}
- private:
- void compress_n(const byte[], size_t blocks);
- };
-
-}
-
-#endif
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S b/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S
deleted file mode 100644
index 6ab5ed78d..000000000
--- a/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-* SHA-1 in x86-32 asm
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/asm_x86_32.h>
-
-START_LISTING(sha1_x86_32_imp.S)
-
-START_FUNCTION(botan_sha160_x86_32_compress)
- SPILL_REGS()
-
-#define PUSHED 4
-
- ASSIGN(EDI, ARG(2))
- ASSIGN(EBP, ARG(3))
-
- ZEROIZE(ESI)
-
-START_LOOP(.LOAD_INPUT)
- ADD_IMM(ESI, 4)
-
- ASSIGN(EAX, ARRAY4(EDI, 0))
- ASSIGN(EBX, ARRAY4(EDI, 1))
- ASSIGN(ECX, ARRAY4(EDI, 2))
- ASSIGN(EDX, ARRAY4(EDI, 3))
-
- ADD_IMM(EDI, 16)
-
- BSWAP(EAX)
- BSWAP(EBX)
- BSWAP(ECX)
- BSWAP(EDX)
-
- ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-4), EAX)
- ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-3), EBX)
- ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-2), ECX)
- ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-1), EDX)
-LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
-
- ADD2_IMM(EDI, EBP, 64)
-
-START_LOOP(.L_SHA_EXPANSION)
- ADD_IMM(ESI, 4)
-
- ZEROIZE(EAX)
- ASSIGN(EBX, ARRAY4(EDI, -1))
- ASSIGN(ECX, ARRAY4(EDI, -2))
- ASSIGN(EDX, ARRAY4(EDI, -3))
-
- XOR(EAX, ARRAY4(EDI, -5))
- XOR(EBX, ARRAY4(EDI, -6))
- XOR(ECX, ARRAY4(EDI, -7))
- XOR(EDX, ARRAY4(EDI, -8))
-
- XOR(EAX, ARRAY4(EDI, -11))
- XOR(EBX, ARRAY4(EDI, -12))
- XOR(ECX, ARRAY4(EDI, -13))
- XOR(EDX, ARRAY4(EDI, -14))
-
- XOR(EAX, ARRAY4(EDI, -13))
- XOR(EBX, ARRAY4(EDI, -14))
- XOR(ECX, ARRAY4(EDI, -15))
- XOR(EDX, ARRAY4(EDI, -16))
-
- ROTL_IMM(EDX, 1)
- ROTL_IMM(ECX, 1)
- ROTL_IMM(EBX, 1)
- XOR(EAX, EDX)
- ROTL_IMM(EAX, 1)
-
- ASSIGN(ARRAY4(EDI, 0), EDX)
- ASSIGN(ARRAY4(EDI, 1), ECX)
- ASSIGN(ARRAY4(EDI, 2), EBX)
- ASSIGN(ARRAY4(EDI, 3), EAX)
-
- ADD_IMM(EDI, 16)
-LOOP_UNTIL_EQ(ESI, 80, .L_SHA_EXPANSION)
-
-#define MAGIC1 0x5A827999
-#define MAGIC2 0x6ED9EBA1
-#define MAGIC3 0x8F1BBCDC
-#define MAGIC4 0xCA62C1D6
-
-#define MSG ESP
-#define T2 EBP
-
-#define F1(A, B, C, D, E, F, N) \
- ASSIGN(T2, ARRAY4(MSG, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, C) ; \
- XOR(E, D) ; \
- ADD3_IMM(F, T2, MAGIC1) ; \
- AND(E, B) ; \
- XOR(E, D) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F2_4(A, B, C, D, E, F, N, MAGIC) \
- ASSIGN(T2, ARRAY4(MSG, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, B) ; \
- XOR(E, C) ; \
- ADD3_IMM(F, T2, MAGIC) ; \
- XOR(E, D) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F3(A, B, C, D, E, F, N) \
- ASSIGN(T2, ARRAY4(MSG, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, B) ; \
- OR(E, C) ; \
- AND(E, D) ; \
- ADD3_IMM(F, T2, MAGIC3) ; \
- ASSIGN(T2, B) ; \
- AND(T2, C) ; \
- OR(E, T2) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F2(A, B, C, D, E, F, MSG) \
- F2_4(A, B, C, D, E, F, MSG, MAGIC2)
-
-#define F4(A, B, C, D, E, F, MSG) \
- F2_4(A, B, C, D, E, F, MSG, MAGIC4)
-
- ASSIGN(EAX, ARG(1))
- ASSIGN(EDI, ARRAY4(EAX, 0))
- ASSIGN(EBX, ARRAY4(EAX, 1))
- ASSIGN(ECX, ARRAY4(EAX, 2))
- ASSIGN(EDX, ARRAY4(EAX, 3))
- ASSIGN(ESI, ARRAY4(EAX, 4))
-
- ASSIGN(ARRAY4(EBP, 80), ESP)
- ASSIGN(ESP, EBP)
-
- /* First Round */
- F1(EAX, EBX, ECX, EDX, ESI, EDI, 0)
- F1(EDI, EAX, EBX, ECX, EDX, ESI, 1)
- F1(ESI, EDI, EAX, EBX, ECX, EDX, 2)
- F1(EDX, ESI, EDI, EAX, EBX, ECX, 3)
- F1(ECX, EDX, ESI, EDI, EAX, EBX, 4)
- F1(EBX, ECX, EDX, ESI, EDI, EAX, 5)
- F1(EAX, EBX, ECX, EDX, ESI, EDI, 6)
- F1(EDI, EAX, EBX, ECX, EDX, ESI, 7)
- F1(ESI, EDI, EAX, EBX, ECX, EDX, 8)
- F1(EDX, ESI, EDI, EAX, EBX, ECX, 9)
- F1(ECX, EDX, ESI, EDI, EAX, EBX, 10)
- F1(EBX, ECX, EDX, ESI, EDI, EAX, 11)
- F1(EAX, EBX, ECX, EDX, ESI, EDI, 12)
- F1(EDI, EAX, EBX, ECX, EDX, ESI, 13)
- F1(ESI, EDI, EAX, EBX, ECX, EDX, 14)
- F1(EDX, ESI, EDI, EAX, EBX, ECX, 15)
- F1(ECX, EDX, ESI, EDI, EAX, EBX, 16)
- F1(EBX, ECX, EDX, ESI, EDI, EAX, 17)
- F1(EAX, EBX, ECX, EDX, ESI, EDI, 18)
- F1(EDI, EAX, EBX, ECX, EDX, ESI, 19)
-
- /* Second Round */
- F2(ESI, EDI, EAX, EBX, ECX, EDX, 20)
- F2(EDX, ESI, EDI, EAX, EBX, ECX, 21)
- F2(ECX, EDX, ESI, EDI, EAX, EBX, 22)
- F2(EBX, ECX, EDX, ESI, EDI, EAX, 23)
- F2(EAX, EBX, ECX, EDX, ESI, EDI, 24)
- F2(EDI, EAX, EBX, ECX, EDX, ESI, 25)
- F2(ESI, EDI, EAX, EBX, ECX, EDX, 26)
- F2(EDX, ESI, EDI, EAX, EBX, ECX, 27)
- F2(ECX, EDX, ESI, EDI, EAX, EBX, 28)
- F2(EBX, ECX, EDX, ESI, EDI, EAX, 29)
- F2(EAX, EBX, ECX, EDX, ESI, EDI, 30)
- F2(EDI, EAX, EBX, ECX, EDX, ESI, 31)
- F2(ESI, EDI, EAX, EBX, ECX, EDX, 32)
- F2(EDX, ESI, EDI, EAX, EBX, ECX, 33)
- F2(ECX, EDX, ESI, EDI, EAX, EBX, 34)
- F2(EBX, ECX, EDX, ESI, EDI, EAX, 35)
- F2(EAX, EBX, ECX, EDX, ESI, EDI, 36)
- F2(EDI, EAX, EBX, ECX, EDX, ESI, 37)
- F2(ESI, EDI, EAX, EBX, ECX, EDX, 38)
- F2(EDX, ESI, EDI, EAX, EBX, ECX, 39)
-
- /* Third Round */
- F3(ECX, EDX, ESI, EDI, EAX, EBX, 40)
- F3(EBX, ECX, EDX, ESI, EDI, EAX, 41)
- F3(EAX, EBX, ECX, EDX, ESI, EDI, 42)
- F3(EDI, EAX, EBX, ECX, EDX, ESI, 43)
- F3(ESI, EDI, EAX, EBX, ECX, EDX, 44)
- F3(EDX, ESI, EDI, EAX, EBX, ECX, 45)
- F3(ECX, EDX, ESI, EDI, EAX, EBX, 46)
- F3(EBX, ECX, EDX, ESI, EDI, EAX, 47)
- F3(EAX, EBX, ECX, EDX, ESI, EDI, 48)
- F3(EDI, EAX, EBX, ECX, EDX, ESI, 49)
- F3(ESI, EDI, EAX, EBX, ECX, EDX, 50)
- F3(EDX, ESI, EDI, EAX, EBX, ECX, 51)
- F3(ECX, EDX, ESI, EDI, EAX, EBX, 52)
- F3(EBX, ECX, EDX, ESI, EDI, EAX, 53)
- F3(EAX, EBX, ECX, EDX, ESI, EDI, 54)
- F3(EDI, EAX, EBX, ECX, EDX, ESI, 55)
- F3(ESI, EDI, EAX, EBX, ECX, EDX, 56)
- F3(EDX, ESI, EDI, EAX, EBX, ECX, 57)
- F3(ECX, EDX, ESI, EDI, EAX, EBX, 58)
- F3(EBX, ECX, EDX, ESI, EDI, EAX, 59)
-
- /* Fourth Round */
- F4(EAX, EBX, ECX, EDX, ESI, EDI, 60)
- F4(EDI, EAX, EBX, ECX, EDX, ESI, 61)
- F4(ESI, EDI, EAX, EBX, ECX, EDX, 62)
- F4(EDX, ESI, EDI, EAX, EBX, ECX, 63)
- F4(ECX, EDX, ESI, EDI, EAX, EBX, 64)
- F4(EBX, ECX, EDX, ESI, EDI, EAX, 65)
- F4(EAX, EBX, ECX, EDX, ESI, EDI, 66)
- F4(EDI, EAX, EBX, ECX, EDX, ESI, 67)
- F4(ESI, EDI, EAX, EBX, ECX, EDX, 68)
- F4(EDX, ESI, EDI, EAX, EBX, ECX, 69)
- F4(ECX, EDX, ESI, EDI, EAX, EBX, 70)
- F4(EBX, ECX, EDX, ESI, EDI, EAX, 71)
- F4(EAX, EBX, ECX, EDX, ESI, EDI, 72)
- F4(EDI, EAX, EBX, ECX, EDX, ESI, 73)
- F4(ESI, EDI, EAX, EBX, ECX, EDX, 74)
- F4(EDX, ESI, EDI, EAX, EBX, ECX, 75)
- F4(ECX, EDX, ESI, EDI, EAX, EBX, 76)
- F4(EBX, ECX, EDX, ESI, EDI, EAX, 77)
- F4(EAX, EBX, ECX, EDX, ESI, EDI, 78)
- F4(EDI, EAX, EBX, ECX, EDX, ESI, 79)
-
- ASSIGN(ESP, ARRAY4(ESP, 80))
-
- ASSIGN(EBP, ARG(1))
- ADD(ARRAY4(EBP, 0), EDX)
- ADD(ARRAY4(EBP, 1), EDI)
- ADD(ARRAY4(EBP, 2), EAX)
- ADD(ARRAY4(EBP, 3), EBX)
- ADD(ARRAY4(EBP, 4), ECX)
-
- RESTORE_REGS()
-END_FUNCTION(botan_sha160_x86_32_compress)
diff --git a/src/lib/hash/sha1_x86_64/info.txt b/src/lib/hash/sha1_x86_64/info.txt
deleted file mode 100644
index db7cdcb92..000000000
--- a/src/lib/hash/sha1_x86_64/info.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-define SHA1_X86_64 20131128
-
-load_on asm_ok
-
-<arch>
-x86_64
-</arch>
-
-<requires>
-asm_x86_64
-sha1
-</requires>
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp b/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp
deleted file mode 100644
index f2fbff1a6..000000000
--- a/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* SHA-160
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/hash_utils.h>
-#include <botan/sha1_x86_64.h>
-
-namespace Botan {
-
-BOTAN_REGISTER_NAMED_T_NOARGS(HashFunction, SHA_160_X86_64, "SHA-160", "x86-64");
-
-namespace {
-
-extern "C"
-void botan_sha160_x86_64_compress(u32bit[5], const byte[64], u32bit[80]);
-
-}
-
-/*
-* SHA-160 Compression Function
-*/
-void SHA_160_X86_64::compress_n(const byte input[], size_t blocks)
- {
- for(size_t i = 0; i != blocks; ++i)
- {
- botan_sha160_x86_64_compress(digest.data(), input, W.data());
- input += hash_block_size();
- }
- }
-
-}
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64.h b/src/lib/hash/sha1_x86_64/sha1_x86_64.h
deleted file mode 100644
index 10bb8bd16..000000000
--- a/src/lib/hash/sha1_x86_64/sha1_x86_64.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* SHA-160 (x86-64)
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SHA_160_X86_64_H__
-#define BOTAN_SHA_160_X86_64_H__
-
-#include <botan/sha160.h>
-
-namespace Botan {
-
-/**
-* SHA-160 in x86-64 assembly
-*/
-class BOTAN_DLL SHA_160_X86_64 : public SHA_160
- {
- public:
- HashFunction* clone() const { return new SHA_160_X86_64; }
- private:
- void compress_n(const byte[], size_t blocks);
- };
-
-}
-
-#endif
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S b/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S
deleted file mode 100644
index dd46a9e56..000000000
--- a/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
-* SHA-1 in x86-64 assembler
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/asm_x86_64.h>
-
-START_LISTING(sha1_x86_64_imp.S)
-
-START_FUNCTION(botan_sha160_x86_64_compress)
-
-#define DIGEST_ARR %rdi
-#define INPUT %rsi
-#define W %rdx
-#define LOOP_CTR %eax
-
-#define A %r8d
-#define B %r9d
-#define C %r10d
-#define D %r11d
-#define E %ecx
-
- ZEROIZE(LOOP_CTR)
-
-ALIGN;
-.LOOP_LOAD_INPUT:
- addl $8, %eax
-
- movq ARRAY8(INPUT, 0), %r8
- movq ARRAY8(INPUT, 1), %r9
- movq ARRAY8(INPUT, 2), %r10
- movq ARRAY8(INPUT, 3), %r11
-
- bswap %r8
- bswap %r9
- bswap %r10
- bswap %r11
-
- rolq $32, %r8
- rolq $32, %r9
- rolq $32, %r10
- rolq $32, %r11
-
- movq %r8, ARRAY8(W, 0)
- movq %r9, ARRAY8(W, 1)
- movq %r10, ARRAY8(W, 2)
- movq %r11, ARRAY8(W, 3)
-
- addq $32, W
- addq $32, INPUT
-
- cmp IMM(16), LOOP_CTR
- jne .LOOP_LOAD_INPUT
-
-/*
-#define A %r8d
-#define B %r9d
-#define C %r10d
-#define D %r11d
-#define E %ecx
-*/
-
-ALIGN;
-.LOOP_EXPANSION:
- addl $4, LOOP_CTR
-
- ZEROIZE(A)
- ASSIGN(B, ARRAY4(W, -1))
- ASSIGN(C, ARRAY4(W, -2))
- ASSIGN(D, ARRAY4(W, -3))
-
- XOR(A, ARRAY4(W, -5))
- XOR(B, ARRAY4(W, -6))
- XOR(C, ARRAY4(W, -7))
- XOR(D, ARRAY4(W, -8))
-
- XOR(A, ARRAY4(W, -11))
- XOR(B, ARRAY4(W, -12))
- XOR(C, ARRAY4(W, -13))
- XOR(D, ARRAY4(W, -14))
-
- XOR(A, ARRAY4(W, -13))
- XOR(B, ARRAY4(W, -14))
- XOR(C, ARRAY4(W, -15))
- XOR(D, ARRAY4(W, -16))
-
- ROTL_IMM(D, 1)
- ROTL_IMM(C, 1)
- ROTL_IMM(B, 1)
- XOR(A, D)
- ROTL_IMM(A, 1)
-
- ASSIGN(ARRAY4(W, 0), D)
- ASSIGN(ARRAY4(W, 1), C)
- ASSIGN(ARRAY4(W, 2), B)
- ASSIGN(ARRAY4(W, 3), A)
-
- addq $16, W
- cmp IMM(80), LOOP_CTR
- jne .LOOP_EXPANSION
-
- subq $320, W
-
-/*
-* Using negative values for SHA-1 constants > 2^31 to work around
-* a bug in binutils not accepting large lea displacements.
-* -0x70E44324 == 0x8F1BBCDC
-* -0x359D3E2A == 0xCA62C1D6
-*/
-#define MAGIC1 0x5A827999
-#define MAGIC2 0x6ED9EBA1
-#define MAGIC3 -0x70E44324
-#define MAGIC4 -0x359D3E2A
-
-#define T %esi
-#define T2 %eax
-
-#define F1(A, B, C, D, E, F, N) \
- ASSIGN(T2, ARRAY4(W, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, C) ; \
- XOR(E, D) ; \
- ADD3_IMM(F, T2, MAGIC1) ; \
- AND(E, B) ; \
- XOR(E, D) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F2_4(A, B, C, D, E, F, N, MAGIC) \
- ASSIGN(T2, ARRAY4(W, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, B) ; \
- XOR(E, C) ; \
- ADD3_IMM(F, T2, MAGIC) ; \
- XOR(E, D) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F3(A, B, C, D, E, F, N) \
- ASSIGN(T2, ARRAY4(W, N)) ; \
- ASSIGN(A, F) ; \
- ROTL_IMM(F, 5) ; \
- ADD(F, E) ; \
- ASSIGN(E, B) ; \
- OR(E, C) ; \
- AND(E, D) ; \
- ADD3_IMM(F, T2, MAGIC3) ; \
- ASSIGN(T2, B) ; \
- AND(T2, C) ; \
- OR(E, T2) ; \
- ROTR_IMM(B, 2) ; \
- ADD(E, F) ;
-
-#define F2(A, B, C, D, E, F, W) \
- F2_4(A, B, C, D, E, F, W, MAGIC2)
-
-#define F4(A, B, C, D, E, F, W) \
- F2_4(A, B, C, D, E, F, W, MAGIC4)
-
- ASSIGN(T, ARRAY4(DIGEST_ARR, 0))
- ASSIGN(B, ARRAY4(DIGEST_ARR, 1))
- ASSIGN(C, ARRAY4(DIGEST_ARR, 2))
- ASSIGN(D, ARRAY4(DIGEST_ARR, 3))
- ASSIGN(E, ARRAY4(DIGEST_ARR, 4))
-
- /* First Round */
- F1(A, B, C, D, E, T, 0)
- F1(T, A, B, C, D, E, 1)
- F1(E, T, A, B, C, D, 2)
- F1(D, E, T, A, B, C, 3)
- F1(C, D, E, T, A, B, 4)
- F1(B, C, D, E, T, A, 5)
- F1(A, B, C, D, E, T, 6)
- F1(T, A, B, C, D, E, 7)
- F1(E, T, A, B, C, D, 8)
- F1(D, E, T, A, B, C, 9)
- F1(C, D, E, T, A, B, 10)
- F1(B, C, D, E, T, A, 11)
- F1(A, B, C, D, E, T, 12)
- F1(T, A, B, C, D, E, 13)
- F1(E, T, A, B, C, D, 14)
- F1(D, E, T, A, B, C, 15)
- F1(C, D, E, T, A, B, 16)
- F1(B, C, D, E, T, A, 17)
- F1(A, B, C, D, E, T, 18)
- F1(T, A, B, C, D, E, 19)
-
- /* Second Round */
- F2(E, T, A, B, C, D, 20)
- F2(D, E, T, A, B, C, 21)
- F2(C, D, E, T, A, B, 22)
- F2(B, C, D, E, T, A, 23)
- F2(A, B, C, D, E, T, 24)
- F2(T, A, B, C, D, E, 25)
- F2(E, T, A, B, C, D, 26)
- F2(D, E, T, A, B, C, 27)
- F2(C, D, E, T, A, B, 28)
- F2(B, C, D, E, T, A, 29)
- F2(A, B, C, D, E, T, 30)
- F2(T, A, B, C, D, E, 31)
- F2(E, T, A, B, C, D, 32)
- F2(D, E, T, A, B, C, 33)
- F2(C, D, E, T, A, B, 34)
- F2(B, C, D, E, T, A, 35)
- F2(A, B, C, D, E, T, 36)
- F2(T, A, B, C, D, E, 37)
- F2(E, T, A, B, C, D, 38)
- F2(D, E, T, A, B, C, 39)
-
- /* Third Round */
- F3(C, D, E, T, A, B, 40)
- F3(B, C, D, E, T, A, 41)
- F3(A, B, C, D, E, T, 42)
- F3(T, A, B, C, D, E, 43)
- F3(E, T, A, B, C, D, 44)
- F3(D, E, T, A, B, C, 45)
- F3(C, D, E, T, A, B, 46)
- F3(B, C, D, E, T, A, 47)
- F3(A, B, C, D, E, T, 48)
- F3(T, A, B, C, D, E, 49)
- F3(E, T, A, B, C, D, 50)
- F3(D, E, T, A, B, C, 51)
- F3(C, D, E, T, A, B, 52)
- F3(B, C, D, E, T, A, 53)
- F3(A, B, C, D, E, T, 54)
- F3(T, A, B, C, D, E, 55)
- F3(E, T, A, B, C, D, 56)
- F3(D, E, T, A, B, C, 57)
- F3(C, D, E, T, A, B, 58)
- F3(B, C, D, E, T, A, 59)
-
- /* Fourth Round */
- F4(A, B, C, D, E, T, 60)
- F4(T, A, B, C, D, E, 61)
- F4(E, T, A, B, C, D, 62)
- F4(D, E, T, A, B, C, 63)
- F4(C, D, E, T, A, B, 64)
- F4(B, C, D, E, T, A, 65)
- F4(A, B, C, D, E, T, 66)
- F4(T, A, B, C, D, E, 67)
- F4(E, T, A, B, C, D, 68)
- F4(D, E, T, A, B, C, 69)
- F4(C, D, E, T, A, B, 70)
- F4(B, C, D, E, T, A, 71)
- F4(A, B, C, D, E, T, 72)
- F4(T, A, B, C, D, E, 73)
- F4(E, T, A, B, C, D, 74)
- F4(D, E, T, A, B, C, 75)
- F4(C, D, E, T, A, B, 76)
- F4(B, C, D, E, T, A, 77)
- F4(A, B, C, D, E, T, 78)
- F4(T, A, B, C, D, E, 79)
-
- ADD(ARRAY4(DIGEST_ARR, 0), D)
- ADD(ARRAY4(DIGEST_ARR, 1), T)
- ADD(ARRAY4(DIGEST_ARR, 2), A)
- ADD(ARRAY4(DIGEST_ARR, 3), B)
- ADD(ARRAY4(DIGEST_ARR, 4), C)
-
-END_FUNCTION(botan_sha160_x86_64_compress)
diff --git a/src/lib/hash/sha2_32/sha2_32.h b/src/lib/hash/sha2_32/sha2_32.h
index 2ea12860d..e51087dc1 100644
--- a/src/lib/hash/sha2_32/sha2_32.h
+++ b/src/lib/hash/sha2_32/sha2_32.h
@@ -19,17 +19,17 @@ namespace Botan {
class BOTAN_DLL SHA_224 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-224"; }
- size_t output_length() const { return 28; }
- HashFunction* clone() const { return new SHA_224; }
+ std::string name() const override { return "SHA-224"; }
+ size_t output_length() const override { return 28; }
+ HashFunction* clone() const override { return new SHA_224; }
- void clear();
+ void clear() override;
SHA_224() : MDx_HashFunction(64, true, true), digest(8)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u32bit> digest;
};
@@ -40,17 +40,17 @@ class BOTAN_DLL SHA_224 : public MDx_HashFunction
class BOTAN_DLL SHA_256 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-256"; }
- size_t output_length() const { return 32; }
- HashFunction* clone() const { return new SHA_256; }
+ std::string name() const override { return "SHA-256"; }
+ size_t output_length() const override { return 32; }
+ HashFunction* clone() const override { return new SHA_256; }
- void clear();
+ void clear() override;
SHA_256() : MDx_HashFunction(64, true, true), digest(8)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u32bit> digest;
};
diff --git a/src/lib/hash/sha2_64/sha2_64.h b/src/lib/hash/sha2_64/sha2_64.h
index 2956d94e8..5aae5effe 100644
--- a/src/lib/hash/sha2_64/sha2_64.h
+++ b/src/lib/hash/sha2_64/sha2_64.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL SHA_384 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-384"; }
- size_t output_length() const { return 48; }
- HashFunction* clone() const { return new SHA_384; }
+ std::string name() const override { return "SHA-384"; }
+ size_t output_length() const override { return 48; }
+ HashFunction* clone() const override { return new SHA_384; }
- void clear();
+ void clear() override;
SHA_384() : MDx_HashFunction(128, true, true, 16), m_digest(8)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u64bit> m_digest;
};
@@ -39,17 +39,17 @@ class BOTAN_DLL SHA_384 : public MDx_HashFunction
class BOTAN_DLL SHA_512 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-512"; }
- size_t output_length() const { return 64; }
- HashFunction* clone() const { return new SHA_512; }
+ std::string name() const override { return "SHA-512"; }
+ size_t output_length() const override { return 64; }
+ HashFunction* clone() const override { return new SHA_512; }
- void clear();
+ void clear() override;
SHA_512() : MDx_HashFunction(128, true, true, 16), m_digest(8)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u64bit> m_digest;
};
@@ -60,16 +60,16 @@ class BOTAN_DLL SHA_512 : public MDx_HashFunction
class BOTAN_DLL SHA_512_256 : public MDx_HashFunction
{
public:
- std::string name() const { return "SHA-512/256"; }
- size_t output_length() const { return 32; }
- HashFunction* clone() const { return new SHA_512_256; }
+ std::string name() const override { return "SHA-512/256"; }
+ size_t output_length() const override { return 32; }
+ HashFunction* clone() const override { return new SHA_512_256; }
- void clear();
+ void clear() override;
SHA_512_256() : MDx_HashFunction(128, true, true, 16), m_digest(8) { clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
secure_vector<u64bit> m_digest;
};
diff --git a/src/lib/hash/skein/skein_512.h b/src/lib/hash/skein/skein_512.h
index 0b1ba319d..dceb34854 100644
--- a/src/lib/hash/skein/skein_512.h
+++ b/src/lib/hash/skein/skein_512.h
@@ -23,20 +23,20 @@ class BOTAN_DLL Skein_512 : public HashFunction
public:
/**
* @param output_bits the output size of Skein in bits
- * @param personalization is a string that will paramaterize the
+ * @param personalization is a string that will parameterize the
* hash output
*/
Skein_512(size_t output_bits = 512,
const std::string& personalization = "");
- size_t hash_block_size() const { return 64; }
- size_t output_length() const { return output_bits / 8; }
+ size_t hash_block_size() const override { return 64; }
+ size_t output_length() const override { return output_bits / 8; }
static Skein_512* make(const Spec& spec);
- HashFunction* clone() const;
- std::string name() const;
- void clear();
+ HashFunction* clone() const override;
+ std::string name() const override;
+ void clear() override;
private:
enum type_code {
SKEIN_KEY = 0,
@@ -49,8 +49,8 @@ class BOTAN_DLL Skein_512 : public HashFunction
SKEIN_OUTPUT = 63
};
- void add_data(const byte input[], size_t length);
- void final_result(byte out[]);
+ void add_data(const byte input[], size_t length) override;
+ void final_result(byte out[]) override;
void ubi_512(const byte msg[], size_t msg_len);
diff --git a/src/lib/hash/tiger/tiger.h b/src/lib/hash/tiger/tiger.h
index df3b869fb..986186dda 100644
--- a/src/lib/hash/tiger/tiger.h
+++ b/src/lib/hash/tiger/tiger.h
@@ -18,15 +18,15 @@ namespace Botan {
class BOTAN_DLL Tiger : public MDx_HashFunction
{
public:
- std::string name() const;
- size_t output_length() const { return hash_len; }
+ std::string name() const override;
+ size_t output_length() const override { return hash_len; }
- HashFunction* clone() const
+ HashFunction* clone() const override
{
return new Tiger(output_length(), passes);
}
- void clear();
+ void clear() override;
/**
* @param out_size specifies the output length; can be 16, 20, or 24
@@ -34,8 +34,8 @@ class BOTAN_DLL Tiger : public MDx_HashFunction
*/
Tiger(size_t out_size = 24, size_t passes = 3);
private:
- void compress_n(const byte[], size_t block);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t block) override;
+ void copy_out(byte[]) override;
static void pass(u64bit& A, u64bit& B, u64bit& C,
const secure_vector<u64bit>& M,
diff --git a/src/lib/hash/whirlpool/whrlpool.h b/src/lib/hash/whirlpool/whrlpool.h
index 4f067f18d..ba91da080 100644
--- a/src/lib/hash/whirlpool/whrlpool.h
+++ b/src/lib/hash/whirlpool/whrlpool.h
@@ -18,17 +18,17 @@ namespace Botan {
class BOTAN_DLL Whirlpool : public MDx_HashFunction
{
public:
- std::string name() const { return "Whirlpool"; }
- size_t output_length() const { return 64; }
- HashFunction* clone() const { return new Whirlpool; }
+ std::string name() const override { return "Whirlpool"; }
+ size_t output_length() const override { return 64; }
+ HashFunction* clone() const override { return new Whirlpool; }
- void clear();
+ void clear() override;
Whirlpool() : MDx_HashFunction(64, true, true, 32), M(8), digest(8)
{ clear(); }
private:
- void compress_n(const byte[], size_t blocks);
- void copy_out(byte[]);
+ void compress_n(const byte[], size_t blocks) override;
+ void copy_out(byte[]) override;
static const u64bit C0[256];
static const u64bit C1[256];
diff --git a/src/lib/kdf/hkdf/hkdf.h b/src/lib/kdf/hkdf/hkdf.h
index c5737b1cc..d8389a886 100644
--- a/src/lib/kdf/hkdf/hkdf.h
+++ b/src/lib/kdf/hkdf/hkdf.h
@@ -25,9 +25,9 @@ class BOTAN_DLL HKDF : public KDF
static HKDF* make(const Spec& spec);
- KDF* clone() const { return new HKDF(m_prf->clone()); }
+ KDF* clone() const override { return new HKDF(m_prf->clone()); }
- std::string name() const { return "HKDF(" + m_prf->name() + ")"; }
+ std::string name() const override { return "HKDF(" + m_prf->name() + ")"; }
size_t kdf(byte out[], size_t out_len,
const byte secret[], size_t secret_len,
diff --git a/src/lib/kdf/prf_tls/prf_tls.h b/src/lib/kdf/prf_tls/prf_tls.h
index e2289a6e8..bb7cc2c4f 100644
--- a/src/lib/kdf/prf_tls/prf_tls.h
+++ b/src/lib/kdf/prf_tls/prf_tls.h
@@ -19,9 +19,9 @@ namespace Botan {
class BOTAN_DLL TLS_PRF : public KDF
{
public:
- std::string name() const { return "TLS-PRF"; }
+ std::string name() const override { return "TLS-PRF"; }
- KDF* clone() const { return new TLS_PRF; }
+ KDF* clone() const override { return new TLS_PRF; }
size_t kdf(byte key[], size_t key_len,
const byte secret[], size_t secret_len,
@@ -39,9 +39,9 @@ class BOTAN_DLL TLS_PRF : public KDF
class BOTAN_DLL TLS_12_PRF : public KDF
{
public:
- std::string name() const { return "TLS-12-PRF(" + m_mac->name() + ")"; }
+ std::string name() const override { return "TLS-12-PRF(" + m_mac->name() + ")"; }
- KDF* clone() const { return new TLS_12_PRF(m_mac->clone()); }
+ KDF* clone() const override { return new TLS_12_PRF(m_mac->clone()); }
size_t kdf(byte key[], size_t key_len,
const byte secret[], size_t secret_len,
diff --git a/src/lib/kdf/prf_x942/prf_x942.h b/src/lib/kdf/prf_x942/prf_x942.h
index 242a83150..d0b23067c 100644
--- a/src/lib/kdf/prf_x942/prf_x942.h
+++ b/src/lib/kdf/prf_x942/prf_x942.h
@@ -18,9 +18,9 @@ namespace Botan {
class BOTAN_DLL X942_PRF : public KDF
{
public:
- std::string name() const { return "X942_PRF(" + m_key_wrap_oid + ")"; }
+ std::string name() const override { return "X942_PRF(" + m_key_wrap_oid + ")"; }
- KDF* clone() const { return new X942_PRF(m_key_wrap_oid); }
+ KDF* clone() const override { return new X942_PRF(m_key_wrap_oid); }
size_t kdf(byte key[], size_t key_len,
const byte secret[], size_t secret_len,
diff --git a/src/lib/mac/cbc_mac/cbc_mac.h b/src/lib/mac/cbc_mac/cbc_mac.h
index 722658174..f1c6d5230 100644
--- a/src/lib/mac/cbc_mac/cbc_mac.h
+++ b/src/lib/mac/cbc_mac/cbc_mac.h
@@ -19,12 +19,12 @@ namespace Botan {
class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode
{
public:
- std::string name() const;
- MessageAuthenticationCode* clone() const;
- size_t output_length() const { return m_cipher->block_size(); }
- void clear();
+ std::string name() const override;
+ MessageAuthenticationCode* clone() const override;
+ size_t output_length() const override { return m_cipher->block_size(); }
+ void clear() override;
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
@@ -36,9 +36,9 @@ class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode
static CBC_MAC* make(const Spec& spec);
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<byte> m_state;
diff --git a/src/lib/mac/cmac/cmac.h b/src/lib/mac/cmac/cmac.h
index f90e5d40c..4f8d22b76 100644
--- a/src/lib/mac/cmac/cmac.h
+++ b/src/lib/mac/cmac/cmac.h
@@ -19,13 +19,13 @@ namespace Botan {
class BOTAN_DLL CMAC : public MessageAuthenticationCode
{
public:
- std::string name() const;
- size_t output_length() const { return m_cipher->block_size(); }
- MessageAuthenticationCode* clone() const;
+ std::string name() const override;
+ size_t output_length() const override { return m_cipher->block_size(); }
+ MessageAuthenticationCode* clone() const override;
- void clear();
+ void clear() override;
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
@@ -47,9 +47,9 @@ class BOTAN_DLL CMAC : public MessageAuthenticationCode
CMAC(const CMAC&) = delete;
CMAC& operator=(const CMAC&) = delete;
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<byte> m_buffer, m_state, m_B, m_P;
diff --git a/src/lib/mac/hmac/hmac.h b/src/lib/mac/hmac/hmac.h
index 6b01eb365..3f5652352 100644
--- a/src/lib/mac/hmac/hmac.h
+++ b/src/lib/mac/hmac/hmac.h
@@ -19,13 +19,13 @@ namespace Botan {
class BOTAN_DLL HMAC : public MessageAuthenticationCode
{
public:
- void clear();
- std::string name() const;
- MessageAuthenticationCode* clone() const;
+ void clear() override;
+ std::string name() const override;
+ MessageAuthenticationCode* clone() const override;
- size_t output_length() const { return m_hash->output_length(); }
+ size_t output_length() const override { return m_hash->output_length(); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
// Absurd max length here is to support PBKDF2
return Key_Length_Specification(0, 512);
@@ -41,9 +41,9 @@ class BOTAN_DLL HMAC : public MessageAuthenticationCode
HMAC(const HMAC&) = delete;
HMAC& operator=(const HMAC&) = delete;
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
std::unique_ptr<HashFunction> m_hash;
secure_vector<byte> m_ikey, m_okey;
diff --git a/src/lib/mac/info.txt b/src/lib/mac/info.txt
index 3931f22e2..3faa16c11 100644
--- a/src/lib/mac/info.txt
+++ b/src/lib/mac/info.txt
@@ -1,3 +1,5 @@
+define MAC 20150626
+
<header:public>
mac.h
</header:public>
diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h
index 2ee971b90..8ad2d1e99 100644
--- a/src/lib/mac/mac.h
+++ b/src/lib/mac/mac.h
@@ -35,12 +35,6 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation,
*/
virtual MessageAuthenticationCode* clone() const = 0;
- /**
- * Get the name of this algorithm.
- * @return name of this algorithm
- */
- virtual std::string name() const = 0;
-
typedef SCAN_Name Spec;
};
diff --git a/src/lib/mac/poly1305/poly1305.cpp b/src/lib/mac/poly1305/poly1305.cpp
index 506150b0f..659667baf 100644
--- a/src/lib/mac/poly1305/poly1305.cpp
+++ b/src/lib/mac/poly1305/poly1305.cpp
@@ -190,7 +190,7 @@ void Poly1305::final_result(byte out[])
if(m_buf_pos != 0)
{
m_buf[m_buf_pos] = 1;
- const auto len = m_buf.size() - m_buf_pos - 1;
+ const size_t len = m_buf.size() - m_buf_pos - 1;
if (len > 0)
{
clear_mem(&m_buf[m_buf_pos+1], len);
diff --git a/src/lib/mac/poly1305/poly1305.h b/src/lib/mac/poly1305/poly1305.h
index 1c7fbf7fd..20bc9b5ad 100644
--- a/src/lib/mac/poly1305/poly1305.h
+++ b/src/lib/mac/poly1305/poly1305.h
@@ -22,21 +22,21 @@ class BOTAN_DLL Poly1305 : public MessageAuthenticationCode
public:
std::string name() const override { return "Poly1305"; }
- MessageAuthenticationCode* clone() const { return new Poly1305; }
+ MessageAuthenticationCode* clone() const override { return new Poly1305; }
- void clear();
+ void clear() override;
- size_t output_length() const { return 16; }
+ size_t output_length() const override { return 16; }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(32);
}
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
secure_vector<u64bit> m_poly;
secure_vector<byte> m_buf;
diff --git a/src/lib/mac/siphash/siphash.h b/src/lib/mac/siphash/siphash.h
index ec57864eb..574835ca4 100644
--- a/src/lib/mac/siphash/siphash.h
+++ b/src/lib/mac/siphash/siphash.h
@@ -17,21 +17,21 @@ class BOTAN_DLL SipHash : public MessageAuthenticationCode
public:
SipHash(size_t c = 2, size_t d = 4) : m_C(c), m_D(d) {}
- void clear();
- std::string name() const;
+ void clear() override;
+ std::string name() const override;
- MessageAuthenticationCode* clone() const;
+ MessageAuthenticationCode* clone() const override;
- size_t output_length() const { return 8; }
+ size_t output_length() const override { return 8; }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(16);
}
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
const size_t m_C, m_D;
secure_vector<u64bit> m_V;
diff --git a/src/lib/mac/x919_mac/x919_mac.h b/src/lib/mac/x919_mac/x919_mac.h
index 7b7d7d88b..9cdcd1527 100644
--- a/src/lib/mac/x919_mac/x919_mac.h
+++ b/src/lib/mac/x919_mac/x919_mac.h
@@ -19,13 +19,13 @@ namespace Botan {
class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode
{
public:
- void clear();
- std::string name() const;
- size_t output_length() const { return 8; }
+ void clear() override;
+ std::string name() const override;
+ size_t output_length() const override { return 8; }
- MessageAuthenticationCode* clone() const;
+ MessageAuthenticationCode* clone() const override;
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(8, 16, 8);
}
@@ -35,9 +35,9 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode
ANSI_X919_MAC(const ANSI_X919_MAC&) = delete;
ANSI_X919_MAC& operator=(const ANSI_X919_MAC&) = delete;
private:
- void add_data(const byte[], size_t);
- void final_result(byte[]);
- void key_schedule(const byte[], size_t);
+ void add_data(const byte[], size_t) override;
+ void final_result(byte[]) override;
+ void key_schedule(const byte[], size_t) override;
std::unique_ptr<BlockCipher> m_des1, m_des2;
secure_vector<byte> m_state;
diff --git a/src/lib/math/bigint/big_rand.cpp b/src/lib/math/bigint/big_rand.cpp
index ab66c6cdd..cfc1facee 100644
--- a/src/lib/math/bigint/big_rand.cpp
+++ b/src/lib/math/bigint/big_rand.cpp
@@ -7,6 +7,7 @@
#include <botan/bigint.h>
#include <botan/parsing.h>
+#include <botan/internal/rounding.h>
namespace Botan {
@@ -14,20 +15,27 @@ namespace Botan {
* Randomize this number
*/
void BigInt::randomize(RandomNumberGenerator& rng,
- size_t bitsize)
+ size_t bitsize, bool set_high_bit)
{
set_sign(Positive);
if(bitsize == 0)
+ {
clear();
+ }
else
{
- secure_vector<byte> array = rng.random_vec((bitsize + 7) / 8);
+ secure_vector<byte> array = rng.random_vec(round_up(bitsize, 8) / 8);
+ // Always cut unwanted bits
if(bitsize % 8)
array[0] &= 0xFF >> (8 - (bitsize % 8));
- array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0);
- binary_decode(array.data(), array.size());
+
+ // Set the highest bit if wanted
+ if (set_high_bit)
+ array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0);
+
+ binary_decode(array);
}
}
@@ -37,12 +45,19 @@ void BigInt::randomize(RandomNumberGenerator& rng,
BigInt BigInt::random_integer(RandomNumberGenerator& rng,
const BigInt& min, const BigInt& max)
{
- BigInt range = max - min;
+ BigInt delta_upper_bound = max - min - 1;
- if(range <= 0)
+ if(delta_upper_bound < 0)
throw Invalid_Argument("random_integer: invalid min/max values");
- return (min + (BigInt(rng, range.bits() + 2) % range));
+ // Choose x in [0, delta_upper_bound]
+ BigInt x;
+ do {
+ auto bitsize = delta_upper_bound.bits();
+ x.randomize(rng, bitsize, false);
+ } while(x > delta_upper_bound);
+
+ return min + x;
}
}
diff --git a/src/lib/math/bigint/bigint.cpp b/src/lib/math/bigint/bigint.cpp
index b5a8e0dd5..0a068c53e 100644
--- a/src/lib/math/bigint/bigint.cpp
+++ b/src/lib/math/bigint/bigint.cpp
@@ -34,7 +34,7 @@ BigInt::BigInt(u64bit n)
*/
BigInt::BigInt(Sign s, size_t size)
{
- m_reg.resize(round_up<size_t>(size, 8));
+ m_reg.resize(round_up(size, 8));
m_signedness = s;
}
@@ -87,9 +87,9 @@ BigInt::BigInt(const byte input[], size_t length, Base base)
/*
* Construct a BigInt from an encoded BigInt
*/
-BigInt::BigInt(RandomNumberGenerator& rng, size_t bits)
+BigInt::BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit)
{
- randomize(rng, bits);
+ randomize(rng, bits, set_high_bit);
}
/*
@@ -142,7 +142,7 @@ u32bit BigInt::to_u32bit() const
{
if(is_negative())
throw Encoding_Error("BigInt::to_u32bit: Number is negative");
- if(bits() >= 32)
+ if(bits() > 32)
throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
u32bit out = 0;
@@ -173,6 +173,11 @@ void BigInt::clear_bit(size_t n)
m_reg[which] &= ~mask;
}
+size_t BigInt::bytes() const
+ {
+ return round_up(bits(), 8) / 8;
+ }
+
/*
* Count how many bits are being used
*/
@@ -253,6 +258,12 @@ BigInt BigInt::abs() const
return x;
}
+void BigInt::grow_to(size_t n)
+ {
+ if(n > size())
+ m_reg.resize(round_up(n, 8));
+ }
+
/*
* Encode this number into bytes
*/
@@ -271,7 +282,7 @@ void BigInt::binary_decode(const byte buf[], size_t length)
const size_t WORD_BYTES = sizeof(word);
clear();
- m_reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8));
+ m_reg.resize(round_up((length / WORD_BYTES) + 1, 8));
for(size_t i = 0; i != length / WORD_BYTES; ++i)
{
diff --git a/src/lib/math/bigint/bigint.h b/src/lib/math/bigint/bigint.h
index fed986882..e3200ca9d 100644
--- a/src/lib/math/bigint/bigint.h
+++ b/src/lib/math/bigint/bigint.h
@@ -42,7 +42,7 @@ class BOTAN_DLL BigInt
/**
* Create empty BigInt
*/
- BigInt() { m_signedness = Positive; }
+ BigInt() {}
/**
* Create BigInt from 64 bit integer
@@ -74,11 +74,15 @@ class BOTAN_DLL BigInt
BigInt(const byte buf[], size_t length, Base base = Binary);
/**
- * Create a random BigInt of the specified size
+ * \brief Create a random BigInt of the specified size
+ *
* @param rng random number generator
* @param bits size in bits
+ * @param set_high_bit if true, the highest bit is always set
+ *
+ * @see randomize
*/
- BigInt(RandomNumberGenerator& rng, size_t bits);
+ BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true);
/**
* Create BigInt of specified size, all zeros
@@ -278,7 +282,7 @@ class BOTAN_DLL BigInt
if(top_word < size())
{
- const auto len = size() - (top_word + 1);
+ const size_t len = size() - (top_word + 1);
if (len > 0)
{
clear_mem(&m_reg[top_word+1], len);
@@ -400,7 +404,7 @@ class BOTAN_DLL BigInt
* Give byte length of the integer
* @result byte length of the represented integer value
*/
- size_t bytes() const { return (bits() + 7) / 8; }
+ size_t bytes() const;
/**
* Get the bit length of the integer
@@ -427,18 +431,20 @@ class BOTAN_DLL BigInt
* Increase internal register buffer to at least n words
* @param n new size of register
*/
- void grow_to(size_t n)
- {
- if(n > size())
- m_reg.resize(n + (8 - n % 8));
- }
+ void grow_to(size_t n);
/**
* Fill BigInt with a random number with size of bitsize
+ *
+ * If \p set_high_bit is true, the highest bit will be set, which causes
+ * the entropy to be \a bits-1. Otherwise the highest bit is randomly chosen
+ * by the rng, causing the entropy to be \a bits.
+ *
* @param rng the random number generator to use
* @param bitsize number of bits the created random value should have
+ * @param set_high_bit if true, the highest bit is always set
*/
- void randomize(RandomNumberGenerator& rng, size_t bitsize = 0);
+ void randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit = true);
/**
* Store BigInt-value in a given byte array
diff --git a/src/lib/math/ec_gfp/curve_gfp.cpp b/src/lib/math/ec_gfp/curve_gfp.cpp
index 64d45572d..96fe873af 100644
--- a/src/lib/math/ec_gfp/curve_gfp.cpp
+++ b/src/lib/math/ec_gfp/curve_gfp.cpp
@@ -1,12 +1,12 @@
/*
* Elliptic curves over GF(p) Montgomery Representation
-* (C) 2014 Jack Lloyd
+* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/curve_gfp.h>
-#include <botan/internal/curve_nistp.h>
+#include <botan/curve_nistp.h>
#include <botan/internal/mp_core.h>
#include <botan/internal/mp_asmi.h>
@@ -115,54 +115,170 @@ void CurveGFp_Montgomery::curve_sqr(BigInt& z, const BigInt& x,
ws.data());
}
-}
+class CurveGFp_NIST : public CurveGFp_Repr
+ {
+ public:
+ CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) :
+ m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS)
+ {
+ }
+
+ const BigInt& get_a() const override { return m_a; }
+
+ const BigInt& get_b() const override { return m_b; }
+
+ size_t get_p_words() const override { return m_p_words; }
+
+ const BigInt& get_a_rep() const override { return m_a; }
+
+ const BigInt& get_b_rep() const override { return m_b; }
+
+ void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override
+ { redc(x, ws); }
+
+ void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override
+ { redc(x, ws); }
+
+ void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
+ secure_vector<word>& ws) const override;
+
+ void curve_sqr(BigInt& z, const BigInt& x,
+ secure_vector<word>& ws) const override;
+ private:
+ virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0;
+
+ // Curve parameters
+ BigInt m_a, m_b;
+ size_t m_p_words; // cache of m_p.sig_words()
+ };
-// Default implementation
-void CurveGFp_Repr::normalize(BigInt& x, secure_vector<word>& ws, size_t bound) const
+void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
+ secure_vector<word>& ws) const
{
- const BigInt& p = get_p();
- const word* prime = p.data();
+ if(x.is_zero() || y.is_zero())
+ {
+ z = 0;
+ return;
+ }
+
const size_t p_words = get_p_words();
+ const size_t output_size = 2*p_words + 1;
+ ws.resize(2*(p_words+2));
- while(x.is_negative())
- x += p;
+ z.grow_to(output_size);
+ z.clear();
- x.grow_to(p_words + 1);
+ bigint_mul(z.mutable_data(), output_size, ws.data(),
+ x.data(), x.size(), x.sig_words(),
+ y.data(), y.size(), y.sig_words());
- if(ws.size() < p_words + 1)
- ws.resize(p_words + 1);
+ this->redc(z, ws);
+ }
- for(size_t i = 0; bound == 0 || i < bound; ++i)
+void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x,
+ secure_vector<word>& ws) const
+ {
+ if(x.is_zero())
{
- const word* xd = x.data();
- word borrow = 0;
+ z = 0;
+ return;
+ }
+
+ const size_t p_words = get_p_words();
+ const size_t output_size = 2*p_words + 1;
- for(size_t i = 0; i != p_words; ++i)
- ws[i] = word_sub(xd[i], prime[i], &borrow);
- ws[p_words] = word_sub(xd[p_words], 0, &borrow);
+ ws.resize(2*(p_words+2));
- if(borrow)
- break;
+ z.grow_to(output_size);
+ z.clear();
- x.swap_reg(ws);
- }
+ bigint_sqr(z.mutable_data(), output_size, ws.data(),
+ x.data(), x.size(), x.sig_words());
+
+ this->redc(z, ws);
}
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+
+/**
+* The NIST P-192 curve
+*/
+class CurveGFp_P192 : public CurveGFp_NIST
+ {
+ public:
+ CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {}
+ const BigInt& get_p() const override { return prime_p192(); }
+ private:
+ void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p192(x, ws); }
+ };
+
+/**
+* The NIST P-224 curve
+*/
+class CurveGFp_P224 : public CurveGFp_NIST
+ {
+ public:
+ CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {}
+ const BigInt& get_p() const override { return prime_p224(); }
+ private:
+ void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p224(x, ws); }
+ };
+
+/**
+* The NIST P-256 curve
+*/
+class CurveGFp_P256 : public CurveGFp_NIST
+ {
+ public:
+ CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {}
+ const BigInt& get_p() const override { return prime_p256(); }
+ private:
+ void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p256(x, ws); }
+ };
+
+/**
+* The NIST P-384 curve
+*/
+class CurveGFp_P384 : public CurveGFp_NIST
+ {
+ public:
+ CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {}
+ const BigInt& get_p() const override { return prime_p384(); }
+ private:
+ void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p384(x, ws); }
+ };
+
+#endif
+
+/**
+* The NIST P-521 curve
+*/
+class CurveGFp_P521 : public CurveGFp_NIST
+ {
+ public:
+ CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {}
+ const BigInt& get_p() const override { return prime_p521(); }
+ private:
+ void redc(BigInt& x, secure_vector<word>& ws) const override { redc_p521(x, ws); }
+ };
+
+}
+
std::shared_ptr<CurveGFp_Repr>
CurveGFp::choose_repr(const BigInt& p, const BigInt& a, const BigInt& b)
{
-#if defined(BOTAN_HAS_CURVEGFP_NISTP_M32)
- if(p == CurveGFp_P192::prime())
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+ if(p == prime_p192())
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P192(a, b));
- if(p == CurveGFp_P224::prime())
+ if(p == prime_p224())
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P224(a, b));
- if(p == CurveGFp_P256::prime())
+ if(p == prime_p256())
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P256(a, b));
- if(p == CurveGFp_P384::prime())
+ if(p == prime_p384())
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P384(a, b));
#endif
- if(p == CurveGFp_P521::prime())
+ if(p == prime_p521())
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_P521(a, b));
return std::shared_ptr<CurveGFp_Repr>(new CurveGFp_Montgomery(p, a, b));
diff --git a/src/lib/math/ec_gfp/curve_gfp.h b/src/lib/math/ec_gfp/curve_gfp.h
index 68fe93274..dde9f633e 100644
--- a/src/lib/math/ec_gfp/curve_gfp.h
+++ b/src/lib/math/ec_gfp/curve_gfp.h
@@ -45,10 +45,6 @@ class CurveGFp_Repr
virtual void curve_sqr(BigInt& z, const BigInt& x,
secure_vector<word>& ws) const = 0;
-
- virtual void normalize(BigInt& x,
- secure_vector<word>& ws,
- size_t bound) const;
};
/**
@@ -141,16 +137,6 @@ class BOTAN_DLL CurveGFp
return z;
}
- /**
- * Adjust x to be in [0,p)
- * @param bound if greater than zero, assume that no more than bound
- * additions or subtractions are required to move x into range.
- */
- void normalize(BigInt& x, secure_vector<word>& ws, size_t bound = 0) const
- {
- m_repr->normalize(x, ws, bound);
- }
-
void swap(CurveGFp& other)
{
std::swap(m_repr, other.m_repr);
diff --git a/src/lib/math/ec_gfp/curve_nistp.cpp b/src/lib/math/ec_gfp/curve_nistp.cpp
index 002cf2d47..bbc11ff21 100644
--- a/src/lib/math/ec_gfp/curve_nistp.cpp
+++ b/src/lib/math/ec_gfp/curve_nistp.cpp
@@ -1,63 +1,51 @@
/*
-* NIST curve reduction
+* NIST prime reductions
* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#include <botan/internal/curve_nistp.h>
+#include <botan/curve_nistp.h>
#include <botan/internal/mp_core.h>
+#include <botan/internal/mp_asmi.h>
namespace Botan {
-void CurveGFp_NIST::curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
- secure_vector<word>& ws) const
- {
- if(x.is_zero() || y.is_zero())
- {
- z = 0;
- return;
- }
+namespace {
- const size_t p_words = get_p_words();
- const size_t output_size = 2*p_words + 1;
- ws.resize(2*(p_words+2));
+void normalize(const BigInt& p, BigInt& x, secure_vector<word>& ws, size_t bound)
+ {
+ const word* prime = p.data();
+ const size_t p_words = p.sig_words();
- z.grow_to(output_size);
- z.clear();
+ while(x.is_negative())
+ x += p;
- bigint_mul(z.mutable_data(), output_size, ws.data(),
- x.data(), x.size(), x.sig_words(),
- y.data(), y.size(), y.sig_words());
+ // TODO: provide a high level function for this compare-and-sub operation
+ x.grow_to(p_words + 1);
- this->redc(z, ws);
- }
+ if(ws.size() < p_words + 1)
+ ws.resize(p_words + 1);
-void CurveGFp_NIST::curve_sqr(BigInt& z, const BigInt& x,
- secure_vector<word>& ws) const
- {
- if(x.is_zero())
+ for(size_t i = 0; bound == 0 || i < bound; ++i)
{
- z = 0;
- return;
- }
-
- const size_t p_words = get_p_words();
- const size_t output_size = 2*p_words + 1;
-
- ws.resize(2*(p_words+2));
+ const word* xd = x.data();
+ word borrow = 0;
- z.grow_to(output_size);
- z.clear();
+ for(size_t i = 0; i != p_words; ++i)
+ ws[i] = word_sub(xd[i], prime[i], &borrow);
+ ws[p_words] = word_sub(xd[p_words], 0, &borrow);
- bigint_sqr(z.mutable_data(), output_size, ws.data(),
- x.data(), x.size(), x.sig_words());
+ if(borrow)
+ break;
- this->redc(z, ws);
+ x.swap_reg(ws);
+ }
}
-//static
-const BigInt& CurveGFp_P521::prime()
+}
+
+const BigInt& prime_p521()
{
static const BigInt p521("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
@@ -65,12 +53,11 @@ const BigInt& CurveGFp_P521::prime()
return p521;
}
-void CurveGFp_P521::redc(BigInt& x, secure_vector<word>& ws) const
+void redc_p521(BigInt& x, secure_vector<word>& ws)
{
- const size_t p_words = get_p_words();
-
- const size_t shift_words = 521 / MP_WORD_BITS,
- shift_bits = 521 % MP_WORD_BITS;
+ const size_t p_full_words = 521 / MP_WORD_BITS;
+ const size_t p_top_bits = 521 % MP_WORD_BITS;
+ const size_t p_words = p_full_words + 1;
const size_t x_sw = x.sig_words();
@@ -81,16 +68,16 @@ void CurveGFp_P521::redc(BigInt& x, secure_vector<word>& ws) const
ws.resize(p_words + 1);
clear_mem(ws.data(), ws.size());
- bigint_shr2(ws.data(), x.data(), x_sw, shift_words, shift_bits);
+ bigint_shr2(ws.data(), x.data(), x_sw, p_full_words, p_top_bits);
x.mask_bits(521);
bigint_add3(x.mutable_data(), x.data(), p_words, ws.data(), p_words);
- normalize(x, ws, max_redc_subtractions());
+ normalize(prime_p521(), x, ws, 1);
}
-#if defined(BOTAN_HAS_CURVEGFP_NISTP_M32)
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
namespace {
@@ -130,14 +117,13 @@ inline void set_u32bit(BigInt& x, size_t i, T v_in)
}
-//static
-const BigInt& CurveGFp_P192::prime()
+const BigInt& prime_p192()
{
static const BigInt p192("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
return p192;
}
-void CurveGFp_P192::redc(BigInt& x, secure_vector<word>& ws) const
+void redc_p192(BigInt& x, secure_vector<word>& ws)
{
const u32bit X6 = get_u32bit(x, 6);
const u32bit X7 = get_u32bit(x, 7);
@@ -192,17 +178,16 @@ void CurveGFp_P192::redc(BigInt& x, secure_vector<word>& ws) const
// No underflow possible
- normalize(x, ws, max_redc_subtractions());
+ normalize(prime_p192(), x, ws, 3);
}
-//static
-const BigInt& CurveGFp_P224::prime()
+const BigInt& prime_p224()
{
static const BigInt p224("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
return p224;
}
-void CurveGFp_P224::redc(BigInt& x, secure_vector<word>& ws) const
+void redc_p224(BigInt& x, secure_vector<word>& ws)
{
const u32bit X7 = get_u32bit(x, 7);
const u32bit X8 = get_u32bit(x, 8);
@@ -271,17 +256,16 @@ void CurveGFp_P224::redc(BigInt& x, secure_vector<word>& ws) const
BOTAN_ASSERT_EQUAL(S >> 32, 0, "No underflow");
- normalize(x, ws, max_redc_subtractions());
+ normalize(prime_p224(), x, ws, 3);
}
-//static
-const BigInt& CurveGFp_P256::prime()
+const BigInt& prime_p256()
{
static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
return p256;
}
-void CurveGFp_P256::redc(BigInt& x, secure_vector<word>& ws) const
+void redc_p256(BigInt& x, secure_vector<word>& ws)
{
const u32bit X8 = get_u32bit(x, 8);
const u32bit X9 = get_u32bit(x, 9);
@@ -396,34 +380,35 @@ void CurveGFp_P256::redc(BigInt& x, secure_vector<word>& ws) const
BOTAN_ASSERT_EQUAL(S >> 32, 0, "No underflow");
+ #if 0
if(S >= 2)
{
BOTAN_ASSERT(S <= 10, "Expected overflow");
static const BigInt P256_mults[9] = {
- 2*get_p(),
- 3*get_p(),
- 4*get_p(),
- 5*get_p(),
- 6*get_p(),
- 7*get_p(),
- 8*get_p(),
- 9*get_p(),
- 10*get_p()
+ 2*CurveGFp_P256::prime(),
+ 3*CurveGFp_P256::prime(),
+ 4*CurveGFp_P256::prime(),
+ 5*CurveGFp_P256::prime(),
+ 6*CurveGFp_P256::prime(),
+ 7*CurveGFp_P256::prime(),
+ 8*CurveGFp_P256::prime(),
+ 9*CurveGFp_P256::prime(),
+ 10*CurveGFp_P256::prime()
};
x -= P256_mults[S - 2];
}
+ #endif
- normalize(x, ws, max_redc_subtractions());
+ normalize(prime_p256(), x, ws, 10);
}
-//static
-const BigInt& CurveGFp_P384::prime()
+const BigInt& prime_p384()
{
static const BigInt p384("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
return p384;
}
-void CurveGFp_P384::redc(BigInt& x, secure_vector<word>& ws) const
+void redc_p384(BigInt& x, secure_vector<word>& ws)
{
const u32bit X12 = get_u32bit(x, 12);
const u32bit X13 = get_u32bit(x, 13);
@@ -569,20 +554,22 @@ void CurveGFp_P384::redc(BigInt& x, secure_vector<word>& ws) const
BOTAN_ASSERT_EQUAL(S >> 32, 0, "No underflow");
set_u32bit(x, 12, S);
+ #if 0
if(S >= 2)
{
BOTAN_ASSERT(S <= 4, "Expected overflow");
static const BigInt P384_mults[3] = {
- 2*get_p(),
- 3*get_p(),
- 4*get_p()
+ 2*CurveGFp_P384::prime(),
+ 3*CurveGFp_P384::prime(),
+ 4*CurveGFp_P384::prime()
};
x -= P384_mults[S - 2];
}
+ #endif
- normalize(x, ws, max_redc_subtractions());
+ normalize(prime_p384(), x, ws, 4);
}
#endif
diff --git a/src/lib/math/ec_gfp/curve_nistp.h b/src/lib/math/ec_gfp/curve_nistp.h
index 0bf707f58..e7af69964 100644
--- a/src/lib/math/ec_gfp/curve_nistp.h
+++ b/src/lib/math/ec_gfp/curve_nistp.h
@@ -1,152 +1,46 @@
/*
-* NIST elliptic curves over GF(p)
-* (C) 2014 Jack Lloyd
+* Arithmetic operations specialized for NIST ECC primes
+* (C) 2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#ifndef BOTAN_GFP_CURVE_NIST_H__
-#define BOTAN_GFP_CURVE_NIST_H__
+#ifndef BOTAN_NIST_PRIMES_H__
+#define BOTAN_NIST_PRIMES_H__
-#include <botan/curve_gfp.h>
-#include <memory>
+#include <botan/bigint.h>
namespace Botan {
-class CurveGFp_NIST : public CurveGFp_Repr
- {
- public:
- CurveGFp_NIST(size_t p_bits, const BigInt& a, const BigInt& b) :
- m_a(a), m_b(b), m_p_words((p_bits + BOTAN_MP_WORD_BITS - 1) / BOTAN_MP_WORD_BITS)
- {
- }
-
- size_t get_p_words() const override { return m_p_words; }
-
- const BigInt& get_a() const override { return m_a; }
-
- const BigInt& get_b() const override { return m_b; }
-
- const BigInt& get_a_rep() const override { return m_a; }
-
- const BigInt& get_b_rep() const override { return m_b; }
-
- void to_curve_rep(BigInt& x, secure_vector<word>& ws) const override
- { redc(x, ws); }
-
- void from_curve_rep(BigInt& x, secure_vector<word>& ws) const override
- { redc(x, ws); }
-
- void curve_mul(BigInt& z, const BigInt& x, const BigInt& y,
- secure_vector<word>& ws) const override;
-
- void curve_sqr(BigInt& z, const BigInt& x,
- secure_vector<word>& ws) const override;
- private:
- virtual void redc(BigInt& x, secure_vector<word>& ws) const = 0;
-
- virtual size_t max_redc_subtractions() const = 0;
-
- // Curve parameters
- BigInt m_a, m_b;
- size_t m_p_words; // cache of m_p.sig_words()
- };
-
-#if (BOTAN_MP_WORD_BITS == 32) || (BOTAN_MP_WORD_BITS == 64)
-
-#define BOTAN_HAS_CURVEGFP_NISTP_M32
-
-/**
-* The NIST P-192 curve
-*/
-class CurveGFp_P192 : public CurveGFp_NIST
- {
- public:
- CurveGFp_P192(const BigInt& a, const BigInt& b) : CurveGFp_NIST(192, a, b) {}
-
- static const BigInt& prime();
-
- const BigInt& get_p() const override { return CurveGFp_P192::prime(); }
-
- private:
- void redc(BigInt& x, secure_vector<word>& ws) const override;
-
- size_t max_redc_subtractions() const override { return 3; }
- };
-
/**
-* The NIST P-224 curve
-*/
-class CurveGFp_P224 : public CurveGFp_NIST
- {
- public:
- CurveGFp_P224(const BigInt& a, const BigInt& b) : CurveGFp_NIST(224, a, b) {}
-
- static const BigInt& prime();
-
- const BigInt& get_p() const override { return CurveGFp_P224::prime(); }
- private:
- void redc(BigInt& x, secure_vector<word>& ws) const override;
-
- size_t max_redc_subtractions() const override { return 3; }
- };
-
-/**
-* The NIST P-256 curve
+* NIST Prime reduction functions.
+*
+* Reduces the value in place
+*
+* ws is a workspace function which is used as a temporary,
+* and will be resized as needed.
*/
-class CurveGFp_P256 : public CurveGFp_NIST
- {
- public:
- CurveGFp_P256(const BigInt& a, const BigInt& b) : CurveGFp_NIST(256, a, b) {}
-
- static const BigInt& prime();
-
- const BigInt& get_p() const override { return CurveGFp_P256::prime(); }
-
- private:
- void redc(BigInt& x, secure_vector<word>& ws) const override;
+BOTAN_DLL const BigInt& prime_p521();
+BOTAN_DLL void redc_p521(BigInt& x, secure_vector<word>& ws);
- size_t max_redc_subtractions() const override { return 10; }
- };
+#if (BOTAN_MP_WORD_BITS == 32) || (BOTAN_MP_WORD_BITS == 64)
-/**
-* The NIST P-384 curve
-*/
-class CurveGFp_P384 : public CurveGFp_NIST
- {
- public:
- CurveGFp_P384(const BigInt& a, const BigInt& b) : CurveGFp_NIST(384, a, b) {}
+#define BOTAN_HAS_NIST_PRIME_REDUCERS_W32
- static const BigInt& prime();
+BOTAN_DLL const BigInt& prime_p384();
+BOTAN_DLL void redc_p384(BigInt& x, secure_vector<word>& ws);
- const BigInt& get_p() const override { return CurveGFp_P384::prime(); }
+BOTAN_DLL const BigInt& prime_p256();
+BOTAN_DLL void redc_p256(BigInt& x, secure_vector<word>& ws);
- private:
- void redc(BigInt& x, secure_vector<word>& ws) const override;
+BOTAN_DLL const BigInt& prime_p224();
+BOTAN_DLL void redc_p224(BigInt& x, secure_vector<word>& ws);
- size_t max_redc_subtractions() const override { return 4; }
- };
+BOTAN_DLL const BigInt& prime_p192();
+BOTAN_DLL void redc_p192(BigInt& x, secure_vector<word>& ws);
#endif
-/**
-* The NIST P-521 curve
-*/
-class CurveGFp_P521 : public CurveGFp_NIST
- {
- public:
- CurveGFp_P521(const BigInt& a, const BigInt& b) : CurveGFp_NIST(521, a, b) {}
-
- static const BigInt& prime();
-
- const BigInt& get_p() const override { return CurveGFp_P521::prime(); }
-
- private:
- void redc(BigInt& x, secure_vector<word>& ws) const override;
-
- size_t max_redc_subtractions() const override { return 1; }
- };
-
}
#endif
diff --git a/src/lib/math/ec_gfp/info.txt b/src/lib/math/ec_gfp/info.txt
index 9af40c752..060551562 100644
--- a/src/lib/math/ec_gfp/info.txt
+++ b/src/lib/math/ec_gfp/info.txt
@@ -2,15 +2,6 @@ define EC_CURVE_GFP 20131128
load_on auto
-<header:public>
-curve_gfp.h
-point_gfp.h
-</header:public>
-
-<header:internal>
-curve_nistp.h
-</header:internal>
-
<requires>
numbertheory
</requires>
diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp
index 2505e4d54..a319d8657 100644
--- a/src/lib/math/ec_gfp/point_gfp.cpp
+++ b/src/lib/math/ec_gfp/point_gfp.cpp
@@ -2,36 +2,55 @@
* Point arithmetic on elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
-* 2008-2011,2012,2014 Jack Lloyd
+* 2008-2011,2012,2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/point_gfp.h>
#include <botan/numthry.h>
+#include <botan/loadstor.h>
namespace Botan {
+const size_t BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS = 20;
+const size_t BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS = 48;
+
+#define BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER 1
+
PointGFp::PointGFp(const CurveGFp& curve) :
- curve(curve),
- coord_x(0),
- coord_y(1),
- coord_z(0)
+ m_curve(curve),
+ m_coord_x(0),
+ m_coord_y(1),
+ m_coord_z(0)
{
- curve.to_rep(coord_x, ws);
- curve.to_rep(coord_y, ws);
- curve.to_rep(coord_z, ws);
+ m_curve.to_rep(m_coord_x, m_monty_ws);
+ m_curve.to_rep(m_coord_y, m_monty_ws);
+ m_curve.to_rep(m_coord_z, m_monty_ws);
}
PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) :
- curve(curve),
- coord_x(x),
- coord_y(y),
- coord_z(1)
+ m_curve(curve),
+ m_coord_x(x),
+ m_coord_y(y),
+ m_coord_z(1)
+ {
+ m_curve.to_rep(m_coord_x, m_monty_ws);
+ m_curve.to_rep(m_coord_y, m_monty_ws);
+ m_curve.to_rep(m_coord_z, m_monty_ws);
+ }
+
+void PointGFp::randomize_repr(RandomNumberGenerator& rng)
{
- curve.to_rep(coord_x, ws);
- curve.to_rep(coord_y, ws);
- curve.to_rep(coord_z, ws);
+ BigInt mask(rng, BOTAN_POINTGFP_RANDOMIZE_BLINDING_BITS, false);
+
+ m_curve.to_rep(mask, m_monty_ws);
+ const BigInt mask2 = curve_mult(mask, mask);
+ const BigInt mask3 = curve_mult(mask2, mask);
+
+ m_coord_x = curve_mult(m_coord_x, mask2);
+ m_coord_y = curve_mult(m_coord_y, mask3);
+ m_coord_z = curve_mult(m_coord_z, mask);
}
// Point addition
@@ -39,15 +58,15 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
{
if(is_zero())
{
- coord_x = rhs.coord_x;
- coord_y = rhs.coord_y;
- coord_z = rhs.coord_z;
+ m_coord_x = rhs.m_coord_x;
+ m_coord_y = rhs.m_coord_y;
+ m_coord_z = rhs.m_coord_z;
return;
}
else if(rhs.is_zero())
return;
- const BigInt& p = curve.get_p();
+ const BigInt& p = m_curve.get_p();
BigInt& rhs_z2 = ws_bn[0];
BigInt& U1 = ws_bn[1];
@@ -64,13 +83,13 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
*/
- curve_sqr(rhs_z2, rhs.coord_z);
- curve_mult(U1, coord_x, rhs_z2);
- curve_mult(S1, coord_y, curve_mult(rhs.coord_z, rhs_z2));
+ curve_sqr(rhs_z2, rhs.m_coord_z);
+ curve_mult(U1, m_coord_x, rhs_z2);
+ curve_mult(S1, m_coord_y, curve_mult(rhs.m_coord_z, rhs_z2));
- curve_sqr(lhs_z2, coord_z);
- curve_mult(U2, rhs.coord_x, lhs_z2);
- curve_mult(S2, rhs.coord_y, curve_mult(coord_z, lhs_z2));
+ curve_sqr(lhs_z2, m_coord_z);
+ curve_mult(U2, rhs.m_coord_x, lhs_z2);
+ curve_mult(S2, rhs.m_coord_y, curve_mult(m_coord_z, lhs_z2));
H = U2;
H -= U1;
@@ -90,7 +109,10 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
return;
}
- *this = PointGFp(curve); // setting myself to zero
+ // setting to zero:
+ m_coord_x = 0;
+ m_coord_y = 1;
+ m_coord_z = 0;
return;
}
@@ -100,22 +122,22 @@ void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
U2 = curve_mult(U1, U2);
- curve_sqr(coord_x, r);
- coord_x -= S2;
- coord_x -= (U2 << 1);
- while(coord_x.is_negative())
- coord_x += p;
+ curve_sqr(m_coord_x, r);
+ m_coord_x -= S2;
+ m_coord_x -= (U2 << 1);
+ while(m_coord_x.is_negative())
+ m_coord_x += p;
- U2 -= coord_x;
+ U2 -= m_coord_x;
if(U2.is_negative())
U2 += p;
- curve_mult(coord_y, r, U2);
- coord_y -= curve_mult(S1, S2);
- if(coord_y.is_negative())
- coord_y += p;
+ curve_mult(m_coord_y, r, U2);
+ m_coord_y -= curve_mult(S1, S2);
+ if(m_coord_y.is_negative())
+ m_coord_y += p;
- curve_mult(coord_z, curve_mult(coord_z, rhs.coord_z), H);
+ curve_mult(m_coord_z, curve_mult(m_coord_z, rhs.m_coord_z), H);
}
// *this *= 2
@@ -123,9 +145,9 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn)
{
if(is_zero())
return;
- else if(coord_y.is_zero())
+ else if(m_coord_y.is_zero())
{
- *this = PointGFp(curve); // setting myself to zero
+ *this = PointGFp(m_curve); // setting myself to zero
return;
}
@@ -133,7 +155,7 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn)
http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc
*/
- const BigInt& p = curve.get_p();
+ const BigInt& p = m_curve.get_p();
BigInt& y_2 = ws_bn[0];
BigInt& S = ws_bn[1];
@@ -145,17 +167,17 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn)
BigInt& y = ws_bn[7];
BigInt& z = ws_bn[8];
- curve_sqr(y_2, coord_y);
+ curve_sqr(y_2, m_coord_y);
- curve_mult(S, coord_x, y_2);
+ curve_mult(S, m_coord_x, y_2);
S <<= 2; // * 4
while(S >= p)
S -= p;
- curve_sqr(z4, curve_sqr(coord_z));
- curve_mult(a_z4, curve.get_a_rep(), z4);
+ curve_sqr(z4, curve_sqr(m_coord_z));
+ curve_mult(a_z4, m_curve.get_a_rep(), z4);
- M = curve_sqr(coord_x);
+ M = curve_sqr(m_coord_x);
M *= 3;
M += a_z4;
while(M >= p)
@@ -180,14 +202,14 @@ void PointGFp::mult2(std::vector<BigInt>& ws_bn)
if(y.is_negative())
y += p;
- curve_mult(z, coord_y, coord_z);
+ curve_mult(z, m_coord_y, m_coord_z);
z <<= 1;
if(z >= p)
z -= p;
- coord_x = x;
- coord_y = y;
- coord_z = z;
+ m_coord_x = x;
+ m_coord_y = y;
+ m_coord_z = z;
}
// arithmetic operators
@@ -221,7 +243,7 @@ PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1,
{
const PointGFp p3 = p1 + p2;
- PointGFp H(p1.curve); // create as zero
+ PointGFp H(p1.get_curve()); // create as zero
size_t bits_left = std::max(z1.bits(), z2.bits());
std::vector<BigInt> ws(9);
@@ -251,22 +273,24 @@ PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1,
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
{
- //BOTAN_ASSERT(point.on_the_curve(), "Input is valid");
+ //BOTAN_ASSERT(point.on_the_curve(), "Input is on the curve");
const CurveGFp& curve = point.get_curve();
- if(scalar.is_zero())
- return PointGFp(curve); // zero point
+ const size_t scalar_bits = scalar.bits();
std::vector<BigInt> ws(9);
- if(scalar.abs() <= 2) // special cases for small values
+ if(scalar_bits <= 2)
{
- byte value = scalar.abs().byte_at(0);
+ const byte abs_val = scalar.byte_at(0);
+
+ if(abs_val == 0)
+ return PointGFp::zero_of(curve);
PointGFp result = point;
- if(value == 2)
+ if(abs_val == 2)
result.mult2(ws);
if(scalar.is_negative())
@@ -275,94 +299,164 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point)
return result;
}
- const size_t scalar_bits = scalar.bits();
+ PointGFp R[2] = { PointGFp(curve), point };
- PointGFp x1(curve); // zero
+ for(size_t i = scalar_bits; i > 0; i--)
+ {
+ const size_t b = scalar.get_bit(i - 1);
+ R[b ^ 1].add(R[b], ws);
+ R[b].mult2(ws);
+ }
- size_t bits_left = scalar_bits;
+ if(scalar.is_negative())
+ R[0].negate();
-#if BOTAN_CURVE_GFP_USE_MONTGOMERY_LADDER
+ //BOTAN_ASSERT(R[0].on_the_curve(), "Output is on the curve");
- PointGFp x2 = point;
- while(bits_left)
+ return R[0];
+ }
+
+Blinded_Point_Multiply::Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h) :
+ m_order(order), m_h(h ? h : 4), m_ws(9)
+ {
+ // Upper bound is a sanity check rather than hard limit
+ if(m_h < 1 || m_h > 8)
+ throw std::invalid_argument("Blinded_Point_Multiply invalid h param");
+
+ const CurveGFp& curve = base.get_curve();
+
+#if BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER
+
+ const PointGFp inv = -base;
+
+ m_U.resize(6*m_h + 3);
+
+ m_U[3*m_h+0] = inv;
+ m_U[3*m_h+1] = PointGFp::zero_of(curve);
+ m_U[3*m_h+2] = base;
+
+ for(size_t i = 1; i <= 3 * m_h + 1; ++i)
{
- if(scalar.get_bit(bits_left - 1))
- {
- x1.add(x2, ws);
- x2.mult2(ws);
- }
- else
- {
- x2.add(x1, ws);
- x1.mult2(ws);
- }
+ m_U[3*m_h+1+i] = m_U[3*m_h+i];
+ m_U[3*m_h+1+i].add(base, m_ws);
- --bits_left;
+ m_U[3*m_h+1-i] = m_U[3*m_h+2-i];
+ m_U[3*m_h+1-i].add(inv, m_ws);
}
-
#else
- const size_t window_bits = 4;
+ m_U.resize(1 << m_h);
+ m_U[0] = PointGFp::zero_of(curve);
+ m_U[1] = base;
+
+ for(size_t i = 2; i < m_U.size(); ++i)
+ {
+ m_U[i] = m_U[i-1];
+ m_U[i].add(base, m_ws);
+ }
+#endif
+ }
- std::vector<PointGFp> Ps(1 << window_bits);
- Ps[0] = x1;
- Ps[1] = point;
+PointGFp Blinded_Point_Multiply::blinded_multiply(const BigInt& scalar_in,
+ RandomNumberGenerator& rng)
+ {
+ if(scalar_in.is_negative())
+ throw std::invalid_argument("Blinded_Point_Multiply scalar must be positive");
+
+ // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
+ const u64bit mask = rng.gen_mask(BOTAN_POINTGFP_MONTGOMERY_BLINDING_BITS);
+ const BigInt scalar = scalar_in + m_order * mask;
+ const size_t scalar_bits = scalar.bits();
+
+ // Randomize each point representation (Coron's 3rd countermeasure)
+ for(size_t i = 0; i != m_U.size(); ++i)
+ m_U[i].randomize_repr(rng);
+
+#if BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER
+ PointGFp R = m_U.at(3*m_h + 2); // base point
+ int32_t alpha = 0;
+
+ R.randomize_repr(rng);
+
+ /*
+ Algorithm 7 from "Randomizing the Montgomery Powering Ladder"
+ Duc-Phong Le, Chik How Tan and Michael Tunstall
+ http://eprint.iacr.org/2015/657
- for(size_t i = 2; i < Ps.size(); ++i)
+ It takes a random walk through (a subset of) the set of addition
+ chains that end in k.
+ */
+ for(size_t i = scalar_bits; i > 0; i--)
{
- Ps[i] = Ps[i-1];
- Ps[i].add(point, ws);
+ const int32_t ki = scalar.get_bit(i);
+
+ // choose gamma from -h,...,h
+ const int32_t gamma = static_cast<int32_t>((rng.next_byte() % (2*m_h))) - m_h;
+ const int32_t l = gamma - 2*alpha + ki - (ki ^ 1);
+
+ R.mult2(m_ws);
+ R.add(m_U.at(3*m_h + 1 + l), m_ws);
+ alpha = gamma;
}
- while(bits_left >= window_bits)
+ const int32_t k0 = scalar.get_bit(0);
+ R.add(m_U[3*m_h + 1 - alpha - (k0 ^ 1)], m_ws);
+
+#else
+
+ size_t bits_left = scalar_bits;
+
+ PointGFp R = m_U[0];
+
+ while(bits_left >= m_h)
{
- for(size_t i = 0; i != window_bits; ++i)
- x1.mult2(ws);
+ for(size_t i = 0; i != m_h; ++i)
+ R.mult2(m_ws);
- const u32bit nibble = scalar.get_substring(bits_left - window_bits, window_bits);
- x1.add(Ps[nibble], ws);
- bits_left -= window_bits;
+ const u32bit nibble = scalar.get_substring(bits_left - m_h, m_h);
+ R.add(m_U[nibble], m_ws);
+ bits_left -= m_h;
}
while(bits_left)
{
- x1.mult2(ws);
+ R.mult2(m_ws);
if(scalar.get_bit(bits_left-1))
- x1.add(point, ws);
+ R.add(m_U[1], m_ws);
--bits_left;
}
-
#endif
- if(scalar.is_negative())
- x1.negate();
+ //BOTAN_ASSERT(R.on_the_curve(), "Output is on the curve");
- //BOTAN_ASSERT(x1.on_the_curve(), "Output is on the curve");
-
- return x1;
+ return R;
}
BigInt PointGFp::get_affine_x() const
{
if(is_zero())
+ abort();
+ if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
- BigInt z2 = curve_sqr(coord_z);
- curve.from_rep(z2, ws);
- z2 = inverse_mod(z2, curve.get_p());
+ BigInt z2 = curve_sqr(m_coord_z);
+ m_curve.from_rep(z2, m_monty_ws);
+ z2 = inverse_mod(z2, m_curve.get_p());
- return curve_mult(z2, coord_x);
+ return curve_mult(z2, m_coord_x);
}
BigInt PointGFp::get_affine_y() const
{
if(is_zero())
+ abort();
+ if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
- BigInt z3 = curve_mult(coord_z, curve_sqr(coord_z));
- z3 = inverse_mod(z3, curve.get_p());
- curve.to_rep(z3, ws);
+ BigInt z3 = curve_mult(m_coord_z, curve_sqr(m_coord_z));
+ z3 = inverse_mod(z3, m_curve.get_p());
+ m_curve.to_rep(z3, m_monty_ws);
- return curve_mult(z3, coord_y);
+ return curve_mult(z3, m_coord_y);
}
bool PointGFp::on_the_curve() const
@@ -376,22 +470,22 @@ bool PointGFp::on_the_curve() const
if(is_zero())
return true;
- const BigInt y2 = curve.from_rep(curve_sqr(coord_y), ws);
- const BigInt x3 = curve_mult(coord_x, curve_sqr(coord_x));
- const BigInt ax = curve_mult(coord_x, curve.get_a_rep());
- const BigInt z2 = curve_sqr(coord_z);
+ const BigInt y2 = m_curve.from_rep(curve_sqr(m_coord_y), m_monty_ws);
+ const BigInt x3 = curve_mult(m_coord_x, curve_sqr(m_coord_x));
+ const BigInt ax = curve_mult(m_coord_x, m_curve.get_a_rep());
+ const BigInt z2 = curve_sqr(m_coord_z);
- if(coord_z == z2) // Is z equal to 1 (in Montgomery form)?
+ if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)?
{
- if(y2 != curve.from_rep(x3 + ax + curve.get_b_rep(), ws))
+ if(y2 != m_curve.from_rep(x3 + ax + m_curve.get_b_rep(), m_monty_ws))
return false;
}
- const BigInt z3 = curve_mult(coord_z, z2);
+ const BigInt z3 = curve_mult(m_coord_z, z2);
const BigInt ax_z4 = curve_mult(ax, curve_sqr(z2));
- const BigInt b_z6 = curve_mult(curve.get_b_rep(), curve_sqr(z3));
+ const BigInt b_z6 = curve_mult(m_curve.get_b_rep(), curve_sqr(z3));
- if(y2 != curve.from_rep(x3 + ax_z4 + b_z6, ws))
+ if(y2 != m_curve.from_rep(x3 + ax_z4 + b_z6, m_monty_ws))
return false;
return true;
@@ -400,11 +494,11 @@ bool PointGFp::on_the_curve() const
// swaps the states of *this and other, does not throw!
void PointGFp::swap(PointGFp& other)
{
- curve.swap(other.curve);
- coord_x.swap(other.coord_x);
- coord_y.swap(other.coord_y);
- coord_z.swap(other.coord_z);
- ws.swap(other.ws);
+ m_curve.swap(other.m_curve);
+ m_coord_x.swap(other.m_coord_x);
+ m_coord_y.swap(other.m_coord_y);
+ m_coord_z.swap(other.m_coord_z);
+ m_monty_ws.swap(other.m_monty_ws);
}
bool PointGFp::operator==(const PointGFp& other) const
diff --git a/src/lib/math/ec_gfp/point_gfp.h b/src/lib/math/ec_gfp/point_gfp.h
index 813ead81e..bb3438697 100644
--- a/src/lib/math/ec_gfp/point_gfp.h
+++ b/src/lib/math/ec_gfp/point_gfp.h
@@ -2,7 +2,7 @@
* Point arithmetic on elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
-* 2008-2011,2014 Jack Lloyd
+* 2008-2011,2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -58,6 +58,11 @@ class BOTAN_DLL PointGFp
*/
PointGFp(const CurveGFp& curve);
+ static PointGFp zero_of(const CurveGFp& curve)
+ {
+ return PointGFp(curve);
+ }
+
/**
* Copy constructor
*/
@@ -113,6 +118,7 @@ class BOTAN_DLL PointGFp
* @param scalar the PointGFp to multiply with *this
* @result resulting PointGFp
*/
+
PointGFp& operator*=(const BigInt& scalar);
/**
@@ -142,7 +148,7 @@ class BOTAN_DLL PointGFp
PointGFp& negate()
{
if(!is_zero())
- coord_y = curve.get_p() - coord_y;
+ m_coord_y = m_curve.get_p() - m_coord_y;
return *this;
}
@@ -150,7 +156,7 @@ class BOTAN_DLL PointGFp
* Return base curve of this point
* @result the curve over GF(p) of this point
*/
- const CurveGFp& get_curve() const { return curve; }
+ const CurveGFp& get_curve() const { return m_curve; }
/**
* get affine x coordinate
@@ -169,7 +175,7 @@ class BOTAN_DLL PointGFp
* @result true, if this point is at infinity, false otherwise.
*/
bool is_zero() const
- { return (coord_x.is_zero() && coord_z.is_zero()); }
+ { return (m_coord_x.is_zero() && m_coord_z.is_zero()); }
/**
* Checks whether the point is to be found on the underlying
@@ -185,33 +191,40 @@ class BOTAN_DLL PointGFp
void swap(PointGFp& other);
/**
+ * Randomize the point representation
+ * The actual value (get_affine_x, get_affine_y) does not change
+ */
+ void randomize_repr(RandomNumberGenerator& rng);
+
+ /**
* Equality operator
*/
bool operator==(const PointGFp& other) const;
private:
+ friend class Blinded_Point_Multiply;
BigInt curve_mult(const BigInt& x, const BigInt& y) const
{
BigInt z;
- curve.mul(z, x, y, ws);
+ m_curve.mul(z, x, y, m_monty_ws);
return z;
}
void curve_mult(BigInt& z, const BigInt& x, const BigInt& y) const
{
- curve.mul(z, x, y, ws);
+ m_curve.mul(z, x, y, m_monty_ws);
}
BigInt curve_sqr(const BigInt& x) const
{
BigInt z;
- curve.sqr(z, x, ws);
+ m_curve.sqr(z, x, m_monty_ws);
return z;
}
void curve_sqr(BigInt& z, const BigInt& x) const
{
- curve.sqr(z, x, ws);
+ m_curve.sqr(z, x, m_monty_ws);
}
/**
@@ -226,9 +239,9 @@ class BOTAN_DLL PointGFp
*/
void mult2(std::vector<BigInt>& workspace);
- CurveGFp curve;
- BigInt coord_x, coord_y, coord_z;
- mutable secure_vector<word> ws; // workspace for Montgomery
+ CurveGFp m_curve;
+ BigInt m_coord_x, m_coord_y, m_coord_z;
+ mutable secure_vector<word> m_monty_ws; // workspace for Montgomery
};
// relational operators
@@ -270,6 +283,22 @@ template<typename Alloc>
PointGFp OS2ECP(const std::vector<byte, Alloc>& data, const CurveGFp& curve)
{ return OS2ECP(data.data(), data.size(), curve); }
+/**
+
+*/
+class BOTAN_DLL Blinded_Point_Multiply
+ {
+ public:
+ Blinded_Point_Multiply(const PointGFp& base, const BigInt& order, size_t h = 0);
+
+ PointGFp blinded_multiply(const BigInt& scalar, RandomNumberGenerator& rng);
+ private:
+ const BigInt& m_order;
+ const size_t m_h;
+ std::vector<BigInt> m_ws;
+ std::vector<PointGFp> m_U;
+ };
+
}
namespace std {
diff --git a/src/lib/math/mp/mp_asm.cpp b/src/lib/math/mp/mp_asm.cpp
index 6941a22e9..cc573a792 100644
--- a/src/lib/math/mp/mp_asm.cpp
+++ b/src/lib/math/mp/mp_asm.cpp
@@ -14,8 +14,6 @@
namespace Botan {
-extern "C" {
-
/*
* Two Operand Addition, No Carry
*/
@@ -185,5 +183,3 @@ void bigint_linmul3(word z[], const word x[], size_t x_size, word y)
}
}
-
-}
diff --git a/src/lib/math/mp/mp_comba.cpp b/src/lib/math/mp/mp_comba.cpp
index a21b25ed6..0170c9fcd 100644
--- a/src/lib/math/mp/mp_comba.cpp
+++ b/src/lib/math/mp/mp_comba.cpp
@@ -10,8 +10,6 @@
namespace Botan {
-extern "C" {
-
/*
* Comba 4x4 Squaring
*/
@@ -1128,5 +1126,3 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
}
}
-
-}
diff --git a/src/lib/math/mp/mp_core.h b/src/lib/math/mp/mp_core.h
index 06f1d4a2d..b97384d18 100644
--- a/src/lib/math/mp/mp_core.h
+++ b/src/lib/math/mp/mp_core.h
@@ -18,8 +18,6 @@ namespace Botan {
*/
const size_t MP_WORD_BITS = BOTAN_MP_WORD_BITS;
-extern "C" {
-
/**
* Two operand addition
* @param x the first operand (and output)
@@ -160,8 +158,6 @@ void bigint_comba_sqr8(word out[16], const word in[8]);
void bigint_comba_sqr9(word out[18], const word in[9]);
void bigint_comba_sqr16(word out[32], const word in[16]);
-}
-
/*
* High Level Multiplication/Squaring Interfaces
*/
diff --git a/src/lib/math/mp/mp_generic/mp_asmi.h b/src/lib/math/mp/mp_generic/mp_asmi.h
index c094436f6..708afdfa0 100644
--- a/src/lib/math/mp/mp_generic/mp_asmi.h
+++ b/src/lib/math/mp/mp_generic/mp_asmi.h
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Word Addition
*/
@@ -202,6 +200,4 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
}
-}
-
#endif
diff --git a/src/lib/math/mp/mp_generic/mp_madd.h b/src/lib/math/mp/mp_generic/mp_madd.h
index d0d56c23f..292c23e97 100644
--- a/src/lib/math/mp/mp_generic/mp_madd.h
+++ b/src/lib/math/mp/mp_generic/mp_madd.h
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Word Multiply/Add
*/
@@ -68,6 +66,4 @@ inline word word_madd3(word a, word b, word c, word* d)
}
-}
-
#endif
diff --git a/src/lib/math/mp/mp_karat.cpp b/src/lib/math/mp/mp_karat.cpp
index faa91040c..96d9adae2 100644
--- a/src/lib/math/mp/mp_karat.cpp
+++ b/src/lib/math/mp/mp_karat.cpp
@@ -13,8 +13,8 @@ namespace Botan {
namespace {
-static const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32;
-static const size_t KARATSUBA_SQUARE_THRESHOLD = 32;
+const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32;
+const size_t KARATSUBA_SQUARE_THRESHOLD = 32;
/*
* Karatsuba Multiplication Operation
diff --git a/src/lib/math/mp/mp_misc.cpp b/src/lib/math/mp/mp_misc.cpp
index bd04818e5..542b0509e 100644
--- a/src/lib/math/mp/mp_misc.cpp
+++ b/src/lib/math/mp/mp_misc.cpp
@@ -11,8 +11,6 @@
namespace Botan {
-extern "C" {
-
/*
* Compare two MP integers
*/
@@ -79,5 +77,3 @@ word bigint_modop(word n1, word n0, word d)
}
}
-
-}
diff --git a/src/lib/math/mp/mp_monty.cpp b/src/lib/math/mp/mp_monty.cpp
index ffceaab9b..820f41e6c 100644
--- a/src/lib/math/mp/mp_monty.cpp
+++ b/src/lib/math/mp/mp_monty.cpp
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Montgomery Reduction Algorithm
*/
@@ -112,5 +110,3 @@ void bigint_monty_sqr(word z[], size_t z_size,
}
}
-
-}
diff --git a/src/lib/math/mp/mp_mulop.cpp b/src/lib/math/mp/mp_mulop.cpp
index 95a0e015e..432c7ef53 100644
--- a/src/lib/math/mp/mp_mulop.cpp
+++ b/src/lib/math/mp/mp_mulop.cpp
@@ -12,8 +12,6 @@
namespace Botan {
-extern "C" {
-
/*
* Simple O(N^2) Multiplication
*/
@@ -73,5 +71,3 @@ void bigint_simple_sqr(word z[], const word x[], size_t x_size)
}
}
-
-}
diff --git a/src/lib/math/mp/mp_shift.cpp b/src/lib/math/mp/mp_shift.cpp
index d58a0c809..1850888a0 100644
--- a/src/lib/math/mp/mp_shift.cpp
+++ b/src/lib/math/mp/mp_shift.cpp
@@ -10,8 +10,6 @@
namespace Botan {
-extern "C" {
-
/*
* Single Operand Left Shift
*/
@@ -133,5 +131,3 @@ void bigint_shr2(word y[], const word x[], size_t x_size,
}
}
-
-}
diff --git a/src/lib/math/mp/mp_x86_32/mp_asmi.h b/src/lib/math/mp/mp_x86_32/mp_asmi.h
index 49ca428d6..95af89fc0 100644
--- a/src/lib/math/mp/mp_x86_32/mp_asmi.h
+++ b/src/lib/math/mp/mp_x86_32/mp_asmi.h
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Helper Macros for x86 Assembly
*/
@@ -235,6 +233,4 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y)
}
-}
-
#endif
diff --git a/src/lib/math/mp/mp_x86_32/mp_madd.h b/src/lib/math/mp/mp_x86_32/mp_madd.h
index b6a60aecd..9c0990398 100644
--- a/src/lib/math/mp/mp_x86_32/mp_madd.h
+++ b/src/lib/math/mp/mp_x86_32/mp_madd.h
@@ -17,8 +17,6 @@
namespace Botan {
-extern "C" {
-
/*
* Helper Macros for x86 Assembly
*/
@@ -62,6 +60,4 @@ inline word word_madd3(word a, word b, word c, word* d)
}
-}
-
#endif
diff --git a/src/lib/math/mp/mp_x86_32_msvc/mp_asmi.h b/src/lib/math/mp/mp_x86_32_msvc/mp_asmi.h
index b4a9af1e3..1887e57ce 100644
--- a/src/lib/math/mp/mp_x86_32_msvc/mp_asmi.h
+++ b/src/lib/math/mp/mp_x86_32_msvc/mp_asmi.h
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Word Addition
*/
@@ -537,6 +535,4 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
}
-}
-
#endif
diff --git a/src/lib/math/mp/mp_x86_64/mp_asmi.h b/src/lib/math/mp/mp_x86_64/mp_asmi.h
index 2c7683650..cd5884867 100644
--- a/src/lib/math/mp/mp_x86_64/mp_asmi.h
+++ b/src/lib/math/mp/mp_x86_64/mp_asmi.h
@@ -13,8 +13,6 @@
namespace Botan {
-extern "C" {
-
/*
* Helper Macros for x86-64 Assembly
*/
@@ -233,7 +231,6 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y)
: "cc");
}
-
#undef ASM
#undef DO_8_TIMES
#undef ADD_OR_SUBTRACT
@@ -244,5 +241,4 @@ inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y)
}
-}
#endif
diff --git a/src/lib/math/mp/mp_x86_64/mp_madd.h b/src/lib/math/mp/mp_x86_64/mp_madd.h
index 25f791da4..6f9185dc0 100644
--- a/src/lib/math/mp/mp_x86_64/mp_madd.h
+++ b/src/lib/math/mp/mp_x86_64/mp_madd.h
@@ -17,8 +17,6 @@
namespace Botan {
-extern "C" {
-
/*
* Helper Macros for x86-64 Assembly
*/
@@ -64,6 +62,4 @@ inline word word_madd3(word a, word b, word c, word* d)
}
-}
-
#endif
diff --git a/src/lib/math/numbertheory/def_powm.h b/src/lib/math/numbertheory/def_powm.h
index 3a56a1693..ef5d6e39b 100644
--- a/src/lib/math/numbertheory/def_powm.h
+++ b/src/lib/math/numbertheory/def_powm.h
@@ -20,11 +20,11 @@ namespace Botan {
class Fixed_Window_Exponentiator : public Modular_Exponentiator
{
public:
- void set_exponent(const BigInt&);
- void set_base(const BigInt&);
- BigInt execute() const;
+ void set_exponent(const BigInt&) override;
+ void set_base(const BigInt&) override;
+ BigInt execute() const override;
- Modular_Exponentiator* copy() const
+ Modular_Exponentiator* copy() const override
{ return new Fixed_Window_Exponentiator(*this); }
Fixed_Window_Exponentiator(const BigInt&, Power_Mod::Usage_Hints);
@@ -42,11 +42,11 @@ class Fixed_Window_Exponentiator : public Modular_Exponentiator
class Montgomery_Exponentiator : public Modular_Exponentiator
{
public:
- void set_exponent(const BigInt&);
- void set_base(const BigInt&);
- BigInt execute() const;
+ void set_exponent(const BigInt&) override;
+ void set_base(const BigInt&) override;
+ BigInt execute() const override;
- Modular_Exponentiator* copy() const
+ Modular_Exponentiator* copy() const override
{ return new Montgomery_Exponentiator(*this); }
Montgomery_Exponentiator(const BigInt&, Power_Mod::Usage_Hints);
diff --git a/src/lib/math/numbertheory/info.txt b/src/lib/math/numbertheory/info.txt
index cf555b456..49f7ab2fb 100644
--- a/src/lib/math/numbertheory/info.txt
+++ b/src/lib/math/numbertheory/info.txt
@@ -1,4 +1,4 @@
-define BIGINT_MATH 20131128
+define NUMBERTHEORY 20131128
load_on auto
@@ -12,20 +12,6 @@ reducer.h
def_powm.h
</header:internal>
-<source>
-dsa_gen.cpp
-jacobi.cpp
-make_prm.cpp
-mp_numth.cpp
-numthry.cpp
-pow_mod.cpp
-powm_fw.cpp
-powm_mnt.cpp
-primes.cpp
-reducer.cpp
-ressol.cpp
-</source>
-
<requires>
bigint
hash
diff --git a/src/lib/math/numbertheory/mp_numth.cpp b/src/lib/math/numbertheory/mp_numth.cpp
index fafc6b03f..6eb938286 100644
--- a/src/lib/math/numbertheory/mp_numth.cpp
+++ b/src/lib/math/numbertheory/mp_numth.cpp
@@ -19,7 +19,7 @@ BigInt square(const BigInt& x)
{
const size_t x_sw = x.sig_words();
- BigInt z(BigInt::Positive, round_up<size_t>(2*x_sw, 16));
+ BigInt z(BigInt::Positive, round_up(2*x_sw, 16));
secure_vector<word> workspace(z.size());
bigint_sqr(z.mutable_data(), z.size(),
diff --git a/src/lib/math/numbertheory/pow_mod.cpp b/src/lib/math/numbertheory/pow_mod.cpp
index 9a9bff2ad..49ff6cca2 100644
--- a/src/lib/math/numbertheory/pow_mod.cpp
+++ b/src/lib/math/numbertheory/pow_mod.cpp
@@ -15,7 +15,7 @@ namespace Botan {
*/
Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints)
{
- core = nullptr;
+ m_core = nullptr;
set_modulus(n, hints);
}
@@ -24,9 +24,9 @@ Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints)
*/
Power_Mod::Power_Mod(const Power_Mod& other)
{
- core = nullptr;
- if(other.core)
- core = other.core->copy();
+ m_core = nullptr;
+ if(other.m_core)
+ m_core = other.m_core->copy();
}
/*
@@ -34,10 +34,10 @@ Power_Mod::Power_Mod(const Power_Mod& other)
*/
Power_Mod& Power_Mod::operator=(const Power_Mod& other)
{
- delete core;
- core = nullptr;
- if(other.core)
- core = other.core->copy();
+ delete m_core;
+ m_core = nullptr;
+ if(other.m_core)
+ m_core = other.m_core->copy();
return (*this);
}
@@ -46,8 +46,8 @@ Power_Mod& Power_Mod::operator=(const Power_Mod& other)
*/
Power_Mod::~Power_Mod()
{
- delete core;
- core = nullptr;
+ delete m_core;
+ m_core = nullptr;
}
/*
@@ -55,12 +55,12 @@ Power_Mod::~Power_Mod()
*/
void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints) const
{
- delete core;
+ delete m_core;
if(n.is_odd())
- core = new Montgomery_Exponentiator(n, hints);
+ m_core = new Montgomery_Exponentiator(n, hints);
else if(n != 0)
- core = new Fixed_Window_Exponentiator(n, hints);
+ m_core = new Fixed_Window_Exponentiator(n, hints);
}
/*
@@ -71,9 +71,9 @@ void Power_Mod::set_base(const BigInt& b) const
if(b.is_zero() || b.is_negative())
throw Invalid_Argument("Power_Mod::set_base: arg must be > 0");
- if(!core)
- throw Internal_Error("Power_Mod::set_base: core was NULL");
- core->set_base(b);
+ if(!m_core)
+ throw Internal_Error("Power_Mod::set_base: m_core was NULL");
+ m_core->set_base(b);
}
/*
@@ -84,9 +84,9 @@ void Power_Mod::set_exponent(const BigInt& e) const
if(e.is_negative())
throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0");
- if(!core)
- throw Internal_Error("Power_Mod::set_exponent: core was NULL");
- core->set_exponent(e);
+ if(!m_core)
+ throw Internal_Error("Power_Mod::set_exponent: m_core was NULL");
+ m_core->set_exponent(e);
}
/*
@@ -94,9 +94,9 @@ void Power_Mod::set_exponent(const BigInt& e) const
*/
BigInt Power_Mod::execute() const
{
- if(!core)
- throw Internal_Error("Power_Mod::execute: core was NULL");
- return core->execute();
+ if(!m_core)
+ throw Internal_Error("Power_Mod::execute: m_core was NULL");
+ return m_core->execute();
}
/*
diff --git a/src/lib/math/numbertheory/pow_mod.h b/src/lib/math/numbertheory/pow_mod.h
index 9a827562e..4f94fd62d 100644
--- a/src/lib/math/numbertheory/pow_mod.h
+++ b/src/lib/math/numbertheory/pow_mod.h
@@ -63,7 +63,7 @@ class BOTAN_DLL Power_Mod
Power_Mod(const Power_Mod&);
virtual ~Power_Mod();
private:
- mutable Modular_Exponentiator* core;
+ mutable Modular_Exponentiator* m_core;
};
/**
diff --git a/src/lib/misc/benchmark/benchmark.cpp b/src/lib/misc/benchmark/benchmark.cpp
index 90d8b1aca..152b45d37 100644
--- a/src/lib/misc/benchmark/benchmark.cpp
+++ b/src/lib/misc/benchmark/benchmark.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/benchmark.h>
+#include <botan/exceptn.h>
#include <botan/lookup.h>
#include <botan/buf_comp.h>
#include <botan/cipher_mode.h>
@@ -153,19 +154,18 @@ algorithm_benchmark(const std::string& name,
size_t buf_size)
{
//Algorithm_Factory& af = global_state().algorithm_factory();
- const auto providers = get_all_providers_of(name);
+ const auto provider_names = get_all_providers_of(name);
+ if (provider_names.empty())
+ throw No_Provider_Found(name);
std::map<std::string, double> all_results; // provider -> ops/sec
- if(!providers.empty())
- {
- const std::chrono::nanoseconds ns_per_provider = milliseconds / providers.size();
+ const std::chrono::nanoseconds ns_per_provider = milliseconds / provider_names.size();
- for(auto provider : providers)
- {
- auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size);
- all_results[provider] = find_first_in(results, { "", "update", "encrypt" });
- }
+ for(auto provider : provider_names)
+ {
+ auto results = time_algorithm_ops(name, provider, rng, ns_per_provider, buf_size);
+ all_results[provider] = find_first_in(results, { "", "update", "encrypt" });
}
return all_results;
diff --git a/src/lib/misc/openpgp/info.txt b/src/lib/misc/openpgp/info.txt
index 72467ee72..b95c88ef7 100644
--- a/src/lib/misc/openpgp/info.txt
+++ b/src/lib/misc/openpgp/info.txt
@@ -3,6 +3,7 @@ define OPENPGP_CODEC 20131128
load_on auto
<requires>
+codec_filt
crc24
filters
</requires>
diff --git a/src/lib/misc/tss/info.txt b/src/lib/misc/tss/info.txt
index c4fed288d..5d0615170 100644
--- a/src/lib/misc/tss/info.txt
+++ b/src/lib/misc/tss/info.txt
@@ -4,4 +4,6 @@ define THRESHOLD_SECRET_SHARING 20131128
rng
filters
hex
+sha1
+sha2_32
</requires>
diff --git a/src/lib/modes/aead/ccm/ccm.h b/src/lib/modes/aead/ccm/ccm.h
index 5af5f984d..58ca447e8 100644
--- a/src/lib/modes/aead/ccm/ccm.h
+++ b/src/lib/modes/aead/ccm/ccm.h
@@ -28,7 +28,7 @@ class BOTAN_DLL CCM_Mode : public AEAD_Mode
std::string name() const override;
- size_t update_granularity() const;
+ size_t update_granularity() const override;
Key_Length_Specification key_spec() const override;
@@ -38,7 +38,7 @@ class BOTAN_DLL CCM_Mode : public AEAD_Mode
void clear() override;
- size_t tag_size() const { return m_tag_size; }
+ size_t tag_size() const override { return m_tag_size; }
protected:
const size_t BS = 16; // intrinsic to CCM definition
diff --git a/src/lib/modes/aead/gcm/gcm.h b/src/lib/modes/aead/gcm/gcm.h
index ea3263c0a..8e7ae8b7f 100644
--- a/src/lib/modes/aead/gcm/gcm.h
+++ b/src/lib/modes/aead/gcm/gcm.h
@@ -26,7 +26,7 @@ class BOTAN_DLL GCM_Mode : public AEAD_Mode
std::string name() const override;
- size_t update_granularity() const;
+ size_t update_granularity() const override;
Key_Length_Specification key_spec() const override;
@@ -121,11 +121,12 @@ class BOTAN_DLL GHASH : public SymmetricAlgorithm
secure_vector<byte> final();
- Key_Length_Specification key_spec() const { return Key_Length_Specification(16); }
+ Key_Length_Specification key_spec() const override
+ { return Key_Length_Specification(16); }
void clear() override;
- std::string name() const { return "GHASH"; }
+ std::string name() const override { return "GHASH"; }
private:
void key_schedule(const byte key[], size_t key_len) override;
diff --git a/src/lib/modes/aead/siv/info.txt b/src/lib/modes/aead/siv/info.txt
index b1e38568e..b76a82422 100644
--- a/src/lib/modes/aead/siv/info.txt
+++ b/src/lib/modes/aead/siv/info.txt
@@ -1,3 +1,8 @@
define AEAD_SIV 20131202
load_on auto
+
+<requires>
+cmac
+ctr
+</requires>
diff --git a/src/lib/modes/cbc/cbc.cpp b/src/lib/modes/cbc/cbc.cpp
index 27f2bce4a..85241cf53 100644
--- a/src/lib/modes/cbc/cbc.cpp
+++ b/src/lib/modes/cbc/cbc.cpp
@@ -105,7 +105,10 @@ size_t CBC_Encryption::minimum_final_size() const
size_t CBC_Encryption::output_length(size_t input_length) const
{
- return round_up(input_length, cipher().block_size());
+ if(input_length == 0)
+ return cipher().block_size();
+ else
+ return round_up(input_length, cipher().block_size());
}
void CBC_Encryption::update(secure_vector<byte>& buffer, size_t offset)
diff --git a/src/lib/modes/cbc/cbc.h b/src/lib/modes/cbc/cbc.h
index 963e92666..7fbcc8837 100644
--- a/src/lib/modes/cbc/cbc.h
+++ b/src/lib/modes/cbc/cbc.h
@@ -88,7 +88,7 @@ class BOTAN_DLL CTS_Encryption : public CBC_Encryption
size_t minimum_final_size() const override;
- bool valid_nonce_length(size_t n) const;
+ bool valid_nonce_length(size_t n) const override;
};
/**
@@ -123,7 +123,7 @@ class BOTAN_DLL CTS_Decryption : public CBC_Decryption
size_t minimum_final_size() const override;
- bool valid_nonce_length(size_t n) const;
+ bool valid_nonce_length(size_t n) const override;
};
}
diff --git a/src/lib/modes/cfb/cfb.h b/src/lib/modes/cfb/cfb.h
index 6d16ba708..25c42e4b0 100644
--- a/src/lib/modes/cfb/cfb.h
+++ b/src/lib/modes/cfb/cfb.h
@@ -10,7 +10,6 @@
#include <botan/cipher_mode.h>
#include <botan/block_cipher.h>
-#include <botan/mode_pad.h>
namespace Botan {
diff --git a/src/lib/modes/ecb/ecb.cpp b/src/lib/modes/ecb/ecb.cpp
index 73a241394..e5794d8e1 100644
--- a/src/lib/modes/ecb/ecb.cpp
+++ b/src/lib/modes/ecb/ecb.cpp
@@ -83,7 +83,10 @@ size_t ECB_Encryption::minimum_final_size() const
size_t ECB_Encryption::output_length(size_t input_length) const
{
- return round_up(input_length, cipher().block_size());
+ if(input_length == 0)
+ return cipher().block_size();
+ else
+ return round_up(input_length, cipher().block_size());
}
void ECB_Encryption::update(secure_vector<byte>& buffer, size_t offset)
diff --git a/src/lib/modes/info.txt b/src/lib/modes/info.txt
index 95104e903..24508ecaa 100644
--- a/src/lib/modes/info.txt
+++ b/src/lib/modes/info.txt
@@ -1,3 +1,5 @@
+define MODES 20150626
+
<header:public>
cipher_mode.h
stream_mode.h
diff --git a/src/lib/modes/mode_pad/mode_pad.h b/src/lib/modes/mode_pad/mode_pad.h
index c4d5baf2e..91102c66c 100644
--- a/src/lib/modes/mode_pad/mode_pad.h
+++ b/src/lib/modes/mode_pad/mode_pad.h
@@ -63,11 +63,11 @@ class BOTAN_DLL PKCS7_Padding : public BlockCipherModePaddingMethod
size_t final_block_bytes,
size_t block_size) const override;
- size_t unpad(const byte[], size_t) const;
+ size_t unpad(const byte[], size_t) const override;
- bool valid_blocksize(size_t bs) const { return (bs > 0 && bs < 256); }
+ bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); }
- std::string name() const { return "PKCS7"; }
+ std::string name() const override { return "PKCS7"; }
};
/**
@@ -80,11 +80,11 @@ class BOTAN_DLL ANSI_X923_Padding : public BlockCipherModePaddingMethod
size_t final_block_bytes,
size_t block_size) const override;
- size_t unpad(const byte[], size_t) const;
+ size_t unpad(const byte[], size_t) const override;
- bool valid_blocksize(size_t bs) const { return (bs > 0 && bs < 256); }
+ bool valid_blocksize(size_t bs) const override { return (bs > 0 && bs < 256); }
- std::string name() const { return "X9.23"; }
+ std::string name() const override { return "X9.23"; }
};
/**
@@ -97,11 +97,11 @@ class BOTAN_DLL OneAndZeros_Padding : public BlockCipherModePaddingMethod
size_t final_block_bytes,
size_t block_size) const override;
- size_t unpad(const byte[], size_t) const;
+ size_t unpad(const byte[], size_t) const override;
- bool valid_blocksize(size_t bs) const { return (bs > 0); }
+ bool valid_blocksize(size_t bs) const override { return (bs > 0); }
- std::string name() const { return "OneAndZeros"; }
+ std::string name() const override { return "OneAndZeros"; }
};
/**
@@ -112,11 +112,11 @@ class BOTAN_DLL Null_Padding : public BlockCipherModePaddingMethod
public:
void add_padding(secure_vector<byte>&, size_t, size_t) const override {}
- size_t unpad(const byte[], size_t size) const { return size; }
+ size_t unpad(const byte[], size_t size) const override { return size; }
- bool valid_blocksize(size_t) const { return true; }
+ bool valid_blocksize(size_t) const override { return true; }
- std::string name() const { return "NoPadding"; }
+ std::string name() const override { return "NoPadding"; }
};
BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec);
diff --git a/src/lib/modes/mode_utils.h b/src/lib/modes/mode_utils.h
index e2e2af83e..53aa41745 100644
--- a/src/lib/modes/mode_utils.h
+++ b/src/lib/modes/mode_utils.h
@@ -54,15 +54,15 @@ T* make_block_cipher_mode_len2(const Transform::Spec& spec)
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE(E, D) \
BOTAN_REGISTER_NAMED_T(Transform, #E, E, make_block_cipher_mode<E>); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, make_block_cipher_mode<D>);
+ BOTAN_REGISTER_NAMED_T(Transform, #D, D, make_block_cipher_mode<D>)
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN(E, D, LEN) \
BOTAN_REGISTER_NAMED_T(Transform, #E, E, (make_block_cipher_mode_len<E, LEN>)); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len<D, LEN>));
+ BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len<D, LEN>))
#define BOTAN_REGISTER_BLOCK_CIPHER_MODE_LEN2(E, D, LEN1, LEN2) \
BOTAN_REGISTER_NAMED_T(Transform, #E, E, (make_block_cipher_mode_len2<E, LEN1, LEN2>)); \
- BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len2<D, LEN1, LEN2>));
+ BOTAN_REGISTER_NAMED_T(Transform, #D, D, (make_block_cipher_mode_len2<D, LEN1, LEN2>))
}
diff --git a/src/lib/modes/stream_mode.h b/src/lib/modes/stream_mode.h
index 80fec96f9..5450bc37d 100644
--- a/src/lib/modes/stream_mode.h
+++ b/src/lib/modes/stream_mode.h
@@ -50,7 +50,7 @@ class BOTAN_DLL Stream_Cipher_Mode : public Cipher_Mode
return secure_vector<byte>();
}
- void key_schedule(const byte key[], size_t length)
+ void key_schedule(const byte key[], size_t length) override
{
m_cipher->set_key(key, length);
}
diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp
index cc0e6d54c..046de216f 100644
--- a/src/lib/modes/xts/xts.cpp
+++ b/src/lib/modes/xts/xts.cpp
@@ -135,7 +135,7 @@ void XTS_Mode::update_tweak(size_t which)
size_t XTS_Encryption::output_length(size_t input_length) const
{
- return round_up(input_length, cipher().block_size());
+ return input_length;
}
void XTS_Encryption::update(secure_vector<byte>& buffer, size_t offset)
@@ -213,7 +213,6 @@ void XTS_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
size_t XTS_Decryption::output_length(size_t input_length) const
{
- // might be less
return input_length;
}
diff --git a/src/lib/passhash/bcrypt/bcrypt.cpp b/src/lib/passhash/bcrypt/bcrypt.cpp
index 3f6a68352..f7cf390e9 100644
--- a/src/lib/passhash/bcrypt/bcrypt.cpp
+++ b/src/lib/passhash/bcrypt/bcrypt.cpp
@@ -90,13 +90,13 @@ std::string make_bcrypt(const std::string& pass,
const std::vector<byte>& salt,
u16bit work_factor)
{
- const byte magic[24] = {
+ auto magic = std::vector<byte>{
0x4F, 0x72, 0x70, 0x68, 0x65, 0x61, 0x6E, 0x42,
0x65, 0x68, 0x6F, 0x6C, 0x64, 0x65, 0x72, 0x53,
0x63, 0x72, 0x79, 0x44, 0x6F, 0x75, 0x62, 0x74
};
- std::vector<byte> ctext(magic, magic + sizeof(magic));
+ std::vector<byte> ctext = magic;
Blowfish blowfish;
diff --git a/src/lib/pbkdf/info.txt b/src/lib/pbkdf/info.txt
index 32876bd44..81f7c1260 100644
--- a/src/lib/pbkdf/info.txt
+++ b/src/lib/pbkdf/info.txt
@@ -1,3 +1,5 @@
+define PBKDF 20150626
+
<requires>
base
</requires>
diff --git a/src/lib/pbkdf/pbkdf1/pbkdf1.cpp b/src/lib/pbkdf/pbkdf1/pbkdf1.cpp
index a2b5957a0..28bac9572 100644
--- a/src/lib/pbkdf/pbkdf1/pbkdf1.cpp
+++ b/src/lib/pbkdf/pbkdf1/pbkdf1.cpp
@@ -11,7 +11,7 @@
namespace Botan {
-BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1")
+BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1");
size_t PKCS5_PBKDF1::pbkdf(byte output_buf[], size_t output_len,
const std::string& passphrase,
diff --git a/src/lib/pbkdf/pbkdf1/pbkdf1.h b/src/lib/pbkdf/pbkdf1/pbkdf1.h
index c93dbe503..3296f8887 100644
--- a/src/lib/pbkdf/pbkdf1/pbkdf1.h
+++ b/src/lib/pbkdf/pbkdf1/pbkdf1.h
@@ -16,7 +16,7 @@ namespace Botan {
/**
* PKCS #5 v1 PBKDF, aka PBKDF1
* Can only generate a key up to the size of the hash output.
-* Unless needed for backwards compatability, use PKCS5_PBKDF2
+* Unless needed for backwards compatibility, use PKCS5_PBKDF2
*/
class BOTAN_DLL PKCS5_PBKDF1 : public PBKDF
{
@@ -27,12 +27,12 @@ class BOTAN_DLL PKCS5_PBKDF1 : public PBKDF
*/
PKCS5_PBKDF1(HashFunction* hash) : m_hash(hash) {}
- std::string name() const
+ std::string name() const override
{
return "PBKDF1(" + m_hash->name() + ")";
}
- PBKDF* clone() const
+ PBKDF* clone() const override
{
return new PKCS5_PBKDF1(m_hash->clone());
}
diff --git a/src/lib/pk_pad/eme_oaep/oaep.h b/src/lib/pk_pad/eme_oaep/oaep.h
index 6765a67e2..13e6efeec 100644
--- a/src/lib/pk_pad/eme_oaep/oaep.h
+++ b/src/lib/pk_pad/eme_oaep/oaep.h
@@ -9,7 +9,6 @@
#define BOTAN_OAEP_H__
#include <botan/eme.h>
-#include <botan/kdf.h>
#include <botan/hash.h>
namespace Botan {
@@ -20,7 +19,7 @@ namespace Botan {
class BOTAN_DLL OAEP : public EME
{
public:
- size_t maximum_input_size(size_t) const;
+ size_t maximum_input_size(size_t) const override;
static OAEP* make(const Spec& spec);
@@ -31,8 +30,8 @@ class BOTAN_DLL OAEP : public EME
OAEP(HashFunction* hash, const std::string& P = "");
private:
secure_vector<byte> pad(const byte[], size_t, size_t,
- RandomNumberGenerator&) const;
- secure_vector<byte> unpad(const byte[], size_t, size_t) const;
+ RandomNumberGenerator&) const override;
+ secure_vector<byte> unpad(const byte[], size_t, size_t) const override;
secure_vector<byte> m_Phash;
std::unique_ptr<HashFunction> m_hash;
diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
index d279b8843..90af17565 100644
--- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
+++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
@@ -46,17 +46,17 @@ secure_vector<byte> EME_PKCS1v15::unpad(const byte in[], size_t inlen,
if(inlen != key_len / 8 || inlen < 10 || in[0] != 0x02)
throw Decoding_Error("PKCS1::unpad");
- size_t seperator = 0;
+ size_t separator = 0;
for(size_t j = 0; j != inlen; ++j)
if(in[j] == 0)
{
- seperator = j;
+ separator = j;
break;
}
- if(seperator < 9)
+ if(separator < 9)
throw Decoding_Error("PKCS1::unpad");
- return secure_vector<byte>(&in[seperator + 1], &in[inlen]);
+ return secure_vector<byte>(&in[separator + 1], &in[inlen]);
}
/*
diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.h b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.h
index b7261433c..83c99e61b 100644
--- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.h
+++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.h
@@ -18,11 +18,11 @@ namespace Botan {
class BOTAN_DLL EME_PKCS1v15 : public EME
{
public:
- size_t maximum_input_size(size_t) const;
+ size_t maximum_input_size(size_t) const override;
private:
secure_vector<byte> pad(const byte[], size_t, size_t,
- RandomNumberGenerator&) const;
- secure_vector<byte> unpad(const byte[], size_t, size_t) const;
+ RandomNumberGenerator&) const override;
+ secure_vector<byte> unpad(const byte[], size_t, size_t) const override;
};
}
diff --git a/src/lib/pk_pad/eme_raw/eme_raw.h b/src/lib/pk_pad/eme_raw/eme_raw.h
index 903d9fc34..04604c72d 100644
--- a/src/lib/pk_pad/eme_raw/eme_raw.h
+++ b/src/lib/pk_pad/eme_raw/eme_raw.h
@@ -8,22 +8,20 @@
#define BOTAN_EME_RAW_H__
#include <botan/eme.h>
-#include <botan/kdf.h>
-#include <botan/hash.h>
namespace Botan {
class BOTAN_DLL EME_Raw : public EME
{
public:
- size_t maximum_input_size(size_t i) const;
+ size_t maximum_input_size(size_t i) const override;
EME_Raw() {}
private:
secure_vector<byte> pad(const byte[], size_t, size_t,
- RandomNumberGenerator&) const;
+ RandomNumberGenerator&) const override;
- secure_vector<byte> unpad(const byte[], size_t, size_t) const;
+ secure_vector<byte> unpad(const byte[], size_t, size_t) const override;
};
}
diff --git a/src/lib/pk_pad/emsa1/emsa1.h b/src/lib/pk_pad/emsa1/emsa1.h
index e81a746fc..3e10162b2 100644
--- a/src/lib/pk_pad/emsa1/emsa1.h
+++ b/src/lib/pk_pad/emsa1/emsa1.h
@@ -28,16 +28,16 @@ class BOTAN_DLL EMSA1 : public EMSA
protected:
size_t hash_output_length() const { return m_hash->output_length(); }
private:
- void update(const byte[], size_t);
- secure_vector<byte> raw_data();
+ void update(const byte[], size_t) override;
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>& msg,
size_t output_bits,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
bool verify(const secure_vector<byte>& coded,
const secure_vector<byte>& raw,
- size_t key_bits);
+ size_t key_bits) override;
std::unique_ptr<HashFunction> m_hash;
};
diff --git a/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.h b/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.h
index 591af2f7d..24d8b99e2 100644
--- a/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.h
+++ b/src/lib/pk_pad/emsa1_bsi/emsa1_bsi.h
@@ -27,7 +27,7 @@ class BOTAN_DLL EMSA1_BSI : public EMSA1
EMSA1_BSI(HashFunction* hash) : EMSA1(hash) {}
private:
secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
};
}
diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
index 2c2fbd2e8..e6ce5ec2f 100644
--- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
+++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp
@@ -7,6 +7,7 @@
#include <botan/internal/pad_utils.h>
#include <botan/emsa_pkcs1.h>
+#include <botan/hash_id.h>
namespace Botan {
diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
index 21ee7c1a2..7bcae3bd1 100644
--- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
+++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
@@ -26,15 +26,15 @@ class BOTAN_DLL EMSA_PKCS1v15 : public EMSA
*/
EMSA_PKCS1v15(HashFunction* hash);
- void update(const byte[], size_t);
+ void update(const byte[], size_t) override;
- secure_vector<byte> raw_data();
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
bool verify(const secure_vector<byte>&, const secure_vector<byte>&,
- size_t);
+ size_t) override;
private:
std::unique_ptr<HashFunction> m_hash;
std::vector<byte> m_hash_id;
@@ -48,15 +48,15 @@ class BOTAN_DLL EMSA_PKCS1v15 : public EMSA
class BOTAN_DLL EMSA_PKCS1v15_Raw : public EMSA
{
public:
- void update(const byte[], size_t);
+ void update(const byte[], size_t) override;
- secure_vector<byte> raw_data();
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
bool verify(const secure_vector<byte>&, const secure_vector<byte>&,
- size_t);
+ size_t) override;
private:
secure_vector<byte> message;
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.h b/src/lib/pk_pad/emsa_pssr/pssr.h
index e51ade494..066c580d8 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.h
+++ b/src/lib/pk_pad/emsa_pssr/pssr.h
@@ -33,17 +33,17 @@ class BOTAN_DLL PSSR : public EMSA
static PSSR* make(const Spec& spec);
private:
- void update(const byte input[], size_t length);
+ void update(const byte input[], size_t length) override;
- secure_vector<byte> raw_data();
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>& msg,
size_t output_bits,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
bool verify(const secure_vector<byte>& coded,
const secure_vector<byte>& raw,
- size_t key_bits);
+ size_t key_bits) override;
size_t SALT_SIZE;
std::unique_ptr<HashFunction> hash;
diff --git a/src/lib/pk_pad/emsa_raw/emsa_raw.h b/src/lib/pk_pad/emsa_raw/emsa_raw.h
index 731405fde..d1d6ac912 100644
--- a/src/lib/pk_pad/emsa_raw/emsa_raw.h
+++ b/src/lib/pk_pad/emsa_raw/emsa_raw.h
@@ -19,13 +19,13 @@ namespace Botan {
class BOTAN_DLL EMSA_Raw : public EMSA
{
private:
- void update(const byte[], size_t);
- secure_vector<byte> raw_data();
+ void update(const byte[], size_t) override;
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
- RandomNumberGenerator&);
+ RandomNumberGenerator&) override;
bool verify(const secure_vector<byte>&, const secure_vector<byte>&,
- size_t);
+ size_t) override;
secure_vector<byte> message;
};
diff --git a/src/lib/pk_pad/emsa_x931/emsa_x931.cpp b/src/lib/pk_pad/emsa_x931/emsa_x931.cpp
index 6b86a25f9..fb1e4343a 100644
--- a/src/lib/pk_pad/emsa_x931/emsa_x931.cpp
+++ b/src/lib/pk_pad/emsa_x931/emsa_x931.cpp
@@ -7,6 +7,7 @@
#include <botan/internal/pad_utils.h>
#include <botan/emsa_x931.h>
+#include <botan/hash_id.h>
namespace Botan {
diff --git a/src/lib/pk_pad/emsa_x931/emsa_x931.h b/src/lib/pk_pad/emsa_x931/emsa_x931.h
index ee57a14ff..29bad4a4a 100644
--- a/src/lib/pk_pad/emsa_x931/emsa_x931.h
+++ b/src/lib/pk_pad/emsa_x931/emsa_x931.h
@@ -26,14 +26,14 @@ class BOTAN_DLL EMSA_X931 : public EMSA
*/
EMSA_X931(HashFunction* hash);
private:
- void update(const byte[], size_t);
- secure_vector<byte> raw_data();
+ void update(const byte[], size_t) override;
+ secure_vector<byte> raw_data() override;
secure_vector<byte> encoding_of(const secure_vector<byte>&, size_t,
- RandomNumberGenerator& rng);
+ RandomNumberGenerator& rng) override;
bool verify(const secure_vector<byte>&, const secure_vector<byte>&,
- size_t);
+ size_t) override;
secure_vector<byte> m_empty_hash;
std::unique_ptr<HashFunction> m_hash;
diff --git a/src/lib/pk_pad/mgf1/mgf1.h b/src/lib/pk_pad/mgf1/mgf1.h
index 3fec898c2..ed2f1d023 100644
--- a/src/lib/pk_pad/mgf1/mgf1.h
+++ b/src/lib/pk_pad/mgf1/mgf1.h
@@ -8,7 +8,6 @@
#ifndef BOTAN_MGF1_H__
#define BOTAN_MGF1_H__
-#include <botan/kdf.h>
#include <botan/hash.h>
namespace Botan {
diff --git a/src/lib/pk_pad/pad_utils.h b/src/lib/pk_pad/pad_utils.h
index 2d261ffa6..3918e133a 100644
--- a/src/lib/pk_pad/pad_utils.h
+++ b/src/lib/pk_pad/pad_utils.h
@@ -9,7 +9,6 @@
#define BOTAN_PK_PAD_UTILS_H__
#include <botan/internal/algo_registry.h>
-#include <botan/hash_id.h>
#include <botan/internal/xor_buf.h>
#include <botan/loadstor.h>
#include <algorithm>
diff --git a/src/lib/pubkey/curve25519/curve25519.cpp b/src/lib/pubkey/curve25519/curve25519.cpp
index b314e16dc..aa0646d04 100644
--- a/src/lib/pubkey/curve25519/curve25519.cpp
+++ b/src/lib/pubkey/curve25519/curve25519.cpp
@@ -126,7 +126,7 @@ class Curve25519_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
PK_Ops::Key_Agreement_with_KDF(kdf),
m_key(key) {}
- secure_vector<byte> raw_agree(const byte w[], size_t w_len)
+ secure_vector<byte> raw_agree(const byte w[], size_t w_len) override
{
return m_key.agree(w, w_len);
}
diff --git a/src/lib/pubkey/curve25519/curve25519.h b/src/lib/pubkey/curve25519/curve25519.h
index 849940505..c3e3d4e60 100644
--- a/src/lib/pubkey/curve25519/curve25519.h
+++ b/src/lib/pubkey/curve25519/curve25519.h
@@ -19,7 +19,7 @@ class BOTAN_DLL Curve25519_PublicKey : public virtual Public_Key
size_t estimated_strength() const override { return 128; }
- size_t max_input_bits() const { return 256; }
+ size_t max_input_bits() const override { return 256; }
bool check_key(RandomNumberGenerator& rng, bool strong) const override;
diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp
index 57310efae..f182a7792 100644
--- a/src/lib/pubkey/dh/dh.cpp
+++ b/src/lib/pubkey/dh/dh.cpp
@@ -88,7 +88,7 @@ class DH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
typedef DH_PrivateKey Key_Type;
DH_KA_Operation(const DH_PrivateKey& key, const std::string& kdf);
- secure_vector<byte> raw_agree(const byte w[], size_t w_len);
+ secure_vector<byte> raw_agree(const byte w[], size_t w_len) override;
private:
const BigInt& m_p;
diff --git a/src/lib/pubkey/dh/dh.h b/src/lib/pubkey/dh/dh.h
index 32ca21440..9911453fb 100644
--- a/src/lib/pubkey/dh/dh.h
+++ b/src/lib/pubkey/dh/dh.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "DH"; }
+ std::string algo_name() const override { return "DH"; }
std::vector<byte> public_value() const;
- size_t max_input_bits() const { return group_p().bits(); }
+ size_t max_input_bits() const override { return group_p().bits(); }
- DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; }
+ DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; }
DH_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits) :
@@ -47,7 +47,7 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
- std::vector<byte> public_value() const;
+ std::vector<byte> public_value() const override;
/**
* Load a DH private key
diff --git a/src/lib/pubkey/dl_algo/dl_algo.h b/src/lib/pubkey/dl_algo/dl_algo.h
index 5d2386e56..18886e5dc 100644
--- a/src/lib/pubkey/dl_algo/dl_algo.h
+++ b/src/lib/pubkey/dl_algo/dl_algo.h
@@ -10,7 +10,6 @@
#include <botan/dl_group.h>
#include <botan/x509_key.h>
-#include <botan/pkcs8.h>
namespace Botan {
@@ -20,11 +19,11 @@ namespace Botan {
class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key
{
public:
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
- AlgorithmIdentifier algorithm_identifier() const;
+ AlgorithmIdentifier algorithm_identifier() const override;
- std::vector<byte> x509_subject_public_key() const;
+ std::vector<byte> x509_subject_public_key() const override;
/**
* Get the DL domain parameters of this key.
@@ -88,7 +87,7 @@ class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey,
public virtual Private_Key
{
public:
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
/**
* Get the secret key x.
@@ -96,7 +95,7 @@ class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey,
*/
const BigInt& get_x() const { return x; }
- secure_vector<byte> pkcs8_private_key() const;
+ secure_vector<byte> pkcs8_private_key() const override;
DL_Scheme_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits,
diff --git a/src/lib/pubkey/dlies/dlies.h b/src/lib/pubkey/dlies/dlies.h
index 3f0647aeb..ed5928080 100644
--- a/src/lib/pubkey/dlies/dlies.h
+++ b/src/lib/pubkey/dlies/dlies.h
@@ -28,9 +28,9 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor
void set_other_key(const std::vector<byte>&);
private:
std::vector<byte> enc(const byte[], size_t,
- RandomNumberGenerator&) const;
+ RandomNumberGenerator&) const override;
- size_t maximum_input_size() const;
+ size_t maximum_input_size() const override;
std::vector<byte> other_key, my_key;
@@ -52,7 +52,7 @@ class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor
size_t mac_key_len = 20);
private:
- secure_vector<byte> dec(const byte[], size_t) const;
+ secure_vector<byte> dec(const byte[], size_t) const override;
std::vector<byte> my_key;
diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp
index 90cc18fdc..ec0830533 100644
--- a/src/lib/pubkey/dsa/dsa.cpp
+++ b/src/lib/pubkey/dsa/dsa.cpp
@@ -148,9 +148,9 @@ class DSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
mod_q = Modular_Reducer(dsa.group_q());
}
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return q.bytes(); }
- size_t max_input_bits() const { return q.bits(); }
+ size_t message_parts() const override { return 2; }
+ size_t message_part_size() const override { return q.bytes(); }
+ size_t max_input_bits() const override { return q.bits(); }
bool with_recovery() const override { return false; }
diff --git a/src/lib/pubkey/dsa/dsa.h b/src/lib/pubkey/dsa/dsa.h
index 294774bf0..2653c9229 100644
--- a/src/lib/pubkey/dsa/dsa.h
+++ b/src/lib/pubkey/dsa/dsa.h
@@ -18,12 +18,12 @@ namespace Botan {
class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "DSA"; }
+ std::string algo_name() const override { return "DSA"; }
- DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; }
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return group_q().bytes(); }
- size_t max_input_bits() const { return group_q().bits(); }
+ DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_57; }
+ size_t message_parts() const override { return 2; }
+ size_t message_part_size() const override { return group_q().bytes(); }
+ size_t max_input_bits() const override { return group_q().bits(); }
DSA_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits) :
@@ -51,7 +51,7 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey,
const DL_Group& group,
const BigInt& private_key = 0);
- bool check_key(RandomNumberGenerator& rng, bool strong) const;
+ bool check_key(RandomNumberGenerator& rng, bool strong) const override;
};
}
diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h
index 5e2800dc5..67ade0c65 100644
--- a/src/lib/pubkey/ec_group/ec_group.h
+++ b/src/lib/pubkey/ec_group/ec_group.h
@@ -140,7 +140,7 @@ inline bool operator!=(const EC_Group& lhs,
return !(lhs == rhs);
}
-// For compatability with 1.8
+// For compatibility with 1.8
typedef EC_Group EC_Domain_Params;
}
diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h
index efc4b02da..6764df0f0 100644
--- a/src/lib/pubkey/ecc_key/ecc_key.h
+++ b/src/lib/pubkey/ecc_key/ecc_key.h
@@ -13,7 +13,6 @@
#include <botan/ec_group.h>
#include <botan/pk_keys.h>
#include <botan/x509_key.h>
-#include <botan/pkcs8.h>
namespace Botan {
@@ -44,12 +43,12 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key
*/
const PointGFp& public_point() const { return public_key; }
- AlgorithmIdentifier algorithm_identifier() const;
+ AlgorithmIdentifier algorithm_identifier() const override;
- std::vector<byte> x509_subject_public_key() const;
+ std::vector<byte> x509_subject_public_key() const override;
bool check_key(RandomNumberGenerator& rng,
- bool strong) const;
+ bool strong) const override;
/**
* Get the domain parameters of this key.
@@ -103,7 +102,7 @@ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey,
EC_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits);
- secure_vector<byte> pkcs8_private_key() const;
+ secure_vector<byte> pkcs8_private_key() const override;
/**
* Get the private key value of this key object.
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index 61d3af816..bad0f2c0b 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -30,7 +30,7 @@ class ECDH_KA_Operation : public PK_Ops::Key_Agreement_with_KDF
l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * key.private_value();
}
- secure_vector<byte> raw_agree(const byte w[], size_t w_len)
+ secure_vector<byte> raw_agree(const byte w[], size_t w_len) override
{
PointGFp point = OS2ECP(w, w_len, curve);
PointGFp S = (cofactor * point) * l_times_priv;
diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h
index 1e806f119..ef3e8ef7a 100644
--- a/src/lib/pubkey/ecdh/ecdh.h
+++ b/src/lib/pubkey/ecdh/ecdh.h
@@ -38,7 +38,7 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey
* Get this keys algorithm name.
* @return this keys algorithm name
*/
- std::string algo_name() const { return "ECDH"; }
+ std::string algo_name() const override { return "ECDH"; }
/**
* Get the maximum number of bits allowed to be fed to this key.
@@ -46,7 +46,8 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey
* @return maximum number of input bits
*/
- size_t max_input_bits() const { return domain().get_order().bits(); }
+ size_t max_input_bits() const override
+ { return domain().get_order().bits(); }
/**
* @return public point value
@@ -82,7 +83,7 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey,
const BigInt& x = 0) :
EC_PrivateKey(rng, domain, x) {}
- std::vector<byte> public_value() const
+ std::vector<byte> public_value() const override
{ return ECDH_PublicKey::public_value(); }
};
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index 2518a14fe..c327a37c3 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -2,14 +2,13 @@
* ECDSA implemenation
* (C) 2007 Manuel Hartl, FlexSecure GmbH
* 2007 Falko Strenzke, FlexSecure GmbH
-* 2008-2010 Jack Lloyd
+* 2008-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/internal/pk_utils.h>
#include <botan/ecdsa.h>
-#include <botan/reducer.h>
#include <botan/keypair.h>
#include <botan/rfc6979.h>
@@ -41,9 +40,10 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
base_point(ecdsa.domain().get_base_point()),
- order(ecdsa.domain().get_order()),
- x(ecdsa.private_value()),
- mod_order(order),
+ m_order(ecdsa.domain().get_order()),
+ m_base_point(ecdsa.domain().get_base_point(), m_order),
+ m_x(ecdsa.private_value()),
+ m_mod_order(m_order),
m_hash(hash_for_deterministic_signature(emsa))
{
}
@@ -52,34 +52,36 @@ class ECDSA_Signature_Operation : public PK_Ops::Signature_with_EMSA
RandomNumberGenerator& rng) override;
size_t message_parts() const override { return 2; }
- size_t message_part_size() const override { return order.bytes(); }
- size_t max_input_bits() const override { return order.bits(); }
+ size_t message_part_size() const override { return m_order.bytes(); }
+ size_t max_input_bits() const override { return m_order.bits(); }
private:
const PointGFp& base_point;
- const BigInt& order;
- const BigInt& x;
- Modular_Reducer mod_order;
+ const BigInt& m_order;
+ Blinded_Point_Multiply m_base_point;
+ const BigInt& m_x;
+ Modular_Reducer m_mod_order;
std::string m_hash;
};
secure_vector<byte>
ECDSA_Signature_Operation::raw_sign(const byte msg[], size_t msg_len,
- RandomNumberGenerator&)
+ RandomNumberGenerator& rng)
{
const BigInt m(msg, msg_len);
- const BigInt k = generate_rfc6979_nonce(x, order, m, m_hash);
+ const BigInt k = generate_rfc6979_nonce(m_x, m_order, m, m_hash);
- const PointGFp k_times_P = base_point * k;
- const BigInt r = mod_order.reduce(k_times_P.get_affine_x());
- const BigInt s = mod_order.multiply(inverse_mod(k, order), mul_add(x, r, m));
+ //const PointGFp k_times_P = base_point * k;
+ const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
+ const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x());
+ const BigInt s = m_mod_order.multiply(inverse_mod(k, m_order), mul_add(m_x, r, m));
// With overwhelming probability, a bug rather than actual zero r/s
BOTAN_ASSERT(s != 0, "invalid s");
BOTAN_ASSERT(r != 0, "invalid r");
- secure_vector<byte> output(2*order.bytes());
+ secure_vector<byte> output(2*m_order.bytes());
r.binary_encode(&output[output.size() / 2 - r.bytes()]);
s.binary_encode(&output[output.size() - s.bytes()]);
return output;
diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h
index 91ddb500d..1eb41a4b9 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.h
+++ b/src/lib/pubkey/ecdsa/ecdsa.h
@@ -38,18 +38,19 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey
* Get this keys algorithm name.
* @result this keys algorithm name ("ECDSA")
*/
- std::string algo_name() const { return "ECDSA"; }
+ std::string algo_name() const override { return "ECDSA"; }
/**
* Get the maximum number of bits allowed to be fed to this key.
* This is the bitlength of the order of the base point.
* @result the maximum number of input bits
*/
- size_t max_input_bits() const { return domain().get_order().bits(); }
+ size_t max_input_bits() const override
+ { return domain().get_order().bits(); }
- size_t message_parts() const { return 2; }
+ size_t message_parts() const override { return 2; }
- size_t message_part_size() const
+ size_t message_part_size() const override
{ return domain().get_order().bytes(); }
protected:
@@ -84,7 +85,7 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey,
const BigInt& x = 0) :
EC_PrivateKey(rng, domain, x) {}
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
};
}
diff --git a/src/lib/pubkey/ecdsa/info.txt b/src/lib/pubkey/ecdsa/info.txt
index 26640328f..e7941d53d 100644
--- a/src/lib/pubkey/ecdsa/info.txt
+++ b/src/lib/pubkey/ecdsa/info.txt
@@ -4,6 +4,7 @@ define ECDSA 20131128
asn1
ec_group
ecc_key
+keypair
numbertheory
rng
rfc6979
diff --git a/src/lib/pubkey/elgamal/elgamal.cpp b/src/lib/pubkey/elgamal/elgamal.cpp
index 2a4de7196..4d0344610 100644
--- a/src/lib/pubkey/elgamal/elgamal.cpp
+++ b/src/lib/pubkey/elgamal/elgamal.cpp
@@ -131,7 +131,8 @@ class ElGamal_Decryption_Operation : public PK_Ops::Decryption_with_EME
public:
typedef ElGamal_PrivateKey Key_Type;
- size_t max_raw_input_bits() const { return mod_p.get_modulus().bits() - 1; }
+ size_t max_raw_input_bits() const override
+ { return mod_p.get_modulus().bits() - 1; }
ElGamal_Decryption_Operation(const ElGamal_PrivateKey& key, const std::string& eme);
diff --git a/src/lib/pubkey/elgamal/elgamal.h b/src/lib/pubkey/elgamal/elgamal.h
index 90940b609..9f287158d 100644
--- a/src/lib/pubkey/elgamal/elgamal.h
+++ b/src/lib/pubkey/elgamal/elgamal.h
@@ -18,10 +18,10 @@ namespace Botan {
class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "ElGamal"; }
- DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; }
+ std::string algo_name() const override { return "ElGamal"; }
+ DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_42; }
- size_t max_input_bits() const { return (group_p().bits() - 1); }
+ size_t max_input_bits() const override { return (group_p().bits() - 1); }
ElGamal_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits) :
@@ -40,7 +40,7 @@ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
ElGamal_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits,
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index 3950c0e43..f04692d12 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -2,7 +2,7 @@
* GOST 34.10-2001 implemenation
* (C) 2007 Falko Strenzke, FlexSecure GmbH
* Manuel Hartl, FlexSecure GmbH
-* (C) 2008-2010 Jack Lloyd
+* (C) 2008-2010,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -16,7 +16,6 @@ namespace Botan {
std::vector<byte> GOST_3410_PublicKey::x509_subject_public_key() const
{
- // Trust CryptoPro to come up with something obnoxious
const BigInt x = public_point().get_affine_x();
const BigInt y = public_point().get_affine_y();
@@ -53,7 +52,7 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id,
{
OID ecc_param_id;
- // Also includes hash and cipher OIDs... brilliant design guys
+ // The parameters also includes hash and cipher OIDs
BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id);
domain_params = EC_Group(ecc_param_id);
@@ -101,21 +100,23 @@ class GOST_3410_Signature_Operation : public PK_Ops::Signature_with_EMSA
GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410,
const std::string& emsa) :
PK_Ops::Signature_with_EMSA(emsa),
- base_point(gost_3410.domain().get_base_point()),
- order(gost_3410.domain().get_order()),
- x(gost_3410.private_value()) {}
+ m_order(gost_3410.domain().get_order()),
+ m_mod_order(m_order),
+ m_base_point(gost_3410.domain().get_base_point(), m_order),
+ m_x(gost_3410.private_value()) {}
size_t message_parts() const override { return 2; }
- size_t message_part_size() const override { return order.bytes(); }
- size_t max_input_bits() const override { return order.bits(); }
+ size_t message_part_size() const override { return m_order.bytes(); }
+ size_t max_input_bits() const override { return m_order.bits(); }
secure_vector<byte> raw_sign(const byte msg[], size_t msg_len,
RandomNumberGenerator& rng) override;
private:
- const PointGFp& base_point;
- const BigInt& order;
- const BigInt& x;
+ const BigInt& m_order;
+ Modular_Reducer m_mod_order;
+ Blinded_Point_Multiply m_base_point;
+ const BigInt& m_x;
};
secure_vector<byte>
@@ -124,26 +125,25 @@ GOST_3410_Signature_Operation::raw_sign(const byte msg[], size_t msg_len,
{
BigInt k;
do
- k.randomize(rng, order.bits()-1);
- while(k >= order);
+ k.randomize(rng, m_order.bits()-1);
+ while(k >= m_order);
BigInt e = decode_le(msg, msg_len);
- e %= order;
+ e = m_mod_order.reduce(e);
if(e == 0)
e = 1;
- PointGFp k_times_P = base_point * k;
+ const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve");
- BigInt r = k_times_P.get_affine_x() % order;
-
- BigInt s = (r*x + k*e) % order;
+ const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x());
+ const BigInt s = m_mod_order.reduce(r*m_x + k*e);
if(r == 0 || s == 0)
throw Invalid_State("GOST 34.10: r == 0 || s == 0");
- secure_vector<byte> output(2*order.bytes());
+ secure_vector<byte> output(2*m_order.bytes());
s.binary_encode(&output[output.size() / 2 - s.bytes()]);
r.binary_encode(&output[output.size() - r.bytes()]);
return output;
@@ -171,7 +171,7 @@ class GOST_3410_Verification_Operation : public PK_Ops::Verification_with_EMSA
bool with_recovery() const override { return false; }
bool verify(const byte msg[], size_t msg_len,
- const byte sig[], size_t sig_len);
+ const byte sig[], size_t sig_len) override;
private:
const PointGFp& base_point;
const PointGFp& public_point;
diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h
index 2356d8e3d..62a627c37 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.h
+++ b/src/lib/pubkey/gost_3410/gost_3410.h
@@ -40,11 +40,11 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey
* Get this keys algorithm name.
* @result this keys algorithm name
*/
- std::string algo_name() const { return "GOST-34.10"; }
+ std::string algo_name() const override { return "GOST-34.10"; }
- AlgorithmIdentifier algorithm_identifier() const;
+ AlgorithmIdentifier algorithm_identifier() const override;
- std::vector<byte> x509_subject_public_key() const;
+ std::vector<byte> x509_subject_public_key() const override;
/**
* Get the maximum number of bits allowed to be fed to this key.
@@ -52,11 +52,11 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey
* @result the maximum number of input bits
*/
- size_t max_input_bits() const { return domain().get_order().bits(); }
+ size_t max_input_bits() const override { return domain().get_order().bits(); }
- size_t message_parts() const { return 2; }
+ size_t message_parts() const override { return 2; }
- size_t message_part_size() const
+ size_t message_part_size() const override
{ return domain().get_order().bytes(); }
protected:
@@ -86,7 +86,7 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey,
const BigInt& x = 0) :
EC_PrivateKey(rng, domain, x) {}
- AlgorithmIdentifier pkcs8_algorithm_identifier() const
+ AlgorithmIdentifier pkcs8_algorithm_identifier() const override
{ return EC_PublicKey::algorithm_identifier(); }
};
diff --git a/src/lib/pubkey/if_algo/if_algo.h b/src/lib/pubkey/if_algo/if_algo.h
index 7fa266aaa..dec731af3 100644
--- a/src/lib/pubkey/if_algo/if_algo.h
+++ b/src/lib/pubkey/if_algo/if_algo.h
@@ -10,7 +10,6 @@
#include <botan/bigint.h>
#include <botan/x509_key.h>
-#include <botan/pkcs8.h>
namespace Botan {
@@ -27,11 +26,11 @@ class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key
IF_Scheme_PublicKey(const BigInt& n, const BigInt& e) :
n(n), e(e) {}
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
- AlgorithmIdentifier algorithm_identifier() const;
+ AlgorithmIdentifier algorithm_identifier() const override;
- std::vector<byte> x509_subject_public_key() const;
+ std::vector<byte> x509_subject_public_key() const override;
/**
* @return public modulus
@@ -43,7 +42,7 @@ class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key
*/
const BigInt& get_e() const { return e; }
- size_t max_input_bits() const { return (n.bits() - 1); }
+ size_t max_input_bits() const override { return (n.bits() - 1); }
size_t estimated_strength() const override;
@@ -71,7 +70,7 @@ class BOTAN_DLL IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey,
const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits);
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
/**
* Get the first prime p.
@@ -95,7 +94,7 @@ class BOTAN_DLL IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey,
const BigInt& get_d1() const { return d1; }
const BigInt& get_d2() const { return d2; }
- secure_vector<byte> pkcs8_private_key() const;
+ secure_vector<byte> pkcs8_private_key() const override;
protected:
IF_Scheme_PrivateKey() {}
diff --git a/src/lib/pubkey/mce/code_based_key_gen.cpp b/src/lib/pubkey/mce/code_based_key_gen.cpp
index 7adf85112..a3749abef 100644
--- a/src/lib/pubkey/mce/code_based_key_gen.cpp
+++ b/src/lib/pubkey/mce/code_based_key_gen.cpp
@@ -156,7 +156,7 @@ McEliece_PrivateKey generate_mceliece_key( RandomNumberGenerator & rng, u32bit e
{
k = (l * ext_deg) / 32;
j = (l * ext_deg) % 32;
- sk[k] ^= F[i].get_coef( l) << j;
+ sk[k] ^= static_cast<u32bit>(F[i].get_coef(l)) << j;
if (j + ext_deg > 32)
{
sk[k + 1] ^= F[i].get_coef( l) >> (32 - j);
diff --git a/src/lib/pubkey/mce/mceliece.h b/src/lib/pubkey/mce/mceliece.h
index b62afee3a..c5f02470f 100644
--- a/src/lib/pubkey/mce/mceliece.h
+++ b/src/lib/pubkey/mce/mceliece.h
@@ -112,9 +112,9 @@ class BOTAN_DLL McEliece_Private_Operation : public PK_Ops::Decryption
public:
McEliece_Private_Operation(const McEliece_PrivateKey& mce_key);
- size_t max_input_bits() const { return m_priv_key.max_input_bits(); }
+ size_t max_input_bits() const override { return m_priv_key.max_input_bits(); }
- secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
+ secure_vector<byte> decrypt(const byte msg[], size_t msg_len) override;
McEliece_PrivateKey const& get_key() const { return m_priv_key; }
@@ -127,8 +127,8 @@ class BOTAN_DLL McEliece_Public_Operation : public PK_Ops::Encryption
public:
McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length);
- size_t max_input_bits() const { return m_pub_key.max_input_bits(); }
- secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&);
+ size_t max_input_bits() const override { return m_pub_key.max_input_bits(); }
+ secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&) override;
McEliece_PublicKey const& get_key() const { return m_pub_key; }
diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp
index 41392f695..8cda0af89 100644
--- a/src/lib/pubkey/mce/mceliece_key.cpp
+++ b/src/lib/pubkey/mce/mceliece_key.cpp
@@ -34,7 +34,7 @@ McEliece_PrivateKey::McEliece_PrivateKey(polyn_gf2m const& goppa_polyn,
m_codimension(ceil_log2(inverse_support.size()) * goppa_polyn.get_degree()),
m_dimension(inverse_support.size() - m_codimension)
{
- };
+ }
McEliece_PrivateKey::McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code_length, size_t t)
{
diff --git a/src/lib/pubkey/mce/mceliece_key.h b/src/lib/pubkey/mce/mceliece_key.h
index 3a0d0eea8..65ab04f16 100644
--- a/src/lib/pubkey/mce/mceliece_key.h
+++ b/src/lib/pubkey/mce/mceliece_key.h
@@ -32,25 +32,25 @@ class BOTAN_DLL McEliece_PublicKey : public virtual Public_Key
McEliece_PublicKey(const McEliece_PublicKey & other);
- std::string algo_name() const { return "McEliece"; }
+ std::string algo_name() const override { return "McEliece"; }
/**
* Get the maximum number of bits allowed to be fed to this key.
* This is the bitlength of the order of the base point.
* @result the maximum number of input bits
*/
- size_t max_input_bits() const
+ size_t max_input_bits() const override
{
return get_message_word_bit_length();
};
- AlgorithmIdentifier algorithm_identifier() const;
+ AlgorithmIdentifier algorithm_identifier() const override;
- size_t estimated_strength() const;
+ size_t estimated_strength() const override;
- std::vector<byte> x509_subject_public_key() const;
+ std::vector<byte> x509_subject_public_key() const override;
- bool check_key(RandomNumberGenerator&, bool) const
+ bool check_key(RandomNumberGenerator&, bool) const override
{ return true; }
u32bit get_t() const { return m_t; }
@@ -78,7 +78,7 @@ class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey,
* This is the bitlength of the order of the base point.
* @result the maximum number of input bits
*/
- size_t max_input_bits() const {
+ size_t max_input_bits() const override {
return m_Linv.size();
};
@@ -91,7 +91,7 @@ class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey,
std::vector<byte> const& public_matrix );
McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code_length, size_t t);
- bool check_key(RandomNumberGenerator& rng, bool strong) const;
+ bool check_key(RandomNumberGenerator& rng, bool strong) const override;
polyn_gf2m const& get_goppa_polyn() const { return m_g; };
std::vector<u32bit> const& get_H_coeffs() const { return m_coeffs; };
@@ -105,7 +105,7 @@ class BOTAN_DLL McEliece_PrivateKey : public virtual McEliece_PublicKey,
{ return m_codimension; };
- secure_vector<byte> pkcs8_private_key() const;
+ secure_vector<byte> pkcs8_private_key() const override;
bool operator==(const McEliece_PrivateKey & other) const;
diff --git a/src/lib/pubkey/mce/polyn_gf2m.cpp b/src/lib/pubkey/mce/polyn_gf2m.cpp
index 0f203ec11..9b3366757 100644
--- a/src/lib/pubkey/mce/polyn_gf2m.cpp
+++ b/src/lib/pubkey/mce/polyn_gf2m.cpp
@@ -146,7 +146,7 @@ polyn_gf2m::polyn_gf2m( std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field )
: m_deg(-1),
coeff(1),
msp_field(sp_field)
- {};
+ {}
polyn_gf2m::polyn_gf2m(int degree, const unsigned char* mem, u32bit mem_byte_len, std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field)
:msp_field(sp_field)
@@ -555,7 +555,7 @@ std::pair<polyn_gf2m, polyn_gf2m> polyn_gf2m::eea_with_coefficients( const polyn
* candiate. If they are all fulfilled, then we know that we have a low
* weight error vector, since the key-equation solving EEA is skipped if
* the degree of tau^2 is low (=m_deg(u0)) and all its odd cofficients are
- * zero (they would cause "full-lenght" contributions from the square
+ * zero (they would cause "full-length" contributions from the square
* root computation).
*/
// Condition for the coefficient to Y to be cancelled out by the
diff --git a/src/lib/pubkey/mceies/info.txt b/src/lib/pubkey/mceies/info.txt
index b4a25329e..547e4a47a 100644
--- a/src/lib/pubkey/mceies/info.txt
+++ b/src/lib/pubkey/mceies/info.txt
@@ -1,5 +1,7 @@
+define MCEIES 20150706
<requires>
+aes
mce
ocb
</requires>
diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp
index 9e9ae1cb8..58dde2e27 100644
--- a/src/lib/pubkey/mceies/mceies.cpp
+++ b/src/lib/pubkey/mceies/mceies.cpp
@@ -45,9 +45,10 @@ mceies_encrypt(const McEliece_PublicKey& pubkey,
BOTAN_ASSERT(mce_ciphertext.size() == mce_code_bytes, "Unexpected size");
- std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/OCB", ENCRYPTION));
+ const std::string algo = "AES-256/OCB";
+ std::unique_ptr<AEAD_Mode> aead(get_aead(algo, ENCRYPTION));
if(!aead)
- throw std::runtime_error("mce_encrypt unable to create AEAD instance");
+ throw std::runtime_error("mce_encrypt unable to create AEAD instance '" + algo + "'");
const size_t nonce_len = aead->default_nonce_length();
@@ -77,9 +78,11 @@ mceies_decrypt(const McEliece_PrivateKey& privkey,
const size_t mce_code_bytes = (privkey.get_code_length() + 7) / 8;
- std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/OCB", DECRYPTION));
+
+ const std::string algo = "AES-256/OCB";
+ std::unique_ptr<AEAD_Mode> aead(get_aead(algo, DECRYPTION));
if(!aead)
- throw std::runtime_error("Unable to create AEAD instance");
+ throw std::runtime_error("Unable to create AEAD instance '" + algo + "'");
const size_t nonce_len = aead->default_nonce_length();
diff --git a/src/lib/pubkey/nr/nr.h b/src/lib/pubkey/nr/nr.h
index 51752f8ce..425ad2642 100644
--- a/src/lib/pubkey/nr/nr.h
+++ b/src/lib/pubkey/nr/nr.h
@@ -18,13 +18,13 @@ namespace Botan {
class BOTAN_DLL NR_PublicKey : public virtual DL_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "NR"; }
+ std::string algo_name() const override { return "NR"; }
- DL_Group::Format group_format() const { return DL_Group::ANSI_X9_57; }
+ DL_Group::Format group_format() const override { return DL_Group::ANSI_X9_57; }
- size_t message_parts() const { return 2; }
- size_t message_part_size() const { return group_q().bytes(); }
- size_t max_input_bits() const { return (group_q().bits() - 1); }
+ size_t message_parts() const override { return 2; }
+ size_t message_part_size() const override { return group_q().bytes(); }
+ size_t max_input_bits() const override { return (group_q().bits() - 1); }
NR_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits);
@@ -41,7 +41,7 @@ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey,
public virtual DL_Scheme_PrivateKey
{
public:
- bool check_key(RandomNumberGenerator& rng, bool strong) const;
+ bool check_key(RandomNumberGenerator& rng, bool strong) const override;
NR_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits,
diff --git a/src/lib/pubkey/pk_keys.h b/src/lib/pubkey/pk_keys.h
index 66811de86..40b7569af 100644
--- a/src/lib/pubkey/pk_keys.h
+++ b/src/lib/pubkey/pk_keys.h
@@ -114,7 +114,7 @@ class BOTAN_DLL Private_Key : public virtual Public_Key
* Self-test after loading a key
* @param rng a random number generator
*/
- void load_check(RandomNumberGenerator& rng) const;
+ void load_check(RandomNumberGenerator& rng) const override;
/**
* Self-test after generating a key
diff --git a/src/lib/pubkey/pk_utils.h b/src/lib/pubkey/pk_utils.h
index 14c304ac5..326a6ea68 100644
--- a/src/lib/pubkey/pk_utils.h
+++ b/src/lib/pubkey/pk_utils.h
@@ -11,6 +11,7 @@
#include <botan/internal/algo_registry.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/numthry.h>
+#include <botan/reducer.h>
#include <algorithm>
namespace Botan {
diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h
index c95ed4469..687485c68 100644
--- a/src/lib/pubkey/pubkey.h
+++ b/src/lib/pubkey/pubkey.h
@@ -377,7 +377,7 @@ class BOTAN_DLL PK_Key_Agreement
class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor
{
public:
- size_t maximum_input_size() const;
+ size_t maximum_input_size() const override;
/**
* Construct an instance.
@@ -388,7 +388,7 @@ class BOTAN_DLL PK_Encryptor_EME : public PK_Encryptor
const std::string& eme);
private:
std::vector<byte> enc(const byte[], size_t,
- RandomNumberGenerator& rng) const;
+ RandomNumberGenerator& rng) const override;
std::unique_ptr<PK_Ops::Encryption> m_op;
};
@@ -407,7 +407,7 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor
PK_Decryptor_EME(const Private_Key& key,
const std::string& eme);
private:
- secure_vector<byte> dec(const byte[], size_t) const;
+ secure_vector<byte> dec(const byte[], size_t) const override;
std::unique_ptr<PK_Ops::Decryption> m_op;
};
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index 13425a46f..5804d0034 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -87,14 +87,14 @@ class RSA_Private_Operation
BigInt blinded_private_op(const BigInt& m) const
{
+ if(m >= n)
+ throw Invalid_Argument("RSA private op - input is too large");
+
return m_blinder.unblind(private_op(m_blinder.blind(m)));
}
BigInt private_op(const BigInt& m) const
{
- if(m >= n)
- throw Invalid_Argument("RSA private op - input is too large");
-
auto future_j1 = std::async(std::launch::async, m_powermod_d1_p, m);
BigInt j2 = m_powermod_d2_q(m);
BigInt j1 = future_j1.get();
@@ -131,7 +131,8 @@ class RSA_Signature_Operation : public PK_Ops::Signature_with_EMSA,
{
const BigInt m(msg, msg_len);
const BigInt x = blinded_private_op(m);
- BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA sign consistency check");
+ const BigInt c = m_powermod_e_n(x);
+ BOTAN_ASSERT(m == c, "RSA sign consistency check");
return BigInt::encode_1363(x, n.bytes());
}
};
@@ -154,7 +155,8 @@ class RSA_Decryption_Operation : public PK_Ops::Decryption_with_EME,
{
const BigInt m(msg, msg_len);
const BigInt x = blinded_private_op(m);
- BOTAN_ASSERT(m == m_powermod_e_n(x), "RSA decrypt consistency check");
+ const BigInt c = m_powermod_e_n(x);
+ BOTAN_ASSERT(m == c, "RSA sign consistency check");
return BigInt::encode_locked(x);
}
};
diff --git a/src/lib/pubkey/rsa/rsa.h b/src/lib/pubkey/rsa/rsa.h
index 67357d859..4a57b9f63 100644
--- a/src/lib/pubkey/rsa/rsa.h
+++ b/src/lib/pubkey/rsa/rsa.h
@@ -19,7 +19,7 @@ namespace Botan {
class BOTAN_DLL RSA_PublicKey : public virtual IF_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "RSA"; }
+ std::string algo_name() const override { return "RSA"; }
RSA_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits) :
@@ -46,7 +46,7 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey,
public IF_Scheme_PrivateKey
{
public:
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
RSA_PrivateKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits,
diff --git a/src/lib/pubkey/rw/rw.cpp b/src/lib/pubkey/rw/rw.cpp
index b706d6730..aa92578af 100644
--- a/src/lib/pubkey/rw/rw.cpp
+++ b/src/lib/pubkey/rw/rw.cpp
@@ -141,10 +141,10 @@ class RW_Verification_Operation : public PK_Ops::Verification_with_EMSA
n(rw.get_n()), powermod_e_n(rw.get_e(), rw.get_n())
{}
- size_t max_input_bits() const { return (n.bits() - 1); }
- bool with_recovery() const { return true; }
+ size_t max_input_bits() const override { return (n.bits() - 1); }
+ bool with_recovery() const override { return true; }
- secure_vector<byte> verify_mr(const byte msg[], size_t msg_len);
+ secure_vector<byte> verify_mr(const byte msg[], size_t msg_len) override;
private:
const BigInt& n;
diff --git a/src/lib/pubkey/rw/rw.h b/src/lib/pubkey/rw/rw.h
index 5d754e817..2a010441e 100644
--- a/src/lib/pubkey/rw/rw.h
+++ b/src/lib/pubkey/rw/rw.h
@@ -18,7 +18,7 @@ namespace Botan {
class BOTAN_DLL RW_PublicKey : public virtual IF_Scheme_PublicKey
{
public:
- std::string algo_name() const { return "RW"; }
+ std::string algo_name() const override { return "RW"; }
RW_PublicKey(const AlgorithmIdentifier& alg_id,
const secure_vector<byte>& key_bits) :
@@ -53,7 +53,7 @@ class BOTAN_DLL RW_PrivateKey : public RW_PublicKey,
RW_PrivateKey(RandomNumberGenerator& rng, size_t bits, size_t = 2);
- bool check_key(RandomNumberGenerator& rng, bool) const;
+ bool check_key(RandomNumberGenerator& rng, bool) const override;
};
}
diff --git a/src/lib/rng/auto_rng/auto_rng.h b/src/lib/rng/auto_rng/auto_rng.h
index bb36f672e..a7b28af92 100644
--- a/src/lib/rng/auto_rng/auto_rng.h
+++ b/src/lib/rng/auto_rng/auto_rng.h
@@ -16,18 +16,18 @@ namespace Botan {
class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator
{
public:
- void randomize(byte out[], size_t len)
+ void randomize(byte out[], size_t len) override
{ m_rng->randomize(out, len); }
- bool is_seeded() const { return m_rng->is_seeded(); }
+ bool is_seeded() const override { return m_rng->is_seeded(); }
- void clear() { m_rng->clear(); }
+ void clear() override { m_rng->clear(); }
- std::string name() const { return m_rng->name(); }
+ std::string name() const override { return m_rng->name(); }
- void reseed(size_t poll_bits = 256) { m_rng->reseed(poll_bits); }
+ void reseed(size_t poll_bits = 256) override { m_rng->reseed(poll_bits); }
- void add_entropy(const byte in[], size_t len)
+ void add_entropy(const byte in[], size_t len) override
{ m_rng->add_entropy(in, len); }
AutoSeeded_RNG() : m_rng(RandomNumberGenerator::make_rng()) {}
diff --git a/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/lib/rng/hmac_drbg/hmac_drbg.h
index 979b754b2..2fefdef0d 100644
--- a/src/lib/rng/hmac_drbg/hmac_drbg.h
+++ b/src/lib/rng/hmac_drbg/hmac_drbg.h
@@ -19,14 +19,14 @@ namespace Botan {
class BOTAN_DLL HMAC_DRBG : public RandomNumberGenerator
{
public:
- void randomize(byte buf[], size_t buf_len);
- bool is_seeded() const;
- void clear();
- std::string name() const;
+ void randomize(byte buf[], size_t buf_len) override;
+ bool is_seeded() const override;
+ void clear() override;
+ std::string name() const override;
- void reseed(size_t poll_bits);
+ void reseed(size_t poll_bits) override;
- void add_entropy(const byte input[], size_t input_len);
+ void add_entropy(const byte input[], size_t input_len) override;
/**
* @param mac the underlying mac function (eg HMAC(SHA-512))
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index 2abd11532..6ee67f66f 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -47,17 +47,35 @@ class BOTAN_DLL RandomNumberGenerator
}
/**
- * Return a random byte
- * @return random byte
+ * Only usable with POD types, only useful with integers
+ * get_random<u64bit>()
*/
- byte next_byte()
+ template<typename T> T get_random()
{
- byte out;
- this->randomize(&out, 1);
- return out;
+ T r;
+ this->randomize(reinterpret_cast<byte*>(&r), sizeof(r));
+ return r;
}
/**
+ * Return a value in range [0,2^bits)
+ */
+ u64bit gen_mask(size_t bits)
+ {
+ if(bits == 0 || bits > 64)
+ throw std::invalid_argument("RandomNumberGenerator::gen_mask invalid argument");
+
+ const u64bit mask = ((1 << bits) - 1);
+ return this->get_random<u64bit>() & mask;
+ }
+
+ /**
+ * Return a random byte
+ * @return random byte
+ */
+ byte next_byte() { return get_random<byte>(); }
+
+ /**
* Check whether this RNG is seeded.
* @return true if this RNG was already seeded, false otherwise.
*/
@@ -120,37 +138,37 @@ class BOTAN_DLL Null_RNG : public RandomNumberGenerator
class BOTAN_DLL Serialized_RNG : public RandomNumberGenerator
{
public:
- void randomize(byte out[], size_t len)
+ void randomize(byte out[], size_t len) override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_rng->randomize(out, len);
}
- bool is_seeded() const
+ bool is_seeded() const override
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_rng->is_seeded();
}
- void clear()
+ void clear() override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_rng->clear();
}
- std::string name() const
+ std::string name() const override
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_rng->name();
}
- void reseed(size_t poll_bits)
+ void reseed(size_t poll_bits) override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_rng->reseed(poll_bits);
}
- void add_entropy(const byte in[], size_t len)
+ void add_entropy(const byte in[], size_t len) override
{
std::lock_guard<std::mutex> lock(m_mutex);
m_rng->add_entropy(in, len);
diff --git a/src/lib/rng/system_rng/info.txt b/src/lib/rng/system_rng/info.txt
index a452a7d9b..987b18c76 100644
--- a/src/lib/rng/system_rng/info.txt
+++ b/src/lib/rng/system_rng/info.txt
@@ -3,6 +3,7 @@ define SYSTEM_RNG 20141202
# Any system with /dev/random or CryptGenRandom
<os>
+android
aix
cygwin
darwin
@@ -18,6 +19,5 @@ netbsd
openbsd
qnx
solaris
-tru64
windows
</os>
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp
index 59a8b014f..1ab80669b 100644
--- a/src/lib/rng/system_rng/system_rng.cpp
+++ b/src/lib/rng/system_rng/system_rng.cpp
@@ -34,14 +34,14 @@ class System_RNG : public RandomNumberGenerator
System_RNG();
~System_RNG();
- void randomize(byte buf[], size_t len);
+ void randomize(byte buf[], size_t len) override;
- bool is_seeded() const { return true; }
- void clear() {}
- std::string name() const { return "system"; }
+ bool is_seeded() const override { return true; }
+ void clear() override {}
+ std::string name() const override { return "system"; }
- void reseed(size_t) {}
- void add_entropy(const byte[], size_t) {}
+ void reseed(size_t) override {}
+ void add_entropy(const byte[], size_t) override {}
private:
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
diff --git a/src/lib/rng/x931_rng/x931_rng.h b/src/lib/rng/x931_rng/x931_rng.h
index 8b1513035..899fed956 100644
--- a/src/lib/rng/x931_rng/x931_rng.h
+++ b/src/lib/rng/x931_rng/x931_rng.h
@@ -19,13 +19,13 @@ namespace Botan {
class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator
{
public:
- void randomize(byte[], size_t);
- bool is_seeded() const;
- void clear();
- std::string name() const;
+ void randomize(byte[], size_t) override;
+ bool is_seeded() const override;
+ void clear() override;
+ std::string name() const override;
- void reseed(size_t poll_bits);
- void add_entropy(const byte[], size_t);
+ void reseed(size_t poll_bits) override;
+ void add_entropy(const byte[], size_t) override;
/**
* @param cipher the block cipher to use in this PRNG
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index 7e4e2b461..df6e1c9c0 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -18,26 +18,26 @@ namespace Botan {
class BOTAN_DLL ChaCha : public StreamCipher
{
public:
- void cipher(const byte in[], byte out[], size_t length);
+ void cipher(const byte in[], byte out[], size_t length) override;
- void set_iv(const byte iv[], size_t iv_len);
+ void set_iv(const byte iv[], size_t iv_len) override;
- bool valid_iv_length(size_t iv_len) const
+ bool valid_iv_length(size_t iv_len) const override
{ return (iv_len == 8 || iv_len == 12); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(16, 32, 16);
}
- void clear();
- std::string name() const { return "ChaCha"; }
+ void clear() override;
+ std::string name() const override { return "ChaCha"; }
- StreamCipher* clone() const { return new ChaCha; }
+ StreamCipher* clone() const override { return new ChaCha; }
protected:
virtual void chacha(byte output[64], const u32bit input[16]);
private:
- void key_schedule(const byte key[], size_t key_len);
+ void key_schedule(const byte key[], size_t key_len) override;
secure_vector<u32bit> m_state;
secure_vector<byte> m_buffer;
diff --git a/src/lib/stream/ctr/ctr.h b/src/lib/stream/ctr/ctr.h
index 1515b0e82..f59f06d5f 100644
--- a/src/lib/stream/ctr/ctr.h
+++ b/src/lib/stream/ctr/ctr.h
@@ -19,24 +19,24 @@ namespace Botan {
class BOTAN_DLL CTR_BE : public StreamCipher
{
public:
- void cipher(const byte in[], byte out[], size_t length);
+ void cipher(const byte in[], byte out[], size_t length) override;
- void set_iv(const byte iv[], size_t iv_len);
+ void set_iv(const byte iv[], size_t iv_len) override;
- bool valid_iv_length(size_t iv_len) const
+ bool valid_iv_length(size_t iv_len) const override
{ return (iv_len <= m_cipher->block_size()); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
- std::string name() const;
+ std::string name() const override;
- CTR_BE* clone() const
+ CTR_BE* clone() const override
{ return new CTR_BE(m_cipher->clone()); }
- void clear();
+ void clear() override;
static CTR_BE* make(const Spec& spec);
@@ -45,7 +45,7 @@ class BOTAN_DLL CTR_BE : public StreamCipher
*/
CTR_BE(BlockCipher* cipher);
private:
- void key_schedule(const byte key[], size_t key_len);
+ void key_schedule(const byte key[], size_t key_len) override;
void increment_counter();
std::unique_ptr<BlockCipher> m_cipher;
diff --git a/src/lib/stream/ofb/ofb.h b/src/lib/stream/ofb/ofb.h
index 09e11644a..32dc199bc 100644
--- a/src/lib/stream/ofb/ofb.h
+++ b/src/lib/stream/ofb/ofb.h
@@ -19,24 +19,24 @@ namespace Botan {
class BOTAN_DLL OFB : public StreamCipher
{
public:
- void cipher(const byte in[], byte out[], size_t length);
+ void cipher(const byte in[], byte out[], size_t length) override;
- void set_iv(const byte iv[], size_t iv_len);
+ void set_iv(const byte iv[], size_t iv_len) override;
- bool valid_iv_length(size_t iv_len) const
+ bool valid_iv_length(size_t iv_len) const override
{ return (iv_len <= m_cipher->block_size()); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return m_cipher->key_spec();
}
- std::string name() const;
+ std::string name() const override;
- OFB* clone() const
+ OFB* clone() const override
{ return new OFB(m_cipher->clone()); }
- void clear();
+ void clear() override;
static OFB* make(const Spec& spec);
@@ -45,7 +45,7 @@ class BOTAN_DLL OFB : public StreamCipher
*/
OFB(BlockCipher* cipher);
private:
- void key_schedule(const byte key[], size_t key_len);
+ void key_schedule(const byte key[], size_t key_len) override;
std::unique_ptr<BlockCipher> m_cipher;
secure_vector<byte> m_buffer;
diff --git a/src/lib/stream/rc4/rc4.h b/src/lib/stream/rc4/rc4.h
index b2006fec5..60c9450b4 100644
--- a/src/lib/stream/rc4/rc4.h
+++ b/src/lib/stream/rc4/rc4.h
@@ -19,14 +19,14 @@ namespace Botan {
class BOTAN_DLL RC4 : public StreamCipher
{
public:
- void cipher(const byte in[], byte out[], size_t length);
+ void cipher(const byte in[], byte out[], size_t length) override;
- void clear();
- std::string name() const;
+ void clear() override;
+ std::string name() const override;
- StreamCipher* clone() const { return new RC4(SKIP); }
+ StreamCipher* clone() const override { return new RC4(SKIP); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(1, 256);
}
@@ -40,7 +40,7 @@ class BOTAN_DLL RC4 : public StreamCipher
~RC4() { clear(); }
private:
- void key_schedule(const byte[], size_t);
+ void key_schedule(const byte[], size_t) override;
void generate();
const size_t SKIP;
diff --git a/src/lib/stream/salsa20/salsa20.h b/src/lib/stream/salsa20/salsa20.h
index a2b3790ce..a5e7a1f14 100644
--- a/src/lib/stream/salsa20/salsa20.h
+++ b/src/lib/stream/salsa20/salsa20.h
@@ -18,23 +18,23 @@ namespace Botan {
class BOTAN_DLL Salsa20 : public StreamCipher
{
public:
- void cipher(const byte in[], byte out[], size_t length);
+ void cipher(const byte in[], byte out[], size_t length) override;
- void set_iv(const byte iv[], size_t iv_len);
+ void set_iv(const byte iv[], size_t iv_len) override;
- bool valid_iv_length(size_t iv_len) const
+ bool valid_iv_length(size_t iv_len) const override
{ return (iv_len == 8 || iv_len == 24); }
- Key_Length_Specification key_spec() const
+ Key_Length_Specification key_spec() const override
{
return Key_Length_Specification(16, 32, 16);
}
- void clear();
- std::string name() const;
- StreamCipher* clone() const { return new Salsa20; }
+ void clear() override;
+ std::string name() const override;
+ StreamCipher* clone() const override { return new Salsa20; }
private:
- void key_schedule(const byte key[], size_t key_len);
+ void key_schedule(const byte key[], size_t key_len) override;
secure_vector<u32bit> m_state;
secure_vector<byte> m_buffer;
diff --git a/src/lib/tls/msg_server_hello.cpp b/src/lib/tls/msg_server_hello.cpp
index 0b352f080..ba7eee3d9 100644
--- a/src/lib/tls/msg_server_hello.cpp
+++ b/src/lib/tls/msg_server_hello.cpp
@@ -1,4 +1,4 @@
-;/*
+/*
* TLS Server Hello and Server Hello Done
* (C) 2004-2011,2015 Jack Lloyd
*
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index 339e74e71..9306092ce 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -216,7 +216,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
std::vector<Handshake_Extension_Type> diff;
std::set_difference(server_extn.begin(), server_extn.end(),
- client_extn.begin(), server_extn.end(),
+ client_extn.begin(), client_extn.end(),
std::back_inserter(diff));
if(!diff.empty())
diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h
index 83e819509..7527b5cdd 100644
--- a/src/lib/tls/tls_extensions.h
+++ b/src/lib/tls/tls_extensions.h
@@ -75,7 +75,7 @@ class Server_Name_Indicator : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_SERVER_NAME_INDICATION; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
Server_Name_Indicator(const std::string& host_name) :
sni_host_name(host_name) {}
@@ -85,9 +85,9 @@ class Server_Name_Indicator : public Extension
std::string host_name() const { return sni_host_name; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return sni_host_name == ""; }
+ bool empty() const override { return sni_host_name == ""; }
private:
std::string sni_host_name;
};
@@ -101,7 +101,7 @@ class SRP_Identifier : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_SRP_IDENTIFIER; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
SRP_Identifier(const std::string& identifier) :
srp_identifier(identifier) {}
@@ -111,9 +111,9 @@ class SRP_Identifier : public Extension
std::string identifier() const { return srp_identifier; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return srp_identifier == ""; }
+ bool empty() const override { return srp_identifier == ""; }
private:
std::string srp_identifier;
};
@@ -127,7 +127,7 @@ class Renegotiation_Extension : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_SAFE_RENEGOTIATION; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
Renegotiation_Extension() {}
@@ -140,9 +140,9 @@ class Renegotiation_Extension : public Extension
const std::vector<byte>& renegotiation_info() const
{ return reneg_data; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return false; } // always send this
+ bool empty() const override { return false; } // always send this
private:
std::vector<byte> reneg_data;
};
@@ -156,13 +156,13 @@ class Maximum_Fragment_Length : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_MAX_FRAGMENT_LENGTH; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
- bool empty() const { return false; }
+ bool empty() const override { return false; }
size_t fragment_size() const { return m_max_fragment; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
/**
* @param max_fragment specifies what maximum fragment size to
@@ -187,7 +187,7 @@ class Application_Layer_Protocol_Notification : public Extension
public:
static Handshake_Extension_Type static_type() { return TLSEXT_ALPN; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
const std::vector<std::string>& protocols() const { return m_protocols; }
@@ -208,9 +208,9 @@ class Application_Layer_Protocol_Notification : public Extension
Application_Layer_Protocol_Notification(TLS_Data_Reader& reader,
u16bit extension_size);
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return m_protocols.empty(); }
+ bool empty() const override { return m_protocols.empty(); }
private:
std::vector<std::string> m_protocols;
};
@@ -224,7 +224,7 @@ class Session_Ticket : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_SESSION_TICKET; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
/**
* @return contents of the session ticket
@@ -247,9 +247,9 @@ class Session_Ticket : public Extension
*/
Session_Ticket(TLS_Data_Reader& reader, u16bit extension_size);
- std::vector<byte> serialize() const { return m_ticket; }
+ std::vector<byte> serialize() const override { return m_ticket; }
- bool empty() const { return false; }
+ bool empty() const override { return false; }
private:
std::vector<byte> m_ticket;
};
@@ -263,14 +263,14 @@ class Supported_Elliptic_Curves : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_USABLE_ELLIPTIC_CURVES; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
static std::string curve_id_to_name(u16bit id);
static u16bit name_to_curve_id(const std::string& name);
const std::vector<std::string>& curves() const { return m_curves; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
Supported_Elliptic_Curves(const std::vector<std::string>& curves) :
m_curves(curves) {}
@@ -278,7 +278,7 @@ class Supported_Elliptic_Curves : public Extension
Supported_Elliptic_Curves(TLS_Data_Reader& reader,
u16bit extension_size);
- bool empty() const { return m_curves.empty(); }
+ bool empty() const override { return m_curves.empty(); }
private:
std::vector<std::string> m_curves;
};
@@ -292,7 +292,7 @@ class Signature_Algorithms : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_SIGNATURE_ALGORITHMS; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
static std::string hash_algo_name(byte code);
static byte hash_algo_code(const std::string& name);
@@ -306,9 +306,9 @@ class Signature_Algorithms : public Extension
return m_supported_algos;
}
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return false; }
+ bool empty() const override { return false; }
Signature_Algorithms(const std::vector<std::string>& hashes,
const std::vector<std::string>& sig_algos);
@@ -331,13 +331,13 @@ class Heartbeat_Support_Indicator : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_HEARTBEAT_SUPPORT; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
bool peer_allowed_to_send() const { return m_peer_allowed_to_send; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return false; }
+ bool empty() const override { return false; }
Heartbeat_Support_Indicator(bool peer_allowed_to_send) :
m_peer_allowed_to_send(peer_allowed_to_send) {}
@@ -357,13 +357,13 @@ class SRTP_Protection_Profiles : public Extension
static Handshake_Extension_Type static_type()
{ return TLSEXT_USE_SRTP; }
- Handshake_Extension_Type type() const { return static_type(); }
+ Handshake_Extension_Type type() const override { return static_type(); }
const std::vector<u16bit>& profiles() const { return m_pp; }
- std::vector<byte> serialize() const;
+ std::vector<byte> serialize() const override;
- bool empty() const { return m_pp.empty(); }
+ bool empty() const override { return m_pp.empty(); }
SRTP_Protection_Profiles(const std::vector<u16bit>& pp) : m_pp(pp) {}
diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h
index befbdb932..7a556a61c 100644
--- a/src/lib/tls/tls_messages.h
+++ b/src/lib/tls/tls_messages.h
@@ -15,7 +15,6 @@
#include <botan/tls_policy.h>
#include <botan/tls_ciphersuite.h>
#include <botan/bigint.h>
-#include <botan/pkcs8.h>
#include <botan/x509cert.h>
#include <vector>
#include <string>
diff --git a/src/lib/utils/asm_x86_32/asm_x86_32.h b/src/lib/utils/asm_x86_32/asm_x86_32.h
deleted file mode 100644
index 7149b8db5..000000000
--- a/src/lib/utils/asm_x86_32/asm_x86_32.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-* Assembly Macros for 32-bit x86
-* (C) 1999-2008 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ASM_MACROS_X86_32_H__
-#define BOTAN_ASM_MACROS_X86_32_H__
-
-/*
-* General/Global Macros
-*/
-#define ALIGN .p2align 4,,15
-
-#define START_LISTING(FILENAME) \
- .file #FILENAME; \
- .text; \
- ALIGN;
-
-#if defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
-
-/*
-* Function Definitions
-*/
-#define START_FUNCTION(func_name) \
- ALIGN; \
- .global func_name; \
- .type func_name,@function; \
-func_name:
-
-#define END_FUNCTION(func_name) \
- ret
-
-/*
-* Loop Control
-*/
-#define START_LOOP(LABEL) \
- ALIGN; \
- LABEL##_LOOP:
-
-#define LOOP_UNTIL_EQ(REG, NUM, LABEL) \
- cmpl IMM(NUM), REG; \
- jne LABEL##_LOOP
-
-#define LOOP_UNTIL_LT(REG, NUM, LABEL) \
- cmpl IMM(NUM), REG; \
- jge LABEL##_LOOP
-
-/*
- Conditional Jumps
-*/
-#define JUMP_IF_ZERO(REG, LABEL) \
- cmpl IMM(0), REG; \
- jz LABEL
-
-#define JUMP_IF_LT(REG, NUM, LABEL) \
- cmpl IMM(NUM), REG; \
- jl LABEL
-
-/*
-* Register Names
-*/
-#define EAX %eax
-#define EBX %ebx
-#define ECX %ecx
-#define EDX %edx
-#define EBP %ebp
-#define EDI %edi
-#define ESI %esi
-#define ESP %esp
-
-/*
-* Memory Access Operations
-*/
-#define ARRAY1(REG, NUM) (NUM)(REG)
-#define ARRAY4(REG, NUM) 4*(NUM)(REG)
-#define ARRAY4_INDIRECT(BASE, OFFSET, NUM) 4*(NUM)(BASE,OFFSET,4)
-#define ARG(NUM) 4*(PUSHED) + ARRAY4(ESP, NUM)
-
-#define ASSIGN(TO, FROM) movl FROM, TO
-#define ASSIGN_BYTE(TO, FROM) movzbl FROM, TO
-
-#define PUSH(REG) pushl REG
-#define POP(REG) popl REG
-
-#define SPILL_REGS() \
- PUSH(EBP) ; \
- PUSH(EDI) ; \
- PUSH(ESI) ; \
- PUSH(EBX)
-
-#define RESTORE_REGS() \
- POP(EBX) ; \
- POP(ESI) ; \
- POP(EDI) ; \
- POP(EBP)
-
-/*
-* ALU Operations
-*/
-#define IMM(VAL) $VAL
-
-#define ADD(TO, FROM) addl FROM, TO
-#define ADD_IMM(TO, NUM) ADD(TO, IMM(NUM))
-#define ADD_W_CARRY(TO1, TO2, FROM) addl FROM, TO1; adcl IMM(0), TO2;
-#define SUB_IMM(TO, NUM) subl IMM(NUM), TO
-#define ADD2_IMM(TO, FROM, NUM) leal NUM(FROM), TO
-#define ADD3_IMM(TO, FROM, NUM) leal NUM(TO,FROM,1), TO
-#define MUL(REG) mull REG
-
-#define SHL_IMM(REG, SHIFT) shll IMM(SHIFT), REG
-#define SHR_IMM(REG, SHIFT) shrl IMM(SHIFT), REG
-#define SHL2_3(TO, FROM) leal 0(,FROM,8), TO
-
-#define XOR(TO, FROM) xorl FROM, TO
-#define AND(TO, FROM) andl FROM, TO
-#define OR(TO, FROM) orl FROM, TO
-#define NOT(REG) notl REG
-#define ZEROIZE(REG) XOR(REG, REG)
-
-#define ROTL_IMM(REG, NUM) roll IMM(NUM), REG
-#define ROTR_IMM(REG, NUM) rorl IMM(NUM), REG
-#define BSWAP(REG) bswapl REG
-
-#endif
diff --git a/src/lib/utils/asm_x86_32/info.txt b/src/lib/utils/asm_x86_32/info.txt
deleted file mode 100644
index 6da494629..000000000
--- a/src/lib/utils/asm_x86_32/info.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-load_on dep
-
-<header:internal>
-asm_x86_32.h
-</header:internal>
-
-<arch>
-x86_32
-</arch>
-
-# ELF systems
-<os>
-linux
-freebsd
-dragonfly
-netbsd
-openbsd
-solaris
-</os>
-
-<cc>
-gcc
-clang
-icc
-</cc>
diff --git a/src/lib/utils/asm_x86_64/asm_x86_64.h b/src/lib/utils/asm_x86_64/asm_x86_64.h
deleted file mode 100644
index eaf4388de..000000000
--- a/src/lib/utils/asm_x86_64/asm_x86_64.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-* Assembly Macros for 64-bit x86
-* (C) 1999-2008 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ASM_MACROS_X86_64_H__
-#define BOTAN_ASM_MACROS_X86_64_H__
-
-/*
-* General/Global Macros
-*/
-#define ALIGN .p2align 4,,15
-
-#define START_LISTING(FILENAME) \
- .file #FILENAME; \
- .text; \
- ALIGN;
-
-#if defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
-
-/*
-* Function Definitions
-*/
-#define START_FUNCTION(func_name) \
- ALIGN; \
- .global func_name; \
- .type func_name,@function; \
-func_name:
-
-#define END_FUNCTION(func_name) \
- ret
-
-/*
-* Conditional Jumps
-*/
-#define JUMP_IF_ZERO(REG, LABEL) \
- cmp IMM(0), REG; \
- jz LABEL
-
-#define JUMP_IF_LT(REG, NUM, LABEL) \
- cmp IMM(NUM), REG; \
- jl LABEL
-
-/*
-* Register Names
-*/
-#define R0 %rax
-#define R1 %rbx
-#define R2 %rcx
-#define R2_32 %ecx
-#define R3 %rdx
-#define R3_32 %edx
-#define R4 %rsp
-#define R5 %rbp
-#define R6 %rsi
-#define R6_32 %esi
-#define R7 %rdi
-#define R8 %r8
-#define R9 %r9
-#define R9_32 %r9d
-#define R10 %r10
-#define R11 %r11
-#define R12 %r12
-#define R13 %r13
-#define R14 %r14
-#define R15 %r15
-#define R16 %r16
-
-#define ARG_1 R7
-#define ARG_2 R6
-#define ARG_2_32 R6_32
-#define ARG_3 R3
-#define ARG_3_32 R3_32
-#define ARG_4 R2
-#define ARG_4_32 R2_32
-#define ARG_5 R8
-#define ARG_6 R9
-#define ARG_6_32 R9_32
-
-#define TEMP_1 R10
-#define TEMP_2 R11
-#define TEMP_3 ARG_6
-#define TEMP_4 ARG_5
-#define TEMP_5 ARG_4
-#define TEMP_5_32 ARG_4_32
-#define TEMP_6 ARG_3
-#define TEMP_7 ARG_2
-#define TEMP_8 ARG_1
-#define TEMP_9 R0
-
-/*
-* Memory Access Operations
-*/
-#define ARRAY8(REG, NUM) 8*(NUM)(REG)
-#define ARRAY4(REG, NUM) 4*(NUM)(REG)
-
-#define ASSIGN(TO, FROM) mov FROM, TO
-
-/*
-* ALU Operations
-*/
-#define IMM(VAL) $VAL
-
-#define ADD(TO, FROM) add FROM, TO
-#define ADD_LAST_CARRY(REG) adc IMM(0), REG
-#define ADD_IMM(TO, NUM) ADD(TO, IMM(NUM))
-#define ADD_W_CARRY(TO1, TO2, FROM) add FROM, TO1; adc IMM(0), TO2;
-#define SUB_IMM(TO, NUM) sub IMM(NUM), TO
-#define MUL(REG) mul REG
-
-#define XOR(TO, FROM) xor FROM, TO
-#define AND(TO, FROM) and FROM, TO
-#define OR(TO, FROM) or FROM, TO
-#define NOT(REG) not REG
-#define ZEROIZE(REG) XOR(REG, REG)
-
-#define RETURN_VALUE_IS(V) ASSIGN(%rax, V)
-
-#define ROTL_IMM(REG, NUM) rol IMM(NUM), REG
-#define ROTR_IMM(REG, NUM) ror IMM(NUM), REG
-#define ADD3_IMM(TO, FROM, NUM) lea NUM(TO,FROM,1), TO
-
-#endif
diff --git a/src/lib/utils/asm_x86_64/info.txt b/src/lib/utils/asm_x86_64/info.txt
deleted file mode 100644
index 0db499d46..000000000
--- a/src/lib/utils/asm_x86_64/info.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-load_on dep
-
-<header:internal>
-asm_x86_64.h
-</header:internal>
-
-<arch>
-x86_64
-</arch>
-
-<cc>
-clang
-gcc
-icc
-</cc>
-
-# ELF systems
-<os>
-linux
-netbsd
-openbsd
-solaris
-</os>
diff --git a/src/lib/utils/calendar.cpp b/src/lib/utils/calendar.cpp
index 3ce5170fc..f071a7328 100644
--- a/src/lib/utils/calendar.cpp
+++ b/src/lib/utils/calendar.cpp
@@ -1,6 +1,7 @@
/*
* Calendar Functions
* (C) 1999-2010 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -8,6 +9,13 @@
#include <botan/calendar.h>
#include <botan/exceptn.h>
#include <ctime>
+#include <sstream>
+#include <iomanip>
+#include <mutex>
+
+#if defined(BOTAN_HAS_BOOST_DATETIME)
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#endif
namespace Botan {
@@ -23,7 +31,7 @@ std::tm do_gmtime(std::time_t time_val)
gmtime_r(&time_val, &tm); // Unix/SUSv2
#else
std::tm* tm_p = std::gmtime(&time_val);
- if (tm_p == 0)
+ if (tm_p == nullptr)
throw Encoding_Error("time_t_to_tm could not convert");
tm = *tm_p;
#endif
@@ -31,11 +39,137 @@ std::tm do_gmtime(std::time_t time_val)
return tm;
}
+#if !defined(BOTAN_TARGET_OS_HAS_TIMEGM) && !defined(BOTAN_TARGET_OS_HAS_MKGMTIME)
+
+#if defined(BOTAN_HAS_BOOST_DATETIME)
+
+std::time_t boost_timegm(std::tm *tm)
+ {
+ const int sec = tm->tm_sec;
+ const int min = tm->tm_min;
+ const int hour = tm->tm_hour;
+ const int day = tm->tm_mday;
+ const int mon = tm->tm_mon + 1;
+ const int year = tm->tm_year + 1900;
+
+ std::time_t out;
+
+ {
+ using namespace boost::posix_time;
+ using namespace boost::gregorian;
+ const auto epoch = ptime(date(1970, 01, 01));
+ const auto time = ptime(date(year, mon, day),
+ hours(hour) + minutes(min) + seconds(sec));
+ const time_duration diff(time - epoch);
+ out = diff.ticks() / diff.ticks_per_second();
+ }
+
+ return out;
+ }
+
+#else
+
+#pragma message "Caution! A fallback version of timegm() is used which is not thread-safe"
+
+std::mutex ENV_TZ;
+
+std::time_t fallback_timegm(std::tm *tm)
+ {
+ std::time_t out;
+ std::string tz_backup;
+
+ ENV_TZ.lock();
+
+ // Store current value of env variable TZ
+ const char* tz_env_pointer = ::getenv("TZ");
+ if (tz_env_pointer != nullptr)
+ tz_backup = std::string(tz_env_pointer);
+
+ // Clear value of TZ
+ ::setenv("TZ", "", 1);
+ ::tzset();
+
+ out = ::mktime(tm);
+
+ // Restore TZ
+ if (!tz_backup.empty())
+ {
+ // setenv makes a copy of the second argument
+ ::setenv("TZ", tz_backup.data(), 1);
+ }
+ else
+ {
+ ::unsetenv("TZ");
+ }
+ ::tzset();
+
+ ENV_TZ.unlock();
+
+ return out;
}
+#endif // BOTAN_HAS_BOOST_DATETIME
+
+#endif
+
+}
+
+std::chrono::system_clock::time_point calendar_point::to_std_timepoint()
+ {
+ if (year < 1970)
+ throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years before 1990.");
+
+ // 32 bit time_t ends at January 19, 2038
+ // https://msdn.microsoft.com/en-us/library/2093ets1.aspx
+ // For consistency reasons, throw after 2037 as long as
+ // no other implementation is available.
+ if (year > 2037)
+ throw Invalid_Argument("calendar_point::to_std_timepoint() does not support years after 2037.");
+
+ // std::tm: struct without any timezone information
+ std::tm tm;
+ tm.tm_isdst = -1; // i.e. no DST information available
+ tm.tm_sec = seconds;
+ tm.tm_min = minutes;
+ tm.tm_hour = hour;
+ tm.tm_mday = day;
+ tm.tm_mon = month - 1;
+ tm.tm_year = year - 1900;
+
+ // Define a function alias `botan_timegm`
+ #if defined(BOTAN_TARGET_OS_HAS_TIMEGM)
+ std::time_t (&botan_timegm)(std::tm *tm) = timegm;
+ #elif defined(BOTAN_TARGET_OS_HAS_MKGMTIME)
+ // http://stackoverflow.com/questions/16647819/timegm-cross-platform
+ std::time_t (&botan_timegm)(std::tm *tm) = _mkgmtime;
+ #elif defined(BOTAN_HAS_BOOST_DATETIME)
+ std::time_t (&botan_timegm)(std::tm *tm) = boost_timegm;
+ #else
+ std::time_t (&botan_timegm)(std::tm *tm) = fallback_timegm;
+ #endif
+
+ // Convert std::tm to std::time_t
+ std::time_t tt = botan_timegm(&tm);
+ if (tt == -1)
+ throw Invalid_Argument("calendar_point couldn't be converted: " + to_string());
+
+ return std::chrono::system_clock::from_time_t(tt);
+ }
+
+std::string calendar_point::to_string() const
+ {
+ // desired format: <YYYY>-<MM>-<dd>T<HH>:<mm>:<ss>
+ std::stringstream output;
+ {
+ using namespace std;
+ output << setfill('0')
+ << setw(4) << year << "-" << setw(2) << month << "-" << setw(2) << day
+ << "T"
+ << setw(2) << hour << ":" << setw(2) << minutes << ":" << setw(2) << seconds;
+ }
+ return output.str();
+ }
+
-/*
-* Convert a time_point to a calendar_point
-*/
calendar_point calendar_value(
const std::chrono::system_clock::time_point& time_point)
{
diff --git a/src/lib/utils/calendar.h b/src/lib/utils/calendar.h
index 4efff0edc..0c87e62dd 100644
--- a/src/lib/utils/calendar.h
+++ b/src/lib/utils/calendar.h
@@ -1,6 +1,7 @@
/*
* Calendar Functions
* (C) 1999-2009 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -10,6 +11,7 @@
#include <botan/types.h>
#include <chrono>
+#include <string>
namespace Botan {
@@ -22,21 +24,21 @@ struct BOTAN_DLL calendar_point
u32bit year;
/** The month, 1 through 12 for Jan to Dec */
- byte month;
+ u32bit month;
/** The day of the month, 1 through 31 (or 28 or 30 based on month */
- byte day;
+ u32bit day;
/** Hour in 24-hour form, 0 to 23 */
- byte hour;
+ u32bit hour;
/** Minutes in the hour, 0 to 60 */
- byte minutes;
+ u32bit minutes;
/** Seconds in the minute, 0 to 60, but might be slightly
larger to deal with leap seconds on some systems
*/
- byte seconds;
+ u32bit seconds;
/**
* Initialize a calendar_point
@@ -47,11 +49,23 @@ struct BOTAN_DLL calendar_point
* @param min the minute
* @param sec the second
*/
- calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) :
+ calendar_point(u32bit y, u32bit mon, u32bit d, u32bit h, u32bit min, u32bit sec) :
year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {}
+
+ /**
+ * Returns an STL timepoint object
+ */
+ std::chrono::system_clock::time_point to_std_timepoint();
+
+ /**
+ * Returns a human readable string of the struct's components.
+ * Formatting might change over time. Currently it is RFC339 'iso-date-time'.
+ */
+ std::string to_string() const;
};
-/*
+/**
+* Convert a time_point to a calendar_point
* @param time_point a time point from the system clock
* @return calendar_point object representing this time point
*/
diff --git a/src/lib/utils/cpuid.cpp b/src/lib/utils/cpuid.cpp
index cdb986396..817bf4f52 100644
--- a/src/lib/utils/cpuid.cpp
+++ b/src/lib/utils/cpuid.cpp
@@ -51,7 +51,7 @@
asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
: "0" (type), "2" (level))
-#elif defined(BOTAN_BUILD_COMPILER_IS_GCC)
+#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
#include <cpuid.h>
diff --git a/src/lib/utils/dyn_load/info.txt b/src/lib/utils/dyn_load/info.txt
index 3dc3c5d03..0cc4e4e73 100644
--- a/src/lib/utils/dyn_load/info.txt
+++ b/src/lib/utils/dyn_load/info.txt
@@ -3,6 +3,7 @@ define DYNAMIC_LOADER 20131128
load_on dep
<os>
+android
freebsd
linux
netbsd
@@ -13,6 +14,7 @@ windows
</os>
<libs>
+android -> dl
linux -> dl
solaris -> dl
</libs>
diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h
index 7a10319c5..eef1b4d43 100644
--- a/src/lib/utils/exceptn.h
+++ b/src/lib/utils/exceptn.h
@@ -20,6 +20,17 @@ typedef std::runtime_error Exception;
typedef std::invalid_argument Invalid_Argument;
/**
+* Unsupported_Argument Exception
+*
+* An argument that is invalid because it is not supported by Botan.
+* It might or might not be valid in another context like a standard.
+*/
+struct BOTAN_DLL Unsupported_Argument : public Invalid_Argument
+ {
+ Unsupported_Argument(const std::string& msg) : Invalid_Argument(msg) {}
+ };
+
+/**
* Invalid_State Exception
*/
struct BOTAN_DLL Invalid_State : public Exception
@@ -102,6 +113,16 @@ struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error
};
/**
+* No_Provider_Found Exception
+*/
+struct BOTAN_DLL No_Provider_Found : public Exception
+ {
+ No_Provider_Found(const std::string& name) :
+ Exception("Could not find any provider for algorithm named \"" + name + "\"")
+ {}
+ };
+
+/**
* Invalid_Algorithm_Name Exception
*/
struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument
@@ -158,6 +179,14 @@ struct BOTAN_DLL Stream_IO_Error : public Exception
};
/**
+* No_Filesystem_Access Exception
+*/
+struct BOTAN_DLL No_Filesystem_Access : public Exception
+ {
+ No_Filesystem_Access() : Exception("No filesystem access enabled.") {}
+ };
+
+/**
* Self Test Failure Exception
*/
struct BOTAN_DLL Self_Test_Failure : public Internal_Error
@@ -172,7 +201,7 @@ struct BOTAN_DLL Self_Test_Failure : public Internal_Error
*/
struct BOTAN_DLL Memory_Exhaustion : public std::bad_alloc
{
- const char* what() const BOTAN_NOEXCEPT
+ const char* what() const BOTAN_NOEXCEPT override
{ return "Ran out of memory, allocation failed"; }
};
diff --git a/src/lib/utils/filesystem.cpp b/src/lib/utils/filesystem.cpp
new file mode 100644
index 000000000..950d4d4e2
--- /dev/null
+++ b/src/lib/utils/filesystem.cpp
@@ -0,0 +1,129 @@
+/*
+* (C) 2015 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/exceptn.h>
+#include <botan/internal/filesystem.h>
+#include <algorithm>
+
+#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+ #include <filesystem>
+#elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
+ #include <boost/filesystem.hpp>
+#elif defined(BOTAN_TARGET_OS_HAS_READDIR)
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <dirent.h>
+ #include <deque>
+ #include <memory>
+ #include <functional>
+#endif
+
+namespace Botan {
+
+namespace {
+
+#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+std::vector<std::string> impl_stl_filesystem(const std::string& dir)
+ {
+ using namespace std::tr2::sys;
+
+ std::vector<std::string> out;
+
+ path p(dir);
+
+ if (is_directory(p))
+ {
+ for (recursive_directory_iterator itr(p), end; itr != end; ++itr)
+ {
+ if (is_regular_file(itr->path()))
+ {
+ out.push_back(itr->path().string());
+ }
+ }
+ }
+
+ return out;
+ }
+#elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
+std::vector<std::string> impl_boost_filesystem(const std::string& dir_path)
+{
+ namespace fs = boost::filesystem;
+
+ std::vector<std::string> out;
+
+ for(fs::recursive_directory_iterator dir(dir_path), end; dir != end; ++dir)
+ {
+ if(fs::is_regular_file(dir->path()))
+ {
+ out.push_back(dir->path().string());
+ }
+ }
+
+ return out;
+}
+#elif defined(BOTAN_TARGET_OS_HAS_READDIR)
+std::vector<std::string> impl_readdir(const std::string& dir_path)
+ {
+ std::vector<std::string> out;
+ std::deque<std::string> dir_list;
+ dir_list.push_back(dir_path);
+
+ while(!dir_list.empty())
+ {
+ const std::string cur_path = dir_list[0];
+ dir_list.pop_front();
+
+ std::unique_ptr<DIR, std::function<int (DIR*)>> dir(::opendir(cur_path.c_str()), ::closedir);
+
+ if(dir)
+ {
+ while(struct dirent* dirent = ::readdir(dir.get()))
+ {
+ const std::string filename = dirent->d_name;
+ if(filename == "." || filename == "..")
+ continue;
+ const std::string full_path = cur_path + '/' + filename;
+
+ struct stat stat_buf;
+
+ if(::lstat(full_path.c_str(), &stat_buf) == -1)
+ continue;
+
+ if(S_ISDIR(stat_buf.st_mode))
+ dir_list.push_back(full_path);
+ else if(S_ISREG(stat_buf.st_mode))
+ out.push_back(full_path);
+ }
+ }
+ }
+
+ return out;
+ }
+#endif
+
+}
+
+std::vector<std::string> get_files_recursive(const std::string& dir)
+ {
+ std::vector<std::string> files;
+
+#if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+ files = impl_stl_filesystem(dir);
+#elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
+ files = impl_boost_filesystem(dir);
+#elif defined(BOTAN_TARGET_OS_HAS_READDIR)
+ files = impl_readdir(dir);
+#else
+ throw No_Filesystem_Access();
+#endif
+
+ std::sort(files.begin(), files.end());
+
+ return files;
+ }
+
+}
diff --git a/src/lib/utils/fs.h b/src/lib/utils/filesystem.h
index 25ec5ecd1..419f94b99 100644
--- a/src/lib/utils/fs.h
+++ b/src/lib/utils/filesystem.h
@@ -1,11 +1,12 @@
/*
* (C) 2015 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
-#ifndef BOTAN_UTIL_FS_H__
-#define BOTAN_UTIL_FS_H__
+#ifndef BOTAN_UTIL_FILESYSTEM_H__
+#define BOTAN_UTIL_FILESYSTEM_H__
#include <botan/types.h>
#include <vector>
@@ -13,8 +14,7 @@
namespace Botan {
-BOTAN_DLL std::vector<std::string>
-list_all_readable_files_in_or_under(const std::string& dir);
+BOTAN_DLL std::vector<std::string> get_files_recursive(const std::string& dir);
}
diff --git a/src/lib/utils/fs.cpp b/src/lib/utils/fs.cpp
deleted file mode 100644
index b1ada17db..000000000
--- a/src/lib/utils/fs.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-* (C) 2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/fs.h>
-#include <algorithm>
-#include <deque>
-#include <functional>
-#include <memory>
-
-#if defined(BOTAN_HAS_BOOST_FILESYSTEM)
- #include <boost/filesystem.hpp>
-
-#elif defined(BOTAN_TARGET_OS_HAS_READDIR)
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dirent.h>
-#endif
-
-namespace Botan {
-
-std::vector<std::string>
-list_all_readable_files_in_or_under(const std::string& dir_path)
- {
- std::vector<std::string> paths;
-
-#if defined(BOTAN_HAS_BOOST_FILESYSTEM)
- namespace fs = boost::filesystem;
-
- fs::recursive_directory_iterator end;
- for(fs::recursive_directory_iterator dir(dir_path); dir != end; ++dir)
- {
- if(fs::is_regular_file(dir->path()))
- paths.push_back(dir->path().string());
- }
-
-#elif defined(BOTAN_TARGET_OS_HAS_READDIR)
-
- std::deque<std::string> dir_list;
- dir_list.push_back(dir_path);
-
- while(!dir_list.empty())
- {
- const std::string cur_path = dir_list[0];
- dir_list.pop_front();
-
- std::unique_ptr<DIR, std::function<int (DIR*)>> dir(::opendir(cur_path.c_str()), ::closedir);
-
- if(dir)
- {
- while(struct dirent* dirent = ::readdir(dir.get()))
- {
- const std::string filename = dirent->d_name;
- if(filename == "." || filename == "..")
- continue;
- const std::string full_path = cur_path + '/' + filename;
-
- struct stat stat_buf;
-
- if(::lstat(full_path.c_str(), &stat_buf) == -1)
- continue;
-
- if(S_ISDIR(stat_buf.st_mode))
- dir_list.push_back(full_path);
- else if(S_ISREG(stat_buf.st_mode))
- paths.push_back(full_path);
- }
- }
- }
-#else
-#if defined(_MSC_VER)
- #pragma message ( "No filesystem access enabled" )
-#else
- #warning "No filesystem access enabled"
-#endif
-#endif
-
- std::sort(paths.begin(), paths.end());
-
- return paths;
- }
-
-}
-
diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt
index 90f45aa3f..b8c7b85d2 100644
--- a/src/lib/utils/info.txt
+++ b/src/lib/utils/info.txt
@@ -2,17 +2,6 @@ define UTIL_FUNCTIONS 20140123
load_on always
-<header:internal>
-bit_ops.h
-donna128.h
-prefetch.h
-rounding.h
-semaphore.h
-stl_util.h
-ta_utils.h
-xor_buf.h
-</header:internal>
-
<header:public>
assert.h
bswap.h
@@ -21,7 +10,6 @@ charset.h
cpuid.h
database.h
exceptn.h
-fs.h
get_byte.h
loadstor.h
mem_ops.h
@@ -31,3 +19,15 @@ rotate.h
types.h
version.h
</header:public>
+
+<header:internal>
+bit_ops.h
+donna128.h
+filesystem.h
+prefetch.h
+rounding.h
+semaphore.h
+stl_util.h
+ta_utils.h
+xor_buf.h
+</header:internal>
diff --git a/src/lib/utils/parsing.cpp b/src/lib/utils/parsing.cpp
index 36b168290..4feea8d60 100644
--- a/src/lib/utils/parsing.cpp
+++ b/src/lib/utils/parsing.cpp
@@ -1,6 +1,7 @@
/*
* Various string utils and parsing functions
* (C) 1999-2007,2013,2014 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -9,6 +10,7 @@
#include <botan/exceptn.h>
#include <botan/charset.h>
#include <botan/get_byte.h>
+#include <limits>
#include <set>
#include <stdexcept>
@@ -18,11 +20,32 @@ u32bit to_u32bit(const std::string& str)
{
try
{
- return std::stoul(str, nullptr);
+ // std::stoul is not strict enough. Ensure that str is digit only [0-9]*
+ for (const char chr : str)
+ {
+ if (chr < '0' || chr > '9')
+ {
+ auto chrAsString = std::string(1, chr);
+ throw Invalid_Argument("String contains non-digit char: " + chrAsString);
+ }
+ }
+
+ const auto integerValue = std::stoul(str);
+
+ // integerValue might be uint64
+ if (integerValue > std::numeric_limits<u32bit>::max())
+ {
+ throw Invalid_Argument("Integer value exceeds 32 bit range: " + std::to_string(integerValue));
+ }
+
+ return integerValue;
}
- catch(std::exception&)
+ catch(std::exception& e)
{
- throw std::runtime_error("Could not read '" + str + "' as decimal string");
+ auto message = std::string("Could not read '" + str + "' as decimal string");
+ auto exceptionMessage = std::string(e.what());
+ if (!exceptionMessage.empty()) message += ": " + exceptionMessage;
+ throw std::runtime_error(message);
}
}
diff --git a/src/lib/utils/rounding.h b/src/lib/utils/rounding.h
index 02edb1929..8ad324225 100644
--- a/src/lib/utils/rounding.h
+++ b/src/lib/utils/rounding.h
@@ -9,22 +9,21 @@
#define BOTAN_ROUNDING_H__
#include <botan/types.h>
+#include <botan/assert.h>
namespace Botan {
/**
* Round up
-* @param n an integer
+* @param n a non-negative integer
* @param align_to the alignment boundary
* @return n rounded up to a multiple of align_to
*/
-template<typename T>
-inline T round_up(T n, T align_to)
+inline size_t round_up(size_t n, size_t align_to)
{
- if(align_to == 0)
- return n;
+ BOTAN_ASSERT(align_to != 0, "align_to must not be 0");
- if(n % align_to || n == 0)
+ if(n % align_to)
n += align_to - (n % align_to);
return n;
}
diff --git a/src/lib/utils/stl_util.h b/src/lib/utils/stl_util.h
index 76cf77ef8..d74cbe713 100644
--- a/src/lib/utils/stl_util.h
+++ b/src/lib/utils/stl_util.h
@@ -1,6 +1,7 @@
/*
* STL Utility Functions
* (C) 1999-2007 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -11,6 +12,7 @@
#include <vector>
#include <string>
#include <map>
+#include <botan/secmem.h>
namespace Botan {
@@ -19,6 +21,11 @@ inline std::vector<byte> to_byte_vector(const std::string& s)
return std::vector<byte>(s.cbegin(), s.cend());
}
+inline std::string to_string(const secure_vector<byte> &bytes)
+ {
+ return std::string(bytes.cbegin(), bytes.cend());
+ }
+
/*
* Searching through a std::map
* @param mapping the map to search
diff --git a/src/lib/utils/types.h b/src/lib/utils/types.h
index d1de9e2a6..f5754983d 100644
--- a/src/lib/utils/types.h
+++ b/src/lib/utils/types.h
@@ -1,6 +1,7 @@
/*
* Low Level Types
* (C) 1999-2007 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -11,7 +12,7 @@
#include <botan/build.h>
#include <botan/assert.h>
#include <cstddef>
-#include <stdint.h>
+#include <cstdint>
#include <memory>
/**
@@ -19,21 +20,19 @@
*/
namespace Botan {
-using ::uint8_t;
-using ::uint16_t;
-using ::uint32_t;
-using ::uint64_t;
-using ::int32_t;
-using ::int64_t;
+using std::uint8_t;
+using std::uint16_t;
+using std::uint32_t;
+using std::uint64_t;
+using std::int32_t;
+using std::int64_t;
+using std::size_t;
-using ::size_t;
-
-typedef uint8_t byte;
-typedef uint16_t u16bit;
-typedef uint32_t u32bit;
-typedef uint64_t u64bit;
-
-typedef int32_t s32bit;
+using byte = std::uint8_t;
+using u16bit = std::uint16_t;
+using u32bit = std::uint32_t;
+using u64bit = std::uint64_t;
+using s32bit = std::int32_t;
/**
* A default buffer size; typically a memory page
@@ -42,11 +41,4 @@ static const size_t DEFAULT_BUFFERSIZE = BOTAN_DEFAULT_BUFFER_SIZE;
}
-namespace Botan_types {
-
-using Botan::byte;
-using Botan::u32bit;
-
-}
-
#endif
diff --git a/src/lib/vendor/boost/info.txt b/src/lib/vendor/boost/info.txt
index c335dcd74..8748c0bf1 100644
--- a/src/lib/vendor/boost/info.txt
+++ b/src/lib/vendor/boost/info.txt
@@ -1,5 +1,6 @@
define BOOST_FILESYSTEM 20131228
define BOOST_ASIO 20131228
+define BOOST_DATETIME 20150720
load_on vendor
diff --git a/src/lib/vendor/openssl/openssl_rsa.cpp b/src/lib/vendor/openssl/openssl_rsa.cpp
index 214f1667d..ef86bf91a 100644
--- a/src/lib/vendor/openssl/openssl_rsa.cpp
+++ b/src/lib/vendor/openssl/openssl_rsa.cpp
@@ -5,6 +5,10 @@
* Botan is released under the Simplified BSD License (see license.txt)
*/
+#include <botan/build.h>
+
+#if defined(BOTAN_HAS_RSA)
+
#include <botan/rsa.h>
#include <botan/internal/pk_utils.h>
#include <functional>
@@ -146,3 +150,5 @@ BOTAN_REGISTER_TYPE(PK_Ops::Decryption, OpenSSL_RSA_Decryption_Operation, "RSA",
}
}
+
+#endif // BOTAN_HAS_RSA
diff --git a/src/ocaml/build.sh b/src/ocaml/build.sh
index 8b1c0825d..a79f7d6ac 100755
--- a/src/ocaml/build.sh
+++ b/src/ocaml/build.sh
@@ -1,3 +1,6 @@
+#!/bin/sh
+set -e
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
# extra ../ is needed due to ocamlbuild chdiring into _build
ocamlbuild -pkg ctypes.foreign -lflags -cclib,-L../../.. -lflags -cclib,-lbotan-1.11 botan.native
diff --git a/src/scripts/ci/after_success.sh b/src/scripts/ci/after_success.sh
index 2fe809f42..5cd01b39a 100755
--- a/src/scripts/ci/after_success.sh
+++ b/src/scripts/ci/after_success.sh
@@ -1,10 +1,13 @@
#!/bin/sh
-
set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
if [ "$BUILD_MODE" = "coverage" ]; then
- lcov --directory . --capture --output-file coverage.info
- lcov --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info
- lcov --list coverage.info
- coveralls-lcov -t $COVERALLS_REPO_TOKEN coverage.info
+ GCOV="/usr/bin/gcov-4.8"
+ /tmp/usr/bin/lcov --gcov-tool "$GCOV" --directory . --capture --output-file coverage.info
+ /tmp/usr/bin/lcov --gcov-tool "$GCOV" --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info
+ /tmp/usr/bin/lcov --gcov-tool "$GCOV" --list coverage.info
+
+ # Assume that $COVERALLS_REPO_TOKEN might not be set (e.g. pull requests)
+ coveralls-lcov --repo-token="$COVERALLS_REPO_TOKEN" coverage.info
fi
diff --git a/src/scripts/ci/appveyor.yml b/src/scripts/ci/appveyor.yml
index 41625440d..aa0c3890c 100644
--- a/src/scripts/ci/appveyor.yml
+++ b/src/scripts/ci/appveyor.yml
@@ -1,9 +1,15 @@
os: Windows Server 2012 R2
+platform:
+ - x86
+ - x86_amd64
+
install:
- - call "%ProgramFiles(x86)%\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
+ - call "%ProgramFiles(x86)%\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %PLATFORM%
+ - cl # check compiler version
build_script:
- - python configure.py --disable-shared --via-amalgamation --cpu=x86_32 --cc=msvc --cc-abi-flags="/bigobj"
+ - python configure.py --disable-shared --via-amalgamation --cpu=%PLATFORM% --cc=msvc
- nmake
- botan-test
+ - nmake install
diff --git a/src/scripts/ci/build.sh b/src/scripts/ci/build.sh
index 2d75a3901..9bf7b0e84 100755
--- a/src/scripts/ci/build.sh
+++ b/src/scripts/ci/build.sh
@@ -1,17 +1,44 @@
-#!/bin/sh
-
+#!/bin/bash
set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
if [ "$BUILD_MODE" = "static" ]; then
- CFG_FLAGS="--disable-shared --via-amalgamation"
+ CFG_FLAGS=(--disable-shared --via-amalgamation)
elif [ "$BUILD_MODE" = "shared" ]; then
- CFG_FLAGS=""
+ CFG_FLAGS=()
elif [ "$BUILD_MODE" = "coverage" ]; then
# lcov gets confused by symlinks
- CFG_FLAGS="--build-mode=coverage --link-method=copy"
+ CFG_FLAGS=(--build-mode=coverage --link-method=copy)
+elif [ "$BUILD_MODE" = "sanitizer" ]; then
+ CFG_FLAGS=(--build-mode=sanitizer)
+fi
+
+if [ "$MODULES" = "min" ]; then
+ CFG_FLAGS+=(--no-autoload --enable-modules=base)
+fi
+
+# Workaround for missing update-alternatives
+# https://github.com/travis-ci/travis-ci/issues/3668
+if [ "$CXX" = "g++" ]; then
+ export CXX="/usr/bin/g++-4.8"
+fi
+
+#enable ccache
+if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+ ccache --max-size=30M
+ ccache --show-stats
+
+ export CXX="ccache $CXX"
fi
$CXX --version
-python configure.py $CFG_FLAGS --cc=$CC --cc-bin=$CXX --with-openssl --with-sqlite --with-zlib
+./configure.py "${CFG_FLAGS[@]}" --cc="$CC" --cc-bin="$CXX" \
+ --with-openssl --with-sqlite --with-zlib \
+ --prefix=/tmp/botan-installation
make -j 2
-./botan-test
+
+if [ "$MODULES" != "min" ]; then
+ ./botan-test
+fi
+
+make install
diff --git a/src/scripts/ci/circle/clang-shared-debug.sh b/src/scripts/ci/circle/clang-shared-debug.sh
new file mode 100755
index 000000000..2ef4e6dd5
--- /dev/null
+++ b/src/scripts/ci/circle/clang-shared-debug.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+BUILD_NICKNAME=$(basename "$0" .sh)
+BUILD_DIR="./build-$BUILD_NICKNAME"
+
+./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --cc=clang
+make -j 2 -f "$BUILD_DIR"/Makefile
+"$BUILD_DIR"/botan-test
diff --git a/src/scripts/ci/circle/clang-static-debug.sh b/src/scripts/ci/circle/clang-static-debug.sh
new file mode 100755
index 000000000..8bf96fcfe
--- /dev/null
+++ b/src/scripts/ci/circle/clang-static-debug.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+BUILD_NICKNAME=$(basename "$0" .sh)
+BUILD_DIR="./build-$BUILD_NICKNAME"
+
+./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --cc=clang --disable-shared --via-amalgamation
+make -j 2 -f "$BUILD_DIR"/Makefile
+"$BUILD_DIR"/botan-test
diff --git a/src/scripts/ci/circle/gcc-shared-debug.sh b/src/scripts/ci/circle/gcc-shared-debug.sh
new file mode 100755
index 000000000..93530b8ac
--- /dev/null
+++ b/src/scripts/ci/circle/gcc-shared-debug.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+BUILD_NICKNAME=$(basename "$0" .sh)
+BUILD_DIR="./build-$BUILD_NICKNAME"
+
+./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug
+make -j 2 -f "$BUILD_DIR"/Makefile
+"$BUILD_DIR"/botan-test
diff --git a/src/scripts/ci/circle/gcc-static-debug.sh b/src/scripts/ci/circle/gcc-static-debug.sh
new file mode 100755
index 000000000..c7d23b9b0
--- /dev/null
+++ b/src/scripts/ci/circle/gcc-static-debug.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+BUILD_NICKNAME=$(basename "$0" .sh)
+BUILD_DIR="./build-$BUILD_NICKNAME"
+
+./configure.py --with-build-dir="$BUILD_DIR" --build-mode=debug --disable-shared --via-amalgamation
+make -j 2 -f "$BUILD_DIR"/Makefile
+"$BUILD_DIR"/botan-test
diff --git a/src/scripts/ci/install.sh b/src/scripts/ci/install.sh
new file mode 100755
index 000000000..364d447bf
--- /dev/null
+++ b/src/scripts/ci/install.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -ev
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+if [ "$BUILD_MODE" = "coverage" ]; then
+ wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz
+ tar -xvf lcov_1.11.orig.tar.gz
+ export PREFIX="/tmp"
+ make -C lcov-1.11/ install
+ gem install coveralls-lcov
+fi
diff --git a/src/scripts/ci/setup.sh b/src/scripts/ci/setup.sh
deleted file mode 100755
index 97019fd57..000000000
--- a/src/scripts/ci/setup.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-
-set -ev
-
-if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
-
- sudo apt-get install -y g++-4.8
- sudo apt-get install -y libssl-dev
- sudo apt-get install -y libz-dev
- sudo apt-get install -y libsqlite3-dev
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90
- sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-4.8 90
-fi
-
-if [ "$BUILD_MODE" = "coverage" ]; then
- wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz
- tar -xvf lcov_1.11.orig.tar.gz
- sudo make -C lcov-1.11/ install
- gem install coveralls-lcov
-fi
diff --git a/src/scripts/comba.py b/src/scripts/comba.py
index fe588f7bc..dcac14657 100755
--- a/src/scripts/comba.py
+++ b/src/scripts/comba.py
@@ -87,8 +87,6 @@ def main(args = None):
#include <botan/internal/mp_asmi.h>
namespace Botan {
-
-extern "C" {
"""
for n in [4,6,8,9,16]:
@@ -110,7 +108,7 @@ extern "C" {
print " }\n"
- print "}\n\n}"
+ print "}"
if __name__ == '__main__':
sys.exit(main())
diff --git a/src/scripts/combine_relnotes.py b/src/scripts/combine_relnotes.py
deleted file mode 100755
index cf9a78ad7..000000000
--- a/src/scripts/combine_relnotes.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/python
-
-"""
-(C) 2014 Jack Lloyd
-
-Botan is released under the Simplified BSD License (see license.txt)
-"""
-
-import re
-import sys
-import os
-import sys
-
-def open_for_utf8(fsname, mode):
- if sys.version_info[0] == 3:
- return open(fsname, mode, encoding='utf-8')
- else:
- return open(fsname, mode)
-
-def combine_relnotes(relnote_dir, with_rst_labels):
-
- relnotes = [p for p in os.listdir(relnote_dir) if p.startswith(('0', '1', '2'))]
-
- re_version = re.compile('Version (\d+\.\d+\.\d+), ([0-9]{4}-[0-9]{2}-[0-9]{2})$')
- re_nyr = re.compile('Version (\d+\.\d+\.\d+), Not Yet Released$')
-
- version_contents = {}
- version_date = {}
- versions = []
- versions_nyr = []
-
- for f in relnotes:
- contents = open_for_utf8(os.path.join(relnote_dir, f), 'r').readlines()
-
- match = re_version.match(contents[0])
-
- if match:
- version = match.group(1)
- date = match.group(2)
- versions.append(version)
- version_date[version] = date
- else:
- match = re_nyr.match(str(contents[0]))
- if not match:
- raise Exception('No version match for %s' % (f))
-
- version = match.group(1)
- versions_nyr.append(version)
-
- version_contents[version] = (''.join(contents)).strip()
-
- def make_label(v):
- if with_rst_labels:
- return ".. _v%s:\n\n" % (v.replace('.', '_'))
- else:
- return ''
-
- s = ''
-
- s += "Release Notes\n"
- s += "========================================\n"
- s += "\n"
-
- date_to_version = {}
- for (v,d) in version_date.items():
- date_to_version.setdefault(d, []).append(v)
-
- if len(versions_nyr) > 0:
- for v in versions_nyr:
- s += make_label(v)
- s += version_contents[v]
- s += "\n\n"
-
- for d in sorted(date_to_version.keys(), reverse=True):
- for v in sorted(date_to_version[d]):
- s += make_label(v)
- s += version_contents[v]
- s += "\n\n"
-
- return s
-
-def main(args = None):
- if args is None:
- args = sys.argv
-
- print(combine_relnotes(args[1], True))
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/src/scripts/dist.py b/src/scripts/dist.py
index d0c042b2a..c0819e2ef 100755
--- a/src/scripts/dist.py
+++ b/src/scripts/dist.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
"""
Release script for botan (http://botan.randombit.net/)
-(C) 2011, 2012, 2013 Jack Lloyd
+(C) 2011, 2012, 2013, 2015 Jack Lloyd
Botan is released under the Simplified BSD License (see license.txt)
"""
@@ -12,20 +12,18 @@ import errno
import logging
import optparse
import os
-import shlex
import shutil
import subprocess
import sys
import tarfile
import datetime
import hashlib
+import re
+import StringIO
def check_subprocess_results(subproc, name):
(stdout, stderr) = subproc.communicate()
- stdout = stdout.strip()
- stderr = stderr.strip()
-
if subproc.returncode != 0:
if stdout != '':
logging.error(stdout)
@@ -38,57 +36,31 @@ def check_subprocess_results(subproc, name):
return stdout
-def run_monotone(db, args):
- cmd = ['mtn', '--db', db] + args
-
+def run_git(args):
+ cmd = ['git'] + args
logging.debug('Running %s' % (' '.join(cmd)))
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ return check_subprocess_results(proc, 'git')
- mtn = subprocess.Popen(cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
-
- return check_subprocess_results(mtn, 'mtn')
-
-def get_certs(db, rev_id):
- tokens = shlex.split(run_monotone(db, ['automate', 'certs', rev_id]))
-
- def usable_cert(cert):
- if 'signature' not in cert or cert['signature'] != 'ok':
- return False
- if 'trust' not in cert or cert['trust'] != 'trusted':
- return False
- if 'name' not in cert or 'value' not in cert:
- return False
- return True
+def datestamp(tag):
+ ts = run_git(['show', '--no-patch', '--format=%ai', tag])
- def cert_builder(tokens):
- pairs = zip(tokens[::2], tokens[1::2])
- current_cert = {}
- for pair in pairs:
- if pair[0] == 'trust':
- if usable_cert(current_cert):
- name = current_cert['name']
- value = current_cert['value']
- current_cert = {}
+ ts_matcher = re.compile('^(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2} .*')
+ match = ts_matcher.match(ts)
- logging.debug('Cert %s "%s" for rev %s' % (name, value, rev_id))
- yield (name, value)
+ if match is None:
+ logging.error('Failed parsing timestamp "%s" of tag %s' % (ts, tag))
+ return 0
- current_cert[pair[0]] = pair[1]
+ return int(match.group(1) + match.group(2) + match.group(3))
- certs = dict(cert_builder(tokens))
- return certs
+def revision_of(tag):
+ return run_git(['show', '--no-patch', '--format=%H', tag]).strip()
-def datestamp(db, rev_id):
- certs = get_certs(db, rev_id)
-
- if 'date' in certs:
- datestamp = int(certs['date'].replace('-','')[0:8])
- logging.info('Using datestamp %s for rev %s' % (datestamp, rev_id))
- return datestamp
-
- logging.info('Could not retreive date for %s' % (rev_id))
- return 0
+def extract_revision(revision, to):
+ tar_val = run_git(['archive', '--format=tar', '--prefix=%s/' % (to), revision])
+ tar_f = tarfile.open(fileobj=StringIO.StringIO(tar_val))
+ tar_f.extractall()
def gpg_sign(keyid, passphrase_file, files, detached = True):
@@ -125,14 +97,9 @@ def parse_args(args):
parser.add_option('--quiet', action='store_true',
default=False, help='Only show errors')
- parser.add_option('--output-dir', metavar='DIR',
- default='.',
+ parser.add_option('--output-dir', metavar='DIR', default='.',
help='Where to place output (default %default)')
- parser.add_option('--mtn-db', metavar='DB',
- default=os.getenv('BOTAN_MTN_DB', ''),
- help='Set monotone db (default \'%default\')')
-
parser.add_option('--print-output-names', action='store_true',
help='Print output archive filenames to stdout')
@@ -176,28 +143,20 @@ def main(args = None):
format = '%(levelname) 7s: %(message)s',
level = log_level())
- if options.mtn_db == '':
- logging.error('No monotone db set (use --mtn-db)')
- return 1
-
- if not os.access(options.mtn_db, os.R_OK):
- logging.error('Monotone db %s not found' % (options.mtn_db))
- return 1
-
- if len(args) == 0 or len(args) >= 3:
+ if len(args) == 0 or len(args) > 2:
logging.error('Usage error, try --help')
return 1
- # Sanity check arguments
-
- if args[0] == 'snapshot':
+ is_snapshot = args[0] == 'snapshot'
+ target_version = None
+ if is_snapshot:
if len(args) == 1:
logging.error('Missing branch name for snapshot command')
return 1
logging.info('Creating snapshot release from branch %s', args[1])
-
+ target_version = 'HEAD'
elif len(args) == 1:
try:
logging.info('Creating release for version %s' % (args[0]))
@@ -205,29 +164,21 @@ def main(args = None):
(major,minor,patch) = map(int, args[0].split('.'))
assert args[0] == '%d.%d.%d' % (major,minor,patch)
+ target_version = args[0]
except:
logging.error('Invalid version number %s' % (args[0]))
return 1
-
else:
logging.error('Usage error, try --help')
return 1
- def selector(args):
- if args[0] == 'snapshot':
- return 'h:' + args[1]
- else:
- return 't:' + args[0]
-
def output_name(args):
- if args[0] == 'snapshot':
+ if is_snapshot:
datestamp = datetime.date.today().isoformat().replace('-', '')
def snapshot_name(branch):
- if branch == 'net.randombit.botan':
+ if branch == 'master':
return 'trunk'
- elif branch == 'net.randombit.botan.1_10':
- return '1.10'
else:
return branch
@@ -235,13 +186,16 @@ def main(args = None):
else:
return 'Botan-' + args[0]
- rev_id = run_monotone(options.mtn_db, ['automate', 'select', selector(args)])
+ logging.info('Creating release for version %s' % (target_version))
+
+ rev_id = revision_of(target_version)
+ rel_date = datestamp(target_version)
if rev_id == '':
- logging.error('No revision matching %s found' % (selector(args)))
+ logging.error('No tag matching %s found' % (target_version))
return 2
- logging.info('Found revision id %s' % (rev_id))
+ logging.info('Found %s at revision id %s released %d' % (target_version, rev_id, rel_date))
output_basename = output_name(args)
@@ -251,11 +205,7 @@ def main(args = None):
logging.info('Removing existing output dir %s' % (output_basename))
shutil.rmtree(output_basename)
- run_monotone(options.mtn_db,
- ['checkout', '--quiet', '-r', rev_id, output_basename])
-
- shutil.rmtree(os.path.join(output_basename, '_MTN'))
- remove_file_if_exists(os.path.join(output_basename, '.mtn-ignore'))
+ extract_revision(rev_id, output_basename)
version_file = os.path.join(output_basename, 'botan_version.py')
@@ -267,9 +217,9 @@ def main(args = None):
def content_rewriter():
for line in contents:
if line == 'release_vc_rev = None\n':
- yield 'release_vc_rev = \'mtn:%s\'\n' % (rev_id)
+ yield 'release_vc_rev = \'git:%s\'\n' % (rev_id)
elif line == 'release_datestamp = 0\n':
- yield 'release_datestamp = %d\n' % (datestamp(options.mtn_db, rev_id))
+ yield 'release_datestamp = %d\n' % (rel_date)
elif line == "release_type = \'unreleased\'\n":
if args[0] == 'snapshot':
yield "release_type = 'snapshot'\n"
@@ -280,7 +230,7 @@ def main(args = None):
open(version_file, 'w').write(''.join(list(content_rewriter())))
else:
- logging.error('Cannot find %s' % (version_file))
+ logging.error('Cannot read %s' % (version_file))
return 2
try:
diff --git a/src/scripts/install.py b/src/scripts/install.py
index b25ec42de..2c69213e5 100755
--- a/src/scripts/install.py
+++ b/src/scripts/install.py
@@ -16,11 +16,6 @@ import shutil
import string
import sys
-if 'dont_write_bytecode' in sys.__dict__:
- sys.dont_write_bytecode = True
-
-import combine_relnotes
-
def parse_command_line(args):
parser = optparse.OptionParser()
@@ -74,6 +69,15 @@ def makedirs(dirname, exist_ok = True):
if e.errno != errno.EEXIST or not exist_ok:
raise e
+# Clear link and create new one
+def force_symlink(target, linkname):
+ try:
+ os.unlink(linkname)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise e
+ os.symlink(target, linkname)
+
def main(args = None):
if args is None:
args = sys.argv
@@ -146,38 +150,25 @@ def main(args = None):
copy_file(os.path.join(out_dir, static_lib),
os.path.join(lib_dir, os.path.basename(static_lib)))
- if bool(cfg['with_shared_lib']):
+ if bool(cfg['build_shared_lib']):
if str(cfg['os']) == "windows":
- shared_lib = process_template('%{lib_prefix}%{libname}.%{so_suffix}') # botan.dll
- copy_executable(os.path.join(out_dir, shared_lib),
- os.path.join(lib_dir, os.path.basename(shared_lib)))
+ soname_base = process_template('%{soname_base}') # botan.dll
+ copy_executable(os.path.join(out_dir, soname_base),
+ os.path.join(lib_dir, soname_base))
else:
- shared_lib = process_template('%{lib_prefix}%{libname}.%{so_suffix}.%{so_abi_rev}.%{version_patch}')
- soname = process_template('%{lib_prefix}%{libname}.%{so_suffix}.%{so_abi_rev}')
- baselib = process_template('%{lib_prefix}%{libname}.%{so_suffix}')
+ soname_patch = process_template('%{soname_patch}')
+ soname_abi = process_template('%{soname_abi}')
+ soname_base = process_template('%{soname_base}')
- copy_executable(os.path.join(out_dir, shared_lib),
- os.path.join(lib_dir, os.path.basename(shared_lib)))
+ copy_executable(os.path.join(out_dir, soname_patch),
+ os.path.join(lib_dir, soname_patch))
prev_cwd = os.getcwd()
try:
os.chdir(lib_dir)
-
- try:
- os.unlink(soname)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise e
-
- try:
- os.unlink(baselib)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise e
-
- os.symlink(shared_lib, soname)
- os.symlink(soname, baselib)
+ force_symlink(soname_patch, soname_abi)
+ force_symlink(soname_patch, soname_base)
finally:
os.chdir(prev_cwd)
@@ -202,8 +193,7 @@ def main(args = None):
for f in [f for f in os.listdir(cfg['doc_dir']) if f.endswith('.txt')]:
copy_file(os.path.join(cfg['doc_dir'], f), os.path.join(target_doc_dir, f))
- with combine_relnotes.open_for_utf8(os.path.join(target_doc_dir, 'news.txt'), 'w+') as news:
- news.write(combine_relnotes.combine_relnotes('doc/relnotes', False))
+ copy_file(os.path.join(cfg['doc_dir'], 'news.rst'), os.path.join(target_doc_dir, 'news.txt'))
logging.info('Botan %s installation complete', cfg['version'])
diff --git a/src/scripts/show_dependencies.py b/src/scripts/show_dependencies.py
index 37cb817d0..937626a86 100755
--- a/src/scripts/show_dependencies.py
+++ b/src/scripts/show_dependencies.py
@@ -13,6 +13,7 @@ Botan is released under the Simplified BSD License (see license.txt)
# global
import argparse
+import copy
import sys
import subprocess
from collections import OrderedDict
@@ -44,6 +45,9 @@ parser.add_argument('--engine',
choices=["fdp", "dot"],
default="fdp",
help='The graph engine (drawing mode only)')
+parser.add_argument('--all', dest='all', action='store_const',
+ const=True, default=False,
+ help='Show all dependencies. Default: direct dependencies only. (list mode only)')
parser.add_argument('--verbose', dest='verbose', action='store_const',
const=True, default=False,
help='Verbose output (default: false)')
@@ -96,35 +100,65 @@ if args.verbose:
if args.verbose:
print("resolving dependencies ...")
+def cartinality(depdict):
+ return sum([len(depdict[k]) for k in depdict])
+
+registered_dependencies = dict()
all_dependencies = dict()
direct_dependencies = dict()
for module in modules:
lst = module.dependencies()
- direct_dependencies[module.basename] = set(lst)
+ registered_dependencies[module.basename] = set(lst) - set([module.basename])
+
+# Get all_dependencies from registered_dependencies
+def add_dependency():
+ for key in all_dependencies:
+ potentially_new_modules_for_key = None
+ new_modules_for_key = None
+ for currently_in in all_dependencies[key]:
+ if currently_in in all_dependencies:
+ potentially_new_modules_for_key = all_dependencies[currently_in] - set([key])
+ if not potentially_new_modules_for_key <= all_dependencies[key]:
+ new_modules_for_key = potentially_new_modules_for_key.copy()
+ break
+ if new_modules_for_key:
+ all_dependencies[key] |= new_modules_for_key
+ return
+
+
+all_dependencies = copy.deepcopy(registered_dependencies)
+direct_dependencies = copy.deepcopy(registered_dependencies)
-all_dependencies = direct_dependencies.copy()
+# Sort
+all_dependencies = OrderedDict(sorted(all_dependencies.items()))
+direct_dependencies = OrderedDict(sorted(direct_dependencies.items()))
#print(direct_dependencies)
-def cartinality(depdict):
- return sum([len(depdict[k]) for k in depdict])
-
-# Sort
-direct_dependencies = OrderedDict(sorted(direct_dependencies.items()))
+last_card = -1
+while True:
+ card = cartinality(all_dependencies)
+ # print(card)
+ if card == last_card:
+ break;
+ last_card = card
+ add_dependency()
+# Return true iff a depends on b,
+# i.e. b is in the dependencies of a
def depends_on(a, b):
- if not a in all_dependencies:
+ if not a in direct_dependencies:
return False
else:
- return b in all_dependencies[a]
+ return b in direct_dependencies[a]
def remove_indirect_dependencies():
for mod in direct_dependencies:
for one in direct_dependencies[mod]:
others = direct_dependencies[mod] - set([one])
for other in others:
- if depends_on(one, other):
+ if depends_on(other, one):
direct_dependencies[mod].remove(one)
return
# Go to next mod
@@ -148,8 +182,12 @@ if args.verbose:
print("Done resolving dependencies.")
if args.mode == "list":
- for key in direct_dependencies:
- print(key.ljust(17) + " : " + ", ".join(sorted(direct_dependencies[key])))
+ if args.all:
+ for key in all_dependencies:
+ print(key.ljust(17) + " : " + ", ".join(sorted(all_dependencies[key])))
+ else:
+ for key in direct_dependencies:
+ print(key.ljust(17) + " : " + ", ".join(sorted(direct_dependencies[key])))
if args.mode == "draw":
import graphviz as gv
diff --git a/src/scripts/update_docs.py b/src/scripts/update_docs.py
new file mode 100755
index 000000000..03b9dd67b
--- /dev/null
+++ b/src/scripts/update_docs.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+
+"""
+A script to automatically write docs to /docs. Currently it generates
+os.rst, a feature table of OS features.
+
+Requires Python 3.
+
+(C) 2015 Simon Warta (Kullo GmbH)
+
+Botan is released under the Simplified BSD License (see license.txt)
+"""
+
+# global
+import argparse
+import glob
+import os
+import sys
+
+# Assume this script is in botan/src/scripts
+botan_root = os.path.join(os.path.dirname(sys.argv[0]), "..", "..")
+
+# locale
+sys.path.append(botan_root)
+from configure import OsInfo
+
+parser = argparse.ArgumentParser(description="")
+parser.add_argument('--verbose', dest='verbose', action='store_const',
+ const=True, default=False,
+ help='Verbose output (default: false)')
+args = parser.parse_args()
+
+def update_os():
+ PAGE_TITLE="Botan OS information"
+ TABLE_TITLE="OS Features"
+
+ files = []
+ files += glob.glob(botan_root + '/src/build-data/os/*.txt')
+ files.sort()
+
+ if len(files) == 0:
+ print("No info.txt files found.")
+ sys.exit(1)
+
+ f1 = open(os.path.join(botan_root, 'doc', 'os.rst'), 'w+')
+
+ all_features = set()
+ oss = {}
+
+ for filename in files:
+ o = OsInfo(filename)
+ oss[o.basename] = o
+ all_features |= set(o.target_features)
+ if args.verbose:
+ print(o.basename)
+ print(o.target_features)
+
+ featurelist = list(all_features)
+ featurelist.sort()
+ oslist = list(oss.keys())
+ oslist.sort()
+
+ if args.verbose:
+ print(featurelist)
+
+ print(PAGE_TITLE, file=f1)
+ print("========================================", file=f1)
+ print("", file=f1)
+
+ print(TABLE_TITLE, file=f1)
+ print("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", file=f1)
+ print("", file=f1)
+
+ print("A summary of OS features as defined in ``src/build-data/os``.", file=f1)
+ print("", file=f1)
+
+ print("::", file=f1)
+ print("", file=f1)
+ for o in oslist:
+ print(" %s: %s" % (o[0:1], o), file=f1)
+ print("", file=f1)
+
+ print('.. csv-table::', file=f1)
+ print(' :header: "Feature", "' + '", "'.join([o[0:1] for o in oslist]) + '"', file=f1)
+ print('', file=f1)
+
+ for f in featurelist:
+ line = ' "' + f + '"'
+ for o in oslist:
+ line += ', "'
+ line += 'X' if f in oss[o].target_features else ' '
+ line += '"'
+ print(line, file=f1)
+ print("", file=f1)
+ print(".. note::", file=f1)
+ print(" This file is auto generated by ``src/scripts/%s``. Dont modify it manually."
+ % os.path.basename(sys.argv[0]), file=f1)
+
+if __name__ == '__main__':
+ update_os()
diff --git a/src/scripts/website.sh b/src/scripts/website.sh
new file mode 100755
index 000000000..525b2fcca
--- /dev/null
+++ b/src/scripts/website.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -e
+which shellcheck > /dev/null && shellcheck "$0" # Run shellcheck on this if available
+
+SPHINX_CONFIG=./src/build-data/sphinx
+SPHINX_BUILDER="html"
+
+WEBSITE_DIR=./www-botan
+WEBSITE_SRC_DIR=./www-src
+
+rm -rf $WEBSITE_SRC_DIR $WEBSITE_DIR
+mkdir -p $WEBSITE_SRC_DIR
+
+cp readme.rst $WEBSITE_SRC_DIR/index.rst
+cp -r doc/news.rst $WEBSITE_SRC_DIR
+echo -e ".. toctree::\n\n index\n news\n" > $WEBSITE_SRC_DIR/contents.rst
+
+sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" $WEBSITE_SRC_DIR $WEBSITE_DIR
+sphinx-build -t website -c "$SPHINX_CONFIG" -b "$SPHINX_BUILDER" doc/manual $WEBSITE_DIR/manual
+rm -rf $WEBSITE_DIR/.doctrees
+rm -f $WEBSITE_DIR/.buildinfo
+rm -rf $WEBSITE_DIR/manual/.doctrees
+rm -f $WEBSITE_DIR/manual/.buildinfo
+cp doc/license.txt doc/pgpkey.txt $WEBSITE_DIR
+
+doxygen build/botan.doxy
+mv build/docs/doxygen $WEBSITE_DIR/doxygen
diff --git a/src/tests/catchy/catch.hpp b/src/tests/catchy/catch.hpp
new file mode 100644
index 000000000..de61226cf
--- /dev/null
+++ b/src/tests/catchy/catch.hpp
@@ -0,0 +1,9416 @@
+/*
+ * Catch v1.2.1
+ * Generated: 2015-06-30 18:23:27.961086
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if (__cplusplus >= 201103L)
+
+# define CATCH_CPP11_OR_GREATER
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+#define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+namespace Catch {
+
+ class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template<typename ContainerT>
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template<typename AssociativeContainerT>
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+ SourceLineInfo( SourceLineInfo const& other );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ std::string file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+#include <ostream>
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template<typename T>
+ class Ptr {
+ public:
+ Ptr() : m_p( NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() { return m_p; }
+ const T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template<typename T = IShared>
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr<IConfig const> getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
+
+ };
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+struct AutoReg {
+
+ AutoReg( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template<typename C>
+ AutoReg( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+ registerTestCase( new MethodTestCase<C>( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ void registerTestCase( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
+
+ std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template<typename T> class ExpressionLhs;
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str("");
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition );
+
+ template<typename T>
+ ExpressionLhs<T const&> operator <= ( T const& operand );
+ ExpressionLhs<bool> operator <= ( bool value );
+
+ template<typename T>
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+ ResultBuilder& setLhs( std::string const& lhs );
+ ResultBuilder& setRhs( std::string const& rhs );
+ ResultBuilder& setOp( std::string const& op );
+
+ void endExpression();
+
+ std::string reconstructExpression() const;
+ AssertionResult build() const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ struct ExprComponents {
+ ExprComponents() : testFalse( false ) {}
+ bool testFalse;
+ std::string lhs, rhs, op;
+ } m_exprComponents;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+ template<typename T>
+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template<typename T1, typename T2, Operator Op>
+ class Evaluator{};
+
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return opCast( lhs ) == opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsNotEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) != opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) < opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) > opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) >= opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) <= opCast( rhs );
+ }
+ };
+
+ template<Operator Op, typename T1, typename T2>
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template<Operator Op, typename T1, typename T2>
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+
+ // unsigned X to long
+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+
+ // int to unsigned X
+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+
+ // long to unsigned X
+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // pointer to long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+ // pointer to int (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ // pointer to nullptr_t (when comparing against nullptr)
+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( NULL, rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, NULL );
+ }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+#include <tuple>
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+ extern std::string unprintableString;
+
+ struct BorgType {
+ template<typename T> BorgType( T const& );
+ };
+
+ struct TrueType { char sizer[1]; };
+ struct FalseType { char sizer[2]; };
+
+ TrueType& testStreamable( std::ostream& );
+ FalseType testStreamable( FalseType );
+
+ FalseType operator<<( std::ostream const&, BorgType const& );
+
+ template<typename T>
+ struct IsStreamInsertable {
+ static std::ostream &s;
+ static T const&t;
+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+ };
+
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T,
+ bool IsEnum = std::is_enum<T>::value
+ >
+ struct EnumStringMaker
+ {
+ static std::string convert( T const& ) { return unprintableString; }
+ };
+
+ template<typename T>
+ struct EnumStringMaker<T,true>
+ {
+ static std::string convert( T const& v )
+ {
+ return ::Catch::toString(
+ static_cast<typename std::underlying_type<T>::type>(v)
+ );
+ }
+ };
+#endif
+ template<bool C>
+ struct StringMakerBase {
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T>
+ static std::string convert( T const& v )
+ {
+ return EnumStringMaker<T>::convert( v );
+ }
+#else
+ template<typename T>
+ static std::string convert( T const& ) { return unprintableString; }
+#endif
+ };
+
+ template<>
+ struct StringMakerBase<true> {
+ template<typename T>
+ static std::string convert( T const& _value ) {
+ std::ostringstream oss;
+ oss << _value;
+ return oss.str();
+ }
+ };
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ inline std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+ template<typename U>
+ static std::string convert( U* p ) {
+ if( !p )
+ return INTERNAL_CATCH_STRINGIFY( NULL );
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+ static std::string convert( R C::* p ) {
+ if( !p )
+ return INTERNAL_CATCH_STRINGIFY( NULL );
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+// static std::string convert( std::vector<T,Allocator> const& v ) {
+// return Detail::rangeToString( v.begin(), v.end() );
+// }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+ return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+
+// toString for tuples
+namespace TupleDetail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct ElementPrinter {
+ static void print( const Tuple& tuple, std::ostream& os )
+ {
+ os << ( N ? ", " : " " )
+ << Catch::toString(std::get<N>(tuple));
+ ElementPrinter<Tuple,N+1>::print(tuple,os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct ElementPrinter<Tuple,N,false> {
+ static void print( const Tuple&, std::ostream& ) {}
+ };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+ static std::string convert( const std::tuple<Types...>& tuple )
+ {
+ std::ostringstream os;
+ os << '{';
+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+ os << " }";
+ return os.str();
+ }
+};
+#endif // CATCH_CONFIG_CPP11_TUPLE
+
+namespace Detail {
+ template<typename T>
+ std::string makeString( T const& value ) {
+ return StringMaker<T>::convert( value );
+ }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+ return StringMaker<T>::convert( value );
+}
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last ) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if( first != last ) {
+ oss << Catch::toString( *first );
+ for( ++first ; first != last ; ++first )
+ oss << ", " << Catch::toString( *first );
+ }
+ oss << " }";
+ return oss.str();
+ }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
+// wrapping them all in a ResultBuilder object
+template<typename T>
+class ExpressionLhs {
+ ExpressionLhs& operator = ( ExpressionLhs const& );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
+# endif
+
+public:
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs( ExpressionLhs const& ) = default;
+ ExpressionLhs( ExpressionLhs && ) = default;
+# endif
+
+ template<typename RhsT>
+ ResultBuilder& operator == ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator != ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator < ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator > ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator <= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator >= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator == ( bool rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator != ( bool rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ void endExpression() {
+ bool value = m_lhs ? true : false;
+ m_rb
+ .setLhs( Catch::toString( value ) )
+ .setResultType( value )
+ .endExpression();
+ }
+
+ // Only simple binary expressions are allowed on the LHS.
+ // If more complex compositions are required then place the sub expression in parentheses
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+private:
+ template<Internal::Operator Op, typename RhsT>
+ ResultBuilder& captureExpression( RhsT const& rhs ) {
+ return m_rb
+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
+ .setLhs( Catch::toString( m_lhs ) )
+ .setRhs( Catch::toString( rhs ) )
+ .setOp( Internal::OperatorTraits<Op>::getName() );
+ }
+
+private:
+ ResultBuilder& m_rb;
+ T m_lhs;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+ template<typename T>
+ inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
+ return ExpressionLhs<T const&>( *this, operand );
+ }
+
+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
+ return ExpressionLhs<bool>( *this, value );
+ }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ std::string message;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+ bool operator < ( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageBuilder {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ : m_info( macroName, lineInfo, type )
+ {}
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ std::ostringstream m_stream;
+ };
+
+ class ScopedMessage {
+ public:
+ ScopedMessage( MessageBuilder const& builder );
+ ScopedMessage( ScopedMessage const& other );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct MessageInfo;
+ class ScopedMessageBuilder;
+ struct Counts;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual void assertionEnded( AssertionResult const& result ) = 0;
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0;
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+
+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_IPHONE
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+#include <string>
+
+namespace Catch{
+
+ bool isDebuggerActive();
+ void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ // The following code snippet based on:
+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
+ #ifdef DEBUG
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_BREAK_INTO_DEBUGGER() \
+ if( Catch::isDebuggerActive() ) { \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ); \
+ }
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
+ #endif
+ #endif
+
+#elif defined(_MSC_VER)
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+ class TestCase;
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ ( __catchResult <= expr ).endExpression(); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( ... ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( exceptionType ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#else
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << log + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( log, macroName ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \
+ try { \
+ std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \
+ __catchResult \
+ .setLhs( Catch::toString( arg ) ) \
+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
+ .setOp( "matches" ) \
+ .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \
+ __catchResult.captureExpression(); \
+ } catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+ Counts operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+ Counts& operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t total() const {
+ return passed + failed + failedButOk;
+ }
+ bool allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool allOk() const {
+ return failed == 0;
+ }
+
+ std::size_t passed;
+ std::size_t failed;
+ std::size_t failedButOk;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+ Totals& operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef CATCH_PLATFORM_WINDOWS
+typedef unsigned long long uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace Catch {
+
+ class Timer {
+ public:
+ Timer() : m_ticks( 0 ) {}
+ void start();
+ unsigned int getElapsedMicroseconds() const;
+ unsigned int getElapsedMilliseconds() const;
+ double getElapsedSeconds() const;
+
+ private:
+ uint64_t m_ticks;
+ };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+ #define INTERNAL_CATCH_SECTION( name, desc ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <iterator>
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+ virtual ~IGenerator() {}
+ virtual T getValue( std::size_t index ) const = 0;
+ virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+ virtual T getValue( std::size_t index ) const {
+ return m_from+static_cast<int>( index );
+ }
+
+ virtual std::size_t size() const {
+ return static_cast<std::size_t>( 1+m_to-m_from );
+ }
+
+private:
+
+ T m_from;
+ T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+ ValuesGenerator(){}
+
+ void add( T value ) {
+ m_values.push_back( value );
+ }
+
+ virtual T getValue( std::size_t index ) const {
+ return m_values[index];
+ }
+
+ virtual std::size_t size() const {
+ return m_values.size();
+ }
+
+private:
+ std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+ CompositeGenerator() : m_totalSize( 0 ) {}
+
+ // *** Move semantics, similar to auto_ptr ***
+ CompositeGenerator( CompositeGenerator& other )
+ : m_fileInfo( other.m_fileInfo ),
+ m_totalSize( 0 )
+ {
+ move( other );
+ }
+
+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
+ m_fileInfo = fileInfo;
+ return *this;
+ }
+
+ ~CompositeGenerator() {
+ deleteAll( m_composed );
+ }
+
+ operator T () const {
+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+ for( size_t index = 0; it != itEnd; ++it )
+ {
+ const IGenerator<T>* generator = *it;
+ if( overallIndex >= index && overallIndex < index + generator->size() )
+ {
+ return generator->getValue( overallIndex-index );
+ }
+ index += generator->size();
+ }
+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+ }
+
+ void add( const IGenerator<T>* generator ) {
+ m_totalSize += generator->size();
+ m_composed.push_back( generator );
+ }
+
+ CompositeGenerator& then( CompositeGenerator& other ) {
+ move( other );
+ return *this;
+ }
+
+ CompositeGenerator& then( T value ) {
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( value );
+ add( valuesGen );
+ return *this;
+ }
+
+private:
+
+ void move( CompositeGenerator& other ) {
+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_totalSize += other.m_totalSize;
+ other.m_composed.clear();
+ }
+
+ std::vector<const IGenerator<T>*> m_composed;
+ std::string m_fileInfo;
+ size_t m_totalSize;
+};
+
+namespace Generators
+{
+ template<typename T>
+ CompositeGenerator<T> between( T from, T to ) {
+ CompositeGenerator<T> generators;
+ generators.add( new BetweenGenerator<T>( from, to ) );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ valuesGen->add( val4 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+
+namespace Catch {
+
+ typedef std::string(*exceptionTranslateFunction)();
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate() const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ virtual std::string translate() const {
+ try {
+ throw;
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ public:
+ explicit Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_scale( 1.0 ),
+ m_value( value )
+ {}
+
+ Approx( Approx const& other )
+ : m_epsilon( other.m_epsilon ),
+ m_scale( other.m_scale ),
+ m_value( other.m_value )
+ {}
+
+ static Approx custom() {
+ return Approx( 0 );
+ }
+
+ Approx operator()( double value ) {
+ Approx approx( value );
+ approx.epsilon( m_epsilon );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ friend bool operator == ( double lhs, Approx const& rhs ) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
+ }
+
+ friend bool operator == ( Approx const& lhs, double rhs ) {
+ return operator==( rhs, lhs );
+ }
+
+ friend bool operator != ( double lhs, Approx const& rhs ) {
+ return !operator==( lhs, rhs );
+ }
+
+ friend bool operator != ( Approx const& lhs, double rhs ) {
+ return !operator==( rhs, lhs );
+ }
+
+ Approx& epsilon( double newEpsilon ) {
+ m_epsilon = newEpsilon;
+ return *this;
+ }
+
+ Approx& scale( double newScale ) {
+ m_scale = newScale;
+ return *this;
+ }
+
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "Approx( " << Catch::toString( m_value ) << " )";
+ return oss.str();
+ }
+
+ private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+ return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ template<typename ExpressionT>
+ struct Matcher : SharedImpl<IShared>
+ {
+ typedef ExpressionT ExpressionType;
+
+ virtual ~Matcher() {}
+ virtual Ptr<Matcher> clone() const = 0;
+ virtual bool match( ExpressionT const& expr ) const = 0;
+ virtual std::string toString() const = 0;
+ };
+
+ template<typename DerivedT, typename ExpressionT>
+ struct MatcherImpl : Matcher<ExpressionT> {
+
+ virtual Ptr<Matcher<ExpressionT> > clone() const {
+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
+ }
+ };
+
+ namespace Generic {
+
+ template<typename ExpressionT>
+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AllOf() {}
+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( !m_matchers[i]->match( expr ) )
+ return false;
+ return true;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " and ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ template<typename ExpressionT>
+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AnyOf() {}
+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( m_matchers[i]->match( expr ) )
+ return true;
+ return false;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " or ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ }
+
+ namespace StdString {
+
+ inline std::string makeString( std::string const& str ) { return str; }
+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
+
+ struct Equals : MatcherImpl<Equals, std::string> {
+ Equals( std::string const& str ) : m_str( str ){}
+ Equals( Equals const& other ) : m_str( other.m_str ){}
+
+ virtual ~Equals();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_str == expr;
+ }
+ virtual std::string toString() const {
+ return "equals: \"" + m_str + "\"";
+ }
+
+ std::string m_str;
+ };
+
+ struct Contains : MatcherImpl<Contains, std::string> {
+ Contains( std::string const& substr ) : m_substr( substr ){}
+ Contains( Contains const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~Contains();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) != std::string::npos;
+ }
+ virtual std::string toString() const {
+ return "contains: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+
+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
+ StartsWith( std::string const& substr ) : m_substr( substr ){}
+ StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~StartsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) == 0;
+ }
+ virtual std::string toString() const {
+ return "starts with: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+
+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
+ EndsWith( std::string const& substr ) : m_substr( substr ){}
+ EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){}
+
+ virtual ~EndsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return expr.find( m_substr ) == expr.size() - m_substr.size();
+ }
+ virtual std::string toString() const {
+ return "ends with: \"" + m_substr + "\"";
+ }
+
+ std::string m_substr;
+ };
+ } // namespace StdString
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+
+ inline Impl::StdString::Equals Equals( std::string const& str ) {
+ return Impl::StdString::Equals( str );
+ }
+ inline Impl::StdString::Equals Equals( const char* str ) {
+ return Impl::StdString::Equals( Impl::StdString::makeString( str ) );
+ }
+ inline Impl::StdString::Contains Contains( std::string const& substr ) {
+ return Impl::StdString::Contains( substr );
+ }
+ inline Impl::StdString::Contains Contains( const char* substr ) {
+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
+ return Impl::StdString::StartsWith( substr );
+ }
+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
+ return Impl::StdString::EndsWith( substr );
+ }
+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+
+} // namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( NULL ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : NULL )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = NULL;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != NULL; }
+ bool none() const { return nullableValue == NULL; }
+
+ bool operator !() const { return nullableValue == NULL; }
+ operator SafeBool::type() const {
+ return SafeBool::makeSafe( some() );
+ }
+
+ private:
+ T* nullableValue;
+ char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestCase;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ TestCaseInfo( TestCaseInfo const& other );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::set<std::string> tags;
+ std::set<std::string> lcaseTags;
+ std::string tagsAsString;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
+ TestCase( TestCase const& other );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ void swap( TestCase& other );
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+ TestCase& operator = ( TestCase const& other );
+
+ private:
+ Ptr<ITestCase> test;
+ };
+
+ TestCase makeTestCase( ITestCase* testCase,
+ std::string const& className,
+ std::string const& name,
+ std::string const& description,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public SharedImpl<ITestCase> {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline size_t registerTestMethods() {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( NULL, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ template<typename MatcherT>
+ struct StringHolder : MatcherImpl<MatcherT, NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ NSString* m_substr;
+ };
+
+ struct Equals : StringHolder<Equals> {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ virtual std::string toString() const {
+ return "equals string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder<Contains> {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ virtual std::string toString() const {
+ return "contains string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder<StartsWith> {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ virtual std::string toString() const {
+ return "starts with: " + Catch::toString( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder<EndsWith> {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ virtual std::string toString() const {
+ return "ends with: " + Catch::toString( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_runner.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern : SharedImpl<> {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ class NamePattern : public Pattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+ NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) {
+ if( startsWith( m_name, "*" ) ) {
+ m_name = m_name.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_name, "*" ) ) {
+ m_name = m_name.substr( 0, m_name.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_name == toLower( testCase.name );
+ case WildcardAtStart:
+ return endsWith( toLower( testCase.name ), m_name );
+ case WildcardAtEnd:
+ return startsWith( toLower( testCase.name ), m_name );
+ case WildcardAtBothEnds:
+ return contains( toLower( testCase.name ), m_name );
+ }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+ throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ }
+ private:
+ std::string m_name;
+ WildcardPosition m_wildcard;
+ };
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+ }
+ private:
+ std::string m_tag;
+ };
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ private:
+ Ptr<Pattern> m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<Ptr<Pattern> > m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
+ if( !(*it)->matches( testCase ) )
+ return false;
+ return true;
+ }
+ };
+
+ public:
+ bool hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+ if( it->matches( testCase ) )
+ return true;
+ return false;
+ }
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag };
+ Mode m_mode;
+ bool m_exclusion;
+ std::size_t m_start, m_pos;
+ std::string m_arg;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+ private:
+ void visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ }
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ Ptr<TestSpec::Pattern> pattern = new T( token );
+ if( m_exclusion )
+ pattern = new TestSpec::ExcludedPattern( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+ void addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+ };
+ inline TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ struct Verbosity { enum Level {
+ NoOutput = 0,
+ Quiet,
+ Normal
+ }; };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : IShared {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual bool forceColour() const = 0;
+ };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+#include <streambuf>
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ class Stream {
+ public:
+ Stream();
+ Stream( std::streambuf* _streamBuf, bool _isOwned );
+ void release();
+
+ std::streambuf* streamBuf;
+
+ private:
+ bool isOwned;
+ };
+
+ std::ostream& cout();
+ std::ostream& cerr();
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct ConfigData {
+
+ ConfigData()
+ : listTests( false ),
+ listTags( false ),
+ listReporters( false ),
+ listTestNamesOnly( false ),
+ showSuccessfulTests( false ),
+ shouldDebugBreak( false ),
+ noThrow( false ),
+ showHelp( false ),
+ showInvisibles( false ),
+ forceColour( false ),
+ abortAfter( -1 ),
+ rngSeed( 0 ),
+ verbosity( Verbosity::Normal ),
+ warnings( WarnAbout::Nothing ),
+ showDurations( ShowDurations::DefaultForReporter ),
+ runOrder( RunTests::InDeclarationOrder )
+ {}
+
+ bool listTests;
+ bool listTags;
+ bool listReporters;
+ bool listTestNamesOnly;
+
+ bool showSuccessfulTests;
+ bool shouldDebugBreak;
+ bool noThrow;
+ bool showHelp;
+ bool showInvisibles;
+ bool forceColour;
+
+ int abortAfter;
+ unsigned int rngSeed;
+
+ Verbosity::Level verbosity;
+ WarnAbout::What warnings;
+ ShowDurations::OrNot showDurations;
+ RunTests::InWhatOrder runOrder;
+
+ std::string reporterName;
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> testsOrTags;
+ };
+
+ class Config : public SharedImpl<IConfig> {
+ private:
+ Config( Config const& other );
+ Config& operator = ( Config const& other );
+ virtual void dummy();
+ public:
+
+ Config()
+ : m_os( Catch::cout().rdbuf() )
+ {}
+
+ Config( ConfigData const& data )
+ : m_data( data ),
+ m_os( Catch::cout().rdbuf() )
+ {
+ if( !data.testsOrTags.empty() ) {
+ TestSpecParser parser( ITagAliasRegistry::get() );
+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+ parser.parse( data.testsOrTags[i] );
+ m_testSpec = parser.testSpec();
+ }
+ }
+
+ virtual ~Config() {
+ m_os.rdbuf( Catch::cout().rdbuf() );
+ m_stream.release();
+ }
+
+ void setFilename( std::string const& filename ) {
+ m_data.outputFilename = filename;
+ }
+
+ std::string const& getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool listTests() const { return m_data.listTests; }
+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool listTags() const { return m_data.listTags; }
+ bool listReporters() const { return m_data.listReporters; }
+
+ std::string getProcessName() const { return m_data.processName; }
+
+ bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+
+ void setStreamBuf( std::streambuf* buf ) {
+ m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
+ }
+
+ void useStream( std::string const& streamName ) {
+ Stream stream = createStream( streamName );
+ setStreamBuf( stream.streamBuf );
+ m_stream.release();
+ m_stream = stream;
+ }
+
+ std::string getReporterName() const { return m_data.reporterName; }
+
+ int abortAfter() const { return m_data.abortAfter; }
+
+ TestSpec const& testSpec() const { return m_testSpec; }
+
+ bool showHelp() const { return m_data.showHelp; }
+ bool showInvisibles() const { return m_data.showInvisibles; }
+
+ // IConfig interface
+ virtual bool allowThrows() const { return !m_data.noThrow; }
+ virtual std::ostream& stream() const { return m_os; }
+ virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
+ virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
+ virtual unsigned int rngSeed() const { return m_data.rngSeed; }
+ virtual bool forceColour() const { return m_data.forceColour; }
+
+ private:
+ ConfigData m_data;
+
+ Stream m_stream;
+ mutable std::ostream m_os;
+ TestSpec m_testSpec;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+#include <map>
+#include <algorithm>
+#include <stdexcept>
+#include <memory>
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+ struct UnpositionalTag {};
+
+ extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+ UnpositionalTag _;
+#endif
+
+ namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ using namespace Tbc;
+
+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+ }
+
+ template<typename T> struct RemoveConstRef{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+ template<typename T> struct IsBool { static const bool value = false; };
+ template<> struct IsBool<bool> { static const bool value = true; };
+
+ template<typename T>
+ void convertInto( std::string const& _source, T& _dest ) {
+ std::stringstream ss;
+ ss << _source;
+ ss >> _dest;
+ if( ss.fail() )
+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+ }
+ inline void convertInto( std::string const& _source, std::string& _dest ) {
+ _dest = _source;
+ }
+ inline void convertInto( std::string const& _source, bool& _dest ) {
+ std::string sourceLC = _source;
+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+ _dest = true;
+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+ _dest = false;
+ else
+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
+ }
+ inline void convertInto( bool _source, bool& _dest ) {
+ _dest = _source;
+ }
+ template<typename T>
+ inline void convertInto( bool, T& ) {
+ throw std::runtime_error( "Invalid conversion" );
+ }
+
+ template<typename ConfigT>
+ struct IArgFunction {
+ virtual ~IArgFunction() {}
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ IArgFunction() = default;
+ IArgFunction( IArgFunction const& ) = default;
+# endif
+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
+ virtual void setFlag( ConfigT& config ) const = 0;
+ virtual bool takesArg() const = 0;
+ virtual IArgFunction* clone() const = 0;
+ };
+
+ template<typename ConfigT>
+ class BoundArgFunction {
+ public:
+ BoundArgFunction() : functionObj( NULL ) {}
+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {}
+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL;
+ delete functionObj;
+ functionObj = newFunctionObj;
+ return *this;
+ }
+ ~BoundArgFunction() { delete functionObj; }
+
+ void set( ConfigT& config, std::string const& value ) const {
+ functionObj->set( config, value );
+ }
+ void setFlag( ConfigT& config ) const {
+ functionObj->setFlag( config );
+ }
+ bool takesArg() const { return functionObj->takesArg(); }
+
+ bool isSet() const {
+ return functionObj != NULL;
+ }
+ private:
+ IArgFunction<ConfigT>* functionObj;
+ };
+
+ template<typename C>
+ struct NullBinder : IArgFunction<C>{
+ virtual void set( C&, std::string const& ) const {}
+ virtual void setFlag( C& ) const {}
+ virtual bool takesArg() const { return true; }
+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+ };
+
+ template<typename C, typename M>
+ struct BoundDataMember : IArgFunction<C>{
+ BoundDataMember( M C::* _member ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ convertInto( stringValue, p.*member );
+ }
+ virtual void setFlag( C& p ) const {
+ convertInto( true, p.*member );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+ M C::* member;
+ };
+ template<typename C, typename M>
+ struct BoundUnaryMethod : IArgFunction<C>{
+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( stringValue, value );
+ (p.*member)( value );
+ }
+ virtual void setFlag( C& p ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( true, value );
+ (p.*member)( value );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+ void (C::*member)( M );
+ };
+ template<typename C>
+ struct BoundNullaryMethod : IArgFunction<C>{
+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ (p.*member)();
+ }
+ virtual void setFlag( C& p ) const {
+ (p.*member)();
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+ void (C::*member)();
+ };
+
+ template<typename C>
+ struct BoundUnaryFunction : IArgFunction<C>{
+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ function( obj );
+ }
+ virtual void setFlag( C& p ) const {
+ function( p );
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+ void (*function)( C& );
+ };
+
+ template<typename C, typename T>
+ struct BoundBinaryFunction : IArgFunction<C>{
+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( stringValue, value );
+ function( obj, value );
+ }
+ virtual void setFlag( C& obj ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( true, value );
+ function( obj, value );
+ }
+ virtual bool takesArg() const { return !IsBool<T>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+ void (*function)( C&, T );
+ };
+
+ } // namespace Detail
+
+ struct Parser {
+ Parser() : separators( " \t=:" ) {}
+
+ struct Token {
+ enum Type { Positional, ShortOpt, LongOpt };
+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+ Type type;
+ std::string data;
+ };
+
+ void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const {
+ const std::string doubleDash = "--";
+ for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
+ parseIntoTokens( argv[i] , tokens);
+ }
+ void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
+ while( !arg.empty() ) {
+ Parser::Token token( Parser::Token::Positional, arg );
+ arg = "";
+ if( token.data[0] == '-' ) {
+ if( token.data.size() > 1 && token.data[1] == '-' ) {
+ token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
+ }
+ else {
+ token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
+ if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
+ arg = "-" + token.data.substr( 1 );
+ token.data = token.data.substr( 0, 1 );
+ }
+ }
+ }
+ if( token.type != Parser::Token::Positional ) {
+ std::size_t pos = token.data.find_first_of( separators );
+ if( pos != std::string::npos ) {
+ arg = token.data.substr( pos+1 );
+ token.data = token.data.substr( 0, pos );
+ }
+ }
+ tokens.push_back( token );
+ }
+ }
+ std::string separators;
+ };
+
+ template<typename ConfigT>
+ struct CommonArgProperties {
+ CommonArgProperties() {}
+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+ Detail::BoundArgFunction<ConfigT> boundField;
+ std::string description;
+ std::string detail;
+ std::string placeholder; // Only value if boundField takes an arg
+
+ bool takesArg() const {
+ return !placeholder.empty();
+ }
+ void validate() const {
+ if( !boundField.isSet() )
+ throw std::logic_error( "option not bound" );
+ }
+ };
+ struct OptionArgProperties {
+ std::vector<std::string> shortNames;
+ std::string longName;
+
+ bool hasShortName( std::string const& shortName ) const {
+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+ }
+ bool hasLongName( std::string const& _longName ) const {
+ return _longName == longName;
+ }
+ };
+ struct PositionalArgProperties {
+ PositionalArgProperties() : position( -1 ) {}
+ int position; // -1 means non-positional (floating)
+
+ bool isFixedPositional() const {
+ return position != -1;
+ }
+ };
+
+ template<typename ConfigT>
+ class CommandLine {
+
+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+ Arg() {}
+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+ std::string dbgName() const {
+ if( !longName.empty() )
+ return "--" + longName;
+ if( !shortNames.empty() )
+ return "-" + shortNames[0];
+ return "positional args";
+ }
+ std::string commands() const {
+ std::ostringstream oss;
+ bool first = true;
+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+ for(; it != itEnd; ++it ) {
+ if( first )
+ first = false;
+ else
+ oss << ", ";
+ oss << "-" << *it;
+ }
+ if( !longName.empty() ) {
+ if( !first )
+ oss << ", ";
+ oss << "--" << longName;
+ }
+ if( !placeholder.empty() )
+ oss << " <" << placeholder << ">";
+ return oss.str();
+ }
+ };
+
+ // NOTE: std::auto_ptr is deprecated in c++11/c++0x
+#if defined(__cplusplus) && __cplusplus > 199711L
+ typedef std::unique_ptr<Arg> ArgAutoPtr;
+#else
+ typedef std::auto_ptr<Arg> ArgAutoPtr;
+#endif
+
+ friend void addOptName( Arg& arg, std::string const& optName )
+ {
+ if( optName.empty() )
+ return;
+ if( Detail::startsWith( optName, "--" ) ) {
+ if( !arg.longName.empty() )
+ throw std::logic_error( "Only one long opt may be specified. '"
+ + arg.longName
+ + "' already specified, now attempting to add '"
+ + optName + "'" );
+ arg.longName = optName.substr( 2 );
+ }
+ else if( Detail::startsWith( optName, "-" ) )
+ arg.shortNames.push_back( optName.substr( 1 ) );
+ else
+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+ }
+ friend void setPositionalArg( Arg& arg, int position )
+ {
+ arg.position = position;
+ }
+
+ class ArgBuilder {
+ public:
+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+ // Bind a non-boolean data member (requires placeholder string)
+ template<typename C, typename M>
+ void bind( M C::* field, std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+ m_arg->placeholder = placeholder;
+ }
+ // Bind a boolean data member (no placeholder required)
+ template<typename C>
+ void bind( bool C::* field ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+ }
+
+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+ template<typename C, typename M>
+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+ m_arg->placeholder = placeholder;
+ }
+
+ // Bind a method taking a single, boolean argument (no placeholder string required)
+ template<typename C>
+ void bind( void (C::* unaryMethod)( bool ) ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+ }
+
+ // Bind a method that takes no arguments (will be called if opt is present)
+ template<typename C>
+ void bind( void (C::* nullaryMethod)() ) {
+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+ template<typename C>
+ void bind( void (* unaryFunction)( C& ) ) {
+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+ template<typename C, typename T>
+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+ m_arg->placeholder = placeholder;
+ }
+
+ ArgBuilder& describe( std::string const& description ) {
+ m_arg->description = description;
+ return *this;
+ }
+ ArgBuilder& detail( std::string const& detail ) {
+ m_arg->detail = detail;
+ return *this;
+ }
+
+ protected:
+ Arg* m_arg;
+ };
+
+ class OptBuilder : public ArgBuilder {
+ public:
+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+ OptBuilder& operator[]( std::string const& optName ) {
+ addOptName( *ArgBuilder::m_arg, optName );
+ return *this;
+ }
+ };
+
+ public:
+
+ CommandLine()
+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+ m_highestSpecifiedArgPosition( 0 ),
+ m_throwOnUnrecognisedTokens( false )
+ {}
+ CommandLine( CommandLine const& other )
+ : m_boundProcessName( other.m_boundProcessName ),
+ m_options ( other.m_options ),
+ m_positionalArgs( other.m_positionalArgs ),
+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+ {
+ if( other.m_floatingArg.get() )
+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+ }
+
+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+ m_throwOnUnrecognisedTokens = shouldThrow;
+ return *this;
+ }
+
+ OptBuilder operator[]( std::string const& optName ) {
+ m_options.push_back( Arg() );
+ addOptName( m_options.back(), optName );
+ OptBuilder builder( &m_options.back() );
+ return builder;
+ }
+
+ ArgBuilder operator[]( int position ) {
+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+ if( position > m_highestSpecifiedArgPosition )
+ m_highestSpecifiedArgPosition = position;
+ setPositionalArg( m_positionalArgs[position], position );
+ ArgBuilder builder( &m_positionalArgs[position] );
+ return builder;
+ }
+
+ // Invoke this with the _ instance
+ ArgBuilder operator[]( UnpositionalTag ) {
+ if( m_floatingArg.get() )
+ throw std::logic_error( "Only one unpositional argument can be added" );
+ m_floatingArg.reset( new Arg() );
+ ArgBuilder builder( m_floatingArg.get() );
+ return builder;
+ }
+
+ template<typename C, typename M>
+ void bindProcessName( M C::* field ) {
+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+ }
+ template<typename C, typename M>
+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+ }
+
+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+ std::size_t maxWidth = 0;
+ for( it = itBegin; it != itEnd; ++it )
+ maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+ for( it = itBegin; it != itEnd; ++it ) {
+ Detail::Text usage( it->commands(), Detail::TextAttributes()
+ .setWidth( maxWidth+indent )
+ .setIndent( indent ) );
+ Detail::Text desc( it->description, Detail::TextAttributes()
+ .setWidth( width - maxWidth - 3 ) );
+
+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+ std::string usageCol = i < usage.size() ? usage[i] : "";
+ os << usageCol;
+
+ if( i < desc.size() && !desc[i].empty() )
+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+ << desc[i];
+ os << "\n";
+ }
+ }
+ }
+ std::string optUsage() const {
+ std::ostringstream oss;
+ optUsage( oss );
+ return oss.str();
+ }
+
+ void argSynopsis( std::ostream& os ) const {
+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+ if( i > 1 )
+ os << " ";
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+ if( it != m_positionalArgs.end() )
+ os << "<" << it->second.placeholder << ">";
+ else if( m_floatingArg.get() )
+ os << "<" << m_floatingArg->placeholder << ">";
+ else
+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
+ }
+ // !TBD No indication of mandatory args
+ if( m_floatingArg.get() ) {
+ if( m_highestSpecifiedArgPosition > 1 )
+ os << " ";
+ os << "[<" << m_floatingArg->placeholder << "> ...]";
+ }
+ }
+ std::string argSynopsis() const {
+ std::ostringstream oss;
+ argSynopsis( oss );
+ return oss.str();
+ }
+
+ void usage( std::ostream& os, std::string const& procName ) const {
+ validate();
+ os << "usage:\n " << procName << " ";
+ argSynopsis( os );
+ if( !m_options.empty() ) {
+ os << " [options]\n\nwhere options are: \n";
+ optUsage( os, 2 );
+ }
+ os << "\n";
+ }
+ std::string usage( std::string const& procName ) const {
+ std::ostringstream oss;
+ usage( oss, procName );
+ return oss.str();
+ }
+
+ ConfigT parse( int argc, char const * const * argv ) const {
+ ConfigT config;
+ parseInto( argc, argv, config );
+ return config;
+ }
+
+ std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const {
+ std::string processName = argv[0];
+ std::size_t lastSlash = processName.find_last_of( "/\\" );
+ if( lastSlash != std::string::npos )
+ processName = processName.substr( lastSlash+1 );
+ m_boundProcessName.set( config, processName );
+ std::vector<Parser::Token> tokens;
+ Parser parser;
+ parser.parseIntoTokens( argc, argv, tokens );
+ return populate( tokens, config );
+ }
+
+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ validate();
+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+ unusedTokens = populateFixedArgs( unusedTokens, config );
+ unusedTokens = populateFloatingArgs( unusedTokens, config );
+ return unusedTokens;
+ }
+
+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ std::vector<std::string> errors;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+ for(; it != itEnd; ++it ) {
+ Arg const& arg = *it;
+
+ try {
+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+ if( arg.takesArg() ) {
+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+ errors.push_back( "Expected argument to option: " + token.data );
+ else
+ arg.boundField.set( config, tokens[++i].data );
+ }
+ else {
+ arg.boundField.setFlag( config );
+ }
+ break;
+ }
+ }
+ catch( std::exception& ex ) {
+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+ }
+ }
+ if( it == itEnd ) {
+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+ unusedTokens.push_back( token );
+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
+ errors.push_back( "unrecognised option: " + token.data );
+ }
+ }
+ if( !errors.empty() ) {
+ std::ostringstream oss;
+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+ it != itEnd;
+ ++it ) {
+ if( it != errors.begin() )
+ oss << "\n";
+ oss << *it;
+ }
+ throw std::runtime_error( oss.str() );
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ int position = 1;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+ if( it != m_positionalArgs.end() )
+ it->second.boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ if( token.type == Parser::Token::Positional )
+ position++;
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ if( !m_floatingArg.get() )
+ return tokens;
+ std::vector<Parser::Token> unusedTokens;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ if( token.type == Parser::Token::Positional )
+ m_floatingArg->boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ }
+ return unusedTokens;
+ }
+
+ void validate() const
+ {
+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+ throw std::logic_error( "No options or arguments specified" );
+
+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
+ itEnd = m_options.end();
+ it != itEnd; ++it )
+ it->validate();
+ }
+
+ private:
+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+ std::vector<Arg> m_options;
+ std::map<int, Arg> m_positionalArgs;
+ ArgAutoPtr m_floatingArg;
+ int m_highestSpecifiedArgPosition;
+ bool m_throwOnUnrecognisedTokens;
+ };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+
+namespace Catch {
+
+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+ inline void abortAfterX( ConfigData& config, int x ) {
+ if( x < 1 )
+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+ config.abortAfter = x;
+ }
+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+
+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
+ if( _warning == "NoAssertions" )
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ else
+ throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
+ }
+ inline void setOrder( ConfigData& config, std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
+ }
+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+ if( seed == "time" ) {
+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
+ }
+ else {
+ std::stringstream ss;
+ ss << seed;
+ ss >> config.rngSeed;
+ if( ss.fail() )
+ throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
+ }
+ }
+ inline void setVerbosity( ConfigData& config, int level ) {
+ // !TBD: accept strings?
+ config.verbosity = static_cast<Verbosity::Level>( level );
+ }
+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+ config.showDurations = _showDurations
+ ? ShowDurations::Always
+ : ShowDurations::Never;
+ }
+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+ std::ifstream f( _filename.c_str() );
+ if( !f.is_open() )
+ throw std::domain_error( "Unable to load input file: " + _filename );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
+ }
+ }
+
+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+ using namespace Clara;
+ CommandLine<ConfigData> cli;
+
+ cli.bindProcessName( &ConfigData::processName );
+
+ cli["-?"]["-h"]["--help"]
+ .describe( "display usage information" )
+ .bind( &ConfigData::showHelp );
+
+ cli["-l"]["--list-tests"]
+ .describe( "list all/matching test cases" )
+ .bind( &ConfigData::listTests );
+
+ cli["-t"]["--list-tags"]
+ .describe( "list all/matching tags" )
+ .bind( &ConfigData::listTags );
+
+ cli["-s"]["--success"]
+ .describe( "include successful tests in output" )
+ .bind( &ConfigData::showSuccessfulTests );
+
+ cli["-b"]["--break"]
+ .describe( "break into debugger on failure" )
+ .bind( &ConfigData::shouldDebugBreak );
+
+ cli["-e"]["--nothrow"]
+ .describe( "skip exception tests" )
+ .bind( &ConfigData::noThrow );
+
+ cli["-i"]["--invisibles"]
+ .describe( "show invisibles (tabs, newlines)" )
+ .bind( &ConfigData::showInvisibles );
+
+ cli["-o"]["--out"]
+ .describe( "output filename" )
+ .bind( &ConfigData::outputFilename, "filename" );
+
+ cli["-r"]["--reporter"]
+// .placeholder( "name[:filename]" )
+ .describe( "reporter to use (defaults to console)" )
+ .bind( &ConfigData::reporterName, "name" );
+
+ cli["-n"]["--name"]
+ .describe( "suite name" )
+ .bind( &ConfigData::name, "name" );
+
+ cli["-a"]["--abort"]
+ .describe( "abort at first failure" )
+ .bind( &abortAfterFirst );
+
+ cli["-x"]["--abortx"]
+ .describe( "abort after x failures" )
+ .bind( &abortAfterX, "no. failures" );
+
+ cli["-w"]["--warn"]
+ .describe( "enable warnings" )
+ .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+// cli.into( &setVerbosity )
+// .describe( "level of verbosity (0=no output)" )
+// .shortOpt( "v")
+// .longOpt( "verbosity" )
+// .placeholder( "level" );
+
+ cli[_]
+ .describe( "which test or tests to use" )
+ .bind( &addTestOrTags, "test name, pattern or tags" );
+
+ cli["-d"]["--durations"]
+ .describe( "show test durations" )
+ .bind( &setShowDurations, "yes/no" );
+
+ cli["-f"]["--input-file"]
+ .describe( "load test names to run from a file" )
+ .bind( &loadTestNamesFromFile, "filename" );
+
+ // Less common commands which don't have a short form
+ cli["--list-test-names-only"]
+ .describe( "list all/matching test cases names only" )
+ .bind( &ConfigData::listTestNamesOnly );
+
+ cli["--list-reporters"]
+ .describe( "list all reporters" )
+ .bind( &ConfigData::listReporters );
+
+ cli["--order"]
+ .describe( "test case order (defaults to decl)" )
+ .bind( &setOrder, "decl|lex|rand" );
+
+ cli["--rng-seed"]
+ .describe( "set a specific seed for random numbers" )
+ .bind( &setRngSeed, "'time'|number" );
+
+ cli["--force-colour"]
+ .describe( "force colourised output" )
+ .bind( &ConfigData::forceColour );
+
+ return cli;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# endif
+# else
+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+ using Tbc::Text;
+ using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+
+ // By intention
+ FileName = LightGrey,
+ Warning = Yellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = Yellow,
+
+ SecondaryText = LightGrey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour const& other );
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved;
+ };
+
+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+#include <assert.h>
+
+namespace Catch
+{
+ struct ReporterConfig {
+ explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& stream() const { return *m_stream; }
+ Ptr<IConfig> fullConfig() const { return m_fullConfig; }
+
+ private:
+ std::ostream* m_stream;
+ Ptr<IConfig> m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ ReporterPreferences()
+ : shouldRedirectStdOut( false )
+ {}
+
+ bool shouldRedirectStdOut;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat() : used( false ) {}
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name ) : name( _name ) {}
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+ virtual ~AssertionStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+# endif
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+ virtual ~SectionStats();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+# endif
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+ virtual ~TestCaseStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+# endif
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+ virtual ~TestGroupStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+# endif
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ virtual ~TestRunStats();
+
+# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestRunStats( TestRunStats const& _other )
+ : runInfo( _other.runInfo ),
+ totals( _other.totals ),
+ aborting( _other.aborting )
+ {}
+# else
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+# endif
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct IStreamingReporter : IShared {
+ virtual ~IStreamingReporter();
+
+ // Implementing class must also provide the following static method:
+ // static std::string getDescription();
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+ };
+
+ struct IReporterFactory {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+
+ struct IReporterRegistry {
+ typedef std::map<std::string, IReporterFactory*> FactoryMap;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ };
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+ inline std::size_t listTests( Config const& config ) {
+
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::size_t matchedTests = 0;
+ TextAttributes nameAttr, tagsAttr;
+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+ tagsAttr.setIndent( 6 );
+
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+ }
+
+ if( !config.testSpec().hasFilters() )
+ Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
+ return matchedTests;
+ }
+
+ inline std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( !config.testSpec().hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Catch::cout() << testCaseInfo.name << std::endl;
+ }
+ return matchedTests;
+ }
+
+ struct TagInfo {
+ TagInfo() : count ( 0 ) {}
+ void add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+ std::string all() const {
+ std::string out;
+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+ it != itEnd;
+ ++it )
+ out += "[" + *it + "]";
+ return out;
+ }
+ std::set<std::string> spellings;
+ std::size_t count;
+ };
+
+ inline std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
+ tagItEnd = it->getTestCaseInfo().tags.end();
+ tagIt != tagItEnd;
+ ++tagIt ) {
+ std::string tagName = *tagIt;
+ std::string lcaseTagName = toLower( tagName );
+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+ countItEnd = tagCounts.end();
+ countIt != countItEnd;
+ ++countIt ) {
+ std::ostringstream oss;
+ oss << " " << std::setw(2) << countIt->second.count << " ";
+ Text wrapper( countIt->second.all(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( oss.str().size() )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+ Catch::cout() << oss.str() << wrapper << "\n";
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
+ return tagCounts.size();
+ }
+
+ inline std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+ std::size_t maxNameLen = 0;
+ for(it = itBegin; it != itEnd; ++it )
+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+ for(it = itBegin; it != itEnd; ++it ) {
+ Text wrapper( it->second->getDescription(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( 7+maxNameLen )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+ Catch::cout() << " "
+ << it->first
+ << ":"
+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
+ << wrapper << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ inline Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_runner_impl.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <map>
+#include <string>
+#include <assert.h>
+
+namespace Catch {
+namespace SectionTracking {
+
+ class TrackedSection {
+
+ typedef std::map<std::string, TrackedSection> TrackedSections;
+
+ public:
+ enum RunState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ Completed
+ };
+
+ TrackedSection( std::string const& name, TrackedSection* parent )
+ : m_name( name ), m_runState( NotStarted ), m_parent( parent )
+ {}
+
+ RunState runState() const { return m_runState; }
+
+ TrackedSection* findChild( std::string const& childName );
+ TrackedSection* acquireChild( std::string const& childName );
+
+ void enter() {
+ if( m_runState == NotStarted )
+ m_runState = Executing;
+ }
+ void leave();
+
+ TrackedSection* getParent() {
+ return m_parent;
+ }
+ bool hasChildren() const {
+ return !m_children.empty();
+ }
+
+ private:
+ std::string m_name;
+ RunState m_runState;
+ TrackedSections m_children;
+ TrackedSection* m_parent;
+ };
+
+ inline TrackedSection* TrackedSection::findChild( std::string const& childName ) {
+ TrackedSections::iterator it = m_children.find( childName );
+ return it != m_children.end()
+ ? &it->second
+ : NULL;
+ }
+ inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) {
+ if( TrackedSection* child = findChild( childName ) )
+ return child;
+ m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) );
+ return findChild( childName );
+ }
+ inline void TrackedSection::leave() {
+ for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end();
+ it != itEnd;
+ ++it )
+ if( it->second.runState() != Completed ) {
+ m_runState = ExecutingChildren;
+ return;
+ }
+ m_runState = Completed;
+ }
+
+ class TestCaseTracker {
+ public:
+ TestCaseTracker( std::string const& testCaseName )
+ : m_testCase( testCaseName, NULL ),
+ m_currentSection( &m_testCase ),
+ m_completedASectionThisRun( false )
+ {}
+
+ bool enterSection( std::string const& name ) {
+ TrackedSection* child = m_currentSection->acquireChild( name );
+ if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
+ return false;
+
+ m_currentSection = child;
+ m_currentSection->enter();
+ return true;
+ }
+ void leaveSection() {
+ m_currentSection->leave();
+ m_currentSection = m_currentSection->getParent();
+ assert( m_currentSection != NULL );
+ m_completedASectionThisRun = true;
+ }
+
+ bool currentSectionHasChildren() const {
+ return m_currentSection->hasChildren();
+ }
+ bool isCompleted() const {
+ return m_testCase.runState() == TrackedSection::Completed;
+ }
+
+ class Guard {
+ public:
+ Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
+ m_tracker.enterTestCase();
+ }
+ ~Guard() {
+ m_tracker.leaveTestCase();
+ }
+ private:
+ Guard( Guard const& );
+ void operator = ( Guard const& );
+ TestCaseTracker& m_tracker;
+ };
+
+ private:
+ void enterTestCase() {
+ m_currentSection = &m_testCase;
+ m_completedASectionThisRun = false;
+ m_testCase.enter();
+ }
+ void leaveTestCase() {
+ m_testCase.leave();
+ }
+
+ TrackedSection m_testCase;
+ TrackedSection* m_currentSection;
+ bool m_completedASectionThisRun;
+ };
+
+} // namespace SectionTracking
+
+using SectionTracking::TestCaseTracker;
+
+} // namespace Catch
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+ // Report the error condition then exit the process
+ inline void fatal( std::string const& message, int exitCode ) {
+ IContext& context = Catch::getCurrentContext();
+ IResultCapture* resultCapture = context.getResultCapture();
+ resultCapture->handleFatalErrorCondition( message );
+
+ if( Catch::alwaysTrue() ) // avoids "no return" warnings
+ exit( exitCode );
+ }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+ void reset() {}
+ };
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct SignalDefs { int id; const char* name; };
+ extern SignalDefs signalDefs[];
+ SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ struct FatalConditionHandler {
+
+ static void handleSignal( int sig ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ if( sig == signalDefs[i].id )
+ fatal( signalDefs[i].name, -sig );
+ fatal( "<unknown signal>", -sig );
+ }
+
+ FatalConditionHandler() : m_isSet( true ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, handleSignal );
+ }
+ ~FatalConditionHandler() {
+ reset();
+ }
+ void reset() {
+ if( m_isSet ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, SIG_DFL );
+ m_isSet = false;
+ }
+ }
+
+ bool m_isSet;
+ };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+ class StreamRedirect {
+
+ public:
+ StreamRedirect( std::ostream& stream, std::string& targetString )
+ : m_stream( stream ),
+ m_prevBuf( stream.rdbuf() ),
+ m_targetString( targetString )
+ {
+ stream.rdbuf( m_oss.rdbuf() );
+ }
+
+ ~StreamRedirect() {
+ m_targetString += m_oss.str();
+ m_stream.rdbuf( m_prevBuf );
+ }
+
+ private:
+ std::ostream& m_stream;
+ std::streambuf* m_prevBuf;
+ std::ostringstream m_oss;
+ std::string& m_targetString;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ RunContext( RunContext const& );
+ void operator =( RunContext const& );
+
+ public:
+
+ explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter )
+ : m_runInfo( config->name() ),
+ m_context( getCurrentMutableContext() ),
+ m_activeTestCase( NULL ),
+ m_config( config ),
+ m_reporter( reporter ),
+ m_prevRunner( m_context.getRunner() ),
+ m_prevResultCapture( m_context.getResultCapture() ),
+ m_prevConfig( m_context.getConfig() )
+ {
+ m_context.setRunner( this );
+ m_context.setConfig( m_config );
+ m_context.setResultCapture( this );
+ m_reporter->testRunStarting( m_runInfo );
+ }
+
+ virtual ~RunContext() {
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+ m_context.setRunner( m_prevRunner );
+ m_context.setConfig( NULL );
+ m_context.setResultCapture( m_prevResultCapture );
+ m_context.setConfig( m_prevConfig );
+ }
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+ }
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+ }
+
+ Totals runTest( TestCase const& testCase ) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting( testInfo );
+
+ m_activeTestCase = &testCase;
+ m_testCaseTracker = TestCaseTracker( testInfo.name );
+
+ do {
+ do {
+ runCurrentTest( redirectedCout, redirectedCerr );
+ }
+ while( !m_testCaseTracker->isCompleted() && !aborting() );
+ }
+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+ Totals deltaTotals = m_totals.delta( prevTotals );
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting() ) );
+
+ m_activeTestCase = NULL;
+ m_testCaseTracker.reset();
+
+ return deltaTotals;
+ }
+
+ Ptr<IConfig const> config() const {
+ return m_config;
+ }
+
+ private: // IResultCapture
+
+ virtual void assertionEnded( AssertionResult const& result ) {
+ if( result.getResultType() == ResultWas::Ok ) {
+ m_totals.assertions.passed++;
+ }
+ else if( !result.isOk() ) {
+ m_totals.assertions.failed++;
+ }
+
+ if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
+ m_messages.clear();
+
+ // Reset working state
+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+ m_lastResult = result;
+ }
+
+ virtual bool sectionStarted (
+ SectionInfo const& sectionInfo,
+ Counts& assertions
+ )
+ {
+ std::ostringstream oss;
+ oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
+
+ if( !m_testCaseTracker->enterSection( oss.str() ) )
+ return false;
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting( sectionInfo );
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+ bool testForMissingAssertions( Counts& assertions ) {
+ if( assertions.total() != 0 ||
+ !m_config->warnAboutMissingAssertions() ||
+ m_testCaseTracker->currentSectionHasChildren() )
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) {
+ if( std::uncaught_exception() ) {
+ m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) );
+ return;
+ }
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ m_testCaseTracker->leaveSection();
+
+ m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) );
+ m_messages.clear();
+ }
+
+ virtual void pushScopedMessage( MessageInfo const& message ) {
+ m_messages.push_back( message );
+ }
+
+ virtual void popScopedMessage( MessageInfo const& message ) {
+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+ }
+
+ virtual std::string getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : "";
+ }
+
+ virtual const AssertionResult* getLastResult() const {
+ return &m_lastResult;
+ }
+
+ virtual void handleFatalErrorCondition( std::string const& message ) {
+ ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
+ resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+ resultBuilder << message;
+ resultBuilder.captureExpression();
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+ m_reporter->sectionEnded( testCaseSectionStats );
+
+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ "",
+ "",
+ false ) );
+ m_totals.testCases.failed++;
+ testGroupEnded( "", m_totals, 1, 1 );
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+ }
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+ }
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+ m_reporter->sectionStarting( testCaseSection );
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ try {
+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+ TestCaseTracker::Guard guard( *m_testCaseTracker );
+
+ Timer timer;
+ timer.start();
+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+ StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+ invokeActiveTestCase();
+ }
+ else {
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ }
+ catch( TestFailureException& ) {
+ // This just means the test was aborted due to failure
+ }
+ catch(...) {
+ makeUnexpectedResultBuilder().useActiveException();
+ }
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( testCaseInfo.okToFail() ) {
+ std::swap( assertions.failedButOk, assertions.failed );
+ m_totals.assertions.failed -= assertions.failedButOk;
+ m_totals.assertions.failedButOk += assertions.failedButOk;
+ }
+
+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+ m_reporter->sectionEnded( testCaseSectionStats );
+ }
+
+ void invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ private:
+
+ ResultBuilder makeUnexpectedResultBuilder() const {
+ return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
+ m_lastAssertionInfo.lineInfo,
+ m_lastAssertionInfo.capturedExpression.c_str(),
+ m_lastAssertionInfo.resultDisposition );
+ }
+
+ void handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it )
+ sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
+ m_unfinishedSections.clear();
+ }
+
+ struct UnfinishedSections {
+ UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
+ : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+ SectionInfo info;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase;
+ Option<TestCaseTracker> m_testCaseTracker;
+ AssertionResult m_lastResult;
+
+ Ptr<IConfig const> m_config;
+ Totals m_totals;
+ Ptr<IStreamingReporter> m_reporter;
+ std::vector<MessageInfo> m_messages;
+ IRunner* m_prevRunner;
+ IResultCapture* m_prevResultCapture;
+ Ptr<IConfig const> m_prevConfig;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<UnfinishedSections> m_unfinishedSections;
+ };
+
+ IResultCapture& getResultCapture() {
+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+ return *capture;
+ else
+ throw std::logic_error( "No result capture instance" );
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber );
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const patchNumber;
+
+ // buildNumber is only used if branchName is not null
+ std::string const branchName;
+ unsigned int const buildNumber;
+
+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
+
+ private:
+ void operator=( Version const& );
+ };
+
+ extern Version libraryVersion;
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+ class Runner {
+
+ public:
+ Runner( Ptr<Config> const& config )
+ : m_config( config )
+ {
+ openStream();
+ makeReporter();
+ }
+
+ Totals runTests() {
+
+ RunContext context( m_config.get(), m_reporter );
+
+ Totals totals;
+
+ context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
+
+ TestSpec testSpec = m_config->testSpec();
+ if( !testSpec.hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+ std::vector<TestCase> testCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
+
+ int testsRunForGroup = 0;
+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+ it != itEnd;
+ ++it ) {
+ testsRunForGroup++;
+ if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
+
+ if( context.aborting() )
+ break;
+
+ totals += context.runTest( *it );
+ m_testsAlreadyRun.insert( *it );
+ }
+ }
+ std::vector<TestCase> skippedTestCases;
+ getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
+
+ for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
+ it != itEnd;
+ ++it )
+ m_reporter->skipTest( *it );
+
+ context.testGroupEnded( "all tests", totals, 1, 1 );
+ return totals;
+ }
+
+ private:
+ void openStream() {
+ // Open output file, if specified
+ if( !m_config->getFilename().empty() ) {
+ m_ofs.open( m_config->getFilename().c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << m_config->getFilename() << "'";
+ throw std::domain_error( oss.str() );
+ }
+ m_config->setStreamBuf( m_ofs.rdbuf() );
+ }
+ }
+ void makeReporter() {
+ std::string reporterName = m_config->getReporterName().empty()
+ ? "console"
+ : m_config->getReporterName();
+
+ m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
+ if( !m_reporter ) {
+ std::ostringstream oss;
+ oss << "No reporter registered with name: '" << reporterName << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ private:
+ Ptr<Config> m_config;
+ std::ofstream m_ofs;
+ Ptr<IStreamingReporter> m_reporter;
+ std::set<TestCase> m_testsAlreadyRun;
+ };
+
+ class Session : NonCopyable {
+ static bool alreadyInstantiated;
+
+ public:
+
+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+ Session()
+ : m_cli( makeCommandLineParser() ) {
+ if( alreadyInstantiated ) {
+ std::string msg = "Only one instance of Catch::Session can ever be used";
+ Catch::cerr() << msg << std::endl;
+ throw std::logic_error( msg );
+ }
+ alreadyInstantiated = true;
+ }
+ ~Session() {
+ Catch::cleanUp();
+ }
+
+ void showHelp( std::string const& processName ) {
+ Catch::cout() << "\nCatch v" << libraryVersion << "\n";
+
+ m_cli.usage( Catch::cout(), processName );
+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+ }
+
+ int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+ try {
+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+ m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
+ if( m_configData.showHelp )
+ showHelp( m_configData.processName );
+ m_config.reset();
+ }
+ catch( std::exception& ex ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "\nError(s) in input:\n"
+ << Text( ex.what(), TextAttributes().setIndent(2) )
+ << "\n\n";
+ }
+ m_cli.usage( Catch::cout(), m_configData.processName );
+ return (std::numeric_limits<int>::max)();
+ }
+ return 0;
+ }
+
+ void useConfigData( ConfigData const& _configData ) {
+ m_configData = _configData;
+ m_config.reset();
+ }
+
+ int run( int argc, char* const argv[] ) {
+
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+
+ int run() {
+ if( m_configData.showHelp )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ std::srand( m_configData.rngSeed );
+
+ Runner runner( m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ return static_cast<int>( runner.runTests().assertions.failed );
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return (std::numeric_limits<int>::max)();
+ }
+ }
+
+ Clara::CommandLine<ConfigData> const& cli() const {
+ return m_cli;
+ }
+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
+ return m_unusedTokens;
+ }
+ ConfigData& configData() {
+ return m_configData;
+ }
+ Config& config() {
+ if( !m_config )
+ m_config = new Config( m_configData );
+ return *m_config;
+ }
+
+ private:
+ Clara::CommandLine<ConfigData> m_cli;
+ std::vector<Clara::Parser::Token> m_unusedTokens;
+ ConfigData m_configData;
+ Ptr<Config> m_config;
+ };
+
+ bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+namespace Catch {
+
+ class TestRegistry : public ITestCaseRegistry {
+ struct LexSort {
+ bool operator() (TestCase i,TestCase j) const { return (i<j);}
+ };
+ struct RandomNumberGenerator {
+ int operator()( int n ) const { return std::rand() % n; }
+ };
+
+ public:
+ TestRegistry() : m_unnamedCount( 0 ) {}
+ virtual ~TestRegistry();
+
+ virtual void registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name == "" ) {
+ std::ostringstream oss;
+ oss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( oss.str() ) );
+ }
+
+ if( m_functions.find( testCase ) == m_functions.end() ) {
+ m_functions.insert( testCase );
+ m_functionsInOrder.push_back( testCase );
+ if( !testCase.isHidden() )
+ m_nonHiddenFunctions.push_back( testCase );
+ }
+ else {
+ TestCase const& prev = *m_functions.find( testCase );
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ virtual std::vector<TestCase> const& getAllTests() const {
+ return m_functionsInOrder;
+ }
+
+ virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
+ return m_nonHiddenFunctions;
+ }
+
+ virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
+
+ for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
+ itEnd = m_functionsInOrder.end();
+ it != itEnd;
+ ++it ) {
+ bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
+ if( includeTest != negated )
+ matchingTestCases.push_back( *it );
+ }
+ sortTests( config, matchingTestCases );
+ }
+
+ private:
+
+ static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
+ break;
+ case RunTests::InRandomOrder:
+ {
+ RandomNumberGenerator rng;
+ std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
+ }
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ }
+ std::set<TestCase> m_functions;
+ std::vector<TestCase> m_functionsInOrder;
+ std::vector<TestCase> m_nonHiddenFunctions;
+ size_t m_unnamedCount;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+ public:
+
+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+ virtual void invoke() const {
+ m_fun();
+ }
+
+ private:
+ virtual ~FreeFunctionTestCase();
+
+ TestFunction m_fun;
+ };
+
+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, "&" ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ AutoReg::AutoReg( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+ }
+
+ AutoReg::~AutoReg() {}
+
+ void AutoReg::registerTestCase( ITestCase* testCase,
+ char const* classOrQualifiedMethodName,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ getMutableRegistryHub().registerTest
+ ( makeTestCase( testCase,
+ extractClassName( classOrQualifiedMethodName ),
+ nameAndDesc.name,
+ nameAndDesc.description,
+ lineInfo ) );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ virtual ~ReporterRegistry() {
+ deleteAllValues( m_factories );
+ }
+
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
+ FactoryMap::const_iterator it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return NULL;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void registerReporter( std::string const& name, IReporterFactory* factory ) {
+ m_factories.insert( std::make_pair( name, factory ) );
+ }
+
+ FactoryMap const& getFactories() const {
+ return m_factories;
+ }
+
+ private:
+ FactoryMap m_factories;
+ };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry() {
+ deleteAll( m_translators );
+ }
+
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( translator );
+ }
+
+ virtual std::string translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ throw;
+ }
+ @catch (NSException *exception) {
+ return Catch::toString( [exception description] );
+ }
+#else
+ throw;
+#endif
+ }
+ catch( TestFailureException& ) {
+ throw;
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return tryTranslators( m_translators.begin() );
+ }
+ }
+
+ std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const {
+ if( it == m_translators.end() )
+ return "Unknown exception";
+
+ try {
+ return (*it)->translate();
+ }
+ catch(...) {
+ return tryTranslators( it+1 );
+ }
+ }
+
+ private:
+ std::vector<const IExceptionTranslator*> m_translators;
+ };
+}
+
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+ RegistryHub( RegistryHub const& );
+ void operator=( RegistryHub const& );
+
+ public: // IRegistryHub
+ RegistryHub() {
+ }
+ virtual IReporterRegistry const& getReporterRegistry() const {
+ return m_reporterRegistry;
+ }
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const {
+ return m_testCaseRegistry;
+ }
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
+ return m_exceptionTranslatorRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ virtual void registerTest( TestCase const& testInfo ) {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ };
+
+ // Single, global, instance
+ inline RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = NULL;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = NULL;
+ cleanUpContext();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <ostream>
+
+namespace Catch {
+
+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+ : m_lineInfo( lineInfo ) {
+ std::ostringstream oss;
+ oss << lineInfo << ": function ";
+ oss << "not implemented";
+ m_what = oss.str();
+ }
+
+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+ return m_what.c_str();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+ class StreamBufBase : public std::streambuf {
+ public:
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+ template<typename WriterF, size_t bufferSize=256>
+ class StreamBufImpl : public StreamBufBase {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() CATCH_NOEXCEPT {
+ sync();
+ }
+
+ private:
+ int overflow( int c ) {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ Stream::Stream()
+ : streamBuf( NULL ), isOwned( false )
+ {}
+
+ Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
+ : streamBuf( _streamBuf ), isOwned( _isOwned )
+ {}
+
+ void Stream::release() {
+ if( isOwned ) {
+ delete streamBuf;
+ streamBuf = NULL;
+ isOwned = false;
+ }
+ }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
+ std::ostream& cout() {
+ return std::cout;
+ }
+ std::ostream& cerr() {
+ return std::cerr;
+ }
+#endif
+}
+
+namespace Catch {
+
+ class Context : public IMutableContext {
+
+ Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {}
+ Context( Context const& );
+ void operator=( Context const& );
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() {
+ return m_runner;
+ }
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+ return getGeneratorsForCurrentTest()
+ .getGeneratorInfo( fileInfo, totalSize )
+ .getCurrentIndex();
+ }
+ virtual bool advanceGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ return generators && generators->moveNext();
+ }
+
+ virtual Ptr<IConfig const> getConfig() const {
+ return m_config;
+ }
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) {
+ m_runner = runner;
+ }
+ virtual void setConfig( Ptr<IConfig const> const& config ) {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
+ std::string testName = getResultCapture()->getCurrentTestName();
+
+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+ m_generatorsByTestName.find( testName );
+ return it != m_generatorsByTestName.end()
+ ? it->second
+ : NULL;
+ }
+
+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ if( !generators ) {
+ std::string testName = getResultCapture()->getCurrentTestName();
+ generators = createGeneratorsForTest();
+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+ }
+ return *generators;
+ }
+
+ private:
+ Ptr<IConfig const> m_config;
+ IRunner* m_runner;
+ IResultCapture* m_resultCapture;
+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+ };
+
+ namespace {
+ Context* currentContext = NULL;
+ }
+ IMutableContext& getCurrentMutableContext() {
+ if( !currentContext )
+ currentContext = new Context();
+ return *currentContext;
+ }
+ IContext& getCurrentContext() {
+ return getCurrentMutableContext();
+ }
+
+ Stream createStream( std::string const& streamName ) {
+ if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
+ if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
+ if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
+
+ throw std::domain_error( "Unknown stream: " + streamName );
+ }
+
+ void cleanUpContext() {
+ delete currentContext;
+ currentContext = NULL;
+ }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() {}
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalAttributes = csbiInfo.wAttributes;
+ }
+
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute );
+ }
+ HANDLE stdoutHandle;
+ WORD originalAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+ return &s_instance;
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0:34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ IColourImpl* platformColourInstance() {
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ return (config && config->forceColour()) || isatty(STDOUT_FILENO)
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = isDebuggerActive()
+ ? NoColourImpl::instance()
+ : platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+ struct GeneratorInfo : IGeneratorInfo {
+
+ GeneratorInfo( std::size_t size )
+ : m_size( size ),
+ m_currentIndex( 0 )
+ {}
+
+ bool moveNext() {
+ if( ++m_currentIndex == m_size ) {
+ m_currentIndex = 0;
+ return false;
+ }
+ return true;
+ }
+
+ std::size_t getCurrentIndex() const {
+ return m_currentIndex;
+ }
+
+ std::size_t m_size;
+ std::size_t m_currentIndex;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class GeneratorsForTest : public IGeneratorsForTest {
+
+ public:
+ ~GeneratorsForTest() {
+ deleteAll( m_generatorsInOrder );
+ }
+
+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+ if( it == m_generatorsByName.end() ) {
+ IGeneratorInfo* info = new GeneratorInfo( size );
+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+ m_generatorsInOrder.push_back( info );
+ return *info;
+ }
+ return *it->second;
+ }
+
+ bool moveNext() {
+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+ for(; it != itEnd; ++it ) {
+ if( (*it)->moveNext() )
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest()
+ {
+ return new GeneratorsForTest();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+ AssertionInfo::AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ capturedExpression( _capturedExpression ),
+ resultDisposition( _resultDisposition )
+ {}
+
+ AssertionResult::AssertionResult() {}
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ AssertionResult::~AssertionResult() {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return !m_info.capturedExpression.empty();
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!" + m_info.capturedExpression;
+ else
+ return m_info.capturedExpression;
+ }
+ std::string AssertionResult::getExpressionInMacro() const {
+ if( m_info.macroName.empty() )
+ return m_info.capturedExpression;
+ else
+ return m_info.macroName + "( " + m_info.capturedExpression + " )";
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ return m_resultData.reconstructedExpression;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ std::string AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+namespace Catch {
+
+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, "." ) ||
+ tag == "hide" ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else
+ return TestCaseInfo::None;
+ }
+ inline bool isReservedTag( std::string const& tag ) {
+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
+ }
+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ if( isReservedTag( tag ) ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "Tag name [" << tag << "] not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n";
+ }
+ {
+ Colour colourGuard( Colour::FileName );
+ Catch::cerr() << _lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ TestCase makeTestCase( ITestCase* _testCase,
+ std::string const& _className,
+ std::string const& _name,
+ std::string const& _descOrTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+ // Parse out tags
+ std::set<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+ char c = _descOrTags[i];
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( prop == TestCaseInfo::IsHidden )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.insert( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.insert( "hide" );
+ tags.insert( "." );
+ }
+
+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, info );
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ tags( _tags ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ std::ostringstream oss;
+ for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) {
+ oss << "[" << *it << "]";
+ std::string lcaseTag = toLower( *it );
+ properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) );
+ lcaseTags.insert( lcaseTag );
+ }
+ tagsAsString = oss.str();
+ }
+
+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+ : name( other.name ),
+ className( other.className ),
+ description( other.description ),
+ tags( other.tags ),
+ lcaseTags( other.lcaseTags ),
+ tagsAsString( other.tagsAsString ),
+ lineInfo( other.lineInfo ),
+ properties( other.properties )
+ {}
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+ TestCase::TestCase( TestCase const& other )
+ : TestCaseInfo( other ),
+ test( other.test )
+ {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::swap( TestCase& other ) {
+ test.swap( other.test );
+ name.swap( other.name );
+ className.swap( other.className );
+ description.swap( other.description );
+ tags.swap( other.tags );
+ lcaseTags.swap( other.lcaseTags );
+ tagsAsString.swap( other.tagsAsString );
+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+ std::swap( lineInfo, other.lineInfo );
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+ TestCase& TestCase::operator = ( TestCase const& other ) {
+ TestCase temp( other );
+ swap( temp );
+ return *this;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+ Version::Version
+ ( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ patchNumber( _patchNumber ),
+ branchName( _branchName ),
+ buildNumber( _buildNumber )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
+ os << version.majorVersion << "."
+ << version.minorVersion << "."
+ << version.patchNumber;
+
+ if( !version.branchName.empty() ) {
+ os << "-" << version.branchName
+ << "." << version.buildNumber;
+ }
+ return os;
+ }
+
+ Version libraryVersion( 1, 2, 1, "", 0 );
+
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
+ : m_info( other.m_info )
+ {}
+
+ ScopedMessage::~ScopedMessage() {
+ getResultCapture().popScopedMessage( m_info );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+ // Deprecated
+ struct IReporter : IShared {
+ virtual ~IReporter();
+
+ virtual bool shouldRedirectStdout() const = 0;
+
+ virtual void StartTesting() = 0;
+ virtual void EndTesting( Totals const& totals ) = 0;
+ virtual void StartGroup( std::string const& groupName ) = 0;
+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+ virtual void Aborted() = 0;
+ virtual void Result( AssertionResult const& result ) = 0;
+ };
+
+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+ {
+ public:
+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+ virtual ~LegacyReporterAdapter();
+
+ virtual ReporterPreferences getPreferences() const;
+ virtual void noMatchingTestCases( std::string const& );
+ virtual void testRunStarting( TestRunInfo const& );
+ virtual void testGroupStarting( GroupInfo const& groupInfo );
+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
+ virtual void sectionStarting( SectionInfo const& sectionInfo );
+ virtual void assertionStarting( AssertionInfo const& );
+ virtual bool assertionEnded( AssertionStats const& assertionStats );
+ virtual void sectionEnded( SectionStats const& sectionStats );
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+ virtual void testRunEnded( TestRunStats const& testRunStats );
+ virtual void skipTest( TestCaseInfo const& );
+
+ private:
+ Ptr<IReporter> m_legacyReporter;
+ };
+}
+
+namespace Catch
+{
+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+ : m_legacyReporter( legacyReporter )
+ {}
+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+ return prefs;
+ }
+
+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+ m_legacyReporter->StartTesting();
+ }
+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+ m_legacyReporter->StartGroup( groupInfo.name );
+ }
+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ m_legacyReporter->StartTestCase( testInfo );
+ }
+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+ }
+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+ // Not on legacy interface
+ }
+
+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+ rb << it->message;
+ rb.setResultType( ResultWas::Info );
+ AssertionResult result = rb.build();
+ m_legacyReporter->Result( result );
+ }
+ }
+ }
+ m_legacyReporter->Result( assertionStats.assertionResult );
+ return true;
+ }
+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+ if( sectionStats.missingAssertions )
+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+ }
+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ m_legacyReporter->EndTestCase
+ ( testCaseStats.testInfo,
+ testCaseStats.totals,
+ testCaseStats.stdOut,
+ testCaseStats.stdErr );
+ }
+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ if( testGroupStats.aborting )
+ m_legacyReporter->Aborted();
+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+ }
+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+ m_legacyReporter->EndTesting( testRunStats.totals );
+ }
+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+ }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace Catch {
+
+ namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+ uint64_t getCurrentTicks() {
+ static uint64_t hz=0, hzo=0;
+ if (!hz) {
+ QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
+ }
+ uint64_t t;
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
+ return ((t-hzo)*1000000)/hz;
+ }
+#else
+ uint64_t getCurrentTicks() {
+ timeval t;
+ gettimeofday(&t,NULL);
+ return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
+ }
+#endif
+ }
+
+ void Timer::start() {
+ m_ticks = getCurrentTicks();
+ }
+ unsigned int Timer::getElapsedMicroseconds() const {
+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+ }
+ unsigned int Timer::getElapsedMilliseconds() const {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ double Timer::getElapsedSeconds() const {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << " " << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << "s";
+ return os;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+ return line < other.line || ( line == other.line && file < other.file );
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << "(" << info.line << ")";
+#else
+ os << info.file << ":" << info.line;
+#endif
+ return os;
+ }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+ std::ostringstream oss;
+ oss << locationInfo << ": Internal Catch error: '" << message << "'";
+ if( alwaysTrue() )
+ throw std::logic_error( oss.str() );
+ }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded )
+ getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#include <iostream>
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sysctl.h>
+
+ namespace Catch{
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ inline bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+#else
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+ std::string unprintableString = "{?}";
+
+ namespace {
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size )
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>( size ), inc = 1;
+ if( Endianness::which() == Endianness::Little ) {
+ i = end-1;
+ end = inc = -1;
+ }
+
+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return os.str();
+ }
+}
+
+std::string toString( std::string const& value ) {
+ std::string s = value;
+ if( getCurrentContext().getConfig()->showInvisibles() ) {
+ for(size_t i = 0; i < s.size(); ++i ) {
+ std::string subs;
+ switch( s[i] ) {
+ case '\n': subs = "\\n"; break;
+ case '\t': subs = "\\t"; break;
+ default: break;
+ }
+ if( !subs.empty() ) {
+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
+ ++i;
+ }
+ }
+ }
+ return "\"" + s + "\"";
+}
+std::string toString( std::wstring const& value ) {
+
+ std::string s;
+ s.reserve( value.size() );
+ for(size_t i = 0; i < value.size(); ++i )
+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+ return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+ return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+ return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value >= 255 )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value >= 255 )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+ return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ std::ostringstream oss;
+ oss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = oss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+std::string toString( const double value ) {
+ return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+ return fpToString( value, 5 ) + "f";
+}
+
+std::string toString( bool value ) {
+ return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+ return value < ' '
+ ? toString( static_cast<unsigned int>( value ) )
+ : Detail::makeString( value );
+}
+
+std::string toString( signed char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+ return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSObject* const& nsObject ) {
+ return toString( [nsObject description] );
+ }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+ ResultBuilder::ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition )
+ : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ),
+ m_shouldDebugBreak( false ),
+ m_shouldThrow( false )
+ {}
+
+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+ m_data.resultType = result;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
+ m_exprComponents.lhs = lhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
+ m_exprComponents.rhs = rhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
+ m_exprComponents.op = op;
+ return *this;
+ }
+
+ void ResultBuilder::endExpression() {
+ m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
+ captureExpression();
+ }
+
+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+ m_assertionInfo.resultDisposition = resultDisposition;
+ m_stream.oss << Catch::translateActiveException();
+ captureResult( ResultWas::ThrewException );
+ }
+
+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+ setResultType( resultType );
+ captureExpression();
+ }
+
+ void ResultBuilder::captureExpression() {
+ AssertionResult result = build();
+ getResultCapture().assertionEnded( result );
+
+ if( !result.isOk() ) {
+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
+ m_shouldDebugBreak = true;
+ if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
+ m_shouldThrow = true;
+ }
+ }
+ void ResultBuilder::react() {
+ if( m_shouldThrow )
+ throw Catch::TestFailureException();
+ }
+
+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+ AssertionResult ResultBuilder::build() const
+ {
+ assert( m_data.resultType != ResultWas::Unknown );
+
+ AssertionResultData data = m_data;
+
+ // Flip bool results if testFalse is set
+ if( m_exprComponents.testFalse ) {
+ if( data.resultType == ResultWas::Ok )
+ data.resultType = ResultWas::ExpressionFailed;
+ else if( data.resultType == ResultWas::ExpressionFailed )
+ data.resultType = ResultWas::Ok;
+ }
+
+ data.message = m_stream.oss.str();
+ data.reconstructedExpression = reconstructExpression();
+ if( m_exprComponents.testFalse ) {
+ if( m_exprComponents.op == "" )
+ data.reconstructedExpression = "!" + data.reconstructedExpression;
+ else
+ data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
+ }
+ return AssertionResult( m_assertionInfo, data );
+ }
+ std::string ResultBuilder::reconstructExpression() const {
+ if( m_exprComponents.op == "" )
+ return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
+ else if( m_exprComponents.op == "matches" )
+ return m_exprComponents.lhs + " " + m_exprComponents.rhs;
+ else if( m_exprComponents.op != "!" ) {
+ if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
+ m_exprComponents.lhs.find("\n") == std::string::npos &&
+ m_exprComponents.rhs.find("\n") == std::string::npos )
+ return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
+ else
+ return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
+ }
+ else
+ return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
+ }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ virtual ~TagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+ void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ static TagAliasRegistry& get();
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+#include <map>
+#include <iostream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return it->second;
+ else
+ return Option<TagAlias>();
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+ it != itEnd;
+ ++it ) {
+ std::size_t pos = expandedTestSpec.find( it->first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ it->second.tag +
+ expandedTestSpec.substr( pos + it->first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+
+ if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" already registered.\n"
+ << "\tFirst seen at " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at " << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ }
+
+ TagAliasRegistry& TagAliasRegistry::get() {
+ static TagAliasRegistry instance;
+ return instance;
+
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+ ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
+
+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+ try {
+ TagAliasRegistry::get().add( alias, tag, lineInfo );
+ }
+ catch( std::exception& ex ) {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << ex.what() << std::endl;
+ exit(1);
+ }
+ }
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+
+namespace Catch {
+
+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {}
+
+ virtual ~StreamingReporterBase();
+
+ virtual void noMatchingTestCases( std::string const& ) {}
+
+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
+ currentTestRunInfo = _testRunInfo;
+ }
+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
+ currentGroupInfo = _groupInfo;
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
+ currentTestCaseInfo = _testInfo;
+ }
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
+ m_sectionStack.push_back( _sectionInfo );
+ }
+
+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
+ currentTestCaseInfo.reset();
+ }
+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
+ currentGroupInfo.reset();
+ }
+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ virtual void skipTest( TestCaseInfo const& ) {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ Ptr<IConfig> m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ };
+
+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+ template<typename T, typename ChildNodeT>
+ struct Node : SharedImpl<> {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode : SharedImpl<> {
+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+ virtual ~SectionNode();
+
+ bool operator == ( SectionNode const& other ) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == ( Ptr<SectionNode> const& other ) const {
+ return operator==( *other );
+ }
+
+ SectionStats stats;
+ typedef std::vector<Ptr<SectionNode> > ChildSections;
+ typedef std::vector<AssertionStats> Assertions;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() ( Ptr<SectionNode> const& node ) const {
+ return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+ }
+ private:
+ void operator=( BySectionInfo const& );
+ SectionInfo const& m_other;
+ };
+
+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {}
+ ~CumulativeReporterBase();
+
+ virtual void testRunStarting( TestRunInfo const& ) {}
+ virtual void testGroupStarting( GroupInfo const& ) {}
+
+ virtual void testCaseStarting( TestCaseInfo const& ) {}
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ Ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = new SectionNode( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ SectionNode::ChildSections::const_iterator it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = new SectionNode( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = node;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {}
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back( assertionStats );
+ return true;
+ }
+ virtual void sectionEnded( SectionStats const& sectionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+ assert( m_sectionStack.size() == 0 );
+ node->children.push_back( m_rootSection );
+ m_testCases.push_back( node );
+ m_rootSection.reset();
+
+ assert( m_deepestSection );
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+ node->children.swap( m_testCases );
+ m_testGroups.push_back( node );
+ }
+ virtual void testRunEnded( TestRunStats const& testRunStats ) {
+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+ node->children.swap( m_testGroups );
+ m_testRuns.push_back( node );
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ virtual void skipTest( TestCaseInfo const& ) {}
+
+ Ptr<IConfig> m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+ std::vector<Ptr<TestCaseNode> > m_testCases;
+ std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+ std::vector<Ptr<TestRunNode> > m_testRuns;
+
+ Ptr<SectionNode> m_rootSection;
+ Ptr<SectionNode> m_deepestSection;
+ std::vector<Ptr<SectionNode> > m_sectionStack;
+
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+ template<typename T>
+ class LegacyReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new LegacyReporterAdapter( new T( config ) );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ LegacyReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+
+ // *** Please Note ***:
+ // - If you end up here looking at a compiler error because it's trying to register
+ // your custom reporter class be aware that the native reporter interface has changed
+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+ // However please consider updating to the new interface as the old one is now
+ // deprecated and will probably be removed quite soon!
+ // Please contact me via github if you have any questions at all about this.
+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+ // no idea who is actually using custom reporters at all (possibly no-one!).
+ // The new interface is designed to minimise exposure to interface changes in the future.
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ ScopedElement( ScopedElement const& other )
+ : m_writer( other.m_writer ){
+ other.m_writer = NULL;
+ }
+
+ ~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer;
+ };
+
+ XmlWriter()
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &Catch::cout() )
+ {}
+
+ XmlWriter( std::ostream& os )
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &os )
+ {}
+
+ ~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+ XmlWriter& startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ stream() << m_indent << "<" << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ ScopedElement scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ stream() << "/>\n";
+ m_tagIsOpen = false;
+ }
+ else {
+ stream() << m_indent << "</" << m_tags.back() << ">\n";
+ }
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() ) {
+ stream() << " " << name << "=\"";
+ writeEncodedText( attribute );
+ stream() << "\"";
+ }
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+ stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
+ return *this;
+ }
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ if( !name.empty() )
+ stream() << " " << name << "=\"" << attribute << "\"";
+ return *this;
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ stream() << m_indent;
+ writeEncodedText( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& writeComment( std::string const& text ) {
+ ensureTagClosed();
+ stream() << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ XmlWriter& writeBlankLine() {
+ ensureTagClosed();
+ stream() << "\n";
+ return *this;
+ }
+
+ void setStream( std::ostream& os ) {
+ m_os = &os;
+ }
+
+ private:
+ XmlWriter( XmlWriter const& );
+ void operator=( XmlWriter const& );
+
+ std::ostream& stream() {
+ return *m_os;
+ }
+
+ void ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ stream() << ">\n";
+ m_tagIsOpen = false;
+ }
+ }
+
+ void newlineIfNecessary() {
+ if( m_needsNewline ) {
+ stream() << "\n";
+ m_needsNewline = false;
+ }
+ }
+
+ void writeEncodedText( std::string const& text ) {
+ static const char* charsToEncode = "<&\"";
+ std::string mtext = text;
+ std::string::size_type pos = mtext.find_first_of( charsToEncode );
+ while( pos != std::string::npos ) {
+ stream() << mtext.substr( 0, pos );
+
+ switch( mtext[pos] ) {
+ case '<':
+ stream() << "&lt;";
+ break;
+ case '&':
+ stream() << "&amp;";
+ break;
+ case '\"':
+ stream() << "&quot;";
+ break;
+ }
+ mtext = mtext.substr( pos+1 );
+ pos = mtext.find_first_of( charsToEncode );
+ }
+ stream() << mtext;
+ }
+
+ bool m_tagIsOpen;
+ bool m_needsNewline;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream* m_os;
+ };
+
+}
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase {
+ public:
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {}
+
+ virtual ~XmlReporter();
+
+ static std::string getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ public: // StreamingReporterBase
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = true;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& s ) {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testInfo ) {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ }
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+
+ // Print the expression if there is one.
+ if( assertionResult.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( assertionResult.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( assertionResult.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( assertionResult.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.scopedElement( "Exception" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.scopedElement( "Fatal Error Condition" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.scopedElement( "Failure" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ default:
+ break;
+ }
+
+ if( assertionResult.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase {
+ public:
+ JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {}
+
+ ~JunitReporter();
+
+ static std::string getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = true;
+ return prefs;
+ }
+
+ virtual void testRunStarting( TestRunInfo const& runInfo ) {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) {
+ suiteTimer.start();
+ stdOutForSuite.str("");
+ stdErrForSuite.str("");
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ stdOutForSuite << testCaseStats.stdOut;
+ stdErrForSuite << testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ virtual void testRunEndedCumulative() {
+ xml.endElement();
+ }
+
+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", "tbd" ); // !TBD
+
+ // Write test cases
+ for( TestGroupNode::ChildNodes::const_iterator
+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
+ it != itEnd;
+ ++it )
+ writeTestCase( **it );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+ }
+
+ void writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ if( rootSection.childSections.empty() )
+ className = "global";
+ }
+ writeSection( className, "", rootSection );
+ }
+
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + "/" + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( SectionNode::ChildSections::const_iterator
+ it = sectionNode.childSections.begin(),
+ itEnd = sectionNode.childSections.end();
+ it != itEnd;
+ ++it )
+ if( className.empty() )
+ writeSection( name, "", **it );
+ else
+ writeSection( className, name, **it );
+ }
+
+ void writeAssertions( SectionNode const& sectionNode ) {
+ for( SectionNode::Assertions::const_iterator
+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+ it != itEnd;
+ ++it )
+ writeAssertion( *it );
+ }
+ void writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ std::ostringstream oss;
+ if( !result.getMessage().empty() )
+ oss << result.getMessage() << "\n";
+ for( std::vector<MessageInfo>::const_iterator
+ it = stats.infoMessages.begin(),
+ itEnd = stats.infoMessages.end();
+ it != itEnd;
+ ++it )
+ if( it->type == ResultWas::Info )
+ oss << it->message << "\n";
+
+ oss << "at " << result.getSourceInfo();
+ xml.writeText( oss.str(), false );
+ }
+ }
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::ostringstream stdOutForSuite;
+ std::ostringstream stdErrForSuite;
+ unsigned int unexpectedExceptions;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+namespace Catch {
+
+ struct ConsoleReporter : StreamingReporterBase {
+ ConsoleReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_headerPrinted( false )
+ {}
+
+ virtual ~ConsoleReporter();
+ static std::string getDescription() {
+ return "Reports test results as plain lines of text";
+ }
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ lazyPrint();
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting( _sectionInfo );
+ }
+ virtual void sectionEnded( SectionStats const& _sectionStats ) {
+ if( _sectionStats.missingAssertions ) {
+ lazyPrint();
+ Colour colour( Colour::ResultError );
+ if( m_sectionStack.size() > 1 )
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if( m_headerPrinted ) {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ m_headerPrinted = false;
+ }
+ else {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ }
+ StreamingReporterBase::sectionEnded( _sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( _testCaseStats );
+ m_headerPrinted = false;
+ }
+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
+ if( currentGroupInfo.used ) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals( _testGroupStats.totals );
+ stream << "\n" << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded( _testGroupStats );
+ }
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotalsDivider( _testRunStats.totals );
+ printTotals( _testRunStats.totals );
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream ),
+ stats( _stats ),
+ result( _stats.assertionResult ),
+ colour( Colour::None ),
+ message( result.getMessage() ),
+ messages( _stats.infoMessages ),
+ printInfoMessages( _printInfoMessages )
+ {
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() ) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ }
+ else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with message";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "explicitly with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if( stats.totals.assertions.total() > 0 ) {
+ if( result.isOk() )
+ stream << "\n";
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ }
+ else {
+ stream << "\n";
+ }
+ printMessage();
+ }
+
+ private:
+ void printResultType() const {
+ if( !passOrFail.empty() ) {
+ Colour colourGuard( colour );
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ Colour colourGuard( Colour::OriginalExpression );
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << "\n";
+ }
+ }
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ stream << "with expansion:\n";
+ Colour colourGuard( Colour::ReconstructedExpression );
+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printMessage() const {
+ if( !messageLabel.empty() )
+ stream << messageLabel << ":" << "\n";
+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+ it != itEnd;
+ ++it ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || it->type != ResultWas::Info )
+ stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+ };
+
+ void lazyPrint() {
+
+ if( !currentTestRunInfo.used )
+ lazyPrintRunInfo();
+ if( !currentGroupInfo.used )
+ lazyPrintGroupInfo();
+
+ if( !m_headerPrinted ) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+ }
+ void lazyPrintRunInfo() {
+ stream << "\n" << getLineOfChars<'~'>() << "\n";
+ Colour colour( Colour::SecondaryText );
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if( m_config->rngSeed() != 0 )
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+ }
+ void lazyPrintGroupInfo() {
+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+ printClosedHeader( "Group: " + currentGroupInfo->name );
+ currentGroupInfo.used = true;
+ }
+ }
+ void printTestCaseAndSectionHeader() {
+ assert( !m_sectionStack.empty() );
+ printOpenHeader( currentTestCaseInfo->name );
+
+ if( m_sectionStack.size() > 1 ) {
+ Colour colourGuard( Colour::Headers );
+
+ std::vector<SectionInfo>::const_iterator
+ it = m_sectionStack.begin()+1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for( ; it != itEnd; ++it )
+ printHeaderString( it->name, 2 );
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+
+ if( !lineInfo.empty() ){
+ stream << getLineOfChars<'-'>() << "\n";
+ Colour colourGuard( Colour::FileName );
+ stream << lineInfo << "\n";
+ }
+ stream << getLineOfChars<'.'>() << "\n" << std::endl;
+ }
+
+ void printClosedHeader( std::string const& _name ) {
+ printOpenHeader( _name );
+ stream << getLineOfChars<'.'>() << "\n";
+ }
+ void printOpenHeader( std::string const& _name ) {
+ stream << getLineOfChars<'-'>() << "\n";
+ {
+ Colour colourGuard( Colour::Headers );
+ printHeaderString( _name );
+ }
+ }
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+ std::size_t i = _string.find( ": " );
+ if( i != std::string::npos )
+ i+=2;
+ else
+ i = 0;
+ stream << Text( _string, TextAttributes()
+ .setIndent( indent+i)
+ .setInitialIndent( indent ) ) << "\n";
+ }
+
+ struct SummaryColumn {
+
+ SummaryColumn( std::string const& _label, Colour::Code _colour )
+ : label( _label ),
+ colour( _colour )
+ {}
+ SummaryColumn addRow( std::size_t count ) {
+ std::ostringstream oss;
+ oss << count;
+ std::string row = oss.str();
+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+ while( it->size() < row.size() )
+ *it = " " + *it;
+ while( it->size() > row.size() )
+ row = " " + row;
+ }
+ rows.push_back( row );
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+ };
+
+ void printTotals( Totals const& totals ) {
+ if( totals.testCases.total() == 0 ) {
+ stream << Colour( Colour::Warning ) << "No tests ran\n";
+ }
+ else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+ stream << " ("
+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
+ << pluralise( totals.testCases.passed, "test case" ) << ")"
+ << "\n";
+ }
+ else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back( SummaryColumn( "", Colour::None )
+ .addRow( totals.testCases.total() )
+ .addRow( totals.assertions.total() ) );
+ columns.push_back( SummaryColumn( "passed", Colour::Success )
+ .addRow( totals.testCases.passed )
+ .addRow( totals.assertions.passed ) );
+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+ .addRow( totals.testCases.failed )
+ .addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+ .addRow( totals.testCases.failedButOk )
+ .addRow( totals.assertions.failedButOk ) );
+
+ printSummaryRow( "test cases", columns, 0 );
+ printSummaryRow( "assertions", columns, 1 );
+ }
+ }
+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+ std::string value = it->rows[row];
+ if( it->label.empty() ) {
+ stream << label << ": ";
+ if( value != "0" )
+ stream << value;
+ else
+ stream << Colour( Colour::Warning ) << "- none -";
+ }
+ else if( value != "0" ) {
+ stream << Colour( Colour::LightGrey ) << " | ";
+ stream << Colour( it->colour )
+ << value << " " << it->label;
+ }
+ }
+ stream << "\n";
+ }
+
+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+ }
+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+ if( i > j && i > k )
+ return i;
+ else if( j > k )
+ return j;
+ else
+ return k;
+ }
+
+ void printTotalsDivider( Totals const& totals ) {
+ if( totals.testCases.total() > 0 ) {
+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+ if( totals.testCases.allPassed() )
+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+ else
+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+ }
+ else {
+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+ }
+ stream << "\n";
+ }
+ void printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << "\n";
+ }
+
+ private:
+ bool m_headerPrinted;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase {
+
+ CompactReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual ~CompactReporter();
+
+ static std::string getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( _testRunStats.totals );
+ stream << "\n" << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream )
+ , stats( _stats )
+ , result( _stats.assertionResult )
+ , messages( _stats.infoMessages )
+ , itMessage( _stats.infoMessages.begin() )
+ , printInfoMessages( _printInfoMessages )
+ {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ printResultType( Colour::ResultSuccess, passedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ if ( ! result.hasExpression() )
+ printRemainingMessages( Colour::None );
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() )
+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+ else
+ printResultType( Colour::Error, failedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "unexpected exception with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "fatal error condition with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "expected exception, got none" );
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType( Colour::None, "info" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType( Colour::None, "warning" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "explicitly" );
+ printRemainingMessages( Colour::None );
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType( Colour::Error, "** internal error **" );
+ break;
+ }
+ }
+
+ private:
+ // Colour::LightGrey
+
+ static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+ static const char* failedString() { return "FAILED"; }
+ static const char* passedString() { return "PASSED"; }
+#else
+ static const char* failedString() { return "failed"; }
+ static const char* passedString() { return "passed"; }
+#endif
+
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ":";
+ }
+
+ void printResultType( Colour::Code colour, std::string passOrFail ) const {
+ if( !passOrFail.empty() ) {
+ {
+ Colour colourGuard( colour );
+ stream << " " << passOrFail;
+ }
+ stream << ":";
+ }
+ }
+
+ void printIssue( std::string issue ) const {
+ stream << " " << issue;
+ }
+
+ void printExpressionWas() {
+ if( result.hasExpression() ) {
+ stream << ";";
+ {
+ Colour colour( dimColour() );
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ stream << " " << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ {
+ Colour colour( dimColour() );
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if ( itMessage != messages.end() ) {
+ stream << " '" << itMessage->message << "'";
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
+ if ( itMessage == messages.end() )
+ return;
+
+ // using messages.end() directly yields compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+ {
+ Colour colourGuard( colour );
+ stream << " with " << pluralise( N, "message" ) << ":";
+ }
+
+ for(; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+ stream << " '" << itMessage->message << "'";
+ if ( ++itMessage != itEnd ) {
+ Colour colourGuard( dimColour() );
+ stream << " and";
+ }
+ }
+ }
+ }
+
+ private:
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+ };
+
+ // Colour, message variants:
+ // - white: No tests ran.
+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+ // - white: Passed [both/all] N test cases (no assertions).
+ // - red: Failed N tests cases, failed M assertions.
+ // - green: Passed [both/all] N tests cases with M assertions.
+
+ std::string bothOrAll( std::size_t count ) const {
+ return count == 1 ? "" : count == 2 ? "both " : "all " ;
+ }
+
+ void printTotals( const Totals& totals ) const {
+ if( totals.testCases.total() == 0 ) {
+ stream << "No tests ran.";
+ }
+ else if( totals.testCases.failed == totals.testCases.total() ) {
+ Colour colour( Colour::ResultError );
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll( totals.assertions.failed ) : "";
+ stream <<
+ "Failed " << bothOrAll( totals.testCases.failed )
+ << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else if( totals.assertions.total() == 0 ) {
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.total() )
+ << pluralise( totals.testCases.total(), "test case" )
+ << " (no assertions).";
+ }
+ else if( totals.assertions.failed ) {
+ Colour colour( Colour::ResultError );
+ stream <<
+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else {
+ Colour colour( Colour::ResultSuccess );
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.passed )
+ << pluralise( totals.testCases.passed, "test case" ) <<
+ " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
+ }
+ }
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+ NonCopyable::~NonCopyable() {}
+ IShared::~IShared() {}
+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+ IContext::~IContext() {}
+ IResultCapture::~IResultCapture() {}
+ ITestCase::~ITestCase() {}
+ ITestCaseRegistry::~ITestCaseRegistry() {}
+ IRegistryHub::~IRegistryHub() {}
+ IMutableRegistryHub::~IMutableRegistryHub() {}
+ IExceptionTranslator::~IExceptionTranslator() {}
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+ IReporter::~IReporter() {}
+ IReporterFactory::~IReporterFactory() {}
+ IReporterRegistry::~IReporterRegistry() {}
+ IStreamingReporter::~IStreamingReporter() {}
+ AssertionStats::~AssertionStats() {}
+ SectionStats::~SectionStats() {}
+ TestCaseStats::~TestCaseStats() {}
+ TestGroupStats::~TestGroupStats() {}
+ TestRunStats::~TestRunStats() {}
+ CumulativeReporterBase::SectionNode::~SectionNode() {}
+ CumulativeReporterBase::~CumulativeReporterBase() {}
+
+ StreamingReporterBase::~StreamingReporterBase() {}
+ ConsoleReporter::~ConsoleReporter() {}
+ CompactReporter::~CompactReporter() {}
+ IRunner::~IRunner() {}
+ IMutableContext::~IMutableContext() {}
+ IConfig::~IConfig() {}
+ XmlReporter::~XmlReporter() {}
+ JunitReporter::~JunitReporter() {}
+ TestRegistry::~TestRegistry() {}
+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
+ IGeneratorInfo::~IGeneratorInfo() {}
+ IGeneratorsForTest::~IGeneratorsForTest() {}
+ TestSpec::Pattern::~Pattern() {}
+ TestSpec::NamePattern::~NamePattern() {}
+ TestSpec::TagPattern::~TagPattern() {}
+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
+
+ Matchers::Impl::StdString::Equals::~Equals() {}
+ Matchers::Impl::StdString::Contains::~Contains() {}
+ Matchers::Impl::StdString::StartsWith::~StartsWith() {}
+ Matchers::Impl::StdString::EndsWith::~EndsWith() {}
+
+ void Config::dummy() {}
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+// Standard C/C++ main entry point
+int main (int argc, char * const argv[]) {
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
+
+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
+#else
+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
+#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
+#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
+
+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
+ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
+#else
+ #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc ) SECTION( " Given: " desc, "" )
+#define WHEN( desc ) SECTION( " When: " desc, "" )
+#define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
+#define THEN( desc ) SECTION( " Then: " desc, "" )
+#define AND_THEN( desc ) SECTION( " And: " desc, "" )
+
+using Catch::Detail::Approx;
+
+// #included from: internal/catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/src/tests/catchy/catchy_tests.h b/src/tests/catchy/catchy_tests.h
new file mode 100644
index 000000000..99ad03f31
--- /dev/null
+++ b/src/tests/catchy/catchy_tests.h
@@ -0,0 +1,128 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#ifndef BOTAN_CATCHY_TESTS_H__
+#define BOTAN_CATCHY_TESTS_H__
+
+#include "catch.hpp"
+#include <botan/build.h>
+
+
+// BEGIN CATCH STD::VECTOR IMPLEMENTATION
+// This is basically https://github.com/philsquared/Catch/pull/466
+#include <vector>
+
+#include <type_traits>
+
+namespace Catch {
+
+namespace Matchers {
+ namespace Impl {
+
+ namespace Generic {
+ template<typename ExpressionT>
+ struct Not : public MatcherImpl<Not<ExpressionT>, ExpressionT>
+ {
+ Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
+ Not( Not const& other ) : m_matcher( other.m_matcher ) {}
+
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ return !m_matcher->match( expr );
+ }
+ virtual std::string toString() const {
+ return "not " + m_matcher->toString();
+ }
+
+ Ptr<Matcher<ExpressionT>> m_matcher;
+ };
+ } // namespace Generic
+
+ namespace StdVector {
+ template<typename T, typename Alloc>
+ struct Equals : MatcherImpl<Equals<T, Alloc>, std::vector<T, Alloc> >
+ {
+ Equals( std::vector<T, Alloc> const& vec ) : m_vector( vec ){}
+ Equals( Equals const& other ) : m_vector( other.m_vector ){}
+
+ virtual ~Equals() {}
+
+ virtual bool match( std::vector<T, Alloc> const& expr ) const {
+ return m_vector == expr;
+ }
+ virtual std::string toString() const {
+ return "equals: std::vector of length " + Catch::toString(m_vector.size());
+ }
+
+ std::vector<T, Alloc> m_vector;
+ };
+ } // namespace StdVector
+
+ namespace Boolean {
+ struct Equals : MatcherImpl<Equals, bool>
+ {
+ Equals( const bool expected ) : m_expected( expected ){}
+ Equals( Equals const& other ) : m_expected( other.m_expected ){}
+
+ virtual ~Equals() override {}
+
+ virtual bool match( bool const& expr ) const {
+ return m_expected == expr;
+ }
+ virtual std::string toString() const {
+ return "== " + Catch::toString(m_expected);
+ }
+
+ bool m_expected;
+ };
+ } // Boolean
+
+ namespace Integer {
+ template<typename T>
+ struct Equals : MatcherImpl<Equals<T>, T>
+ {
+ Equals( const T expected ) : m_expected( expected ){}
+ Equals( Equals const& other ) : m_expected( other.m_expected ){}
+
+ virtual ~Equals() override {}
+
+ virtual bool match( T const& expr ) const {
+ return m_expected == expr;
+ }
+ virtual std::string toString() const {
+ return "== " + Catch::toString(m_expected);
+ }
+
+ T m_expected;
+ };
+ } // namespace Integer
+
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
+ return Impl::Generic::Not<ExpressionT>( m );
+ }
+
+ template <typename T, typename Alloc>
+ inline Impl::StdVector::Equals<T, Alloc> Equals( std::vector<T, Alloc> const& vec ) {
+ return Impl::StdVector::Equals<T, Alloc>( vec );
+ }
+
+ template <typename T,
+ typename = typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type>
+ inline Impl::Integer::Equals<T> Equals( T expected ) {
+ return Impl::Integer::Equals<T>( expected );
+ }
+
+ inline Impl::Boolean::Equals Equals( bool expected ) {
+ return Impl::Boolean::Equals( expected );
+ }
+
+} // namespace Matchers
+} // namespace Catch
+// END CATCH STD::VECTOR IMPLEMENTATION
+
+#endif // BOTAN_CATCHY_TESTS_H__
diff --git a/src/tests/catchy/test_base.cpp b/src/tests/catchy/test_base.cpp
new file mode 100644
index 000000000..057b29eb3
--- /dev/null
+++ b/src/tests/catchy/test_base.cpp
@@ -0,0 +1,25 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+#include <botan/symkey.h>
+
+using namespace Botan;
+
+TEST_CASE("OctetString", "[base]")
+ {
+ auto empty = secure_vector<byte>{ };
+ auto one = secure_vector<byte>{ 94 }; // ^
+ auto some = secure_vector<byte>{ 0x48, 0x65, 0x6c, 0x6c, 0x6f }; // Hello
+ auto utf8 = secure_vector<byte>{ 0xc3, 0xb6 }; // ö
+
+ auto os_empty = OctetString("");
+ auto os_one = OctetString("5e");
+ auto os_some = OctetString("48656c6c6f");
+ auto os_utf8 = OctetString("c3b6");
+
+ CHECK_THAT(os_empty.bits_of(), Equals(empty));
+ CHECK_THAT(os_one.bits_of(), Equals(one));
+ CHECK_THAT(os_some.bits_of(), Equals(some));
+ CHECK_THAT(os_utf8.bits_of(), Equals(utf8));
+ }
diff --git a/src/tests/catchy/test_base64.cpp b/src/tests/catchy/test_base64.cpp
new file mode 100644
index 000000000..fe7739a8d
--- /dev/null
+++ b/src/tests/catchy/test_base64.cpp
@@ -0,0 +1,232 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#if defined(BOTAN_HAS_BASE64_CODEC)
+
+#include <botan/base64.h>
+
+namespace {
+std::vector<Botan::byte> toStdVector(const Botan::secure_vector<Botan::byte> &in)
+ {
+ return std::vector<Botan::byte>(in.cbegin(), in.cend());
+ }
+
+std::vector<Botan::byte> toStdVector(const std::string &in)
+ {
+ return std::vector<Botan::byte>(in.cbegin(), in.cend());
+ }
+}
+
+TEST_CASE("Base64 encode empty string", "[base64]")
+ {
+ // common knowledge
+ auto emptyString = std::string("");
+ auto emptyVector = std::vector<Botan::byte>(emptyString.cbegin(), emptyString.cend());
+ CHECK_THAT(Botan::base64_encode(emptyVector), Equals(""));
+ }
+
+TEST_CASE("Base64 encode short string", "[base64]")
+ {
+ // test vectors from http://tools.ietf.org/html/rfc4648
+ auto in1 = std::vector<Botan::byte>{ 'f' };
+ auto in2 = std::vector<Botan::byte>{ 'f', 'o' };
+ auto in3 = std::vector<Botan::byte>{ 'f', 'o', 'o' };
+ CHECK_THAT(Botan::base64_encode(in1), Equals("Zg=="));
+ CHECK_THAT(Botan::base64_encode(in2), Equals("Zm8="));
+ CHECK_THAT(Botan::base64_encode(in3), Equals("Zm9v"));
+ }
+
+TEST_CASE("Base64 encode string", "[base64]")
+ {
+ // Generated by: echo -n "xyz" | base64
+ auto in1 = std::vector<Botan::byte>{ 'h','e','l','l','o',' ','w','o','r','l','d' };
+ auto in2 = std::vector<Botan::byte>{ 'h','e','l','l','o',' ','w','o','r','l','d','!' };
+ auto in3 = std::vector<Botan::byte>{ 'H','e','l','l','o',',',' ','w','o','r','l','d','.' };
+ auto in4 = std::vector<Botan::byte>{ 'T','h','e',' ','1','2',' ','c','h','a','r','s' };
+ auto in5 = std::vector<Botan::byte>{ 'T','h','e',' ','1','3',' ','c','h','a','r','s','.' };
+ auto in6 = std::vector<Botan::byte>{ 'T','h','e',' ','1','4',' ','c','h','a','r','s','.','.' };
+ auto in7 = std::vector<Botan::byte>{ 'T','h','e',' ','1','5',' ','c','h','a','r','s','.','.','.' };
+ CHECK_THAT(Botan::base64_encode(in1), Equals("aGVsbG8gd29ybGQ="));
+ CHECK_THAT(Botan::base64_encode(in2), Equals("aGVsbG8gd29ybGQh"));
+ CHECK_THAT(Botan::base64_encode(in3), Equals("SGVsbG8sIHdvcmxkLg=="));
+ CHECK_THAT(Botan::base64_encode(in4), Equals("VGhlIDEyIGNoYXJz"));
+ CHECK_THAT(Botan::base64_encode(in5), Equals("VGhlIDEzIGNoYXJzLg=="));
+ CHECK_THAT(Botan::base64_encode(in6), Equals("VGhlIDE0IGNoYXJzLi4="));
+ CHECK_THAT(Botan::base64_encode(in7), Equals("VGhlIDE1IGNoYXJzLi4u"));
+ }
+
+TEST_CASE("Base64 encode string special chars", "[base64]")
+ {
+ // Generated by: echo -n "xyz" | base64
+ auto in1 = toStdVector("An UTF-8 uuml: ü");
+ auto in2 = toStdVector("Weird German 2 byte thing: ß.");
+ CHECK_THAT(Botan::base64_encode(in1), Equals("QW4gVVRGLTggdXVtbDogw7w="));
+ CHECK_THAT(Botan::base64_encode(in2), Equals("V2VpcmQgR2VybWFuIDIgYnl0ZSB0aGluZzogw58u"));
+ }
+
+TEST_CASE("Base64 encode empty binary", "[base64]")
+ {
+ auto binary0 = std::vector<unsigned char>{};
+ CHECK_THAT(Botan::base64_encode(binary0), Equals(""));
+ }
+
+TEST_CASE("Base64 encode binary", "[base64]")
+ {
+ // Generated by: cat /dev/urandom | head -c 3 | tee /tmp/mybinary | hexdump -C && cat /tmp/mybinary | base64
+ std::vector<unsigned char> binary1 = {0x9b};
+ CHECK_THAT(Botan::base64_encode(binary1), Equals("mw=="));
+
+ std::vector<unsigned char> binary2 = {0x1c, 0x60};
+ CHECK_THAT(Botan::base64_encode(binary2), Equals("HGA="));
+
+ std::vector<unsigned char> binary3 = {0x81, 0x34, 0xbd};
+ CHECK_THAT(Botan::base64_encode(binary3), Equals("gTS9"));
+
+ std::vector<unsigned char> binary4 = {0x5e, 0x6c, 0xff, 0xde};
+ CHECK_THAT(Botan::base64_encode(binary4), Equals("Xmz/3g=="));
+
+ std::vector<unsigned char> binary5 = {0xb2, 0xcd, 0xf0, 0xdc, 0x7f};
+ CHECK_THAT(Botan::base64_encode(binary5), Equals("ss3w3H8="));
+
+ std::vector<unsigned char> binary6 = {0xfc, 0x56, 0x2d, 0xda, 0xd4, 0x0e};
+ CHECK_THAT(Botan::base64_encode(binary6), Equals("/FYt2tQO"));
+
+ std::vector<unsigned char> binary7 = {0x29, 0xb2, 0x32, 0x2e, 0x88, 0x41, 0xe8};
+ CHECK_THAT(Botan::base64_encode(binary7), Equals("KbIyLohB6A=="));
+
+ std::vector<unsigned char> binary8 = {0x0f, 0x0f, 0xce, 0xd9, 0x49, 0x7a, 0xaf, 0x92};
+ CHECK_THAT(Botan::base64_encode(binary8), Equals("Dw/O2Ul6r5I="));
+
+ std::vector<unsigned char> binary9 = {0x27, 0x0f, 0xb1, 0x89, 0x82, 0x80, 0x0d, 0xa6, 0x40};
+ CHECK_THAT(Botan::base64_encode(binary9), Equals("Jw+xiYKADaZA"));
+ }
+
+TEST_CASE("Base64 decode empty string", "[base64]")
+ {
+ // common knowledge
+ auto outVector = toStdVector(Botan::base64_decode(""));
+ CHECK_THAT(outVector, Equals(std::vector<Botan::byte>{}));
+ }
+
+TEST_CASE("Base64 decode short string", "[base64]")
+ {
+ // test vectors from http://tools.ietf.org/html/rfc4648
+ CHECK_THAT(toStdVector(Botan::base64_decode("Zg==")), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("Zm8=")), Equals(toStdVector("fo")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("Zm9v")), Equals(toStdVector("foo")));
+ }
+
+TEST_CASE("Base64 decode string", "[base64]")
+ {
+ // Generated by: echo -n "xyz" | base64
+ CHECK_THAT(toStdVector(Botan::base64_decode("aGVsbG8gd29ybGQ=")), Equals(toStdVector("hello world")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("aGVsbG8gd29ybGQh")), Equals(toStdVector("hello world!")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("SGVsbG8sIHdvcmxkLg==")), Equals(toStdVector("Hello, world.")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDEyIGNoYXJz")), Equals(toStdVector("The 12 chars")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDEzIGNoYXJzLg==")), Equals(toStdVector("The 13 chars.")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDE0IGNoYXJzLi4=")), Equals(toStdVector("The 14 chars..")));
+ CHECK_THAT(toStdVector(Botan::base64_decode("VGhlIDE1IGNoYXJzLi4u")), Equals(toStdVector("The 15 chars...")));
+ }
+
+TEST_CASE("Base64 decode string special chars", "[base64]")
+ {
+ // Generated by: echo -n "xyz" | base64
+ auto in1 = std::string("QW4gVVRGLTggdXVtbDogw7w=");
+ auto in2 = std::string("V2VpcmQgR2VybWFuIDIgYnl0ZSB0aGluZzogw58u");
+ auto out1 = std::string("An UTF-8 uuml: ü");
+ auto out2 = std::string("Weird German 2 byte thing: ß.");
+ CHECK_THAT(toStdVector(Botan::base64_decode(in1)), Equals(toStdVector(out1)));
+ CHECK_THAT(toStdVector(Botan::base64_decode(in2)), Equals(toStdVector(out2)));
+ }
+
+TEST_CASE("Base64 decode binary", "[base64]")
+ {
+ // Generated by: cat /dev/urandom | head -c 3 | tee /tmp/mybinary | hexdump -C && cat /tmp/mybinary | base64
+ std::vector<unsigned char> binary0 = {};
+ CHECK_THAT(toStdVector(Botan::base64_decode("")), Equals(binary0));
+
+ std::vector<unsigned char> binary1 = {0x9b};
+ CHECK_THAT(toStdVector(Botan::base64_decode("mw==")), Equals(binary1));
+
+ std::vector<unsigned char> binary2 = {0x1c, 0x60};
+ CHECK_THAT(toStdVector(Botan::base64_decode("HGA=")), Equals(binary2));
+
+ std::vector<unsigned char> binary3 = {0x81, 0x34, 0xbd};
+ CHECK_THAT(toStdVector(Botan::base64_decode("gTS9")), Equals(binary3));
+
+ std::vector<unsigned char> binary4 = {0x5e, 0x6c, 0xff, 0xde};
+ CHECK_THAT(toStdVector(Botan::base64_decode("Xmz/3g==")), Equals(binary4));
+
+ std::vector<unsigned char> binary5 = {0xb2, 0xcd, 0xf0, 0xdc, 0x7f};
+ CHECK_THAT(toStdVector(Botan::base64_decode("ss3w3H8=")), Equals(binary5));
+
+ std::vector<unsigned char> binary6 = {0xfc, 0x56, 0x2d, 0xda, 0xd4, 0x0e};
+ CHECK_THAT(toStdVector(Botan::base64_decode("/FYt2tQO")), Equals(binary6));
+
+ std::vector<unsigned char> binary7 = {0x29, 0xb2, 0x32, 0x2e, 0x88, 0x41, 0xe8};
+ CHECK_THAT(toStdVector(Botan::base64_decode("KbIyLohB6A==")), Equals(binary7));
+
+ std::vector<unsigned char> binary8 = {0x0f, 0x0f, 0xce, 0xd9, 0x49, 0x7a, 0xaf, 0x92};
+ CHECK_THAT(toStdVector(Botan::base64_decode("Dw/O2Ul6r5I=")), Equals(binary8));
+
+ std::vector<unsigned char> binary9 = {0x27, 0x0f, 0xb1, 0x89, 0x82, 0x80, 0x0d, 0xa6, 0x40};
+ CHECK_THAT(toStdVector(Botan::base64_decode("Jw+xiYKADaZA")), Equals(binary9));
+ }
+
+TEST_CASE("Base64 decode and ignore whitespace", "[base64]")
+ {
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string(" Zg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Z g=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg =="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg= ="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg== "), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\rZg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\nZg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\tZg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\r=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\n=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\t=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\r"), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\n"), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\t"), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\r Zg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\n Zg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("\t Zg=="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\r =="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\n =="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg\t =="), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\r "), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\n "), true)), Equals(toStdVector("f")));
+ CHECK_THAT(toStdVector(Botan::base64_decode(std::string("Zg==\t "), true)), Equals(toStdVector("f")));
+ }
+
+TEST_CASE("Base64 decode and don't ignore whitespace", "[base64]")
+ {
+ CHECK_THROWS(Botan::base64_decode(std::string(" Zg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Z g=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg =="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg= ="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg== "), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\rZg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\nZg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\tZg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\r=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\n=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\t=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\r"), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\n"), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\t"), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\r Zg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\n Zg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("\t Zg=="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\r =="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\n =="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg\t =="), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\r "), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\n "), false));
+ CHECK_THROWS(Botan::base64_decode(std::string("Zg==\t "), false));
+ }
+
+#endif // BOTAN_HAS_BASE64_CODEC
diff --git a/src/tests/catchy/test_bigint.cpp b/src/tests/catchy/test_bigint.cpp
new file mode 100644
index 000000000..67821eaf0
--- /dev/null
+++ b/src/tests/catchy/test_bigint.cpp
@@ -0,0 +1,169 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#if defined(BOTAN_HAS_BIGINT)
+
+#include <botan/bigint.h>
+
+using namespace Botan;
+
+TEST_CASE("Bigint basics", "[bigint]")
+ {
+ SECTION("in 0-bit border")
+ {
+ BigInt a(0u);
+ CHECK_THAT(a.bits(), Equals(0));
+ CHECK_THAT(a.bytes(), Equals(0));
+ CHECK_THAT(a.to_u32bit(), Equals(0));
+ }
+ SECTION("above 0-bit border")
+ {
+ BigInt a(1u);
+ CHECK_THAT(a.bits(), Equals(1));
+ CHECK_THAT(a.bytes(), Equals(1));
+ CHECK_THAT(a.to_u32bit(), Equals(1));
+ }
+ SECTION("in 8-bit border")
+ {
+ BigInt a(255u);
+ CHECK_THAT(a.bits(), Equals(8));
+ CHECK_THAT(a.bytes(), Equals(1));
+ CHECK_THAT(a.to_u32bit(), Equals(255));
+ }
+ SECTION("above 8-bit border")
+ {
+ BigInt a(256u);
+ CHECK_THAT(a.bits(), Equals(9));
+ CHECK_THAT(a.bytes(), Equals(2));
+ CHECK_THAT(a.to_u32bit(), Equals(256));
+ }
+ SECTION("in 16-bit border")
+ {
+ BigInt a(65535u);
+ CHECK_THAT(a.bits(), Equals(16));
+ CHECK_THAT(a.bytes(), Equals(2));
+ CHECK_THAT(a.to_u32bit(), Equals(65535));
+ }
+ SECTION("above 16-bit border")
+ {
+ BigInt a(65536u);
+ CHECK_THAT(a.bits(), Equals(17));
+ CHECK_THAT(a.bytes(), Equals(3));
+ CHECK_THAT(a.to_u32bit(), Equals(65536));
+ }
+ SECTION("in 32-bit border")
+ {
+ BigInt a(4294967295u);
+ CHECK_THAT(a.bits(), Equals(32));
+ CHECK_THAT(a.bytes(), Equals(4));
+ CHECK_THAT(a.to_u32bit(), Equals(4294967295u));
+ }
+ SECTION("above 32-bit border")
+ {
+ BigInt a(4294967296u);
+ CHECK_THAT(a.bits(), Equals(33));
+ CHECK_THAT(a.bytes(), Equals(5));
+ CHECK_THROWS( a.to_u32bit() );
+ }
+ }
+
+TEST_CASE("Bigint random_integer", "[bigint]")
+ {
+ RandomNumberGenerator *rng = RandomNumberGenerator::make_rng();
+
+ SECTION("min is 0")
+ {
+ // 0–9
+ const size_t MIN = 0;
+ const size_t MAX = 10; // excluded
+ const int ITERATIONS = 10000;
+
+ std::vector<int> counts(MAX, 0);
+ std::vector<double> ratios(MAX, 1.0);
+
+ for (size_t i = 0; i < ITERATIONS; i++)
+ {
+ BigInt b = BigInt::random_integer(*rng, MIN, MAX);
+ size_t x = b.to_u32bit();
+ counts[x]++;
+ }
+
+ std::stringstream debug;
+ for (size_t d = MIN; d < MAX; ++d)
+ {
+ auto ratio = static_cast<double>(counts[d]) / ITERATIONS;
+ ratios[d] = ratio;
+
+ if (!debug.str().empty())
+ {
+ debug << ", ";
+ }
+ debug << d << ": " << std::setprecision(3) << ratio;
+ }
+
+ INFO( debug.str() )
+
+ // Have ~ 10 % on each digit from 0-9
+ CHECK(( 0.085 <= ratios[0] )); CHECK(( ratios[0] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[1] )); CHECK(( ratios[1] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[2] )); CHECK(( ratios[2] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[3] )); CHECK(( ratios[3] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[4] )); CHECK(( ratios[4] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[5] )); CHECK(( ratios[5] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[6] )); CHECK(( ratios[6] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[7] )); CHECK(( ratios[7] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[8] )); CHECK(( ratios[8] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[9] )); CHECK(( ratios[9] <= 0.115 ));
+ //CHECK( false );
+ }
+
+ SECTION("min is 10")
+ {
+ // 10–19
+ const size_t MIN = 10;
+ const size_t MAX = 20; // excluded
+ const size_t ITERATIONS = 10000;
+
+ std::vector<int> counts(MAX, 0);
+ std::vector<double> ratios(MAX, 1.0);
+
+ for (size_t i = 0; i < ITERATIONS; i++)
+ {
+ BigInt b = BigInt::random_integer(*rng, MIN, MAX);
+ size_t x = b.to_u32bit();
+ counts[x]++;
+ }
+
+ std::stringstream debug;
+ for (size_t d = MIN; d < MAX; ++d)
+ {
+ auto ratio = static_cast<double>(counts[d]) / ITERATIONS;
+ ratios[d] = ratio;
+
+ if (!debug.str().empty())
+ {
+ debug << ", ";
+ }
+ debug << d << ": " << std::setprecision(3) << ratio;
+ }
+
+ INFO( debug.str() )
+
+ // Have ~ 10 % on each digit from 10-19
+ CHECK(( 0.085 <= ratios[10] )); CHECK(( ratios[10] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[11] )); CHECK(( ratios[11] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[12] )); CHECK(( ratios[12] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[13] )); CHECK(( ratios[13] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[14] )); CHECK(( ratios[14] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[15] )); CHECK(( ratios[15] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[16] )); CHECK(( ratios[16] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[17] )); CHECK(( ratios[17] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[18] )); CHECK(( ratios[18] <= 0.115 ));
+ CHECK(( 0.085 <= ratios[19] )); CHECK(( ratios[19] <= 0.115 ));
+ //CHECK( false );
+ }
+ }
+
+#endif
diff --git a/src/tests/catchy/test_cvc.cpp b/src/tests/catchy/test_cvc.cpp
new file mode 100644
index 000000000..2ac6be848
--- /dev/null
+++ b/src/tests/catchy/test_cvc.cpp
@@ -0,0 +1,40 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#if defined(BOTAN_HAS_CVC)
+
+#include <botan/eac_asn_obj.h>
+
+TEST_CASE("human readable time", "[EAC_Time]")
+ {
+ auto time1 = Botan::EAC_Time("2008-02-01");
+ auto time2 = Botan::EAC_Time("2008/02/28");
+ auto time3 = Botan::EAC_Time("2004-06-14");
+
+ CHECK(( time1.time_is_set() == true ));
+ CHECK(( time2.time_is_set() == true ));
+ CHECK(( time3.time_is_set() == true ));
+
+ CHECK(( time1.readable_string() == "2008/02/01" ));
+ CHECK(( time2.readable_string() == "2008/02/28" ));
+ CHECK(( time3.readable_string() == "2004/06/14" ));
+ }
+
+TEST_CASE("no time", "[EAC_Time]")
+ {
+ auto time = Botan::EAC_Time("");
+ CHECK(( time.time_is_set() == false ));
+ }
+
+TEST_CASE("invalis time", "[EAC_Time]")
+ {
+ CHECK_THROWS( Botan::EAC_Time(" ") );
+ CHECK_THROWS( Botan::EAC_Time("2008`02-01") );
+ CHECK_THROWS( Botan::EAC_Time("9999-02-01") );
+ CHECK_THROWS( Botan::EAC_Time("2000-02-01 17") );
+ CHECK_THROWS( Botan::EAC_Time("999921") );
+ }
+
+#endif // BOTAN_HAS_CVC
diff --git a/src/tests/catchy/test_stl_util.cpp b/src/tests/catchy/test_stl_util.cpp
new file mode 100644
index 000000000..f7c2c9990
--- /dev/null
+++ b/src/tests/catchy/test_stl_util.cpp
@@ -0,0 +1,21 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#include <botan/internal/stl_util.h>
+
+TEST_CASE("secure vector to string", "[STL_Util]")
+ {
+ using namespace Botan;
+ auto empty = secure_vector<byte>{ };
+ auto one = secure_vector<byte>{ 94 };
+ auto some = secure_vector<byte>{ 0x48, 0x65, 0x6c, 0x6c, 0x6f };
+ // echo -n "ö" | hexdump -C
+ auto utf8 = secure_vector<byte>{ 0xc3, 0xb6 };
+
+ CHECK_THAT(to_string(empty), Equals(""));
+ CHECK_THAT(to_string(one), Equals("^"));
+ CHECK_THAT(to_string(some), Equals("Hello"));
+ CHECK_THAT(to_string(utf8), Equals("ö"));
+ }
diff --git a/src/tests/catchy/test_utils.cpp b/src/tests/catchy/test_utils.cpp
new file mode 100644
index 000000000..a01cffa2b
--- /dev/null
+++ b/src/tests/catchy/test_utils.cpp
@@ -0,0 +1,195 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#include <botan/calendar.h>
+#include <botan/parsing.h>
+#include <botan/internal/rounding.h>
+
+using namespace Botan;
+
+TEST_CASE("round_up strictly positive", "[utils]")
+ {
+ CHECK_THAT(round_up( 1, 10), Equals(10));
+ CHECK_THAT(round_up( 3, 10), Equals(10));
+ CHECK_THAT(round_up( 9, 10), Equals(10));
+ CHECK_THAT(round_up(10, 10), Equals(10));
+
+ CHECK_THAT(round_up( 1, 4), Equals( 4));
+ CHECK_THAT(round_up( 3, 4), Equals( 4));
+ CHECK_THAT(round_up( 4, 4), Equals( 4));
+ CHECK_THAT(round_up( 9, 4), Equals(12));
+ CHECK_THAT(round_up(10, 4), Equals(12));
+ }
+
+TEST_CASE("round_up zero", "[utils]")
+ {
+ CHECK_THAT(round_up(0, 2), Equals(0));
+ CHECK_THAT(round_up(0, 10), Equals(0));
+ CHECK_THAT(round_up(0, 1000), Equals(0));
+ CHECK_THAT(round_up(0, 99999), Equals(0));
+ CHECK_THAT(round_up(0, 2222222), Equals(0));
+ }
+
+TEST_CASE("round_up invalid input", "[utils]")
+ {
+ CHECK_THROWS(round_up(3, 0));
+ CHECK_THROWS(round_up(5, 0));
+ }
+
+TEST_CASE("calendar_point constructor works", "[utils]")
+ {
+ {
+ auto point1 = calendar_point(1988, 04, 23, 14, 37, 28);
+ CHECK_THAT(point1.year, Equals(1988));
+ CHECK_THAT(point1.month, Equals(4));
+ CHECK_THAT(point1.day, Equals(23));
+ CHECK_THAT(point1.hour, Equals(14));
+ CHECK_THAT(point1.minutes, Equals(37));
+ CHECK_THAT(point1.seconds, Equals(28));
+ }
+
+ {
+ auto point2 = calendar_point(1800, 01, 01, 0, 0, 0);
+ CHECK_THAT(point2.year, Equals(1800));
+ CHECK_THAT(point2.month, Equals(1));
+ CHECK_THAT(point2.day, Equals(1));
+ CHECK_THAT(point2.hour, Equals(0));
+ CHECK_THAT(point2.minutes, Equals(0));
+ CHECK_THAT(point2.seconds, Equals(0));
+ }
+
+ {
+ auto point = calendar_point(2037, 12, 31, 24, 59, 59);
+ CHECK_THAT(point.year, Equals(2037));
+ CHECK_THAT(point.month, Equals(12));
+ CHECK_THAT(point.day, Equals(31));
+ CHECK_THAT(point.hour, Equals(24));
+ CHECK_THAT(point.minutes, Equals(59));
+ CHECK_THAT(point.seconds, Equals(59));
+ }
+
+ {
+ auto point = calendar_point(2100, 5, 1, 0, 0, 0);
+ CHECK_THAT(point.year, Equals(2100));
+ CHECK_THAT(point.month, Equals(5));
+ CHECK_THAT(point.day, Equals(1));
+ CHECK_THAT(point.hour, Equals(0));
+ CHECK_THAT(point.minutes, Equals(0));
+ CHECK_THAT(point.seconds, Equals(0));
+ }
+ }
+
+TEST_CASE("calendar_point to stl timepoint and back", "[utils]")
+ {
+ SECTION("default test")
+ {
+ auto in = calendar_point(1988, 04, 23, 14, 37, 28);
+ auto out = calendar_value(in.to_std_timepoint());
+ CHECK_THAT(out.year, Equals(1988));
+ CHECK_THAT(out.month, Equals(4));
+ CHECK_THAT(out.day, Equals(23));
+ CHECK_THAT(out.hour, Equals(14));
+ CHECK_THAT(out.minutes, Equals(37));
+ CHECK_THAT(out.seconds, Equals(28));
+ }
+
+ // _mkgmtime on Windows does not work for dates before 1970
+ SECTION("first possible time point")
+ {
+ auto in = calendar_point(1970, 01, 01, 00, 00, 00);
+ auto out = calendar_value(in.to_std_timepoint());
+ CHECK_THAT(out.year, Equals(1970));
+ CHECK_THAT(out.month, Equals(01));
+ CHECK_THAT(out.day, Equals(01));
+ CHECK_THAT(out.hour, Equals(00));
+ CHECK_THAT(out.minutes, Equals(00));
+ CHECK_THAT(out.seconds, Equals(00));
+ }
+
+ SECTION("latest possible time point")
+ {
+ auto in = calendar_point(2037, 12, 31, 23, 59, 59);
+ auto out = calendar_value(in.to_std_timepoint());
+ CHECK_THAT(out.year, Equals(2037));
+ CHECK_THAT(out.month, Equals(12));
+ CHECK_THAT(out.day, Equals(31));
+ CHECK_THAT(out.hour, Equals(23));
+ CHECK_THAT(out.minutes, Equals(59));
+ CHECK_THAT(out.seconds, Equals(59));
+ }
+
+ SECTION("year too early")
+ {
+ {
+ auto in = calendar_point(1800, 01, 01, 0, 0, 0);
+ CHECK_THROWS(in.to_std_timepoint());
+ }
+
+ {
+ auto in = calendar_point(1899, 12, 31, 23, 59, 59);
+ CHECK_THROWS(in.to_std_timepoint());
+ }
+
+ {
+ auto in = calendar_point(1969, 12, 31, 23, 59, 58); // time_t = -2
+ CHECK_THROWS(in.to_std_timepoint());
+ }
+
+ {
+ auto in = calendar_point(1969, 12, 31, 23, 59, 59); // time_t = -1
+ CHECK_THROWS(in.to_std_timepoint());
+ }
+ }
+
+ SECTION("year too late")
+ {
+ auto in = calendar_point(2038, 01, 01, 0, 0, 0);
+ CHECK_THROWS(in.to_std_timepoint());
+ }
+ }
+
+TEST_CASE("uint32 parsing valid", "[utils]")
+ {
+ CHECK_THAT(to_u32bit("0"), Equals(0));
+ CHECK_THAT(to_u32bit("1"), Equals(1));
+ CHECK_THAT(to_u32bit("2"), Equals(2));
+ CHECK_THAT(to_u32bit("10"), Equals(10));
+ CHECK_THAT(to_u32bit("100"), Equals(100));
+ CHECK_THAT(to_u32bit("1000"), Equals(1000));
+ CHECK_THAT(to_u32bit("10000"), Equals(10000));
+ CHECK_THAT(to_u32bit("100000"), Equals(100000));
+ CHECK_THAT(to_u32bit("1000000"), Equals(1000000));
+ // biggest allowed value
+ CHECK_THAT(to_u32bit("4294967295"), Equals(4294967295));
+
+ // leading zeros
+ CHECK_THAT(to_u32bit("00"), Equals(0));
+ CHECK_THAT(to_u32bit("01"), Equals(1));
+ CHECK_THAT(to_u32bit("02"), Equals(2));
+ CHECK_THAT(to_u32bit("010"), Equals(10));
+ CHECK_THAT(to_u32bit("0000000000000000000000000010"), Equals(10));
+
+ // leading and trailing whitespace
+ CHECK_THROWS(to_u32bit(" 1"));
+ CHECK_THROWS(to_u32bit(" 1 "));
+ CHECK_THROWS(to_u32bit("\n1"));
+ CHECK_THROWS(to_u32bit("1\n"));
+ CHECK_THROWS(to_u32bit("1 5"));
+ CHECK_THROWS(to_u32bit("1\t5"));
+ CHECK_THROWS(to_u32bit("1\n5"));
+
+ // Other stuff that is no digit
+ CHECK_THROWS(to_u32bit("1Z"));
+
+ // invalid input
+ CHECK_THROWS(to_u32bit(""));
+ CHECK_THROWS(to_u32bit(" "));
+ CHECK_THROWS(to_u32bit("!"));
+ //CHECK_THROWS(to_u32bit("1!"));
+ CHECK_THROWS(to_u32bit("!1"));
+
+ // Avoid overflow: value too big for uint32
+ CHECK_THROWS(to_u32bit("4294967296"));
+ }
diff --git a/src/tests/catchy/test_x509.cpp b/src/tests/catchy/test_x509.cpp
new file mode 100644
index 000000000..cb2f8f0cf
--- /dev/null
+++ b/src/tests/catchy/test_x509.cpp
@@ -0,0 +1,142 @@
+// (C) 2015 Simon Warta (Kullo GmbH)
+// Botan is released under the Simplified BSD License (see license.txt)
+
+#include "catchy_tests.h"
+
+#if defined(BOTAN_HAS_ASN1)
+
+#include <botan/exceptn.h>
+#include <botan/asn1_time.h>
+
+using namespace Botan;
+using namespace Catch;
+
+TEST_CASE("human readable time", "[X509]")
+ {
+ auto time1 = X509_Time("0802010000Z", ASN1_Tag::UTC_TIME);
+ auto time2 = X509_Time("0802011724Z", ASN1_Tag::UTC_TIME);
+ auto time3 = X509_Time("040614233430Z", ASN1_Tag::UTC_TIME);
+
+ CHECK_THAT(time1.time_is_set(), Equals(true));
+ CHECK_THAT(time2.time_is_set(), Equals(true));
+ CHECK_THAT(time3.time_is_set(), Equals(true));
+
+ CHECK_THAT(time1.readable_string(), Equals("2008/02/01 00:00:00 UTC"));
+ CHECK_THAT(time2.readable_string(), Equals("2008/02/01 17:24:00 UTC"));
+ CHECK_THAT(time3.readable_string(), Equals("2004/06/14 23:34:30 UTC"));
+ }
+
+TEST_CASE("Implicit copy constructor", "[X509]")
+ {
+ auto time_orig = X509_Time("0802010000Z", ASN1_Tag::UTC_TIME);
+ auto time_copy = time_orig;
+
+ // Check that implicit copy and assignment work:
+ // time_copy and time_orig must have the same data but
+ // must sit at different places in memory
+ CHECK((time_orig == time_copy));
+
+ auto address1 = reinterpret_cast<uintptr_t>(&time_orig);
+ auto address2 = reinterpret_cast<uintptr_t>(&time_copy);
+
+ CHECK_THAT(address1, Not(Equals(address2)));
+ }
+
+TEST_CASE("no time", "[X509]")
+ {
+ auto time = X509_Time();
+ CHECK_THAT(time.time_is_set(), Equals(false));
+ }
+
+TEST_CASE("valid UTCTime", "[X509]")
+ {
+ SECTION("precision: minute; including timezone: no", "Length 11")
+ {
+ CHECK_NOTHROW(X509_Time("0802010000Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("0802011724Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("0406142334Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("9906142334Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("0006142334Z", ASN1_Tag::UTC_TIME));
+ }
+
+ SECTION("precision: seconds; including timezone: no", "Length 13")
+ {
+ CHECK_NOTHROW(X509_Time("080201000000Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("080201172412Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("040614233433Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("990614233444Z", ASN1_Tag::UTC_TIME));
+ CHECK_NOTHROW(X509_Time("000614233455Z", ASN1_Tag::UTC_TIME));
+ }
+
+ SECTION("precision: minute; including timezone: yes", "Length 15")
+ {
+ // Valid times that are not supported by Botan
+ CHECK_THROWS_AS(X509_Time("0802010000-0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("0802011724+0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("0406142334-0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("9906142334+0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("0006142334-0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("0006142334+0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ }
+
+ SECTION("precision: seconds; including timezone: yes", "Length 17")
+ {
+ // Valid times that are not supported by Botan
+ CHECK_THROWS_AS(X509_Time("080201000000-0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("080201172412+0000", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("040614233433-0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("990614233444+0500", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("000614233455-0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ CHECK_THROWS_AS(X509_Time("000614233455+0530", ASN1_Tag::UTC_TIME), Unsupported_Argument);
+ }
+ }
+
+TEST_CASE("invalid UTCTime", "[X509]")
+ {
+ // invalid length
+ CHECK_THROWS(X509_Time("", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time(" ", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2008`02-01", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("9999-02-01", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2000-02-01 17", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("999921", ASN1_Tag::UTC_TIME));
+
+ // valid length 13 -> range check
+ CHECK_THROWS(X509_Time("080201000061Z", ASN1_Tag::UTC_TIME)); // seconds too big (61)
+ CHECK_THROWS(X509_Time("080201000060Z", ASN1_Tag::UTC_TIME)); // seconds too big (60, leap seconds not covered by the standard)
+ CHECK_THROWS(X509_Time("0802010000-1Z", ASN1_Tag::UTC_TIME)); // seconds too small (-1)
+ CHECK_THROWS(X509_Time("080201006000Z", ASN1_Tag::UTC_TIME)); // minutes too big (60)
+ CHECK_THROWS(X509_Time("080201240000Z", ASN1_Tag::UTC_TIME)); // hours too big (24:00)
+
+ // valid length 13 -> invalid numbers
+ CHECK_THROWS(X509_Time("08020123112 Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08020123112!Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08020123112,Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08020123112\nZ", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("080201232 33Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("080201232!33Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("080201232,33Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("080201232\n33Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("0802012 3344Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("0802012!3344Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("0802012,3344Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08022\n334455Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08022 334455Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08022!334455Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08022,334455Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("08022\n334455Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("082 33445511Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("082!33445511Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("082,33445511Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("082\n33445511Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2 2211221122Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2!2211221122Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2,2211221122Z", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("2\n2211221122Z", ASN1_Tag::UTC_TIME));
+
+ // wrong time zone
+ CHECK_THROWS(X509_Time("0802010000", ASN1_Tag::UTC_TIME));
+ CHECK_THROWS(X509_Time("0802010000z", ASN1_Tag::UTC_TIME));
+ }
+
+#endif // BOTAN_HAS_ASN1
diff --git a/src/tests/data/fuzz/x509/afl_000.pem b/src/tests/data/fuzz/x509/afl_000.pem
new file mode 100644
index 000000000..5bd3a97d0
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_000.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIEYMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_001.pem b/src/tests/data/fuzz/x509/afl_001.pem
new file mode 100644
index 000000000..9bf1fcecb
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_001.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MICzAJBGCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_002.pem b/src/tests/data/fuzz/x509/afl_002.pem
new file mode 100644
index 000000000..fbadfd772
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_002.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4EAABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_003.pem b/src/tests/data/fuzz/x509/afl_003.pem
new file mode 100644
index 000000000..86041ccfd
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_003.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgOjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWzXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_004.pem b/src/tests/data/fuzz/x509/afl_004.pem
new file mode 100644
index 000000000..4c818d9c3
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_004.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4EAADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_005.pem b/src/tests/data/fuzz/x509/afl_005.pem
new file mode 100644
index 000000000..fa101ff3a
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_005.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICATECCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1uEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_006.pem b/src/tests/data/fuzz/x509/afl_006.pem
new file mode 100644
index 000000000..af95cabfb
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_006.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCCqGSIb9ycEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG6yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAU4AwAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_007.pem b/src/tests/data/fuzz/x509/afl_007.pem
new file mode 100644
index 000000000..30145a8fa
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_007.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICAIN CAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_008.pem b/src/tests/data/fuzz/x509/afl_008.pem
new file mode 100644
index 000000000..5be654ce4
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_008.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMfAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIEYMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_009.pem b/src/tests/data/fuzz/x509/afl_009.pem
new file mode 100644
index 000000000..7434298ea
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_009.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MICATECCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhUgQ3liZXJU
+cnVzdcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_010.pem b/src/tests/data/fuzz/x509/afl_010.pem
new file mode 100644
index 000000000..2640094e5
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_010.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAAIGHADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwADAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_011.pem b/src/tests/data/fuzz/x509/afl_011.pem
new file mode 100644
index 000000000..176669d6d
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_011.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICATECCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTA0GCSqGSIb3DQEBBAUAMEUxCMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OT1wWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXvcmApy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_012.pem b/src/tests/data/fuzz/x509/afl_012.pem
new file mode 100644
index 000000000..baf1a7786
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_012.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICATECCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OPI2PnPfMD+fQ2qLTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAFMQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_013.pem b/src/tests/data/fuzz/x509/afl_013.pem
new file mode 100644
index 000000000..bbb050f76
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_013.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICATECCAWMCAgGjMA0GCSqGAMTE0dURSBDeWJlcXRydXN0ISIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlcXRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor7M4sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9t1tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_014.pem b/src/tests/data/fuzz/x509/afl_014.pem
new file mode 100644
index 000000000..b68d8c8e2
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_014.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCATDKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_015.pem b/src/tests/data/fuzz/x509/afl_015.pem
new file mode 100644
index 000000000..ea8638e31
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_015.pem
@@ -0,0 +1,5 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVgYD
+VQQKEw9HVEUgQ29ycG9yYX===============================lR===============================ydXN0IFJv
+b3QwHhcNOTYwMY
+-----END CEc \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_016.pem b/src/tests/data/fuzz/x509/afl_016.pem
new file mode 100644
index 000000000..3bd2fc312
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_016.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIBBAUAMEUxCCATEgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBHeFhVYAA1DeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPm1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAO4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1LvZ46WXTeorKeDWanOB5rCJo9Px4KWl
+IjeaY8JIILTbcRPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_017.pem b/src/tests/data/fuzz/x509/afl_017.pem
new file mode 100644
index 000000000..6ec87b82b
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_017.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIBBAUAMEUxCCATEgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMpK+ULjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPm1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAO4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5rCJo9Px4KWl
+IjeaY8JIILTbcRPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_018.pem b/src/tests/data/fuzz/x509/afl_018.pem
new file mode 100644
index 000000000..be7ecaec6
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_018.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKAgQc45k+625h8BSb2
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_019.pem b/src/tests/data/fuzz/x509/afl_019.pem
new file mode 100644
index 000000000..d0603430f
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_019.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xgDCERTNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQA45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_020.pem b/src/tests/data/fuzz/x509/afl_020.pem
new file mode 100644
index 000000000..10cba363d
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_020.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MICfMA0GCSqGSIb3DQEBAQUAA4RHADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_021.pem b/src/tests/data/fuzz/x509/afl_021.pem
new file mode 100644
index 000000000..5e861a5aa
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_021.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCZgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAlWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46-----BKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_022.pem b/src/tests/data/fuzz/x509/afl_022.pem
new file mode 100644
index 000000000..7ffa58208
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_022.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE-----
+MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUKQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4BSb2CBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt CERTiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_023.pem b/src/tests/data/fuzz/x509/afl_023.pem
new file mode 100644
index 000000000..ace8de7a1
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_023.pem
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MICAgECCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv
+b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV
+UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU
+cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv
+RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M
+ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5
+1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4RBABKz
+dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl
+IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy
+bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY
+-----END CERTIFICATE----- \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_024.pem b/src/tests/data/fuzz/x509/afl_024.pem
new file mode 100644
index 000000000..57243fc2e
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_024.pem
@@ -0,0 +1,3 @@
+0�q�-
+MIIvLmCCAW]C---BE���CERT---
+MIIvcmCCAW]C \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_025.pem b/src/tests/data/fuzz/x509/afl_025.pem
new file mode 100644
index 000000000..f1e877697
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_025.pem
@@ -0,0 +1,3 @@
+0�q�-
+MIIfLm CAW]C--����mCCAW-BE����CERT-#-
+MIIvGmCCAW]C \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_026.pem b/src/tests/data/fuzz/x509/afl_026.pem
new file mode 100644
index 000000000..899e1d71d
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_026.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_027.pem b/src/tests/data/fuzz/x509/afl_027.pem
new file mode 100644
index 000000000..8504c3d8c
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_027.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_028.pem b/src/tests/data/fuzz/x509/afl_028.pem
new file mode 100644
index 000000000..d4f588112
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_028.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_029.pem b/src/tests/data/fuzz/x509/afl_029.pem
new file mode 100644
index 000000000..59591e0b8
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_029.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_030.pem b/src/tests/data/fuzz/x509/afl_030.pem
new file mode 100644
index 000000000..be3106dcc
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_030.pem
@@ -0,0 +1 @@
+0����----BcCAWqG \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_031.pem b/src/tests/data/fuzz/x509/afl_031.pem
new file mode 100644
index 000000000..1bdb26461
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_031.pem
@@ -0,0 +1 @@
+0�q�BEG���II�m8CAW]C \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_032.pem b/src/tests/data/fuzz/x509/afl_032.pem
new file mode 100644
index 000000000..436f7ce70
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_032.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_033.pem b/src/tests/data/fuzz/x509/afl_033.pem
new file mode 100644
index 000000000..f1aa4028e
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_033.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_034.pem b/src/tests/data/fuzz/x509/afl_034.pem
new file mode 100644
index 000000000..11c8448d0
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_034.pem
@@ -0,0 +1,4 @@
+-----BEGIN CERTIFICATE-----
+MIBBAUAMEUxCzAJBgNoBAYTAlVTMRgwFgYT
+VQQKEw9HVEUgQ29ycG9yYXRpb24xHXY
+-----END CERTIFICATE-----DA \ No newline at end of file
diff --git a/src/tests/data/fuzz/x509/afl_035.pem b/src/tests/data/fuzz/x509/afl_035.pem
new file mode 100644
index 000000000..1ff6f1f71
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_035.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_036.pem b/src/tests/data/fuzz/x509/afl_036.pem
new file mode 100644
index 000000000..8171e93c9
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_036.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_037.pem b/src/tests/data/fuzz/x509/afl_037.pem
new file mode 100644
index 000000000..f3f4403b9
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_037.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_038.pem b/src/tests/data/fuzz/x509/afl_038.pem
new file mode 100644
index 000000000..bfdd13e44
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_038.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_039.pem b/src/tests/data/fuzz/x509/afl_039.pem
new file mode 100644
index 000000000..9e888f879
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_039.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_040.pem b/src/tests/data/fuzz/x509/afl_040.pem
new file mode 100644
index 000000000..dbde6a784
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_040.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_041.pem b/src/tests/data/fuzz/x509/afl_041.pem
new file mode 100644
index 000000000..5405ae442
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_041.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_042.pem b/src/tests/data/fuzz/x509/afl_042.pem
new file mode 100644
index 000000000..6862f605a
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_042.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_043.pem b/src/tests/data/fuzz/x509/afl_043.pem
new file mode 100644
index 000000000..56b0ddead
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_043.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_044.pem b/src/tests/data/fuzz/x509/afl_044.pem
new file mode 100644
index 000000000..c250a4c73
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_044.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_045.pem b/src/tests/data/fuzz/x509/afl_045.pem
new file mode 100644
index 000000000..d3d2fbb7f
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_045.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_046.pem b/src/tests/data/fuzz/x509/afl_046.pem
new file mode 100644
index 000000000..0c65e9a45
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_046.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_047.pem b/src/tests/data/fuzz/x509/afl_047.pem
new file mode 100644
index 000000000..9e1ad3030
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_047.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_048.pem b/src/tests/data/fuzz/x509/afl_048.pem
new file mode 100644
index 000000000..e7f577414
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_048.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_049.pem b/src/tests/data/fuzz/x509/afl_049.pem
new file mode 100644
index 000000000..60a5b63bd
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_049.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_050.pem b/src/tests/data/fuzz/x509/afl_050.pem
new file mode 100644
index 000000000..2407ec731
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_050.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_051.pem b/src/tests/data/fuzz/x509/afl_051.pem
new file mode 100644
index 000000000..c6f0bf36f
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_051.pem
Binary files differ
diff --git a/src/tests/data/fuzz/x509/afl_052.pem b/src/tests/data/fuzz/x509/afl_052.pem
new file mode 100644
index 000000000..3f2b126f6
--- /dev/null
+++ b/src/tests/data/fuzz/x509/afl_052.pem
Binary files differ
diff --git a/src/tests/nist_x509.cpp b/src/tests/nist_x509.cpp
index 734f2b355..04b569d32 100644
--- a/src/tests/nist_x509.cpp
+++ b/src/tests/nist_x509.cpp
@@ -18,7 +18,7 @@
#if defined(BOTAN_HAS_X509_CERTIFICATES)
#include <botan/x509path.h>
-#include <botan/fs.h>
+#include <botan/internal/filesystem.h>
#include <algorithm>
#include <iostream>
@@ -37,10 +37,14 @@ size_t test_nist_x509()
const std::string root_test_dir = "src/tests/data/nist_x509/";
const size_t total_tests = 76;
- if(list_all_readable_files_in_or_under(root_test_dir).empty())
+ try
{
- std::cout << "No FS access, skipping NIST X.509 validation tests" << std::endl;
- test_report("NIST X.509 path validation", 0, 0);
+ // Do nothing, just test filesystem access
+ get_files_recursive(root_test_dir);
+ }
+ catch(No_Filesystem_Access)
+ {
+ std::cout << "Warning: No filesystem access, skipping NIST X.509 validation tests" << std::endl;
return 0;
}
@@ -57,17 +61,17 @@ size_t test_nist_x509()
for(size_t test_no = 1; test_no <= total_tests; ++test_no)
{
const std::string test_dir = root_test_dir + "/test" + (test_no <= 9 ? "0" : "") + std::to_string(test_no);
- const std::vector<std::string> all_files = list_all_readable_files_in_or_under(test_dir);
+
+ const std::vector<std::string> all_files = get_files_recursive(test_dir);
+ if (all_files.empty())
+ std::cout << "Warning: No test files found in '" << test_dir << "'" << std::endl;
std::vector<std::string> certs, crls;
std::string root_cert, to_verify;
- for(size_t k = 0; k != all_files.size(); k++)
+ for(const auto &current : all_files)
{
- const std::string current = all_files[k];
-
- if(current.find("int") != std::string::npos &&
- current.find(".crt") != std::string::npos)
+ if(current.find("int") != std::string::npos && current.find(".crt") != std::string::npos)
certs.push_back(current);
else if(current.find("root.crt") != std::string::npos)
root_cert = current;
@@ -96,7 +100,7 @@ size_t test_nist_x509()
for(size_t i = 0; i != crls.size(); i++)
{
- DataSource_Stream in(crls[i]);
+ DataSource_Stream in(crls[i], true);
X509_CRL crl(in);
store.add_crl(crl);
}
@@ -208,14 +212,14 @@ std::map<size_t, Path_Validation_Result::Code> get_expected()
In the case of the tests currently in the suite, the default
method (with acceptable policy being "any-policy" and with no
- explict policy required), will almost always result in a verified
+ explicit policy required), will almost always result in a verified
status. This is not particularly helpful. So, we should do several
different tests for each test set:
1) With the user policy as any-policy and no explicit policy
2) With the user policy as any-policy and an explicit policy required
3) With the user policy as test-policy-1 (2.16.840.1.101.3.1.48.1) and
- an explict policy required
+ an explicit policy required
4) With the user policy as either test-policy-1 or test-policy-2 and an
explicit policy required
@@ -234,9 +238,9 @@ std::map<size_t, Path_Validation_Result::Code> get_expected()
expected_results[43] = Certificate_Status_Code::VERIFIED;
expected_results[44] = Certificate_Status_Code::VERIFIED;
- //expected_results[45] = Certificate_Status_Code::EXPLICT_POLICY_REQUIRED;
+ //expected_results[45] = Certificate_Status_Code::EXPLICIT_POLICY_REQUIRED;
//expected_results[46] = Certificate_Status_Code::ACCEPT;
- //expected_results[47] = Certificate_Status_Code::EXPLICT_POLICY_REQUIRED;
+ //expected_results[47] = Certificate_Status_Code::EXPLICIT_POLICY_REQUIRED;
expected_results[48] = Certificate_Status_Code::VERIFIED;
expected_results[49] = Certificate_Status_Code::VERIFIED;
diff --git a/src/tests/outdata/.gitkeep b/src/tests/outdata/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/tests/outdata/.gitkeep
diff --git a/src/tests/test_aead.cpp b/src/tests/test_aead.cpp
index e9f002e19..5fe4011fb 100644
--- a/src/tests/test_aead.cpp
+++ b/src/tests/test_aead.cpp
@@ -6,6 +6,8 @@
#include "tests.h"
+#if defined(BOTAN_HAS_AEAD_MODES)
+
#include <botan/hex.h>
#include <botan/aead.h>
#include <iostream>
@@ -31,7 +33,7 @@ size_t aead_test(const std::string& algo,
std::unique_ptr<Cipher_Mode> dec(get_aead(algo, DECRYPTION));
if(!enc || !dec)
- throw std::runtime_error("Unknown AEAD " + algo);
+ throw std::runtime_error("Unknown AEAD '" + algo + "'");
enc->set_key(key);
dec->set_key(key);
@@ -141,5 +143,11 @@ size_t test_aead()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "aead", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/aead", test);
}
+
+#else
+
+SKIP_TEST(aead);
+
+#endif // BOTAN_HAS_AEAD_MODES
diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp
index 82fc49861..e6aa4a434 100644
--- a/src/tests/test_bigint.cpp
+++ b/src/tests/test_bigint.cpp
@@ -6,6 +6,10 @@
#include "tests.h"
+#if defined(BOTAN_HAS_BIGINT)
+
+#if defined(BOTAN_HAS_NUMBERTHEORY)
+
#include <vector>
#include <string>
#include <fstream>
@@ -13,15 +17,132 @@
#include <cstdlib>
#include <iterator>
-
+#include <sstream>
#include <botan/bigint.h>
#include <botan/exceptn.h>
#include <botan/numthry.h>
+#include <botan/reducer.h>
+
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+#include <botan/curve_nistp.h>
+#endif
using namespace Botan;
namespace {
+BOTAN_TEST_CASE(bigint_to_u32bit, "BigInt to_u32bit", {
+ for(size_t i = 0; i != 32; ++i)
+ {
+ const u32bit in = 1 << i;
+ BOTAN_TEST(in, BigInt(in).to_u32bit(), "in range round trips");
+ }
+ });
+
+BigInt test_integer(RandomNumberGenerator& rng, size_t bits, BigInt max)
+ {
+ /*
+ Produces integers with long runs of ones and zeros, for testing for
+ carry handling problems.
+ */
+ BigInt x = 0;
+
+ auto flip_prob = [](size_t i) {
+ if(i % 64 == 0)
+ return .5;
+ if(i % 32 == 0)
+ return .4;
+ if(i % 8 == 0)
+ return .05;
+ return .01;
+ };
+
+ bool active = rng.next_byte() % 2;
+ for(size_t i = 0; i != bits; ++i)
+ {
+ x <<= 1;
+ x += static_cast<int>(active);
+
+ const double prob = flip_prob(i);
+ const double sample = double(rng.next_byte() % 100) / 100.0; // biased
+
+ if(sample < prob)
+ active = !active;
+ }
+
+ if(max > 0)
+ {
+ while(x >= max)
+ {
+ const size_t b = x.bits() - 1;
+ BOTAN_ASSERT(x.get_bit(b) == true, "Set");
+ x.clear_bit(b);
+ }
+ }
+
+ return x;
+ }
+
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+
+void nist_redc_test(Test_State& _test,
+ const std::string& prime_name,
+ const BigInt& p,
+ std::function<void (BigInt&, secure_vector<word>&)> redc_fn)
+ {
+ auto& rng = test_rng();
+ const BigInt p2 = p*p;
+ const size_t trials = 100;
+ const size_t p_bits = p.bits();
+
+ Modular_Reducer p_redc(p);
+ secure_vector<word> ws;
+
+ for(size_t i = 0; i != trials; ++i)
+ {
+ const BigInt x = test_integer(rng, 2*p_bits, p2);
+
+ // TODO: time and report all three approaches
+ const BigInt v1 = x % p;
+ const BigInt v2 = p_redc.reduce(x);
+
+ BigInt v3 = x;
+ redc_fn(v3, ws);
+
+ BOTAN_TEST(v1, v2, "reference");
+ BOTAN_TEST(v2, v3, "specialized");
+
+ if(v1 != v2 || v2 != v3)
+ std::cout << "Prime " << prime_name << " input " << x << "\n";
+ }
+ }
+
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+
+BOTAN_TEST_CASE(bigint_redc_p192, "P-192 reduction", {
+ nist_redc_test(_test, "P-192", prime_p192(), redc_p192);
+ });
+
+BOTAN_TEST_CASE(bigint_redc_p224, "P-224 reduction", {
+ nist_redc_test(_test, "P-224", prime_p224(), redc_p224);
+ });
+
+BOTAN_TEST_CASE(bigint_redc_p256, "P-256 reduction", {
+ nist_redc_test(_test, "P-256", prime_p256(), redc_p256);
+ });
+
+BOTAN_TEST_CASE(bigint_redc_p384, "P-384 reduction", {
+ nist_redc_test(_test, "P-384", prime_p384(), redc_p384);
+ });
+
+#endif
+
+BOTAN_TEST_CASE(bigint_redc_p521, "P-521 reduction", {
+ nist_redc_test(_test, "P-521", prime_p521(), redc_p521);
+ });
+
+#endif
+
void strip_comments(std::string& line)
{
if(line.find('#') != std::string::npos)
@@ -342,9 +463,7 @@ size_t test_bigint()
std::vector<std::string> substr = parse(line);
-#if DEBUG
- std::cout << "Testing: " << algorithm << std::endl;
-#endif
+ // std::cout << "Testing: " << algorithm << std::endl;
size_t new_errors = 0;
if(algorithm.find("Addition") != std::string::npos)
@@ -379,6 +498,31 @@ size_t test_bigint()
<< std::dec << alg_count << std::endl;
}
+ total_errors += test_bigint_to_u32bit();
+
+#if defined(BOTAN_HAS_EC_CURVE_GFP)
+
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+ total_errors += test_bigint_redc_p192();
+ total_errors += test_bigint_redc_p224();
+ total_errors += test_bigint_redc_p256();
+ total_errors += test_bigint_redc_p384();
+ #endif
+
+ total_errors += test_bigint_redc_p521();
+#endif
+
return total_errors;
}
+#else
+
+UNTESTED_WARNING(bigint);
+
+#endif // BOTAN_HAS_NUMBERTHEORY
+
+#else
+
+SKIP_TEST(bigint);
+
+#endif // BOTAN_HAS_BIGINT
diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp
index 50801cf21..509cf1c0c 100644
--- a/src/tests/test_block.cpp
+++ b/src/tests/test_block.cpp
@@ -81,5 +81,5 @@ size_t test_block()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "block", test_bc);
+ return run_tests_in_dir(TEST_DATA_DIR "/block", test_bc);
}
diff --git a/src/tests/test_c25519.cpp b/src/tests/test_c25519.cpp
index 46d9c1bea..5531289a2 100644
--- a/src/tests/test_c25519.cpp
+++ b/src/tests/test_c25519.cpp
@@ -5,19 +5,19 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_CURVE_25519)
+
+#include "test_pubkey.h"
+
#include <botan/curve25519.h>
+#include <botan/pkcs8.h>
#include <botan/hex.h>
#include <iostream>
#include <fstream>
-#endif
using namespace Botan;
-#if defined(BOTAN_HAS_CURVE_25519)
-
namespace {
size_t curve25519_scalar_kat(const std::string& secret_h,
@@ -40,23 +40,85 @@ size_t curve25519_scalar_kat(const std::string& secret_h,
return 0;
}
+size_t c25519_roundtrip()
+ {
+ auto& rng = test_rng();
+
+ try
+ {
+ // First create keys
+ Curve25519_PrivateKey a_priv_gen(rng);
+ Curve25519_PrivateKey b_priv_gen(rng);
+
+ const std::string a_pass = "alice pass";
+ const std::string b_pass = "bob pass";
+
+ // Then serialize to encrypted storage
+ const auto pbe_time = std::chrono::milliseconds(10);
+ const std::string a_priv_pem = PKCS8::PEM_encode(a_priv_gen, rng, a_pass, pbe_time);
+ const std::string b_priv_pem = PKCS8::PEM_encode(b_priv_gen, rng, b_pass, pbe_time);
+
+ // Reload back into memory
+ DataSource_Memory a_priv_ds(a_priv_pem);
+ DataSource_Memory b_priv_ds(b_priv_pem);
+
+ std::unique_ptr<Private_Key> a_priv(PKCS8::load_key(a_priv_ds, rng, [a_pass]() { return a_pass; }));
+ std::unique_ptr<Private_Key> b_priv(PKCS8::load_key(b_priv_ds, rng, b_pass));
+
+ // Export public keys as PEM
+ const std::string a_pub_pem = X509::PEM_encode(*a_priv);
+ const std::string b_pub_pem = X509::PEM_encode(*b_priv);
+
+ DataSource_Memory a_pub_ds(a_pub_pem);
+ DataSource_Memory b_pub_ds(b_pub_pem);
+
+ std::unique_ptr<Public_Key> a_pub(X509::load_key(a_pub_ds));
+ std::unique_ptr<Public_Key> b_pub(X509::load_key(b_pub_ds));
+
+ Curve25519_PublicKey* a_pub_key = dynamic_cast<Curve25519_PublicKey*>(a_pub.get());
+ Curve25519_PublicKey* b_pub_key = dynamic_cast<Curve25519_PublicKey*>(b_pub.get());
+
+ PK_Key_Agreement a_ka(*a_priv, "KDF2(SHA-256)");
+ PK_Key_Agreement b_ka(*b_priv, "KDF2(SHA-256)");
+
+ const std::string context = "shared context value";
+ SymmetricKey a_key = a_ka.derive_key(32, b_pub_key->public_value(), context);
+ SymmetricKey b_key = b_ka.derive_key(32, a_pub_key->public_value(), context);
+
+ if(a_key != b_key)
+ return 1;
+ }
+ catch(std::exception& e)
+ {
+ std::cout << "C25519 rt fail: " << e.what() << std::endl;
+ return 1;
+ }
+
+ return 0;
+ }
+
+
}
-#endif
size_t test_curve25519()
{
+ test_report("Curve25519", 1, c25519_roundtrip());
+
size_t fails = 0;
-#if defined(BOTAN_HAS_CURVE_25519)
- std::ifstream c25519_scalar(PK_TEST_DATA_DIR "/c25519_scalar.vec");
+ std::ifstream c25519_scalar(TEST_DATA_DIR_PK "/c25519_scalar.vec");
fails += run_tests_bb(c25519_scalar, "Curve25519 ScalarMult", "Out", true,
[](std::map<std::string, std::string> m) -> size_t
{
return curve25519_scalar_kat(m["Secret"], m["Basepoint"], m["Out"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(curve25519);
+
+#endif // BOTAN_HAS_CURVE_25519
diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp
index 9b83737a0..b68262385 100644
--- a/src/tests/test_compression.cpp
+++ b/src/tests/test_compression.cpp
@@ -1,4 +1,7 @@
#include "tests.h"
+
+#if defined(BOTAN_HAS_COMPRESSION)
+
#include <botan/compression.h>
#include <botan/hex.h>
#include <iostream>
@@ -123,3 +126,9 @@ size_t test_compression()
return fails;
}
+
+#else
+
+SKIP_TEST(compression);
+
+#endif // BOTAN_HAS_COMPRESSION
diff --git a/src/tests/test_cvc.cpp b/src/tests/test_cvc.cpp
index 9b11dea7c..f25775852 100644
--- a/src/tests/test_cvc.cpp
+++ b/src/tests/test_cvc.cpp
@@ -8,10 +8,11 @@
*/
#include "tests.h"
-#include <botan/build.h>
#if defined(BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES)
+#if defined(BOTAN_HAS_ECDSA) && defined(BOTAN_HAS_RSA)
+
#include <iosfwd>
#include <iostream>
#include <iterator>
@@ -571,6 +572,15 @@ size_t test_cvc()
return 0;
}
+
+#else
+
+UNTESTED_WARNING(cvc);
+
+#endif // BOTAN_HAS_ECDSA && BOTAN_HAS_RSA
+
#else
-size_t test_cvc() { return 0; }
-#endif
+
+SKIP_TEST(cvc);
+
+#endif // BOTAN_HAS_CARD_VERIFIABLE_CERTIFICATES
diff --git a/src/tests/test_dh.cpp b/src/tests/test_dh.cpp
index afafd222a..e48d41154 100644
--- a/src/tests/test_dh.cpp
+++ b/src/tests/test_dh.cpp
@@ -5,10 +5,11 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
+#include "test_pubkey.h"
+
#include <botan/pubkey.h>
#include <botan/dh.h>
#include <botan/hex.h>
@@ -49,22 +50,24 @@ size_t dh_sig_kat(const std::string& p,
}
}
-#endif
size_t test_dh()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
- std::ifstream dh_sig(PK_TEST_DATA_DIR "/dh.vec");
+ std::ifstream dh_sig(TEST_DATA_DIR_PK "/dh.vec");
fails += run_tests_bb(dh_sig, "DH Kex", "K", true,
[](std::map<std::string, std::string> m) -> size_t
{
return dh_sig_kat(m["P"], m["G"], m["X"], m["Y"], m["KDF"], m["OutLen"], m["K"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(dh);
+
+#endif // BOTAN_HAS_DIFFIE_HELLMAN
diff --git a/src/tests/test_dlies.cpp b/src/tests/test_dlies.cpp
index ee37f33e2..f282a9387 100644
--- a/src/tests/test_dlies.cpp
+++ b/src/tests/test_dlies.cpp
@@ -5,23 +5,24 @@
*/
#include "tests.h"
+
+#if defined(BOTAN_HAS_DLIES)
+
+#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
+
#include "test_pubkey.h"
-#include <botan/hex.h>
#include <iostream>
#include <fstream>
-#if defined(BOTAN_HAS_DLIES)
-
- #include <botan/pubkey.h>
- #include <botan/lookup.h>
- #include <botan/dlies.h>
- #include <botan/dh.h>
-#endif
+#include <botan/dlies.h>
+#include <botan/dh.h>
+#include <botan/hex.h>
+#include <botan/pubkey.h>
+#include <botan/lookup.h>
using namespace Botan;
-#if defined(BOTAN_HAS_DLIES)
namespace {
size_t dlies_kat(const std::string& p,
@@ -69,22 +70,30 @@ size_t dlies_kat(const std::string& p,
}
}
-#endif
size_t test_dlies()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_DLIES)
- std::ifstream dlies(PK_TEST_DATA_DIR "/dlies.vec");
+ std::ifstream dlies(TEST_DATA_DIR_PK "/dlies.vec");
fails += run_tests_bb(dlies, "DLIES Encryption", "Ciphertext", true,
[](std::map<std::string, std::string> m) -> size_t
{
return dlies_kat(m["P"], m["G"], m["X1"], m["X2"], m["Msg"], m["Ciphertext"]);
});
-#endif
return fails;
}
+#else
+
+UNTESTED_WARNING(dlies);
+
+#endif // BOTAN_HAS_DIFFIE_HELLMAN
+
+#else
+
+SKIP_TEST(dlies);
+
+#endif // BOTAN_HAS_DLIES
diff --git a/src/tests/test_dsa.cpp b/src/tests/test_dsa.cpp
index b31bda9fe..37b2851af 100644
--- a/src/tests/test_dsa.cpp
+++ b/src/tests/test_dsa.cpp
@@ -5,10 +5,10 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_DSA)
+#include "test_pubkey.h"
#include <botan/pubkey.h>
#include <botan/dsa.h>
@@ -47,22 +47,24 @@ size_t dsa_sig_kat(const std::string& p,
}
}
-#endif
size_t test_dsa()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_DSA)
- std::ifstream dsa_sig(PK_TEST_DATA_DIR "/dsa.vec");
+ std::ifstream dsa_sig(TEST_DATA_DIR_PK "/dsa.vec");
fails += run_tests_bb(dsa_sig, "DSA Signature", "Signature", false,
[](std::map<std::string, std::string> m) -> size_t
{
return dsa_sig_kat(m["P"], m["Q"], m["G"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(dsa);
+
+#endif // BOTAN_HAS_DSA
diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp
new file mode 100644
index 000000000..b8537ec64
--- /dev/null
+++ b/src/tests/test_ecc_pointmul.cpp
@@ -0,0 +1,83 @@
+/*
+* (C) 2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_ECC_GROUP)
+
+#if defined(BOTAN_HAS_ECDSA)
+
+#include "test_pubkey.h"
+
+#include <botan/pubkey.h>
+#include <botan/ecdsa.h>
+#include <botan/oids.h>
+#include <botan/hex.h>
+#include <iostream>
+#include <fstream>
+
+using namespace Botan;
+
+namespace {
+
+size_t ecc_point_mul(const std::string& group_id,
+ const std::string& m_s,
+ const std::string& X_s,
+ const std::string& Y_s)
+ {
+ EC_Group group(OIDS::lookup(group_id));
+
+ const BigInt m(m_s);
+ const BigInt X(X_s);
+ const BigInt Y(Y_s);
+
+ PointGFp p = group.get_base_point() * m;
+
+ size_t fails = 0;
+
+ if(p.get_affine_x() != X)
+ {
+ std::cout << p.get_affine_x() << " != " << X << std::endl;
+ ++fails;
+ }
+
+ if(p.get_affine_y() != Y)
+ {
+ std::cout << p.get_affine_y() << " != " << Y << std::endl;
+ ++fails;
+ }
+
+ return fails;
+ }
+
+}
+
+size_t test_ecc_pointmul()
+ {
+ size_t fails = 0;
+
+ std::ifstream ecc_mul(TEST_DATA_DIR_PK "/ecc.vec");
+
+ fails += run_tests_bb(ecc_mul, "ECC Point Mult", "Y", false,
+ [](std::map<std::string, std::string> m) -> size_t
+ {
+ return ecc_point_mul(m["Group"], m["m"], m["X"], m["Y"]);
+ });
+
+ return fails;
+ }
+
+#else
+
+UNTESTED_WARNING(ecc_pointmul);
+
+#endif // BOTAN_HAS_ECDSA
+
+#else
+
+SKIP_TEST(ecc_pointmul);
+
+#endif // BOTAN_HAS_ECC_GROUP
diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp
index 53f32ab49..8d385b4bf 100644
--- a/src/tests/test_ecdsa.cpp
+++ b/src/tests/test_ecdsa.cpp
@@ -5,10 +5,11 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_ECDSA)
+#include "test_pubkey.h"
+
#include <botan/pubkey.h>
#include <botan/ecdsa.h>
#include <botan/oids.h>
@@ -24,7 +25,6 @@ size_t ecdsa_sig_kat(const std::string& group_id,
const std::string& x,
const std::string& hash,
const std::string& msg,
- const std::string& nonce,
const std::string& signature)
{
auto& rng = test_rng();
@@ -38,73 +38,28 @@ size_t ecdsa_sig_kat(const std::string& group_id,
PK_Signer sign(ecdsa, padding);
return validate_signature(verify, sign, "ECDSA/" + group_id + '/' + hash,
- msg, rng, nonce, signature);
- }
-
-size_t ecc_point_mul(const std::string& group_id,
- const std::string& m_s,
- const std::string& X_s,
- const std::string& Y_s)
- {
- EC_Group group(OIDS::lookup(group_id));
-
- const BigInt m(m_s);
- const BigInt X(X_s);
- const BigInt Y(Y_s);
-
- PointGFp p = group.get_base_point() * m;
-
- size_t fails = 0;
-
- if(p.get_affine_x() != X)
- {
- std::cout << p.get_affine_x() << " != " << X << std::endl;
- ++fails;
- }
-
- if(p.get_affine_y() != Y)
- {
- std::cout << p.get_affine_y() << " != " << Y << std::endl;
- ++fails;
- }
-
- return fails;
+ msg, rng, signature);
}
}
-#endif
-
-size_t test_ecc_pointmul()
+size_t test_ecdsa()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_ECC_GROUP)
- std::ifstream ecc_mul(PK_TEST_DATA_DIR "/ecc.vec");
+ std::ifstream ecdsa_sig(TEST_DATA_DIR_PK "/ecdsa.vec");
- fails += run_tests_bb(ecc_mul, "ECC Point Mult", "Y", false,
+ fails += run_tests_bb(ecdsa_sig, "ECDSA Signature", "Signature", false,
[](std::map<std::string, std::string> m) -> size_t
{
- return ecc_point_mul(m["Group"], m["m"], m["X"], m["Y"]);
+ return ecdsa_sig_kat(m["Group"], m["X"], m["Hash"], m["Msg"], m["Signature"]);
});
-#endif
return fails;
}
-size_t test_ecdsa()
- {
- size_t fails = 0;
-
-#if defined(BOTAN_HAS_ECDSA)
- std::ifstream ecdsa_sig(PK_TEST_DATA_DIR "/ecdsa.vec");
+#else
- fails += run_tests_bb(ecdsa_sig, "ECDSA Signature", "Signature", false,
- [](std::map<std::string, std::string> m) -> size_t
- {
- return ecdsa_sig_kat(m["Group"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]);
- });
-#endif
+SKIP_TEST(ecdsa);
- return fails;
- }
+#endif // BOTAN_HAS_ECDSA
diff --git a/src/tests/test_elg.cpp b/src/tests/test_elg.cpp
index cfe6375fb..7bfb02e46 100644
--- a/src/tests/test_elg.cpp
+++ b/src/tests/test_elg.cpp
@@ -5,23 +5,20 @@
*/
#include "tests.h"
+
+#if defined(BOTAN_HAS_ELGAMAL)
+
#include "test_pubkey.h"
#include <botan/hex.h>
+#include <botan/elgamal.h>
+#include <botan/pubkey.h>
+#include <botan/dl_group.h>
#include <iostream>
#include <fstream>
-#if defined(BOTAN_HAS_ELGAMAL)
- #include <botan/elgamal.h>
-
- #include <botan/pubkey.h>
- #include <botan/dl_group.h>
-#endif
-
using namespace Botan;
-#if defined(BOTAN_HAS_ELGAMAL)
-
namespace {
size_t elgamal_kat(const std::string& p,
@@ -53,14 +50,12 @@ size_t elgamal_kat(const std::string& p,
}
}
-#endif
size_t test_elgamal()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_ELGAMAL)
- std::ifstream elgamal_enc(PK_TEST_DATA_DIR "/elgamal.vec");
+ std::ifstream elgamal_enc(TEST_DATA_DIR_PK "/elgamal.vec");
fails += run_tests_bb(elgamal_enc, "ElGamal Encryption", "Ciphertext", true,
[](std::map<std::string, std::string> m) -> size_t
@@ -68,7 +63,12 @@ size_t test_elgamal()
return elgamal_kat(m["P"], m["G"], m["X"], m["Msg"],
m["Padding"], m["Nonce"], m["Ciphertext"]);
});
-#endif
return fails;
}
+
+#else
+
+SKIP_TEST(elgamal);
+
+#endif // BOTAN_HAS_ELGAMAL
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
new file mode 100644
index 000000000..5aa4930b9
--- /dev/null
+++ b/src/tests/test_ffi.cpp
@@ -0,0 +1,397 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "catchy/catchy_tests.h"
+
+#if defined(BOTAN_HAS_FFI)
+
+#include <botan/version.h>
+
+#include <botan/hex.h>
+#include <botan/ffi.h>
+
+using Botan::hex_encode;
+using Botan::hex_decode;
+
+TEST_CASE("FFI versioning", "[ffi]")
+ {
+ CHECK_THAT(botan_ffi_api_version(), Equals(BOTAN_HAS_FFI));
+ CHECK_THAT(botan_version_major(), Equals(Botan::version_major()));
+ CHECK_THAT(botan_version_minor(), Equals(Botan::version_minor()));
+ CHECK_THAT(botan_version_patch(), Equals(Botan::version_patch()));
+ }
+
+TEST_CASE("FFI hex", "[ffi]")
+ {
+ const std::vector<uint8_t> bin = { 0xAA, 0xDE, 0x01 };
+ std::string out;
+ out.resize(2*bin.size());
+
+ CHECK_THAT(botan_hex_encode(bin.data(), bin.size(), &out[0], 0), Equals(0));
+ CHECK_THAT(out, Equals("AADE01"));
+
+ CHECK_THAT(botan_hex_encode(bin.data(), bin.size(), &out[0], BOTAN_FFI_HEX_LOWER_CASE), Equals(0));
+ CHECK_THAT(out, Equals("aade01"));
+ }
+
+TEST_CASE("FFI RNG", "[ffi]")
+ {
+ botan_rng_t rng;
+ unsigned char buf[512];
+
+ CHECK(botan_rng_init(&rng, "bad_type") < 0);
+
+ const std::vector<std::string> types = { "system", "user" };
+
+ for(const auto type : types)
+ {
+ REQUIRE_THAT(botan_rng_init(&rng, type.c_str()), Equals(0));
+ CHECK_THAT(botan_rng_get(rng, buf, sizeof(buf)), Equals(0));
+ CHECK_THAT(botan_rng_reseed(rng, 256), Equals(0));
+
+ int ret = botan_rng_destroy(rng); // Catch evalues expresstion multiple times
+ CHECK_THAT(ret, Equals(0));
+ }
+ }
+
+TEST_CASE("FFI hash", "[ffi]")
+ {
+ botan_hash_t hash;
+ CHECK(botan_hash_init(&hash, "SHA-256", 1) < 0);
+ REQUIRE_THAT(botan_hash_init(&hash, "SHA-256", 0), Equals(0));
+
+ /*
+ char namebuf[32];
+ CHECK(botan_hash_name(hash, namebuf, 5) < 0);
+ CHECK_THAT(botan_hash_name(hash, namebuf, 31));
+ CHECK(std::string(namebuf) == "SHA-256");
+ */
+
+ size_t ol;
+ CHECK_THAT(botan_hash_output_length(hash, &ol), Equals(0));
+ CHECK_THAT(ol, Equals(32));
+
+ const char* s = "ABC";
+
+ std::vector<uint8_t> outbuf(ol);
+
+ int retUpdate = botan_hash_update(hash, reinterpret_cast<const uint8_t*>(s), 3);
+ CHECK_THAT(retUpdate, Equals(0));
+
+ int retFinal = botan_hash_final(hash, outbuf.data());
+ CHECK_THAT(retFinal, Equals(0));
+
+ //CHECK_ARRAY(outbuf, "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
+ CHECK_THAT(hex_encode(outbuf), Equals("B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78"));
+
+ CHECK_THAT(botan_hash_clear(hash), Equals(0));
+ int ret = botan_hash_destroy(hash);
+ CHECK_THAT(ret, Equals(0));
+ }
+
+TEST_CASE("FFI mac", "[ffi]")
+ {
+ botan_mac_t mac;
+ CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-256)", 1), Equals(-1)); // bad flag
+ CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-259)", 0), Equals(-2)); // bad name
+ CHECK_THAT(botan_mac_init(&mac, "HMAC(SHA-256)", 0), Equals(0));
+
+ //char namebuf[32];
+ //CHECK(botan_mac_name(mac, namebuf, 10) < 0);
+ //CHECK_THAT(botan_mac_name(mac, namebuf, 31), Equals(0));
+ //CHECK(std::string(namebuf) == "HMAC(SHA-256)");
+
+ size_t ol;
+ CHECK_THAT(botan_mac_output_length(mac, &ol), Equals(0));
+ CHECK_THAT(ol, Equals(32));
+
+ const uint8_t key[] = { 0xAA, 0xBB, 0xCC, 0xDD };
+
+ CHECK_THAT(botan_mac_set_key(mac, key, 4), Equals(0));
+ const char* s = "ABC";
+
+ std::vector<uint8_t> outbuf(ol);
+
+ int retUpdate = botan_mac_update(mac, reinterpret_cast<const uint8_t*>(s), 3);
+ CHECK_THAT(retUpdate, Equals(0));
+
+ int retFinal = botan_mac_final(mac, outbuf.data());
+ CHECK_THAT(retFinal, Equals(0));
+
+ CHECK_THAT(hex_encode(outbuf), Equals("1A82EEA984BC4A7285617CC0D05F1FE1D6C96675924A81BC965EE8FF7B0697A7"));
+
+ CHECK_THAT(botan_mac_clear(mac), Equals(0));
+
+ int retDestroy = botan_mac_destroy(mac);
+ CHECK_THAT(retDestroy, Equals(0));
+ }
+
+TEST_CASE("FFI PBKDF", "[ffi]")
+ {
+ const std::vector<uint8_t> salt = hex_decode("ED1F39A0A7F3889AAF7E60743B3BC1CC2C738E60");
+ const std::string passphrase = "ltexmfeyylmlbrsyikaw";
+ const size_t out_len = 10;
+ const size_t iterations = 1000;
+
+ std::vector<uint8_t> outbuf(out_len);
+
+ CHECK_THAT(botan_pbkdf("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), iterations),
+ Equals(0));
+
+ CHECK_THAT(hex_encode(outbuf), Equals("027AFADD48F4BE8DCC4F"));
+
+ size_t iters_10ms, iters_100ms;
+ CHECK_THAT(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), 10, &iters_10ms),
+ Equals(0));
+ CHECK_THAT(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), 100, &iters_100ms),
+ Equals(0));
+
+ CHECK(iters_10ms >= 10000);
+
+ /*
+ * Tests deactivated due to consistetly failing in debug mode where -W0 is set
+ * (./configure.py --build-mode=debug).
+ * See also: https://github.com/randombit/botan/commit/30b0e3c88e94ba04c1843798f7ac74a008e01d9b
+ */
+ /*
+ INFO("Iterations " << iters_10ms << " " << iters_100ms);
+ const double ratio = static_cast<double>(iters_100ms) / iters_10ms;
+ // Loose timing to avoid false positives on CI
+ CHECK(ratio >= 3);
+ CHECK(ratio <= 15);
+ */
+ }
+
+TEST_CASE("FFI KDF", "[ffi]")
+ {
+ const std::vector<uint8_t> secret = hex_decode("92167440112E");
+ const std::vector<uint8_t> salt = hex_decode("45A9BEDED69163123D0348F5185F61ABFB1BF18D6AEA454F");
+ const size_t out_len = 18;
+ std::vector<uint8_t> out_buf(out_len);
+
+ REQUIRE_THAT(botan_kdf("KDF2(SHA-1)", out_buf.data(), out_len,
+ secret.data(), secret.size(), salt.data(), salt.size()),
+ Equals(0));
+
+ CHECK_THAT(hex_encode(out_buf), Equals("3A5DC9AA1C872B4744515AC2702D6396FC2A"));
+ }
+
+TEST_CASE("FFI bcrypt", "[ffi]")
+ {
+ botan_rng_t rng;
+ botan_rng_init(&rng, "system");
+
+ std::vector<uint8_t> outbuf(62);
+ size_t ol = outbuf.size();
+
+ CHECK_THAT(botan_bcrypt_generate(outbuf.data(), &ol, "password", rng, 10, 0), Equals(0));
+ botan_rng_destroy(rng);
+
+ CHECK_THAT(botan_bcrypt_is_valid("wrong", reinterpret_cast<const char*>(outbuf.data())), Equals(1));
+ CHECK_THAT(botan_bcrypt_is_valid("password", reinterpret_cast<const char*>(outbuf.data())), Equals(0));
+ }
+
+TEST_CASE("FFI RSA", "[ffi]")
+ {
+ botan_rng_t rng;
+ botan_rng_init(&rng, "system");
+
+ botan_privkey_t priv;
+ REQUIRE_THAT(botan_privkey_create_rsa(&priv, rng, 2048), Equals(0));
+
+ botan_pubkey_t pub;
+ CHECK_THAT(botan_privkey_export_pubkey(&pub, priv), Equals(0));
+
+ std::string name(64, '\x00');
+ size_t name_len = name.size();
+ CHECK_THAT(botan_pubkey_algo_name(pub, &name[0], &name_len), Equals(0));
+ name.resize(name_len - 1);
+
+ CHECK_THAT(name, Equals("RSA"));
+
+ botan_pk_op_encrypt_t encrypt;
+ CHECK_THAT(botan_pk_op_encrypt_create(&encrypt, pub, "OAEP(SHA-256)", 0), Equals(0));
+
+ std::vector<uint8_t> plaintext(32);
+ CHECK_THAT(botan_rng_get(rng, plaintext.data(), plaintext.size()), Equals(0));
+
+ std::vector<uint8_t> ciphertext(256); // TODO: no way to know this size from API
+ size_t ctext_len = ciphertext.size();
+ CHECK_THAT(botan_pk_op_encrypt(encrypt, rng, ciphertext.data(), &ctext_len,
+ plaintext.data(), plaintext.size()),
+ Equals(0));
+ ciphertext.resize(ctext_len);
+
+ int retEncryptDestroy = botan_pk_op_encrypt_destroy(encrypt);
+ CHECK_THAT(retEncryptDestroy, Equals(0));
+ //CHECK(botan_pk_op_encrypt_destroy(encrypt) < 0);
+
+ botan_pk_op_decrypt_t decrypt;
+ CHECK_THAT(botan_pk_op_decrypt_create(&decrypt, priv, "OAEP(SHA-256)", 0), Equals(0));
+
+ std::vector<uint8_t> decrypted(256); // TODO as with above
+ size_t decrypted_len = decrypted.size();
+ CHECK_THAT(botan_pk_op_decrypt(decrypt, decrypted.data(), &decrypted_len,
+ ciphertext.data(), ciphertext.size()),
+ Equals(0));
+ decrypted.resize(decrypted_len);
+
+ CHECK_THAT(hex_encode(plaintext), Equals(hex_encode(decrypted)));
+
+ int retDecryptDestroy = botan_pk_op_decrypt_destroy(decrypt);
+ CHECK_THAT(retDecryptDestroy, Equals(0));
+ //CHECK(botan_pk_op_decrypt_destroy(decrypt) < 0);
+
+ botan_rng_destroy(rng);
+ }
+
+TEST_CASE("FFI ECDSA", "[ffi]")
+ {
+ botan_rng_t rng;
+ botan_rng_init(&rng, "system");
+
+ botan_privkey_t priv;
+ int rc = botan_privkey_create_ecdsa(&priv, rng, "secp384r1");
+
+ botan_pubkey_t pub;
+ CHECK_THAT(botan_privkey_export_pubkey(&pub, priv), Equals(0));
+
+ std::string name(64, '\x00');
+ size_t name_len = name.size();
+ CHECK_THAT(botan_pubkey_algo_name(pub, &name[0], &name_len), Equals(0));
+ name.resize(name_len - 1);
+
+ CHECK_THAT(name, Equals("ECDSA"));
+
+ botan_pk_op_sign_t signer;
+ CHECK_THAT(botan_pk_op_sign_create(&signer, priv, "EMSA1(SHA-384)", 0), Equals(0));
+
+ std::vector<uint8_t> message(1280);
+ CHECK_THAT(botan_rng_get(rng, message.data(), message.size()), Equals(0));
+
+ // TODO: break input into multiple calls to update
+ int retSignUpdate = botan_pk_op_sign_update(signer, message.data(), message.size());
+ CHECK_THAT(retSignUpdate, Equals(0));
+
+ std::vector<uint8_t> signature(96); // TODO: no way to derive this from API
+ size_t sig_len = signature.size();
+
+ int retSignFinish = botan_pk_op_sign_finish(signer, rng, signature.data(), &sig_len);
+ CHECK_THAT(retSignFinish, Equals(0));
+
+ signature.resize(sig_len);
+
+ int retSignDestroy = botan_pk_op_sign_destroy(signer);
+ CHECK_THAT(retSignDestroy, Equals(0));
+
+ botan_pk_op_verify_t verifier;
+ int retVerifyCreate = botan_pk_op_verify_create(&verifier, pub, "EMSA1(SHA-384)", 0);
+ CHECK_THAT(retVerifyCreate, Equals(0));
+
+ {
+ int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
+ CHECK_THAT(retVerifyUpdate, Equals(0));
+ int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
+ CHECK_THAT(retVerifyFinish, Equals(0));
+ }
+
+ // TODO: randomize this
+ signature[0] ^= 1;
+ {
+ int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
+ CHECK_THAT(retVerifyUpdate, Equals(0));
+ int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
+ CHECK_THAT(retVerifyFinish, Equals(1));
+ }
+
+ message[0] ^= 1;
+ {
+ int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
+ CHECK_THAT(retVerifyUpdate, Equals(0));
+ int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
+ CHECK_THAT(retVerifyFinish, Equals(1));
+ }
+
+ signature[0] ^= 1;
+ {
+ int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
+ CHECK_THAT(retVerifyUpdate, Equals(0));
+ int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
+ CHECK_THAT(retVerifyFinish, Equals(1));
+ }
+
+ message[0] ^= 1;
+ {
+ int retVerifyUpdate = botan_pk_op_verify_update(verifier, message.data(), message.size());
+ CHECK_THAT(retVerifyUpdate, Equals(0));
+ int retVerifyFinish = botan_pk_op_verify_finish(verifier, signature.data(), signature.size());
+ CHECK_THAT(retVerifyFinish, Equals(0));
+ }
+
+ int retVerifyDestroy = botan_pk_op_verify_destroy(verifier);
+ CHECK_THAT(retVerifyDestroy, Equals(0));
+
+ botan_rng_destroy(rng);
+ }
+
+TEST_CASE("FFI ECDH", "[ffi]")
+ {
+ botan_rng_t rng;
+ botan_rng_init(&rng, "system");
+
+ botan_privkey_t priv1;
+ CHECK_THAT(botan_privkey_create_ecdh(&priv1, rng, "secp256r1"), Equals(0));
+ botan_privkey_t priv2;
+ CHECK_THAT(botan_privkey_create_ecdh(&priv2, rng, "secp256r1"), Equals(0));
+
+ botan_pubkey_t pub1;
+ CHECK_THAT(botan_privkey_export_pubkey(&pub1, priv1), Equals(0));
+ botan_pubkey_t pub2;
+ CHECK_THAT(botan_privkey_export_pubkey(&pub2, priv2), Equals(0));
+
+ botan_pk_op_ka_t ka1;
+ CHECK_THAT(botan_pk_op_key_agreement_create(&ka1, priv1, "KDF2(SHA-256)", 0), Equals(0));
+ botan_pk_op_ka_t ka2;
+ CHECK_THAT(botan_pk_op_key_agreement_create(&ka2, priv2, "KDF2(SHA-256)", 0), Equals(0));
+
+ std::vector<uint8_t> pubkey1(256); // length problem again
+ size_t pubkey1_len = pubkey1.size();
+ CHECK_THAT(botan_pk_op_key_agreement_export_public(priv1, pubkey1.data(), &pubkey1_len), Equals(0));
+ pubkey1.resize(pubkey1_len);
+
+ std::vector<uint8_t> pubkey2(256); // length problem again
+ size_t pubkey2_len = pubkey2.size();
+ CHECK_THAT(botan_pk_op_key_agreement_export_public(priv2, pubkey2.data(), &pubkey2_len), Equals(0));
+ pubkey2.resize(pubkey2_len);
+
+ std::vector<uint8_t> salt(32);
+ CHECK_THAT(botan_rng_get(rng, salt.data(), salt.size()), Equals(0));
+
+ const size_t shared_key_len = 64;
+
+ std::vector<uint8_t> key1(shared_key_len);
+ size_t key1_len = key1.size();
+ CHECK_THAT(botan_pk_op_key_agreement(ka1, key1.data(), &key1_len,
+ pubkey2.data(), pubkey2.size(),
+ salt.data(), salt.size()),
+ Equals(0));
+
+ std::vector<uint8_t> key2(shared_key_len);
+ size_t key2_len = key2.size();
+ CHECK_THAT(botan_pk_op_key_agreement(ka2, key2.data(), &key2_len,
+ pubkey1.data(), pubkey1.size(),
+ salt.data(), salt.size()),
+ Equals(0));
+
+ CHECK_THAT(hex_encode(key1), Equals(hex_encode(key2)));
+
+ botan_rng_destroy(rng);
+ }
+
+#endif
diff --git a/src/tests/test_fuzzer.cpp b/src/tests/test_fuzzer.cpp
new file mode 100644
index 000000000..212a313a8
--- /dev/null
+++ b/src/tests/test_fuzzer.cpp
@@ -0,0 +1,68 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+#include <chrono>
+#include <iostream>
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
+#include <botan/x509cert.h>
+#include <botan/x509_crl.h>
+#include <botan/internal/filesystem.h>
+#include <botan/base64.h>
+
+#endif
+
+namespace {
+
+size_t test_x509_fuzz()
+ {
+ size_t fails = 0;
+
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+
+ size_t tests = 0;
+ const std::string fuzz_data = TEST_DATA_DIR "/fuzz";
+
+ for(auto vec: Botan::get_files_recursive(fuzz_data + "/x509"))
+ {
+ ++tests;
+
+ auto start = std::chrono::system_clock::now();
+ try
+ {
+ // TODO: check for memory consumption?
+ Botan::X509_Certificate cert(vec);
+ }
+ catch(std::exception& e)
+ {
+ //std::cout << e.what() << "\n";
+ }
+ auto end = std::chrono::system_clock::now();
+
+ uint64_t duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+
+ if(duration > 100)
+ {
+ std::cout << "Fuzzer test " << vec << " took " << duration << " ms" << std::endl;
+ }
+ }
+
+ test_report("Fuzzer checks", tests, fails);
+#endif
+
+ return fails;
+ }
+
+}
+
+size_t test_fuzzer()
+ {
+ size_t fails = 0;
+ fails += test_x509_fuzz();
+ return fails;
+ }
diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp
index 08dc1555b..2f59f7736 100644
--- a/src/tests/test_gost_3410.cpp
+++ b/src/tests/test_gost_3410.cpp
@@ -5,10 +5,11 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_GOST_34_10_2001)
+#include "test_pubkey.h"
+
#include <botan/pubkey.h>
#include <botan/gost_3410.h>
#include <botan/oids.h>
@@ -42,22 +43,24 @@ size_t gost_verify(const std::string& group_id,
}
}
-#endif
size_t test_gost_3410()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_GOST_34_10_2001)
- std::ifstream ecdsa_sig(PK_TEST_DATA_DIR "/gost_3410.vec");
+ std::ifstream ecdsa_sig(TEST_DATA_DIR_PK "/gost_3410.vec");
fails += run_tests_bb(ecdsa_sig, "GOST-34.10 Signature", "Signature", true,
[](std::map<std::string, std::string> m) -> size_t
{
return gost_verify(m["Group"], m["Pubkey"], m["Hash"], m["Msg"], m["Signature"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(gost_3410);
+
+#endif // BOTAN_HAS_GOST_34_10_2001
diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp
index abc3a2f95..a69ba3ef3 100644
--- a/src/tests/test_hash.cpp
+++ b/src/tests/test_hash.cpp
@@ -101,5 +101,5 @@ size_t test_hash()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "hash", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/hash", test);
}
diff --git a/src/tests/test_kdf.cpp b/src/tests/test_kdf.cpp
index 2ce8077ef..65814f0d6 100644
--- a/src/tests/test_kdf.cpp
+++ b/src/tests/test_kdf.cpp
@@ -6,6 +6,8 @@
#include "tests.h"
+#if defined(BOTAN_HAS_KDF_BASE)
+
#include <botan/kdf.h>
#include <botan/lookup.h>
#include <botan/hex.h>
@@ -33,5 +35,11 @@ size_t test_kdf()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "kdf", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/kdf", test);
}
+
+#else
+
+SKIP_TEST(kdf);
+
+#endif // BOTAN_HAS_KDF_BASE
diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp
index e191a6ed7..6ab87274f 100644
--- a/src/tests/test_mac.cpp
+++ b/src/tests/test_mac.cpp
@@ -6,6 +6,8 @@
#include "tests.h"
+#if defined(BOTAN_HAS_MAC)
+
#include <botan/lookup.h>
#include <botan/mac.h>
#include <botan/hex.h>
@@ -91,5 +93,11 @@ size_t test_mac()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "mac", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/mac", test);
}
+
+#else
+
+SKIP_TEST(mac);
+
+#endif // BOTAN_HAS_MAC
diff --git a/src/tests/test_mceliece.cpp b/src/tests/test_mceliece.cpp
index 8f1d3b6a3..616f64be9 100644
--- a/src/tests/test_mceliece.cpp
+++ b/src/tests/test_mceliece.cpp
@@ -8,21 +8,21 @@
#include "tests.h"
+#if defined(BOTAN_HAS_MCELIECE)
+
#include <botan/pubkey.h>
-#include <botan/ecdsa.h>
-#include <botan/rsa.h>
-#include <botan/x509cert.h>
#include <botan/oids.h>
#include <botan/mceliece.h>
#include <botan/mce_kem.h>
-#include <botan/mceies.h>
#include <botan/loadstor.h>
-
#include <botan/hex.h>
-
#include <iostream>
#include <memory>
+#if defined(BOTAN_HAS_MCEIES)
+#include <botan/mceies.h>
+#endif
+
using namespace Botan;
#define CHECK_MESSAGE(expr, print) do {if(!(expr)) {std::cout << print << std::endl; return 1;} }while(0)
@@ -159,11 +159,11 @@ size_t test_mceliece_raw(const McEliece_PrivateKey& sk,
return err_cnt;
}
+#if defined(BOTAN_HAS_MCEIES)
size_t test_mceies(const McEliece_PrivateKey& sk,
const McEliece_PublicKey& pk,
RandomNumberGenerator& rng)
{
-
size_t fails = 0;
for(size_t i = 0; i != 5; ++i)
@@ -207,6 +207,7 @@ size_t test_mceies(const McEliece_PrivateKey& sk,
return fails;
}
+#endif // BOTAN_HAS_MCEIES
}
@@ -214,7 +215,7 @@ size_t test_mceliece()
{
auto& rng = test_rng();
- size_t fails = 0;
+ size_t fails = 0;
size_t params__n__t_min_max[] = {
256, 5, 15,
512, 5, 33,
@@ -239,9 +240,10 @@ size_t test_mceliece()
}
catch(std::exception& e)
{
- std::cout << e.what();
+ std::cout << e.what() << std::endl;
fails++;
}
+ tests += 1;
McEliece_PrivateKey sk1(rng, code_length, t);
const McEliece_PublicKey& pk1 = sk1;
@@ -276,9 +278,10 @@ size_t test_mceliece()
}
catch(std::exception& e)
{
- std::cout << e.what();
+ std::cout << e.what() << std::endl;
fails++;
}
+ tests += 1;
try
{
@@ -286,24 +289,33 @@ size_t test_mceliece()
}
catch(std::exception& e)
{
- std::cout << e.what();
+ std::cout << e.what() << std::endl;
fails++;
}
+ tests += 1;
+#if defined(BOTAN_HAS_MCEIES)
try
{
fails += test_mceies(sk, pk, rng);
}
catch(std::exception& e)
{
- std::cout << e.what();
+ std::cout << e.what() << std::endl;
fails++;
}
+ tests += 1;
+#endif // BOTAN_HAS_MCEIES
- tests += 4;
}
}
test_report("McEliece", tests, fails);
return fails;
}
+
+#else
+
+SKIP_TEST(mceliece);
+
+#endif // BOTAN_HAS_MCELIECE
diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp
index 35853ba82..bfbb46355 100644
--- a/src/tests/test_modes.cpp
+++ b/src/tests/test_modes.cpp
@@ -6,6 +6,10 @@
#include "tests.h"
+#if defined(BOTAN_HAS_MODES)
+
+#if defined(BOTAN_HAS_FILTERS)
+
#include <botan/hex.h>
#include <botan/lookup.h>
#include <botan/cipher_mode.h>
@@ -94,5 +98,17 @@ size_t test_modes()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "modes", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/modes", test);
}
+
+#else
+
+UNTESTED_WARNING(modes);
+
+#endif // BOTAN_HAS_FILTERS
+
+#else
+
+SKIP_TEST(modes);
+
+#endif // BOTAN_HAS_MODES
diff --git a/src/tests/test_nr.cpp b/src/tests/test_nr.cpp
index 25d84606c..334b10359 100644
--- a/src/tests/test_nr.cpp
+++ b/src/tests/test_nr.cpp
@@ -5,22 +5,20 @@
*/
#include "tests.h"
-#include "test_pubkey.h"
#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- #include <botan/nr.h>
- #include <botan/pubkey.h>
- #include <botan/dl_group.h>
-#endif
+
+#include "test_pubkey.h"
#include <botan/hex.h>
+#include <botan/nr.h>
+#include <botan/pubkey.h>
+#include <botan/dl_group.h>
#include <iostream>
#include <fstream>
using namespace Botan;
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
-
namespace {
size_t nr_sig_kat(const std::string& p,
@@ -51,22 +49,24 @@ size_t nr_sig_kat(const std::string& p,
}
}
-#endif
size_t test_nr()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_NYBERG_RUEPPEL)
- std::ifstream nr_sig(PK_TEST_DATA_DIR "/nr.vec");
+ std::ifstream nr_sig(TEST_DATA_DIR_PK "/nr.vec");
fails += run_tests_bb(nr_sig, "NR Signature", "Signature", true,
[](std::map<std::string, std::string> m) -> size_t
{
return nr_sig_kat(m["P"], m["Q"], m["G"], m["X"], m["Hash"], m["Msg"], m["Nonce"], m["Signature"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(nr);
+
+#endif // BOTAN_HAS_NYBERG_RUEPPEL
diff --git a/src/tests/test_ocb.cpp b/src/tests/test_ocb.cpp
index 513b34dc2..4069625b5 100644
--- a/src/tests/test_ocb.cpp
+++ b/src/tests/test_ocb.cpp
@@ -5,9 +5,12 @@
*/
#include "tests.h"
-#include <iostream>
#if defined(BOTAN_HAS_AEAD_OCB)
+
+#if defined(BOTAN_HAS_AES)
+
+#include <iostream>
#include <botan/ocb.h>
#include <botan/hex.h>
#include <botan/sha2_32.h>
@@ -102,14 +105,11 @@ size_t test_ocb_long(size_t keylen, size_t taglen,
}
}
-#endif
size_t test_ocb()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_AEAD_OCB)
-
fails += test_ocb_long(128, 128, "67E944D23256C5E0B6C61FA22FDF1EA2");
fails += test_ocb_long(192, 128, "F673F2C3E7174AAE7BAE986CA9F29E17");
fails += test_ocb_long(256, 128, "D90EB8E9C977C88B79DD793D7FFA161C");
@@ -120,7 +120,18 @@ size_t test_ocb()
fails += test_ocb_long(192, 64, "0066BC6E0EF34E24");
fails += test_ocb_long(256, 64, "7D4EA5D445501CBE");
test_report("OCB long", 9, fails);
-#endif
return fails;
}
+
+#else
+
+UNTESTED_WARNING(ocb);
+
+#endif // BOTAN_HAS_AES
+
+#else
+
+SKIP_TEST(ocb);
+
+#endif // BOTAN_HAS_AEAD_OCB
diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp
index 703a7bc80..8f765fa1d 100644
--- a/src/tests/test_pbkdf.cpp
+++ b/src/tests/test_pbkdf.cpp
@@ -6,6 +6,8 @@
#include "tests.h"
+#if defined(BOTAN_HAS_PBKDF)
+
#include <botan/pbkdf.h>
#include <botan/lookup.h>
#include <botan/hex.h>
@@ -35,5 +37,11 @@ size_t test_pbkdf()
});
};
- return run_tests_in_dir(TEST_DATA_DIR "pbkdf", test);
+ return run_tests_in_dir(TEST_DATA_DIR "/pbkdf", test);
}
+
+#else
+
+SKIP_TEST(pbkdf);
+
+#endif // BOTAN_HAS_PBKDF
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index 00ece8559..c3f2017f6 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -5,6 +5,9 @@
*/
#include "tests.h"
+
+#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
+
#include "test_rng.h"
#include "test_pubkey.h"
@@ -16,13 +19,9 @@
#include <memory>
#include <botan/oids.h>
-
-#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)
- #include <botan/x509_key.h>
- #include <botan/pkcs8.h>
- #include <botan/pubkey.h>
-
-#endif
+#include <botan/x509_key.h>
+#include <botan/pkcs8.h>
+#include <botan/pubkey.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -401,3 +400,9 @@ size_t test_pk_keygen()
return fails;
}
+
+#else
+
+SKIP_TEST(pk_keygen);
+
+#endif // BOTAN_HAS_PUBLIC_KEY_CRYPTO
diff --git a/src/tests/test_rng.cpp b/src/tests/test_rng.cpp
index 81a539f1e..d129ed208 100644
--- a/src/tests/test_rng.cpp
+++ b/src/tests/test_rng.cpp
@@ -31,7 +31,7 @@ RandomNumberGenerator* get_rng(const std::string& algo_str, const std::string& i
public:
AllOnce_RNG(const std::vector<byte>& in) : Fixed_Output_RNG(in) {}
- Botan::secure_vector<byte> random_vec(size_t)
+ Botan::secure_vector<byte> random_vec(size_t) override
{
Botan::secure_vector<byte> vec(this->remaining());
this->randomize(vec.data(), vec.size());
diff --git a/src/tests/test_rng.h b/src/tests/test_rng.h
index bf4032699..f1d40f7f1 100644
--- a/src/tests/test_rng.h
+++ b/src/tests/test_rng.h
@@ -18,7 +18,7 @@ using Botan::byte;
class Fixed_Output_RNG : public Botan::RandomNumberGenerator
{
public:
- bool is_seeded() const { return !buf.empty(); }
+ bool is_seeded() const override { return !buf.empty(); }
byte random()
{
@@ -30,22 +30,22 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator
return out;
}
- void reseed(size_t) {}
+ void reseed(size_t) override {}
- void randomize(byte out[], size_t len)
+ void randomize(byte out[], size_t len) override
{
for(size_t j = 0; j != len; j++)
out[j] = random();
}
- void add_entropy(const byte b[], size_t s)
+ void add_entropy(const byte b[], size_t s) override
{
buf.insert(buf.end(), b, b + s);
}
- std::string name() const { return "Fixed_Output_RNG"; }
+ std::string name() const override { return "Fixed_Output_RNG"; }
- void clear() throw() {}
+ void clear() throw() override {}
Fixed_Output_RNG(const std::vector<byte>& in)
{
diff --git a/src/tests/test_rsa.cpp b/src/tests/test_rsa.cpp
index 4133d13c0..940525574 100644
--- a/src/tests/test_rsa.cpp
+++ b/src/tests/test_rsa.cpp
@@ -5,6 +5,9 @@
*/
#include "tests.h"
+
+#if defined(BOTAN_HAS_RSA)
+
#include "test_pubkey.h"
#include <botan/pubkey.h>
@@ -88,9 +91,9 @@ size_t rsa_sig_verify(const std::string& e,
size_t test_rsa()
{
- std::ifstream rsa_enc(PK_TEST_DATA_DIR "/rsaes.vec");
- std::ifstream rsa_sig(PK_TEST_DATA_DIR "/rsa_sig.vec");
- std::ifstream rsa_verify(PK_TEST_DATA_DIR "/rsa_verify.vec");
+ std::ifstream rsa_enc(TEST_DATA_DIR_PK "/rsaes.vec");
+ std::ifstream rsa_sig(TEST_DATA_DIR_PK "/rsa_sig.vec");
+ std::ifstream rsa_verify(TEST_DATA_DIR_PK "/rsa_verify.vec");
size_t fails = 0;
@@ -118,3 +121,8 @@ size_t test_rsa()
return fails;
}
+#else
+
+SKIP_TEST(rsa);
+
+#endif // BOTAN_HAS_RSA
diff --git a/src/tests/test_rw.cpp b/src/tests/test_rw.cpp
index f5a4f8cdb..286bcacdf 100644
--- a/src/tests/test_rw.cpp
+++ b/src/tests/test_rw.cpp
@@ -5,21 +5,19 @@
*/
#include "tests.h"
+
+#if defined(BOTAN_HAS_RW)
+
#include "test_pubkey.h"
#include <botan/hex.h>
#include <iostream>
#include <fstream>
-
-#if defined(BOTAN_HAS_RW)
-
- #include <botan/pubkey.h>
- #include <botan/rw.h>
-#endif
+#include <botan/pubkey.h>
+#include <botan/rw.h>
using namespace Botan;
-#if defined(BOTAN_HAS_RW)
namespace {
const std::string padding = "EMSA2(SHA-1)";
@@ -60,15 +58,13 @@ size_t rw_sig_verify(const std::string& e,
}
}
-#endif
size_t test_rw()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_RW)
- std::ifstream rw_sig(PK_TEST_DATA_DIR "/rw_sig.vec");
- std::ifstream rw_verify(PK_TEST_DATA_DIR "/rw_verify.vec");
+ std::ifstream rw_sig(TEST_DATA_DIR_PK "/rw_sig.vec");
+ std::ifstream rw_verify(TEST_DATA_DIR_PK "/rw_verify.vec");
fails += run_tests_bb(rw_sig, "RW Signature", "Signature", true,
[](std::map<std::string, std::string> m) -> size_t
@@ -81,8 +77,12 @@ size_t test_rw()
{
return rw_sig_verify(m["E"], m["N"], m["Msg"], m["Signature"]);
});
-#endif
return fails;
}
+#else
+
+SKIP_TEST(rw);
+
+#endif // BOTAN_HAS_RW
diff --git a/src/tests/test_srp6.cpp b/src/tests/test_srp6.cpp
index fcc049c11..dd05d02a5 100644
--- a/src/tests/test_srp6.cpp
+++ b/src/tests/test_srp6.cpp
@@ -1,4 +1,7 @@
#include "tests.h"
+
+#if defined(BOTAN_HAS_SRP6)
+
#include <botan/srp6.h>
#include <iostream>
@@ -37,3 +40,9 @@ size_t test_srp6()
return fails;
}
+
+#else
+
+SKIP_TEST(srp6);
+
+#endif // BOTAN_HAS_SRP6
diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp
index 0e9f67c9f..4828d44fd 100644
--- a/src/tests/test_stream.cpp
+++ b/src/tests/test_stream.cpp
@@ -6,6 +6,8 @@
#include "tests.h"
+#if defined(BOTAN_HAS_STREAM_CIPHER)
+
#include <botan/stream_cipher.h>
#include <botan/lookup.h>
#include <botan/hex.h>
@@ -83,3 +85,9 @@ size_t test_stream()
return run_tests_in_dir(TEST_DATA_DIR "/stream", test);
}
+
+#else
+
+SKIP_TEST(stream);
+
+#endif // BOTAN_HAS_STREAM_CIPHER
diff --git a/src/tests/test_tss.cpp b/src/tests/test_tss.cpp
index 23ea89b19..c5440634b 100644
--- a/src/tests/test_tss.cpp
+++ b/src/tests/test_tss.cpp
@@ -6,11 +6,10 @@
#include "tests.h"
-#include <botan/hex.h>
-#include <iostream>
-
#if defined(BOTAN_HAS_THRESHOLD_SECRET_SHARING)
+#include <iostream>
+#include <botan/hex.h>
#include <botan/tss.h>
size_t test_tss()
@@ -52,10 +51,9 @@ size_t test_tss()
return fails;
}
+
#else
-size_t test_tss()
- {
- std::cout << "Skipping TSS tests" << std::endl;
- return 1;
- }
-#endif
+
+SKIP_TEST(tss);
+
+#endif // BOTAN_HAS_THRESHOLD_SECRET_SHARING
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index 539737437..763417209 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -8,12 +8,19 @@
#include <iostream>
#include <fstream>
#include <botan/auto_rng.h>
-#include <botan/fs.h>
+#include <botan/internal/filesystem.h>
+
+#define CATCH_CONFIG_RUNNER
+#define CATCH_CONFIG_CONSOLE_WIDTH 60
+#define CATCH_CONFIG_COLOUR_NONE
+#include "catchy/catch.hpp"
#if defined(BOTAN_HAS_SYSTEM_RNG)
#include <botan/system_rng.h>
#endif
+using namespace Botan;
+
Botan::RandomNumberGenerator& test_rng()
{
#if defined(BOTAN_HAS_SYSTEM_RNG)
@@ -28,34 +35,50 @@ size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std:
{
size_t fails = 0;
- for(auto vec: Botan::list_all_readable_files_in_or_under(dir))
- fails += fn(vec);
+ try
+ {
+ auto files = get_files_recursive(dir);
+
+ if (files.empty())
+ std::cout << "Warning: No test files found in '" << dir << "'" << std::endl;
+
+ for(const auto file: files)
+ fails += fn(file);
+ }
+ catch(No_Filesystem_Access)
+ {
+ std::cout << "Warning: No filesystem access available to read test files in '" << dir << "'" << std::endl;
+ }
+
return fails;
}
-size_t run_tests(const std::vector<test_fn>& tests)
+size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests)
{
size_t fails = 0;
- for(auto& test : tests)
+ for(const auto& row : tests)
{
+ auto name = row.first;
+ auto test = row.second;
try
{
fails += test();
}
catch(std::exception& e)
{
- std::cout << "Exception escaped test: " << e.what() << std::endl;
+ std::cout << name << ": Exception escaped test: " << e.what() << std::endl;
++fails;
}
catch(...)
{
- std::cout << "Exception escaped test" << std::endl;
+ std::cout << name << ": Exception escaped test" << std::endl;
++fails;
}
}
// Summary for test suite
+ std::cout << "===============" << std::endl;
test_report("Tests", 0, fails);
return fails;
@@ -210,6 +233,17 @@ int help(char* argv0)
return 1;
}
+int test_catchy()
+ {
+ // drop arc and arv for now
+ int catchy_result = Catch::Session().run();
+ if (catchy_result != 0)
+ {
+ std::exit(EXIT_FAILURE);
+ }
+ return 0;
+ }
+
}
int main(int argc, char* argv[])
@@ -225,12 +259,15 @@ int main(int argc, char* argv[])
if(target == "-h" || target == "--help" || target == "help")
return help(argv[0]);
- std::vector<test_fn> tests;
+ std::vector<std::pair<std::string, test_fn>> tests;
#define DEF_TEST(test) do { if(target == "all" || target == #test) \
- tests.push_back(test_ ## test); \
+ tests.push_back(std::make_pair(#test, test_ ## test)); \
} while(0)
+ // unittesting framework in sub-folder tests/catchy
+ DEF_TEST(catchy);
+
DEF_TEST(block);
DEF_TEST(modes);
DEF_TEST(aead);
@@ -267,6 +304,7 @@ int main(int argc, char* argv[])
DEF_TEST(mceliece);
DEF_TEST(ecc_unit);
+ DEF_TEST(ecc_randomized);
DEF_TEST(ecdsa_unit);
DEF_TEST(ecdh_unit);
DEF_TEST(pk_keygen);
@@ -275,6 +313,7 @@ int main(int argc, char* argv[])
DEF_TEST(nist_x509);
DEF_TEST(tls);
DEF_TEST(compression);
+ DEF_TEST(fuzzer);
if(tests.empty())
{
diff --git a/src/tests/tests.h b/src/tests/tests.h
index a086281e7..14ec5a17b 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -1,5 +1,6 @@
/*
* (C) 2014,2015 Jack Lloyd
+* (C) 2015 Simon Warta (Kullo GmbH)
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -7,12 +8,15 @@
#ifndef BOTAN_TESTS_H__
#define BOTAN_TESTS_H__
+#include <botan/build.h>
#include <botan/rng.h>
#include <functional>
#include <istream>
#include <map>
#include <string>
#include <vector>
+#include <iostream>
+#include <sstream>
Botan::RandomNumberGenerator& test_rng();
@@ -39,14 +43,78 @@ size_t run_tests_in_dir(const std::string& dir, std::function<size_t (const std:
// Run a list of tests
typedef std::function<size_t ()> test_fn;
-size_t run_tests(const std::vector<test_fn>& tests);
+size_t run_tests(const std::vector<std::pair<std::string, test_fn>>& tests);
void test_report(const std::string& name, size_t ran, size_t failed);
-#define TEST(expr, msg) do { if(!(expr)) { ++fails; std::cout << msg; } while(0)
-
-#define LIB_SRC_DIR "lib/"
-#define TEST_DATA_DIR "src/tests/data/"
-#define PK_TEST_DATA_DIR "src/tests/data/pubkey"
+class Test_State
+ {
+ public:
+ void started(const std::string& /*msg*/) { m_tests_run++; }
+
+ void test_ran(const char* msg);
+
+ void failure(const char* test, const std::string& what_failed)
+ {
+ std::cout << "FAIL " << test << " " << what_failed << "\n";
+ m_tests_failed++;
+ }
+
+ size_t ran() const { return m_tests_run; }
+ size_t failed() const { return m_tests_failed; }
+ private:
+ size_t m_tests_run = 0, m_tests_failed = 0;
+ };
+
+#define BOTAN_CONFIRM_NOTHROW(block) do { \
+ try { block } \
+ catch(std::exception& e) { \
+ _test.failure(BOTAN_CURRENT_FUNCTION, e.what()); \
+ } } while(0) \
+
+#define BOTAN_TEST(lhs, rhs, msg) do { \
+ _test.started(msg); \
+ BOTAN_CONFIRM_NOTHROW({ \
+ const auto lhs_val = lhs; \
+ const auto rhs_val = rhs; \
+ const bool cmp = lhs_val == rhs_val; \
+ if(!cmp) \
+ { \
+ std::ostringstream fmt; \
+ fmt << "expr '" << #lhs << " == " << #rhs << "' false, " \
+ << "actually " << lhs_val << " " << rhs_val \
+ << " (" << msg << ")"; \
+ _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \
+ } \
+ }); \
+ } while(0)
+
+#define BOTAN_CONFIRM(expr, msg) do { \
+ _test.started(msg); \
+ BOTAN_CONFIRM_NOTHROW({ \
+ const bool expr_val = expr; \
+ if(!expr_val) \
+ { \
+ std::ostringstream fmt; \
+ fmt << "expr '" << #expr << " false (" << msg << ")"; \
+ _test.failure(BOTAN_CURRENT_FUNCTION, fmt.str()); \
+ } \
+ }); \
+ } while(0)
+
+#define BOTAN_TEST_CASE(name, descr, block) size_t test_ ## name() { \
+ Test_State _test; \
+ BOTAN_CONFIRM_NOTHROW(block); \
+ test_report(descr, _test.ran(), _test.failed()); \
+ return _test.failed(); \
+ }
+
+//#define TEST(expr, msg) do { if(!(expr)) { ++fails; std::cout << msg; } while(0)
+
+#define TEST_DATA_DIR "src/tests/data"
+#define TEST_DATA_DIR_PK "src/tests/data/pubkey"
+#define TEST_DATA_DIR_ECC "src/tests/data/ecc"
+
+#define TEST_OUTDATA_DIR "src/tests/outdata"
int test_main(int argc, char* argv[]);
@@ -70,6 +138,7 @@ size_t test_dh();
size_t test_dlies();
size_t test_elgamal();
size_t test_ecc_pointmul();
+size_t test_ecc_random();
size_t test_ecdsa();
size_t test_gost_3410();
size_t test_curve25519();
@@ -89,6 +158,7 @@ size_t test_pk_keygen();
size_t test_bigint();
size_t test_ecc_unit();
+size_t test_ecc_randomized();
size_t test_ecdsa_unit();
size_t test_ecdh_unit();
@@ -102,4 +172,33 @@ size_t test_nist_x509();
size_t test_srp6();
size_t test_compression();
+size_t test_fuzzer();
+
+#define SKIP_TEST(testname) \
+ size_t test_ ## testname() { \
+ std::cout << "Skipping tests: " << # testname << std::endl; \
+ return 0; \
+ } \
+
+/*
+ * Warn if a test requires loading more modules than necessary to build
+ * the lib. E.g.
+ * $ ./configure.py --no-autoload --enable-modules='ocb'
+ * $ make
+ * $ ./botan-test ocb
+ * warns the user whereas
+ * $ ./configure.py --no-autoload --enable-modules='ocb,aes'
+ * $ make
+ * $ ./botan-test ocb
+ * runs the test.
+ */
+#define UNTESTED_WARNING(testname) \
+ size_t test_ ## testname() { \
+ std::cout << "Skipping tests: " << # testname << std::endl; \
+ std::cout << "WARNING: " << # testname << " has been compiled " \
+ << "but is not tested due to other missing modules." \
+ << std::endl; \
+ return 0; \
+ } \
+
#endif
diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp
index 4c35caa48..bd813b37e 100644
--- a/src/tests/unit_ecc.cpp
+++ b/src/tests/unit_ecc.cpp
@@ -6,13 +6,12 @@
#include "tests.h"
-#include <botan/hex.h>
-#include <iostream>
-#include <memory>
-
#if defined(BOTAN_HAS_ECC_GROUP)
+#include <iostream>
+#include <memory>
#include <botan/bigint.h>
+#include <botan/hex.h>
#include <botan/numthry.h>
#include <botan/curve_gfp.h>
#include <botan/point_gfp.h>
@@ -817,9 +816,9 @@ size_t test_curve_cp_ctor()
return 0;
}
-size_t ecc_randomized_test()
- {
- const std::vector<std::string> groups = {
+namespace {
+
+const std::vector<std::string> ec_groups = {
"brainpool160r1",
"brainpool192r1",
"brainpool224r1",
@@ -850,11 +849,16 @@ size_t ecc_randomized_test()
"x962_p239v3"
};
+}
+
+}
+
+BOTAN_TEST_CASE(ecc_randomized, "ECC Randomized", {
auto& rng = test_rng();
size_t fails = 0;
size_t tests = 0;
- for(auto&& group_name : groups)
+ for(auto&& group_name : ec_groups)
{
EC_Group group(group_name);
@@ -862,8 +866,8 @@ size_t ecc_randomized_test()
const BigInt& group_order = group.get_order();
const PointGFp inf = base_point * group_order;
- CHECK(inf.is_zero());
- CHECK(inf.on_the_curve());
+ BOTAN_CONFIRM(inf.is_zero(), "Group math ok");
+ BOTAN_CONFIRM(inf.on_the_curve(), "Infinity still on the curve");
try
{
@@ -871,6 +875,9 @@ size_t ecc_randomized_test()
{
++tests;
+ const size_t h = 1 + (rng.next_byte() % 8);
+ Blinded_Point_Multiply blind(base_point, group_order, h);
+
const BigInt a = BigInt::random_integer(rng, 2, group_order);
const BigInt b = BigInt::random_integer(rng, 2, group_order);
const BigInt c = a + b;
@@ -879,16 +886,24 @@ size_t ecc_randomized_test()
const PointGFp Q = base_point * b;
const PointGFp R = base_point * c;
+ const PointGFp P1 = blind.blinded_multiply(a, rng);
+ const PointGFp Q1 = blind.blinded_multiply(b, rng);
+ const PointGFp R1 = blind.blinded_multiply(c, rng);
+
const PointGFp A1 = P + Q;
const PointGFp A2 = Q + P;
- CHECK(A1 == R);
- CHECK(A2 == R);
- CHECK(P.on_the_curve());
- CHECK(Q.on_the_curve());
- CHECK(R.on_the_curve());
- CHECK(A1.on_the_curve());
- CHECK(A2.on_the_curve());
+ BOTAN_TEST(A1, R, "Addition");
+ BOTAN_TEST(A2, R, "Addition");
+ BOTAN_CONFIRM(P.on_the_curve(), "On the curve");
+ BOTAN_CONFIRM(Q.on_the_curve(), "On the curve");
+ BOTAN_CONFIRM(R.on_the_curve(), "On the curve");
+ BOTAN_CONFIRM(A1.on_the_curve(), "On the curve");
+ BOTAN_CONFIRM(A2.on_the_curve(), "On the curve");
+
+ BOTAN_TEST(P, P1, "P1");
+ BOTAN_TEST(Q, Q1, "Q1");
+ BOTAN_TEST(R, R1, "R1");
}
}
catch(std::exception& e)
@@ -897,19 +912,13 @@ size_t ecc_randomized_test()
++fails;
}
}
+ });
- test_report("ECC Randomized", tests, fails);
- return fails;
- }
-#endif
-
-}
size_t test_ecc_unit()
{
size_t fails = 0;
-#if defined(BOTAN_HAS_ECC_GROUP)
fails += test_point_turn_on_sp_red_mul();
fails += test_coordinates();
fails += test_point_transformation ();
@@ -937,8 +946,12 @@ size_t test_ecc_unit()
test_report("ECC", 0, fails);
- ecc_randomized_test();
-#endif
-
return fails;
}
+
+#else
+
+SKIP_TEST(ecc_unit);
+SKIP_TEST(ecc_randomized);
+
+#endif // BOTAN_HAS_ECC_GROUP
diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp
index 432fc22bd..22625d230 100644
--- a/src/tests/unit_ecdsa.cpp
+++ b/src/tests/unit_ecdsa.cpp
@@ -11,15 +11,19 @@
#include "tests.h"
#if defined(BOTAN_HAS_ECDSA)
-#include <botan/hex.h>
+#if defined(BOTAN_HAS_RSA)
+
+#include <botan/hex.h>
+#include <botan/pkcs8.h>
#include <botan/pubkey.h>
#include <botan/ecdsa.h>
#include <botan/rsa.h>
+#include <botan/oids.h>
+
#if defined(BOTAN_HAS_X509_CERTIFICATES)
#include <botan/x509cert.h>
#endif
-#include <botan/oids.h>
#include <iostream>
#include <fstream>
@@ -27,8 +31,6 @@
using namespace Botan;
-#define ECC_TEST_DATA_DIR TEST_DATA_DIR "/ecc"
-
#define CHECK_MESSAGE(expr, print) try { if(!(expr)) { ++fails; std::cout << print << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
#define CHECK(expr) try { if(!(expr)) { ++fails; std::cout << #expr << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
@@ -97,7 +99,7 @@ size_t test_hash_larger_than_n(RandomNumberGenerator& rng)
#if defined(BOTAN_HAS_X509_CERTIFICATES)
size_t test_decode_ecdsa_X509()
{
- X509_Certificate cert(ECC_TEST_DATA_DIR "/CSCA.CSCA.csca-germany.1.crt");
+ X509_Certificate cert(TEST_DATA_DIR_ECC "/CSCA.CSCA.csca-germany.1.crt");
size_t fails = 0;
CHECK_MESSAGE(OIDS::lookup(cert.signature_algorithm().oid) == "ECDSA/EMSA1(SHA-224)", "error reading signature algorithm from x509 ecdsa certificate");
@@ -115,8 +117,8 @@ size_t test_decode_ecdsa_X509()
size_t test_decode_ver_link_SHA256()
{
- X509_Certificate root_cert(ECC_TEST_DATA_DIR "/root2_SHA256.cer");
- X509_Certificate link_cert(ECC_TEST_DATA_DIR "/link_SHA256.cer");
+ X509_Certificate root_cert(TEST_DATA_DIR_ECC "/root2_SHA256.cer");
+ X509_Certificate link_cert(TEST_DATA_DIR_ECC "/link_SHA256.cer");
size_t fails = 0;
std::unique_ptr<X509_PublicKey> pubkey(root_cert.subject_public_key());
@@ -127,8 +129,8 @@ size_t test_decode_ver_link_SHA256()
size_t test_decode_ver_link_SHA1()
{
- X509_Certificate root_cert(ECC_TEST_DATA_DIR "/root_SHA1.163.crt");
- X509_Certificate link_cert(ECC_TEST_DATA_DIR "/link_SHA1.166.crt");
+ X509_Certificate root_cert(TEST_DATA_DIR_ECC "/root_SHA1.163.crt");
+ X509_Certificate link_cert(TEST_DATA_DIR_ECC "/link_SHA1.166.crt");
size_t fails = 0;
std::unique_ptr<X509_PublicKey> pubkey(root_cert.subject_public_key());
@@ -239,14 +241,14 @@ size_t test_create_pkcs8(RandomNumberGenerator& rng)
//cout << "\nequal: " << (rsa_key == rsa_key2) << std::endl;
//DSA_PrivateKey key(DL_Group("dsa/jce/1024"));
- std::ofstream rsa_priv_key(ECC_TEST_DATA_DIR "/rsa_private.pkcs8.pem");
+ std::ofstream rsa_priv_key(TEST_OUTDATA_DIR "/rsa_private.pkcs8.pem");
rsa_priv_key << PKCS8::PEM_encode(rsa_key);
EC_Group dom_pars(OID("1.3.132.0.8"));
ECDSA_PrivateKey key(rng, dom_pars);
// later used by other tests :(
- std::ofstream priv_key(ECC_TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem");
+ std::ofstream priv_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem");
priv_key << PKCS8::PEM_encode(key);
}
catch (std::exception& e)
@@ -264,14 +266,14 @@ size_t test_create_and_verify(RandomNumberGenerator& rng)
EC_Group dom_pars(OID("1.3.132.0.8"));
ECDSA_PrivateKey key(rng, dom_pars);
- std::ofstream priv_key(ECC_TEST_DATA_DIR "/dompar_private.pkcs8.pem");
+ std::ofstream priv_key(TEST_OUTDATA_DIR "/dompar_private.pkcs8.pem");
priv_key << PKCS8::PEM_encode(key);
- std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(ECC_TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
+ std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
ECDSA_PrivateKey* loaded_ec_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
CHECK_MESSAGE(loaded_ec_key, "the loaded key could not be converted into an ECDSA_PrivateKey");
- std::unique_ptr<PKCS8_PrivateKey> loaded_key_1(PKCS8::load_key(ECC_TEST_DATA_DIR "/rsa_private.pkcs8.pem", rng));
+ std::unique_ptr<PKCS8_PrivateKey> loaded_key_1(PKCS8::load_key(TEST_OUTDATA_DIR "/rsa_private.pkcs8.pem", rng));
ECDSA_PrivateKey* loaded_rsa_key = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_1.get());
CHECK_MESSAGE(!loaded_rsa_key, "the loaded key is ECDSA_PrivateKey -> shouldn't be, is a RSA-Key");
@@ -387,7 +389,7 @@ size_t test_read_pkcs8(RandomNumberGenerator& rng)
try
{
- std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(ECC_TEST_DATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
+ std::unique_ptr<PKCS8_PrivateKey> loaded_key(PKCS8::load_key(TEST_OUTDATA_DIR "/wo_dompar_private.pkcs8.pem", rng));
ECDSA_PrivateKey* ecdsa = dynamic_cast<ECDSA_PrivateKey*>(loaded_key.get());
CHECK_MESSAGE(ecdsa, "the loaded key could not be converted into an ECDSA_PrivateKey");
@@ -408,7 +410,7 @@ size_t test_read_pkcs8(RandomNumberGenerator& rng)
try
{
- std::unique_ptr<PKCS8_PrivateKey> loaded_key_nodp(PKCS8::load_key(ECC_TEST_DATA_DIR "/nodompar_private.pkcs8.pem", rng));
+ std::unique_ptr<PKCS8_PrivateKey> loaded_key_nodp(PKCS8::load_key(TEST_DATA_DIR_ECC "/nodompar_private.pkcs8.pem", rng));
// anew in each test with unregistered domain-parameters
ECDSA_PrivateKey* ecdsa_nodp = dynamic_cast<ECDSA_PrivateKey*>(loaded_key_nodp.get());
CHECK_MESSAGE(ecdsa_nodp, "the loaded key could not be converted into an ECDSA_PrivateKey");
@@ -424,7 +426,7 @@ size_t test_read_pkcs8(RandomNumberGenerator& rng)
try
{
std::unique_ptr<PKCS8_PrivateKey> loaded_key_withdp(
- PKCS8::load_key(ECC_TEST_DATA_DIR "/withdompar_private.pkcs8.pem", rng));
+ PKCS8::load_key(TEST_DATA_DIR_ECC "/withdompar_private.pkcs8.pem", rng));
std::cout << "Unexpected success: loaded key with unknown OID" << std::endl;
++fails;
@@ -447,7 +449,7 @@ size_t test_ecc_key_with_rfc5915_extensions(RandomNumberGenerator& rng)
try
{
std::unique_ptr<PKCS8_PrivateKey> pkcs8(
- PKCS8::load_key(ECC_TEST_DATA_DIR "/ecc_private_with_rfc5915_ext.pem", rng));
+ PKCS8::load_key(TEST_DATA_DIR_ECC "/ecc_private_with_rfc5915_ext.pem", rng));
if(!dynamic_cast<ECDSA_PrivateKey*>(pkcs8.get()))
{
@@ -493,6 +495,12 @@ size_t test_ecdsa_unit()
#else
-size_t test_ecdsa_unit() { return 0; }
+UNTESTED_WARNING(ecdsa_unit);
-#endif
+#endif // BOTAN_HAS_RSA
+
+#else
+
+SKIP_TEST(ecdsa_unit);
+
+#endif // BOTAN_HAS_ECDSA
diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp
index 8eb2d1a96..116eb2cdf 100644
--- a/src/tests/unit_tls.cpp
+++ b/src/tests/unit_tls.cpp
@@ -15,6 +15,7 @@
#include <botan/x509self.h>
#include <botan/rsa.h>
#include <botan/x509_ca.h>
+#include <botan/auto_rng.h>
#include <botan/hex.h>
#include <iostream>
@@ -96,14 +97,25 @@ class Credentials_Manager_Test : public Botan::Credentials_Manager
{
return m_key.get();
}
+
+ SymmetricKey psk(const std::string& type,
+ const std::string& context,
+ const std::string&) override
+ {
+ if(type == "tls-server" && context == "session-ticket")
+ return SymmetricKey("AABBCCDDEEFF012345678012345678");
+ throw Exception("No PSK set for " + context);
+ }
+
public:
X509_Certificate m_server_cert, m_ca_cert;
std::unique_ptr<Private_Key> m_key;
std::vector<std::unique_ptr<Certificate_Store>> m_stores;
};
-Credentials_Manager* create_creds(RandomNumberGenerator& rng)
+Credentials_Manager* create_creds()
{
+ AutoSeeded_RNG rng;
std::unique_ptr<Private_Key> ca_key(new RSA_PrivateKey(rng, 1024));
X509_Cert_Options ca_opts;
@@ -120,7 +132,7 @@ Credentials_Manager* create_creds(RandomNumberGenerator& rng)
Private_Key* server_key = new RSA_PrivateKey(rng, 1024);
X509_Cert_Options server_opts;
- server_opts.common_name = "localhost";
+ server_opts.common_name = "server.example.com";
server_opts.country = "US";
PKCS10_Request req = X509::create_cert_req(server_opts,
@@ -207,12 +219,15 @@ size_t basic_test_handshake(RandomNumberGenerator& rng,
creds,
policy,
rng,
- TLS::Server_Information(),
+ TLS::Server_Information("server.example.com"),
offer_version,
protocols_offered);
while(true)
{
+ if(client.is_closed() && server.is_closed())
+ break;
+
if(client.is_active())
client.send("1");
if(server.is_active())
@@ -272,7 +287,16 @@ size_t basic_test_handshake(RandomNumberGenerator& rng,
}
if(s2c_data.size() && c2s_data.size())
- break;
+ {
+ SymmetricKey client_key = client.key_material_export("label", "context", 32);
+ SymmetricKey server_key = server.key_material_export("label", "context", 32);
+
+ if(client_key != server_key)
+ return 1;
+
+ server.close();
+ client.close();
+ }
}
return 0;
@@ -293,7 +317,7 @@ size_t test_tls()
Test_Policy default_policy;
auto& rng = test_rng();
- std::unique_ptr<Credentials_Manager> basic_creds(create_creds(rng));
+ std::unique_ptr<Credentials_Manager> basic_creds(create_creds());
errors += basic_test_handshake(rng, TLS::Protocol_Version::TLS_V10, *basic_creds, default_policy);
errors += basic_test_handshake(rng, TLS::Protocol_Version::TLS_V11, *basic_creds, default_policy);
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index 2388dc920..f77be1992 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -6,8 +6,17 @@
#include "tests.h"
-#include <botan/filters.h>
+#if defined(BOTAN_HAS_X509_CERTIFICATES)
+#if defined(BOTAN_HAS_RSA) && defined(BOTAN_HAS_DSA)
+
+#include <botan/calendar.h>
+#include <botan/filters.h>
+#include <botan/pkcs8.h>
+#include <botan/pkcs10.h>
+#include <botan/x509self.h>
+#include <botan/x509path.h>
+#include <botan/x509_ca.h>
#if defined(BOTAN_HAS_RSA)
#include <botan/rsa.h>
@@ -21,25 +30,19 @@
#include <botan/ecdsa.h>
#endif
-#if defined(BOTAN_HAS_X509_CERTIFICATES)
- #include <botan/x509self.h>
- #include <botan/x509path.h>
- #include <botan/x509_ca.h>
- #include <botan/pkcs10.h>
-#endif
-
-using namespace Botan;
-
#include <iostream>
#include <memory>
-
-#if defined(BOTAN_HAS_X509_CERTIFICATES) && \
- defined(BOTAN_HAS_RSA) && \
- defined(BOTAN_HAS_DSA)
+using namespace Botan;
namespace {
+X509_Time from_date(const int y, const int m, const int d)
+ {
+ auto t = calendar_point(y, m, d, 0, 0, 0);
+ return X509_Time(t.to_std_timepoint());
+ }
+
u64bit key_id(const Public_Key* key)
{
Pipe pipe(new Hash_Filter("SHA-1", 8));
@@ -170,11 +173,11 @@ size_t test_x509()
/* Sign the requests to create the certs */
X509_Certificate user1_cert =
ca.sign_request(user1_req, rng,
- X509_Time("2008-01-01"), X509_Time("2100-01-01"));
+ from_date(2008, 01, 01), from_date(2033, 01, 01));
X509_Certificate user2_cert = ca.sign_request(user2_req, rng,
- X509_Time("2008-01-01"),
- X509_Time("2100-01-01"));
+ from_date(2008, 01, 01),
+ from_date(2033, 01, 01));
X509_CRL crl1 = ca.new_crl(rng);
/* Verify the certs */
@@ -251,7 +254,12 @@ size_t test_x509()
#else
-size_t test_x509() { return 0; }
+UNTESTED_WARNING(x509);
-#endif
+#endif // BOTAN_HAS_RSA && BOTAN_HAS_DSA
+
+#else
+
+SKIP_TEST(x509);
+#endif // BOTAN_HAS_X509_CERTIFICATES