Z-Botan 0.1.1.2 → 0.2.0.0
raw patch · 82 files changed
+22001/−525 lines, 82 filesdep ~Z-IOPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: Z-IO
API changes (from Hackage documentation)
- Z.Crypto.KDF: AES128 :: BlockCipherType
- Z.Crypto.KDF: AES192 :: BlockCipherType
- Z.Crypto.KDF: AES256 :: BlockCipherType
- Z.Crypto.KDF: ARIA128 :: BlockCipherType
- Z.Crypto.KDF: ARIA192 :: BlockCipherType
- Z.Crypto.KDF: ARIA256 :: BlockCipherType
- Z.Crypto.KDF: Blowfish :: BlockCipherType
- Z.Crypto.KDF: CAST128 :: BlockCipherType
- Z.Crypto.KDF: CAST256 :: BlockCipherType
- Z.Crypto.KDF: Camellia128 :: BlockCipherType
- Z.Crypto.KDF: Camellia192 :: BlockCipherType
- Z.Crypto.KDF: Camellia256 :: BlockCipherType
- Z.Crypto.KDF: Cascade :: BlockCipherType -> BlockCipherType -> BlockCipherType
- Z.Crypto.KDF: DES :: BlockCipherType
- Z.Crypto.KDF: DESX :: BlockCipherType
- Z.Crypto.KDF: IDEA :: BlockCipherType
- Z.Crypto.KDF: KASUMI :: BlockCipherType
- Z.Crypto.KDF: Lion :: HashType -> StreamCipherType -> Int -> BlockCipherType
- Z.Crypto.KDF: MISTY1 :: BlockCipherType
- Z.Crypto.KDF: Noekeon :: BlockCipherType
- Z.Crypto.KDF: OMAC :: BlockCipherType -> MACType
- Z.Crypto.KDF: SEED :: BlockCipherType
- Z.Crypto.KDF: SHACAL2 :: BlockCipherType
- Z.Crypto.KDF: SM4 :: BlockCipherType
- Z.Crypto.KDF: Serpent :: BlockCipherType
- Z.Crypto.KDF: Threefish512 :: BlockCipherType
- Z.Crypto.KDF: TripleDES :: BlockCipherType
- Z.Crypto.KDF: Twofish :: BlockCipherType
- Z.Crypto.KDF: XTEA :: BlockCipherType
- Z.Crypto.KDF: data BlockCipherType
- Z.Crypto.MAC: OMAC :: BlockCipherType -> MACType
- Z.Crypto.PubKey: DL :: DLType -> DLGroup -> KeyType
- Z.Crypto.PubKey: ECC :: ECCType -> ECGroup -> KeyType
- Z.Crypto.PubKey: GOST_34_10 :: ECCType
- Z.Crypto.PubKey: GOST_34_10_2012_256 :: ECCType
- Z.Crypto.PubKey: GOST_34_10_2012_512 :: ECCType
- Z.Crypto.PubKey: McEliece :: Word32 -> Word32 -> KeyType
- Z.Crypto.PubKey: SM2_Enc :: ECCType
- Z.Crypto.PubKey: SM2_Sig :: ECCType
- Z.Crypto.PubKey: data DLType
- Z.Crypto.PubKey: data ECCType
- Z.Crypto.PubKey: pattern McElieceDefault :: KeyType
- Z.Crypto.PubKey: pattern RSADefault :: KeyType
- Z.Crypto.PubKey: pattern XMSSDefault :: KeyType
+ Z.Botan.FFI: botan_x509_certstore_load_system :: MBA# BotanStructT -> IO CInt
+ Z.Crypto.PubKey: GOST_34'10 :: ECGroup -> KeyType
+ Z.Crypto.PubKey: sm2Decrypt :: HasCallStack => PrivKey -> HashType -> Bytes -> Bytes
+ Z.Crypto.PubKey: sm2Encrypt :: HasCallStack => PubKey -> HashType -> RNG -> Bytes -> IO Bytes
+ Z.Crypto.X509: mozillaCertStore :: CertStore
+ Z.Crypto.X509: systemCertStore :: CertStore
- Z.Crypto.FPE: decryptFPE :: FPE -> MPI -> Bytes -> IO MPI
+ Z.Crypto.FPE: decryptFPE :: HasCallStack => FPE -> MPI -> Bytes -> IO MPI
- Z.Crypto.FPE: encryptFPE :: FPE -> MPI -> Bytes -> IO MPI
+ Z.Crypto.FPE: encryptFPE :: HasCallStack => FPE -> MPI -> Bytes -> IO MPI
- Z.Crypto.FPE: newFPE :: MPI -> Bytes -> IO FPE
+ Z.Crypto.FPE: newFPE :: HasCallStack => MPI -> Bytes -> IO FPE
- Z.Crypto.Hash: updateHash :: Hash -> Bytes -> IO ()
+ Z.Crypto.Hash: updateHash :: HasCallStack => Hash -> Bytes -> IO ()
- Z.Crypto.KDF: kdf :: KDFType -> Int -> Bytes -> Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: kdf :: HasCallStack => KDFType -> Int -> Bytes -> Bytes -> Bytes -> IO Bytes
- Z.Crypto.KDF: kdf' :: KDFType -> Int -> Bytes -> IO Bytes
+ Z.Crypto.KDF: kdf' :: HasCallStack => KDFType -> Int -> Bytes -> IO Bytes
- Z.Crypto.KDF: pbkdf :: PBKDFType -> Int -> CBytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: pbkdf :: HasCallStack => PBKDFType -> Int -> CBytes -> Bytes -> IO Bytes
- Z.Crypto.KDF: pbkdfTimed :: PBKDFType -> Int -> Int -> CBytes -> Bytes -> IO Bytes
+ Z.Crypto.KDF: pbkdfTimed :: HasCallStack => PBKDFType -> Int -> Int -> CBytes -> Bytes -> IO Bytes
- Z.Crypto.KeyWrap: keyUnwrap :: Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KeyWrap: keyUnwrap :: HasCallStack => Bytes -> Bytes -> IO Bytes
- Z.Crypto.KeyWrap: keyWrap :: Bytes -> Bytes -> IO Bytes
+ Z.Crypto.KeyWrap: keyWrap :: HasCallStack => Bytes -> Bytes -> IO Bytes
- Z.Crypto.MAC: newMAC :: MACType -> IO MAC
+ Z.Crypto.MAC: newMAC :: HasCallStack => MACType -> IO MAC
- Z.Crypto.MPI: isPrim :: RNG -> MPI -> Int -> IO Bool
+ Z.Crypto.MPI: isPrim :: HasCallStack => RNG -> MPI -> Int -> IO Bool
- Z.Crypto.MPI: randBits :: RNG -> Int -> IO MPI
+ Z.Crypto.MPI: randBits :: HasCallStack => RNG -> Int -> IO MPI
- Z.Crypto.MPI: randRange :: RNG -> MPI -> MPI -> IO MPI
+ Z.Crypto.MPI: randRange :: HasCallStack => RNG -> MPI -> MPI -> IO MPI
- Z.Crypto.MPI: toWord32 :: HasCallStack => MPI -> Word32
+ Z.Crypto.MPI: toWord32 :: MPI -> Word32
- Z.Crypto.OTP: checkHOTP :: HOTP -> Word32 -> Word64 -> Int -> IO (Bool, Word64)
+ Z.Crypto.OTP: checkHOTP :: HasCallStack => HOTP -> Word32 -> Word64 -> Int -> IO (Bool, Word64)
- Z.Crypto.OTP: checkTOTP :: TOTP -> Word32 -> Word64 -> Int -> IO Bool
+ Z.Crypto.OTP: checkTOTP :: HasCallStack => TOTP -> Word32 -> Word64 -> Int -> IO Bool
- Z.Crypto.OTP: genHOTP :: HOTP -> Word64 -> IO Word32
+ Z.Crypto.OTP: genHOTP :: HasCallStack => HOTP -> Word64 -> IO Word32
- Z.Crypto.OTP: genTOTP :: TOTP -> Word64 -> IO Word32
+ Z.Crypto.OTP: genTOTP :: HasCallStack => TOTP -> Word64 -> IO Word32
- Z.Crypto.OTP: newHOTP :: Bytes -> OTPAlgo -> OTPDigitLen -> IO HOTP
+ Z.Crypto.OTP: newHOTP :: HasCallStack => Bytes -> OTPAlgo -> OTPDigitLen -> IO HOTP
- Z.Crypto.OTP: newTOTP :: Bytes -> OTPAlgo -> OTPDigitLen -> Int -> IO TOTP
+ Z.Crypto.OTP: newTOTP :: HasCallStack => Bytes -> OTPAlgo -> OTPDigitLen -> Int -> IO TOTP
- Z.Crypto.PubKey: DH :: DLType
+ Z.Crypto.PubKey: DH :: DLGroup -> KeyType
- Z.Crypto.PubKey: DSA :: DLType
+ Z.Crypto.PubKey: DSA :: DLGroup -> KeyType
- Z.Crypto.PubKey: ECDH :: ECCType
+ Z.Crypto.PubKey: ECDH :: ECGroup -> KeyType
- Z.Crypto.PubKey: ECDSA :: ECCType
+ Z.Crypto.PubKey: ECDSA :: ECGroup -> KeyType
- Z.Crypto.PubKey: ECGDSA :: ECCType
+ Z.Crypto.PubKey: ECGDSA :: ECGroup -> KeyType
- Z.Crypto.PubKey: ECKCDSA :: ECCType
+ Z.Crypto.PubKey: ECKCDSA :: ECGroup -> KeyType
- Z.Crypto.PubKey: ElGamal :: DLType
+ Z.Crypto.PubKey: ElGamal :: DLGroup -> KeyType
- Z.Crypto.PubKey: SM2 :: ECCType
+ Z.Crypto.PubKey: SM2 :: ECGroup -> KeyType
- Z.Crypto.PubKey: exportKeyAgreementPublic :: PrivKey -> IO Bytes
+ Z.Crypto.PubKey: exportKeyAgreementPublic :: HasCallStack => PrivKey -> IO Bytes
- Z.Crypto.PubKey: exportPrivKeyEncryptedDER :: PrivKey -> RNG -> CBytes -> IO Bytes
+ Z.Crypto.PubKey: exportPrivKeyEncryptedDER :: HasCallStack => PrivKey -> RNG -> CBytes -> IO Bytes
- Z.Crypto.PubKey: exportPrivKeyEncryptedPEM :: PrivKey -> RNG -> CBytes -> IO Text
+ Z.Crypto.PubKey: exportPrivKeyEncryptedPEM :: HasCallStack => PrivKey -> RNG -> CBytes -> IO Text
- Z.Crypto.PubKey: finalSigner :: Signer -> RNG -> IO Bytes
+ Z.Crypto.PubKey: finalSigner :: HasCallStack => Signer -> RNG -> IO Bytes
- Z.Crypto.PubKey: finalVerifier :: Verifier -> Bytes -> IO Bool
+ Z.Crypto.PubKey: finalVerifier :: HasCallStack => Verifier -> Bytes -> IO Bool
- Z.Crypto.PubKey: keyAgree :: KeyAgreement -> Bytes -> Bytes -> IO Bytes
+ Z.Crypto.PubKey: keyAgree :: HasCallStack => KeyAgreement -> Bytes -> Bytes -> IO Bytes
- Z.Crypto.PubKey: loadPrivKey :: RNG -> Bytes -> CBytes -> IO PrivKey
+ Z.Crypto.PubKey: loadPrivKey :: HasCallStack => RNG -> Bytes -> CBytes -> IO PrivKey
- Z.Crypto.PubKey: newDHPrivKey :: MPI -> MPI -> MPI -> PrivKey
+ Z.Crypto.PubKey: newDHPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey
- Z.Crypto.PubKey: newDHPubKey :: MPI -> MPI -> MPI -> PubKey
+ Z.Crypto.PubKey: newDHPubKey :: HasCallStack => MPI -> MPI -> MPI -> PubKey
- Z.Crypto.PubKey: newDSAPrivKey :: MPI -> MPI -> MPI -> MPI -> PrivKey
+ Z.Crypto.PubKey: newDSAPrivKey :: HasCallStack => MPI -> MPI -> MPI -> MPI -> PrivKey
- Z.Crypto.PubKey: newDSAPubKey :: MPI -> MPI -> MPI -> MPI -> PubKey
+ Z.Crypto.PubKey: newDSAPubKey :: HasCallStack => MPI -> MPI -> MPI -> MPI -> PubKey
- Z.Crypto.PubKey: newElGamalPrivKey :: MPI -> MPI -> MPI -> PrivKey
+ Z.Crypto.PubKey: newElGamalPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey
- Z.Crypto.PubKey: newElGamalPubKey :: MPI -> MPI -> MPI -> PubKey
+ Z.Crypto.PubKey: newElGamalPubKey :: HasCallStack => MPI -> MPI -> MPI -> PubKey
- Z.Crypto.PubKey: newKeyAgreement :: PrivKey -> KDFType -> IO KeyAgreement
+ Z.Crypto.PubKey: newKeyAgreement :: HasCallStack => PrivKey -> KDFType -> IO KeyAgreement
- Z.Crypto.PubKey: newKeyPair :: KeyType -> RNG -> IO (PrivKey, PubKey)
+ Z.Crypto.PubKey: newKeyPair :: HasCallStack => KeyType -> RNG -> IO (PrivKey, PubKey)
- Z.Crypto.PubKey: newPrivKey :: KeyType -> RNG -> IO PrivKey
+ Z.Crypto.PubKey: newPrivKey :: HasCallStack => KeyType -> RNG -> IO PrivKey
- Z.Crypto.PubKey: newRSAPrivKey :: MPI -> MPI -> MPI -> PrivKey
+ Z.Crypto.PubKey: newRSAPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey
- Z.Crypto.PubKey: newRSAPubKey :: MPI -> MPI -> PubKey
+ Z.Crypto.PubKey: newRSAPubKey :: HasCallStack => MPI -> MPI -> PubKey
- Z.Crypto.PubKey: newSigner :: PrivKey -> EMSA -> SignFmt -> IO Signer
+ Z.Crypto.PubKey: newSigner :: HasCallStack => PrivKey -> EMSA -> SignFmt -> IO Signer
- Z.Crypto.PubKey: newVerifier :: PubKey -> EMSA -> SignFmt -> IO Verifier
+ Z.Crypto.PubKey: newVerifier :: HasCallStack => PubKey -> EMSA -> SignFmt -> IO Verifier
- Z.Crypto.PubKey: pkDecrypt :: PrivKey -> EMEPadding -> Bytes -> Bytes
+ Z.Crypto.PubKey: pkDecrypt :: HasCallStack => PrivKey -> EMEPadding -> Bytes -> Bytes
- Z.Crypto.PubKey: pkEncrypt :: PubKey -> EMEPadding -> RNG -> Bytes -> IO Bytes
+ Z.Crypto.PubKey: pkEncrypt :: HasCallStack => PubKey -> EMEPadding -> RNG -> Bytes -> IO Bytes
- Z.Crypto.PubKey: privKeyAlgoName :: PrivKey -> IO Bytes
+ Z.Crypto.PubKey: privKeyAlgoName :: PrivKey -> IO Text
- Z.Crypto.PubKey: pubKeyParam :: HasCallStack => PubKey -> CBytes -> MPI
+ Z.Crypto.PubKey: pubKeyParam :: PubKey -> CBytes -> MPI
- Z.Crypto.PubKey: sinkToSigner :: HasCallStack => Signer -> Sink Bytes
+ Z.Crypto.PubKey: sinkToSigner :: HasCallStack => HasCallStack => Signer -> Sink Bytes
- Z.Crypto.PubKey: updateSigner :: Signer -> Bytes -> IO ()
+ Z.Crypto.PubKey: updateSigner :: HasCallStack => Signer -> Bytes -> IO ()
- Z.Crypto.PubKey: updateVerifier :: Verifier -> Bytes -> IO ()
+ Z.Crypto.PubKey: updateVerifier :: HasCallStack => Verifier -> Bytes -> IO ()
- Z.Crypto.PubKey: withPubKey :: HasCallStack => PubKey -> (BotanStructT -> IO r) -> IO r
+ Z.Crypto.PubKey: withPubKey :: PubKey -> (BotanStructT -> IO r) -> IO r
- Z.Crypto.PwdHash: genBcrypt :: Bytes -> RNG -> Int -> IO Bytes
+ Z.Crypto.PwdHash: genBcrypt :: HasCallStack => Bytes -> RNG -> Int -> IO Bytes
- Z.Crypto.PwdHash: validBcrypt :: Bytes -> Bytes -> IO Bool
+ Z.Crypto.PwdHash: validBcrypt :: HasCallStack => Bytes -> Bytes -> IO Bool
- Z.Crypto.RNG: addEntropyRNG :: RNG -> Bytes -> IO ()
+ Z.Crypto.RNG: addEntropyRNG :: HasCallStack => RNG -> Bytes -> IO ()
- Z.Crypto.RNG: getRNG :: IO RNG
+ Z.Crypto.RNG: getRNG :: HasCallStack => IO RNG
- Z.Crypto.RNG: getRandom :: RNG -> Int -> IO Bytes
+ Z.Crypto.RNG: getRandom :: HasCallStack => RNG -> Int -> IO Bytes
- Z.Crypto.RNG: newRNG :: RNGType -> IO RNG
+ Z.Crypto.RNG: newRNG :: HasCallStack => RNGType -> IO RNG
- Z.Crypto.RNG: reseedRNG :: RNG -> Int -> IO ()
+ Z.Crypto.RNG: reseedRNG :: HasCallStack => RNG -> Int -> IO ()
- Z.Crypto.RNG: reseedRNGFromRNG :: RNG -> RNG -> Int -> IO ()
+ Z.Crypto.RNG: reseedRNGFromRNG :: HasCallStack => RNG -> RNG -> Int -> IO ()
- Z.Crypto.RNG: withRNG :: RNG -> (BotanStructT -> IO a) -> IO a
+ Z.Crypto.RNG: withRNG :: HasCallStack => RNG -> (BotanStructT -> IO a) -> IO a
- Z.Crypto.X509: certDNIssuer :: Cert -> CBytes -> Int -> IO Text
+ Z.Crypto.X509: certDNIssuer :: HasCallStack => Cert -> CBytes -> Int -> IO Text
- Z.Crypto.X509: certDNSubject :: Cert -> CBytes -> Int -> IO Text
+ Z.Crypto.X509: certDNSubject :: HasCallStack => Cert -> CBytes -> Int -> IO Text
- Z.Crypto.X509: certToText :: Cert -> IO Text
+ Z.Crypto.X509: certToText :: HasCallStack => Cert -> IO Text
- Z.Crypto.X509: certUsage :: Cert -> KeyUsageConstraint -> IO ()
+ Z.Crypto.X509: certUsage :: HasCallStack => Cert -> KeyUsageConstraint -> IO ()
- Z.Crypto.X509: loadCRL :: Bytes -> IO CRL
+ Z.Crypto.X509: loadCRL :: HasCallStack => Bytes -> IO CRL
- Z.Crypto.X509: loadCRLFile :: CBytes -> IO CRL
+ Z.Crypto.X509: loadCRLFile :: HasCallStack => CBytes -> IO CRL
- Z.Crypto.X509: loadCertStoreFile :: CBytes -> IO CertStore
+ Z.Crypto.X509: loadCertStoreFile :: HasCallStack => CBytes -> IO CertStore
- Z.Crypto.X509: verifyCert :: [Cert] -> [Cert] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
+ Z.Crypto.X509: verifyCert :: HasCallStack => [Cert] -> [Cert] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
- Z.Crypto.X509: verifyCertCRL :: [Cert] -> [Cert] -> [CRL] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
+ Z.Crypto.X509: verifyCertCRL :: HasCallStack => [Cert] -> [Cert] -> [CRL] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
- Z.Crypto.X509: verifyCertCRL' :: [Cert] -> CertStore -> [CRL] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
+ Z.Crypto.X509: verifyCertCRL' :: HasCallStack => [Cert] -> CertStore -> [CRL] -> Int -> CBytes -> Word64 -> Cert -> IO (Maybe CBytes)
Files
- ChangeLog.md +7/−1
- Z-Botan.cabal +10/−2
- Z/Botan/FFI.hsc +2/−0
- Z/Crypto/Cipher.hs +20/−0
- Z/Crypto/FPE.hs +9/−3
- Z/Crypto/Hash.hs +6/−1
- Z/Crypto/KDF.hs +20/−16
- Z/Crypto/KeyWrap.hs +5/−2
- Z/Crypto/MAC.hs +6/−4
- Z/Crypto/MPI.hs +32/−5
- Z/Crypto/OTP.hs +16/−6
- Z/Crypto/PubKey.hs +159/−146
- Z/Crypto/PwdHash.hs +6/−2
- Z/Crypto/RNG.hs +14/−7
- Z/Crypto/X509.hs +69/−13
- third_party/botan/botan_all.cpp too large to diff
- third_party/botan/doc/abi.rst +21/−0
- third_party/botan/doc/api_ref/bigint.rst +279/−0
- third_party/botan/doc/api_ref/block_cipher.rst +361/−0
- third_party/botan/doc/api_ref/cipher_modes.rst +384/−0
- third_party/botan/doc/api_ref/compression.rst +90/−0
- third_party/botan/doc/api_ref/contents.rst +39/−0
- third_party/botan/doc/api_ref/credentials_manager.rst +186/−0
- third_party/botan/doc/api_ref/cryptobox.rst +32/−0
- third_party/botan/doc/api_ref/ecc.rst +284/−0
- third_party/botan/doc/api_ref/env_vars.rst +20/−0
- third_party/botan/doc/api_ref/ffi.rst +1203/−0
- third_party/botan/doc/api_ref/filters.rst +733/−0
- third_party/botan/doc/api_ref/fpe.rst +98/−0
- third_party/botan/doc/api_ref/hash.rst +348/−0
- third_party/botan/doc/api_ref/kdf.rst +106/−0
- third_party/botan/doc/api_ref/keywrap.rst +60/−0
- third_party/botan/doc/api_ref/message_auth_codes.rst +268/−0
- third_party/botan/doc/api_ref/otp.rst +98/−0
- third_party/botan/doc/api_ref/passhash.rst +219/−0
- third_party/botan/doc/api_ref/pbkdf.rst +190/−0
- third_party/botan/doc/api_ref/pkcs11.rst +1419/−0
- third_party/botan/doc/api_ref/psk_db.rst +108/−0
- third_party/botan/doc/api_ref/pubkey.rst +954/−0
- third_party/botan/doc/api_ref/python.rst +668/−0
- third_party/botan/doc/api_ref/rng.rst +281/−0
- third_party/botan/doc/api_ref/roughtime.rst +6/−0
- third_party/botan/doc/api_ref/secmem.rst +31/−0
- third_party/botan/doc/api_ref/srp.rst +77/−0
- third_party/botan/doc/api_ref/stream_ciphers.rst +211/−0
- third_party/botan/doc/api_ref/tls.rst +1926/−0
- third_party/botan/doc/api_ref/tpm.rst +113/−0
- third_party/botan/doc/api_ref/tss.rst +45/−0
- third_party/botan/doc/api_ref/versions.rst +100/−0
- third_party/botan/doc/api_ref/x509.rst +914/−0
- third_party/botan/doc/authors.txt +102/−0
- third_party/botan/doc/building.rst +1019/−0
- third_party/botan/doc/cli.rst +406/−0
- third_party/botan/doc/contents.rst +25/−0
- third_party/botan/doc/credits.rst +156/−0
- third_party/botan/doc/deprecated.rst +297/−0
- third_party/botan/doc/dev_ref/configure.rst +407/−0
- third_party/botan/doc/dev_ref/contents.rst +20/−0
- third_party/botan/doc/dev_ref/continuous_integration.rst +75/−0
- third_party/botan/doc/dev_ref/contributing.rst +268/−0
- third_party/botan/doc/dev_ref/fuzzing.rst +91/−0
- third_party/botan/doc/dev_ref/mistakes.rst +77/−0
- third_party/botan/doc/dev_ref/oids.rst +43/−0
- third_party/botan/doc/dev_ref/os.rst +61/−0
- third_party/botan/doc/dev_ref/reading_list.rst +93/−0
- third_party/botan/doc/dev_ref/release_process.rst +129/−0
- third_party/botan/doc/dev_ref/test_framework.rst +314/−0
- third_party/botan/doc/dev_ref/todo.rst +199/−0
- third_party/botan/doc/goals.rst +131/−0
- third_party/botan/doc/index.rst +58/−0
- third_party/botan/doc/old_news.rst +4336/−0
- third_party/botan/doc/packaging.rst +59/−0
- third_party/botan/doc/pgpkey.txt +198/−0
- third_party/botan/doc/roadmap.rst +54/−0
- third_party/botan/doc/security.rst +352/−0
- third_party/botan/doc/side_channels.rst +449/−0
- third_party/botan/doc/support.rst +70/−0
- third_party/botan/src/bogo_shim/config.json +128/−0
- third_party/botan/src/lib/ffi/ffi.h +2/−0
- third_party/botan/src/lib/ffi/ffi_cert.cpp +34/−1
- third_party/cacert.md +1/−1
- third_party/cacert.pem +94/−315
ChangeLog.md view
@@ -1,8 +1,14 @@ # Revision history for z-botan +## 0.2.0.0 -- 2020-05-12++* Simplify `KeyType` in `Z.Crypto.PubKey`.+* Add `sm2Encrypt`, `sm2Decrypt` to `Z.Crypto.PubKey`.+* Add `systemCertStore`, `mozillaCertStore` to `Z.Crypto.X509`.+ ## 0.1.1.2 -- 2020-05-11 -* Export 'KeySpec' from `Z.Crypto.Cipher`.+* Export `KeySpec` from `Z.Crypto.Cipher`. ## 0.1.0.0 -- 2020-05-11
Z-Botan.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: Z-Botan-version: 0.1.1.2+version: 0.2.0.0 synopsis: Crypto for Haskell description: Crypto for Haskell, based on <http://botan.randombit.net/ Botan> license: BSD-3-Clause@@ -23,10 +23,16 @@ third_party/botan/src/**/*.h third_party/botan/src/**/*.in third_party/botan/src/**/*.txt+ third_party/botan/src/**/*.json+ third_party/botan/doc/**/*.txt+ third_party/botan/doc/**/*.rst third_party/botan/build/include/external/cabal.placeholder third_party/cacert.md third_party/cacert.pem +-- https://curl.se/docs/caextract.html+data-files: third_party/cacert.pem+ custom-setup setup-depends: , base >=4.5 && <5.0@@ -55,6 +61,8 @@ Z.Crypto.PwdHash Z.Crypto.RNG Z.Crypto.X509+ other-modules: Paths_Z_Botan+ autogen-modules: Paths_Z_Botan build-depends: , base >=4.12 && <5.0@@ -64,7 +72,7 @@ , stm ^>=2.5 , time == 1.11.* , Z-Data >=0.8.2 && < 0.9- , Z-IO ^>=0.8+ , Z-IO >=0.8 && < 0.9 include-dirs: include third_party/botan third_party/botan/build/include
Z/Botan/FFI.hsc view
@@ -668,6 +668,8 @@ foreign import ccall unsafe botan_x509_certstore_load_file :: MBA## BotanStructT -> BA## Word8 -> IO CInt +foreign import ccall unsafe botan_x509_certstore_load_system :: MBA## BotanStructT -> IO CInt+ foreign import ccall unsafe "&botan_x509_certstore_destroy" botan_x509_certstore_destroy :: FunPtr (BotanStructT -> IO ()) --------------------------------------------------------------------------------
Z/Crypto/Cipher.hs view
@@ -175,6 +175,7 @@ deriving anyclass (T.Print, JSON) blockCipherTypeToCBytes :: BlockCipherType -> CBytes+{-# INLINABLE blockCipherTypeToCBytes #-} blockCipherTypeToCBytes b = case b of AES128 -> "AES-128" AES192 -> "AES-192"@@ -233,6 +234,7 @@ -- | Pass 'BlockCipher' to FFI as 'botan_block_cipher_t'. withBlockCipher :: HasCallStack => BlockCipher -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withBlockCipher #-} withBlockCipher (BlockCipher bc _ _ _) = withBotanStruct bc data KeySpec = KeySpec@@ -246,6 +248,7 @@ -- | Create a new block cipher. -- newBlockCipher :: HasCallStack => BlockCipherType -> IO BlockCipher+{-# INLINABLE newBlockCipher #-} newBlockCipher typ = do let name = blockCipherTypeToCBytes typ bc <- newBotanStruct@@ -266,6 +269,7 @@ -- | Set the cipher key, which is required before encrypting or decrypting. -- setBlockCipherKey :: HasCallStack => BlockCipher -> V.Bytes -> IO ()+{-# INLINABLE setBlockCipherKey #-} setBlockCipherKey (BlockCipher bc _ _ _) key = withBotanStruct bc $ \ pbc -> do withPrimVectorUnsafe key $ \ pkey key_off key_len -> do@@ -274,6 +278,7 @@ -- | Clear the internal state (such as keys) of this cipher object. clearBlockCipher :: HasCallStack => BlockCipher -> IO ()+{-# INLINABLE clearBlockCipher #-} clearBlockCipher (BlockCipher bc _ _ _) = withBotanStruct bc (throwBotanIfMinus_ . botan_block_cipher_clear) @@ -285,6 +290,7 @@ -> V.Bytes -- ^ blocks of data, length must be equal to block_size * number_of_blocks -> Int -- ^ number of blocks -> IO V.Bytes+{-# INLINABLE encryptBlocks #-} encryptBlocks (BlockCipher bc _ blockSiz _) blocks n = do let inputLen = V.length blocks when (inputLen /= blockSiz * n) $@@ -303,6 +309,7 @@ -> V.Bytes -- ^ blocks of data, length must be equal to block_size * number_of_blocks -> Int -- ^ number of blocks -> IO V.Bytes+{-# INLINABLE decryptBlocks #-} decryptBlocks (BlockCipher bc _ blockSiz _) blocks n = do let inputLen = V.length blocks when (inputLen /= blockSiz * n) $@@ -345,6 +352,7 @@ deriving anyclass (T.Print, JSON) streamCipherTypeToCBytes :: StreamCipherType -> CBytes+{-# INLINABLE streamCipherTypeToCBytes #-} streamCipherTypeToCBytes s = case s of CTR_BE b -> CB.concat ["CTR-BE(", blockCipherTypeToCBytes b, ")"] OFB b -> CB.concat ["OFB(", blockCipherTypeToCBytes b, ")"]@@ -358,6 +366,7 @@ -- | Create a new stream cipher. -- newStreamCipher :: HasCallStack => StreamCipherType -> CipherDirection -> IO Cipher+{-# INLINABLE newStreamCipher #-} newStreamCipher typ dir = do let name = streamCipherTypeToCBytes typ ci <- newBotanStruct@@ -499,6 +508,7 @@ deriving anyclass (T.Print, JSON) cipherTypeToCBytes :: CipherMode -> CBytes+{-# INLINABLE cipherTypeToCBytes #-} cipherTypeToCBytes ct = case ct of ChaCha20Poly1305 -> "ChaCha20Poly1305" GCM bct -> blockCipherTypeToCBytes bct <> "/GCM"@@ -535,11 +545,13 @@ -- | Pass 'Cipher' to FFI as 'botan_cipher_t'. withCipher :: HasCallStack => Cipher -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withCipher #-} withCipher (Cipher c _ _ _ _ _) = withBotanStruct c -- | Create a new cipher. -- newCipher :: HasCallStack => CipherMode -> CipherDirection -> IO Cipher+{-# INLINABLE newCipher #-} newCipher typ dir = do let name = cipherTypeToCBytes typ ci <- newBotanStruct@@ -568,6 +580,7 @@ -- | Clear the internal state (such as keys) of this cipher object. -- clearCipher :: HasCallStack => Cipher -> IO ()+{-# INLINABLE clearCipher #-} clearCipher (Cipher ci _ _ _ _ _) = withBotanStruct ci (throwBotanIfMinus_ . botan_cipher_clear) @@ -579,12 +592,14 @@ -- by botan_cipher_set_key with the original key. -- resetCipher :: HasCallStack => Cipher -> IO ()+{-# INLINABLE resetCipher #-} resetCipher (Cipher ci _ _ _ _ _) = withBotanStruct ci (throwBotanIfMinus_ . botan_cipher_reset) -- | Set the key for this cipher object -- setCipherKey :: HasCallStack => Cipher -> V.Bytes -> IO ()+{-# INLINABLE setCipherKey #-} setCipherKey (Cipher ci _ _ _ _ _) key = withBotanStruct ci $ \ pci -> do withPrimVectorUnsafe key $ \ pkey key_off key_len -> do@@ -594,6 +609,7 @@ -- | Set the associated data. Will fail if cipher is not an AEAD. -- setAssociatedData :: HasCallStack => Cipher -> V.Bytes -> IO ()+{-# INLINABLE setAssociatedData #-} setAssociatedData (Cipher ci _ _ _ _ _) ad = withBotanStruct ci $ \ pci -> do withPrimVectorUnsafe ad $ \ pad ad_off ad_len -> do@@ -606,6 +622,7 @@ => Cipher -> V.Bytes -- ^ nonce -> IO ()+{-# INLINABLE startCipher #-} startCipher (Cipher ci _ _ _ _ _) nonce = withBotanStruct ci $ \ pci -> do withPrimVectorUnsafe nonce $ \ pnonce nonce_off nonce_len -> do@@ -620,6 +637,7 @@ => Cipher -> V.Bytes -> IO (V.Bytes, V.Bytes) -- ^ trailing input, output+{-# INLINABLE updateCipher #-} updateCipher (Cipher ci _ _ _ _ _) input = withBotanStruct ci $ \ pci -> do withPrimVectorUnsafe input $ \ in_p in_off in_len -> do@@ -636,6 +654,7 @@ => Cipher -> V.Bytes -> IO V.Bytes+{-# INLINABLE finishCipher #-} finishCipher (Cipher ci _ ug _ tag_len _) input = withBotanStruct ci $ \ pci -> do withPrimVectorUnsafe input $ \ in_p in_off in_len -> do@@ -656,6 +675,7 @@ -- which may not be suitable for arbitrary bytes streams. -- cipherBIO :: HasCallStack => Cipher -> IO (BIO V.Bytes V.Bytes)+{-# INLINABLE cipherBIO #-} cipherBIO c = do trailingRef <- newIORef V.empty return $ \ k mbs -> case mbs of
Z/Crypto/FPE.hs view
@@ -31,9 +31,11 @@ -- | Initialize an FPE operation to encrypt/decrypt integers less than n. It is -- expected that n is trivially factorable into small integers. Common usage -- would be n to be a power of 10.-newFPE :: MPI -- ^ mod (n)+newFPE :: HasCallStack+ => MPI -- ^ mod (n) -> V.Bytes -- ^ key -> IO FPE+{-# INLINABLE newFPE #-} newFPE mpi key = withMPI mpi $ \ mpi' -> withPrimVectorUnsafe key $ \ key' keyOff keyLen ->@@ -42,10 +44,12 @@ botan_fpe_destroy -- | Encrypts the value x modulo the value n using the key and tweak specified. Returns an integer less than n. The tweak is a value that does not need to be secret that parameterizes the encryption function. For instance, if you were encrypting a database column with a single key, you could use a per-row-unique integer index value as the tweak. The same tweak value must be used during decryption.-encryptFPE :: FPE+encryptFPE :: HasCallStack+ =>FPE -> MPI -> V.Bytes -- ^ tweak -> IO MPI+{-# INLINABLE encryptFPE #-} encryptFPE (FPE fpe) mpi tweak = do mpi' <- copyMPI mpi withBotanStruct fpe $ \ fpe' ->@@ -57,10 +61,12 @@ -- | Decrypts an FE1 ciphertext. The tweak must be the same as that provided to the encryption function. Returns the plaintext integer. -- Note that there is not any implicit authentication or checking of data in FE1, so if you provide an incorrect key or tweak the result is simply a random integer.-decryptFPE :: FPE+decryptFPE :: HasCallStack+ => FPE -> MPI -> V.Bytes -- ^ tweak -> IO MPI+{-# INLINABLE decryptFPE #-} decryptFPE (FPE fpe) mpi tweak = do mpi' <- copyMPI mpi withBotanStruct fpe $ \ fpe' ->
Z/Crypto/Hash.hs view
@@ -179,10 +179,12 @@ -- | Pass Hash to FFI as @botan_hash_t@ withHash :: HasCallStack => Hash -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withHash #-} withHash (Hash h _ _) = withBotanStruct h -- | Create a new 'Hash' object. newHash :: HasCallStack => HashType -> IO Hash+{-# INLINABLE newHash #-} newHash typ = do let name = hashTypeToCBytes typ bs <- newBotanStruct@@ -196,6 +198,7 @@ -- | Copies the state of the hash object to a new hash object. copyHash :: HasCallStack => Hash -> IO Hash+{-# INLINABLE copyHash #-} copyHash (Hash bts0 name siz) = do s <- newBotanStruct (\ bts -> withBotanStruct bts0 $ \ pbts0 ->@@ -205,11 +208,13 @@ -- | Reset the state of Hash object back to clean, as if no input has been supplied. clearHash :: HasCallStack => Hash -> IO ()+{-# INLINABLE clearHash #-} clearHash (Hash bts _ _) = throwBotanIfMinus_ (withBotanStruct bts botan_hash_clear) -- | Feed a chunk of input into a hash object.-updateHash :: Hash -> V.Bytes -> IO ()+updateHash :: HasCallStack => Hash -> V.Bytes -> IO ()+{-# INLINABLE updateHash #-} updateHash (Hash bts _ _) bs = withBotanStruct bts $ \ pbts -> withPrimVectorUnsafe bs $ \ pbs off len ->
Z/Crypto/KDF.hs view
@@ -14,7 +14,6 @@ module Z.Crypto.KDF ( -- * KDF KDFType(..)- , BlockCipherType (..) , HashType(..) , MACType(..) , kdf@@ -30,7 +29,6 @@ import Z.Botan.Exception import Z.Botan.FFI-import Z.Crypto.Cipher (BlockCipherType (..)) import Z.Crypto.Hash (HashType (..), hashTypeToCBytes) import Z.Crypto.MAC (MACType (..), macTypeToCBytes) import Z.Data.CBytes (CBytes, withCBytes, withCBytesUnsafe)@@ -90,13 +88,14 @@ kdfTypeToCBytes (SP800_56C mt ) = CB.concat [ "SP800-56C(" , macTypeToCBytes mt, ")"] -- | Derive a key using the given KDF algorithm.-kdf- :: KDFType -- ^ the name of the given PBKDF algorithm- -> Int -- ^ length of output key- -> V.Bytes -- ^ secret- -> V.Bytes -- ^ salt- -> V.Bytes -- ^ label- -> IO V.Bytes+kdf :: HasCallStack+ => KDFType -- ^ the name of the given PBKDF algorithm+ -> Int -- ^ length of output key+ -> V.Bytes -- ^ secret+ -> V.Bytes -- ^ salt+ -> V.Bytes -- ^ label+ -> IO V.Bytes+{-# INLINABLE kdf #-} kdf algo siz secret salt label = withCBytesUnsafe (kdfTypeToCBytes algo) $ \ algoBA -> withPrimVectorUnsafe secret $ \ secretBA secretOff secretLen ->@@ -112,11 +111,12 @@ labelBA labelOff labelLen) -- | Derive a key using the given KDF algorithm, with default empty salt and label.-kdf'- :: KDFType -- ^ the name of the given PBKDF algorithm- -> Int -- ^ length of output key- -> V.Bytes -- ^ secret- -> IO V.Bytes+kdf' :: HasCallStack+ => KDFType -- ^ the name of the given PBKDF algorithm+ -> Int -- ^ length of output key+ -> V.Bytes -- ^ secret+ -> IO V.Bytes+{-# INLINABLE kdf' #-} kdf' algo siz secret = kdf algo siz secret mempty mempty --------------------------------------------@@ -152,11 +152,13 @@ pbkdfTypeToParam (OpenPGP_S2K ht i) = (CB.concat [ "OpenPGP-S2K(" , hashTypeToCBytes ht, ")"], i, 0, 0) -- | Derive a key from a passphrase for a number of iterations using the given PBKDF algorithm and params.-pbkdf :: PBKDFType -- ^ PBKDF algorithm type+pbkdf :: HasCallStack+ => PBKDFType -- ^ PBKDF algorithm type -> Int -- ^ length of output key -> CBytes -- ^ passphrase -> V.Bytes -- ^ salt -> IO V.Bytes+{-# INLINABLE pbkdf #-} pbkdf typ siz pwd salt = do withCBytesUnsafe algo $ \ algoBA -> withCBytesUnsafe pwd $ \ pwdBA ->@@ -174,12 +176,14 @@ -- | Derive a key from a passphrase using the given PBKDF algorithm, the iteration params are -- ignored and PBKDF is run until given milliseconds have passed.-pbkdfTimed :: PBKDFType -- ^ the name of the given PBKDF algorithm+pbkdfTimed :: HasCallStack+ => PBKDFType -- ^ the name of the given PBKDF algorithm -> Int -- ^ run until milliseconds have passwd -> Int -- ^ length of output key -> CBytes -- ^ passphrase -> V.Bytes -- ^ salt -> IO V.Bytes+{-# INLINABLE pbkdfTimed #-} pbkdfTimed typ msec siz pwd s = do -- we want run it in new OS thread without stop GC from running -- if the expected time is too long(>0.1s)
Z/Crypto/KeyWrap.hs view
@@ -12,12 +12,14 @@ -} module Z.Crypto.KeyWrap where +import Z.Botan.Exception import Z.Botan.FFI import qualified Z.Data.Vector as V import Z.Foreign -- | Wrap the input key using kek (the key encryption key), and return the result. It will be 8 bytes longer than the input key.-keyWrap :: V.Bytes -- ^ key+keyWrap :: HasCallStack+ => V.Bytes -- ^ key -> V.Bytes -- ^ kek -> IO V.Bytes {-# INLINABLE keyWrap #-}@@ -28,7 +30,8 @@ hs_botan_key_wrap3394 key' keyOff keyLen kek' kekOff kekLen -- | Unwrap a key wrapped with rfc3394_keywrap.-keyUnwrap :: V.Bytes -- ^ wrapped key+keyUnwrap :: HasCallStack+ => V.Bytes -- ^ wrapped key -> V.Bytes -- ^ kek -> IO V.Bytes {-# INLINABLE keyUnwrap #-}
Z/Crypto/MAC.hs view
@@ -46,8 +46,6 @@ data MACType = CMAC BlockCipherType -- ^ A modern CBC-MAC variant that avoids the security problems of plain CBC-MAC. -- Approved by NIST. Also sometimes called OMAC.- | OMAC BlockCipherType- -- ^ | GMAC BlockCipherType -- ^ GMAC is related to the GCM authenticated cipher mode. -- It is quite slow unless hardware support for carryless multiplications is available.@@ -74,7 +72,6 @@ macTypeToCBytes :: MACType -> CBytes macTypeToCBytes (CMAC bc ) = CB.concat ["CMAC(", blockCipherTypeToCBytes bc, ")"]-macTypeToCBytes (OMAC bc ) = CB.concat ["OMAC(", blockCipherTypeToCBytes bc, ")"] macTypeToCBytes (GMAC bc ) = CB.concat ["GMAC(", blockCipherTypeToCBytes bc, ")"] macTypeToCBytes (CBC_MAC bc) = CB.concat ["CBC-MAC(", blockCipherTypeToCBytes bc, ")"] macTypeToCBytes (HMAC ht) = CB.concat ["HMAC(", hashTypeToCBytes ht, ")"]@@ -94,10 +91,12 @@ -- | Pass MAC to FFI as 'botan_mac_t'. withMAC :: HasCallStack => MAC -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withMAC #-} withMAC (MAC m _ _) = withBotanStruct m -- | Create a new 'MAC' object.-newMAC :: MACType -> IO MAC+newMAC :: HasCallStack => MACType -> IO MAC+{-# INLINABLE newMAC #-} newMAC typ = do let name = macTypeToCBytes typ bs <- newBotanStruct@@ -111,6 +110,7 @@ -- | Set the random key. setKeyMAC :: HasCallStack => MAC -> V.Bytes -> IO ()+{-# INLINABLE setKeyMAC #-} setKeyMAC (MAC bts _ _) bs = withBotanStruct bts $ \pbts-> withPrimVectorUnsafe bs $ \pbs off len ->@@ -118,6 +118,7 @@ -- | Feed a chunk of input into a 'MAC' object. updateMAC :: HasCallStack => MAC -> V.Bytes -> IO ()+{-# INLINABLE updateMAC #-} updateMAC (MAC bts _ _) bs = withBotanStruct bts $ \ pbts -> withPrimVectorUnsafe bs $ \ pbs off len ->@@ -132,6 +133,7 @@ -- | Reset the state of MAC object back to clean, as if no input has been supplied. clearMAC :: HasCallStack => MAC -> IO ()+{-# INLINABLE clearMAC #-} clearMAC (MAC bts _ _) = throwBotanIfMinus_ (withBotanStruct bts hs_botan_mac_clear)
Z/Crypto/MPI.hs view
@@ -324,35 +324,42 @@ zero = unsafeNewMPI (\ _ -> return ()) newMPI :: (BotanStructT -> IO a) -> IO MPI+{-# INLINABLE newMPI #-} newMPI f = do mp <- newBotanStruct (\ bts -> botan_mp_init bts) botan_mp_destroy _ <- withBotanStruct mp f return (MPI mp) newMPI' :: (BotanStructT -> IO a) -> IO (MPI, a)+{-# INLINABLE newMPI' #-} newMPI' f = do mp <- newBotanStruct (\ bts -> botan_mp_init bts) botan_mp_destroy r <- withBotanStruct mp f return (MPI mp, r) copyMPI :: MPI -> IO MPI+{-# INLINABLE copyMPI #-} copyMPI (MPI a) = do withBotanStruct a $ \ btsa -> do newMPI (\ bts -> botan_mp_set_from_mp bts btsa) withMPI :: MPI -> (BotanStructT -> IO a) -> IO a+{-# INLINABLE withMPI #-} withMPI (MPI bts) f = withBotanStruct bts f unsafeWithMPI :: MPI -> (BotanStructT -> IO a) -> a+{-# INLINABLE unsafeWithMPI #-} unsafeWithMPI (MPI bts) f = unsafeDupablePerformIO (withBotanStruct bts f) unsafeNewMPI :: (BotanStructT -> IO a) -> MPI+{-# INLINABLE unsafeNewMPI #-} unsafeNewMPI f = unsafeDupablePerformIO $ do mp <- newBotanStruct (\ bts -> botan_mp_init bts) botan_mp_destroy _ <- withBotanStruct mp f return (MPI mp) unsafeNewMPI' :: (BotanStructT -> IO a) -> (MPI, a)+{-# INLINABLE unsafeNewMPI' #-} unsafeNewMPI' f = unsafeDupablePerformIO $ do mp <- newBotanStruct (\ bts -> botan_mp_init bts) botan_mp_destroy r <- withBotanStruct mp f@@ -360,26 +367,31 @@ -- | Get 'MPI' 's byte size. byteSize :: MPI -> Int+{-# INLINABLE byteSize #-} byteSize mp = fromIntegral @CSize . fst . unsafeWithMPI mp $ \ bts -> allocPrimUnsafe (botan_mp_num_bytes bts) -- | Get 'MPI' 's bit size. bitSize :: MPI -> Int+{-# INLINABLE bitSize #-} bitSize mp = fromIntegral @CSize . fst . unsafeWithMPI mp $ \ bts -> allocPrimUnsafe (botan_mp_num_bits bts) -- | Set 'MPI' from an integer value. fromCInt :: CInt -> MPI+{-# INLINABLE fromCInt #-} fromCInt x = unsafeNewMPI $ \ bts -> botan_mp_set_from_int bts x -- | Convert a MPI to 'Word32', the sign is ignored.-toWord32 :: HasCallStack => MPI -> Word32+toWord32 :: MPI -> Word32+{-# INLINABLE toWord32 #-} toWord32 mp = fst . unsafeWithMPI mp $ \ bts -> allocPrimUnsafe (botan_mp_to_uint32 bts) -- | Write a 'MPI' in decimal format, with negative sign if < 0. toDecimal :: MPI -> B.Builder ()+{-# INLINABLE toDecimal #-} toDecimal mp = do when (isNegative mp) (B.word8 MINUS) -- botan write \NUL terminator@@ -389,6 +401,7 @@ -- | Parse a 'MPI' in decimal format, parse leading minus sign. fromDecimal :: P.Parser MPI+{-# INLINABLE fromDecimal #-} fromDecimal = do sign <- P.peek let neg = sign == MINUS@@ -404,6 +417,7 @@ -- | Write a 'MPI' in hexadecimal format(without '0x' prefix), the sign is ignored. toHex :: MPI -> B.Builder ()+{-# INLINABLE toHex #-} toHex mp = -- botan write \NUL terminator let !siz = byteSize mp `unsafeShiftL` 1@@ -414,6 +428,7 @@ -- | Parse a 'MPI' in hexadecimal format(without '0x' prefix), no sign is allowed. fromHex :: P.Parser MPI+{-# INLINABLE fromHex #-} fromHex = do v@(V.PrimVector (A.PrimArray ba#) s l) <- P.takeWhile1 isHexDigit let (x, r) = unsafeNewMPI' $ \ bts -> hs_botan_mp_set_from_hex bts ba# s l@@ -422,21 +437,25 @@ else return x isNegative :: MPI -> Bool+{-# INLINABLE isNegative #-} isNegative mp = unsafeWithMPI mp $ \ bts -> do r <- botan_mp_is_negative bts return $! r == 1 isZero :: MPI -> Bool+{-# INLINABLE isZero #-} isZero mp = unsafeWithMPI mp $ \ bts -> do r <- botan_mp_is_zero bts return $! r == 1 isOdd :: MPI -> Bool+{-# INLINABLE isOdd #-} isOdd mp = unsafeWithMPI mp $ \ bts -> do r <- botan_mp_is_odd bts return $! r == 1 isEven :: MPI -> Bool+{-# INLINABLE isEven #-} isEven mp = unsafeWithMPI mp $ \ bts -> do r <- botan_mp_is_even bts return $! r == 1@@ -445,6 +464,7 @@ -- | mulMod x y mod = x times y modulo mod mulMod :: MPI -> MPI -> MPI -> MPI+{-# INLINABLE mulMod #-} mulMod x y m = unsafeNewMPI $ \ btsr -> withMPI x $ \ btsx ->@@ -455,6 +475,7 @@ -- | Modular exponentiation. powMod base exp mod = base power exp module mod powMod :: MPI -> MPI -> MPI -> MPI+{-# INLINABLE powMod #-} powMod x y m = unsafeNewMPI $ \ btsr -> withMPI x $ \ btsx ->@@ -466,6 +487,7 @@ -- -- If no modular inverse exists (for instance because in and modulus are not relatively prime), return 0. modInverse :: MPI -> MPI -> MPI+{-# INLINABLE modInverse #-} modInverse x y = unsafeNewMPI $ \ btsr -> withMPI x $ \ btsx ->@@ -473,17 +495,20 @@ botan_mp_mod_inverse btsr btsx btsy -- | Create a random 'MPI' of the specified bit size.-randBits :: RNG -> Int -> IO MPI+randBits :: HasCallStack => RNG -> Int -> IO MPI+{-# INLINABLE randBits #-} randBits rng x = do newMPI $ \ bts -> withRNG rng $ \ bts_rng -> throwBotanIfMinus_ (botan_mp_rand_bits bts bts_rng (fromIntegral (max x 0))) -- | Create a random 'MPI' within the provided range.-randRange :: RNG+randRange :: HasCallStack+ => RNG -> MPI -- ^ lower bound -> MPI -- ^ upper bound -> IO MPI+{-# INLINABLE randRange #-} randRange rng lower upper = do newMPI $ \ bts -> withRNG rng $ \ bts_rng ->@@ -493,10 +518,11 @@ -- | Compute the greatest common divisor of x and y. gcd :: MPI -> MPI -> MPI+{-# INLINABLE gcd #-} gcd x y = unsafeNewMPI $ \ bts -> withMPI x $ \ bts_x -> withMPI y $ \ bts_y ->- throwBotanIfMinus_ (botan_mp_gcd bts bts_x bts_y)+ botan_mp_gcd bts bts_x bts_y -- | Test if n is prime. --@@ -504,7 +530,8 @@ -- set test_prob to the desired assurance level. -- For example if test_prob is 64, then sufficient Miller-Rabin iterations will run to -- assure there is at most a 1/2**64 chance that n is composite.-isPrim :: RNG -> MPI -> Int -> IO Bool+isPrim :: HasCallStack => RNG -> MPI -> Int -> IO Bool+{-# INLINABLE isPrim #-} isPrim rng x prob = do withRNG rng $ \ bts_rng -> withMPI x $ \ bts_x -> do
Z/Crypto/OTP.hs view
@@ -57,7 +57,8 @@ pattern OTP_DIGIT_7 = 7 pattern OTP_DIGIT_8 = 8 -newHOTP :: V.Bytes -> OTPAlgo -> OTPDigitLen -> IO HOTP+newHOTP :: HasCallStack => V.Bytes -> OTPAlgo -> OTPDigitLen -> IO HOTP+{-# INLINABLE newHOTP #-} newHOTP key otpAlgo digits = withPrimVectorUnsafe key $ \ key' keyOff keyLen -> withCBytesUnsafe (hashTypeToCBytes otpAlgo) $ \ hashAlgo' ->@@ -66,19 +67,23 @@ botan_hotp_destroy -- | Generate a HOTP code for the provided counter.-genHOTP :: HOTP -- ^ the HOTP object+genHOTP :: HasCallStack+ => HOTP -- ^ the HOTP object -> Word64 -- ^ HOTP counter -> IO Word32+{-# INLINABLE genHOTP #-} genHOTP (HOTP hotp) counter = withBotanStruct hotp $ \ hotp' -> fst <$> allocPrimUnsafe (\ code -> botan_hotp_generate hotp' code counter) -- | Verify a HOTP code.-checkHOTP :: HOTP -- ^ the HOTP object+checkHOTP :: HasCallStack+ => HOTP -- ^ the HOTP object -> Word32 -- ^ the presented HOTP code -> Word64 -- ^ the HOTP counter -> Int -- ^ resync range -> IO (Bool, Word64)+{-# INLINABLE checkHOTP #-} checkHOTP (HOTP totp) code c range = do withBotanStruct totp $ \ totp' -> do (nc, ret) <- allocPrimUnsafe $ \ nc' ->@@ -96,7 +101,8 @@ deriving (Show, Generic) deriving anyclass T.Print -newTOTP :: V.Bytes -> OTPAlgo -> OTPDigitLen -> Int -> IO TOTP+newTOTP :: HasCallStack => V.Bytes -> OTPAlgo -> OTPDigitLen -> Int -> IO TOTP+{-# INLINABLE newTOTP #-} newTOTP key otpAlgo digits timeStep = withPrimVectorUnsafe key $ \ key' keyOff keyLen -> withCBytesUnsafe (hashTypeToCBytes otpAlgo) $ \ hashAlgo' ->@@ -105,20 +111,24 @@ botan_totp_destroy -- | Generate a TOTP code for the provided timestamp.-genTOTP :: TOTP -- ^ the TOTP object+genTOTP :: HasCallStack+ => TOTP -- ^ the TOTP object -> Word64 -- ^ the current local timestamp -> IO Word32+{-# INLINABLE genTOTP #-} genTOTP (TOTP totp) timestamp = withBotanStruct totp $ \ totp' -> fst <$> allocPrimUnsafe (\ code -> botan_totp_generate totp' code timestamp) -- | Verify a TOTP code.-checkTOTP :: TOTP -- ^ the TOTP object+checkTOTP :: HasCallStack+ => TOTP -- ^ the TOTP object -> Word32 -- ^ the presented OTP -> Word64 -- ^ timestamp the current local timestamp -> Int -- ^ specifies the acceptable amount of clock drift -- (in terms of time steps) between the two hosts. -> IO Bool+{-# INLINABLE checkTOTP #-} checkTOTP (TOTP totp) code timestamp driftAmount = do withBotanStruct totp $ \ totp' -> do ret <- botan_totp_check totp' code timestamp (fromIntegral driftAmount)
Z/Crypto/PubKey.hs view
@@ -8,14 +8,12 @@ Stability : experimental Portability : non-portable -This module is used for Public Key Cryptography.-Public key cryptography (also called asymmetric cryptography) is a collection of techniques allowing for encryption, signatures, and key agreement.+This module is used for Public key cryptography. Public key cryptography (also called asymmetric cryptography) is a collection of techniques allowing for encryption, signatures, and key agreement. -} module Z.Crypto.PubKey ( -- * Asymmetric cryptography algorithms- KeyType(..), pattern RSADefault, pattern McElieceDefault, pattern XMSSDefault- , ECCType(..), DLType(..)+ KeyType(..) -- * Key generation and manipulation , PrivKey(..), PubKey(..) , newPrivKey, newKeyPair, privKeyToPubKey@@ -34,6 +32,8 @@ -- * Encrypt & Decrypt , pkEncrypt , pkDecrypt+ , sm2Encrypt+ , sm2Decrypt , EMEPadding(..) -- * Sign & verify , EMSA(..), SignFmt(..)@@ -159,49 +159,43 @@ -- Key Types -- --------------- --- | Public Key Cryptography Algorithms.+-- | Public key cryptography algorithms. data KeyType- = Curve25519- | -- | RSA key of the given size, namely n bits- RSA Word32- -- | eXtended Merkle Signature Scheme, see <xmss https://botan.randombit.net/handbook/api_ref/pubkey.html#extended-merkle-signature-scheme-xmss>- | XMSS XMSSType- -- | Ed25519 high-speed high-security signatures- | Ed25519- -- | Elliptic-curve cryptography, see 'ECCType'- | ECC ECCType ECGroup- -- | Asymmetric algorithm based on the discrete logarithm problem, see 'DLType'- | DL DLType DLGroup- -- | McEliece is a cryptographic scheme based on error correcting codes which is thought to be resistant to quantum computers. See <mceliece https://botan.randombit.net/handbook/api_ref/pubkey.html#mceliece>.- | McEliece- Word32 -- ^ n- Word32 -- ^ t-+ = RSA Word32 -- ^ RSA key of the given size, namely n bits, support encryption and signature.+ | SM2 ECGroup -- ^ Public key algorithms specified by China, support encryption and signature.+ | ElGamal DLGroup -- ^ ElGamal encryption system, support encryption. -keyTypeToCBytes :: KeyType -> (CBytes, CBytes)-keyTypeToCBytes keyType' = case keyType' of- Curve25519 -> ("Curve25519", "")- RSA bits -> ("RSA", CB.buildCBytes $ B.int bits)- McEliece n t -> ("McEliece", CB.buildCBytes $ B.int n >> B.char8 ',' >> B.int t)- XMSS xmss -> ("XMSS", xmss)- Ed25519 -> ("Ed25519", "")- ECC ecc grp -> (eccToCBytes ecc, grp)- DL dl grp -> (dlToCBytes dl, grp)+ | DSA DLGroup -- ^ Digital Signature Algorithm based on the discrete logarithm problem.+ | ECDSA ECGroup -- ^ Digital Signature Algorithm which uses elliptic curve cryptography.+ | ECKCDSA ECGroup -- ^ Korean Certificate-based Digital Signature Algorithm.+ | ECGDSA ECGroup -- ^ Elliptic Curve German Digital Signature Algorithm.+ | GOST_34'10 ECGroup -- ^ Cryptographic algorithms defined by the Russian national standards, support signature.+ | Ed25519 -- ^ Ed25519 elliptic-curve signatures, see <https://ed25519.cr.yp.to/ ed25519>.+ | XMSS XMSSType -- ^ eXtended Merkle Signature Scheme, see <xmss https://botan.randombit.net/handbook/api_ref/pubkey.html#extended-merkle-signature-scheme-xmss>. --- | Default RSA Key type(3072 bits).-pattern RSADefault :: KeyType-pattern RSADefault = RSA 3072+ | DH DLGroup -- ^ The Diffie–Hellman key exchange.+ | ECDH ECGroup -- ^ The Elliptic-curve Diffie–Hellman key exchange.+ | Curve25519 -- ^ The Curve25519 Diffie–Hellman key exchange. --- | Default McEliece key type.-pattern McElieceDefault :: KeyType-pattern McElieceDefault = McEliece 2960 57+keyTypeToCBytes :: KeyType -> (CBytes, CBytes)+keyTypeToCBytes keyType = case keyType of+ RSA bits -> ("RSA", CB.buildCBytes $ B.int bits)+ SM2 grp -> ("SM2", grp)+ ElGamal grp -> ("ElGamal", grp)+ DSA grp -> ("DSA", grp)+ ECDSA grp -> ("ECDSA", grp)+ ECKCDSA grp -> ("ECKCDSA", grp)+ ECGDSA grp -> ("ECGDSA", grp)+ GOST_34'10 grp -> ("GOST_34.10", grp)+ Ed25519 -> ("Ed25519", "")+ XMSS xms -> ("XMSS", xms)+ DH grp -> ("DH", grp)+ ECDH grp -> ("ECDH", grp)+ Curve25519 -> ("Curve25519", "") -- | A type wrapper. type XMSSType = CBytes -pattern XMSSDefault :: KeyType-pattern XMSSDefault = XMSS XMSS_SHA2_10_512- pattern XMSS_SHA2_10_256 :: XMSSType pattern XMSS_SHA2_10_256 = "XMSS-SHA2_10_256" @@ -238,24 +232,6 @@ pattern XMSS_SHAKE_20_512 :: XMSSType pattern XMSS_SHAKE_20_512 = "XMSS-SHAKE_20_512" --- | Algorithms based on elliptic curve.-data ECCType- = ECDSA | ECDH | ECKCDSA | ECGDSA | SM2 | SM2_Sig- | SM2_Enc | GOST_34_10 | GOST_34_10_2012_256 | GOST_34_10_2012_512--eccToCBytes :: ECCType -> CBytes-eccToCBytes = \ case- ECDSA -> "ECDSA"- ECDH -> "ECDH"- ECKCDSA -> "ECKCDSA"- ECGDSA -> "ECGDSA"- SM2 -> "SM2"- SM2_Sig -> "SM2_Sig"- SM2_Enc -> "SM2_Enc"- GOST_34_10 -> "GOST-34.10"- GOST_34_10_2012_256 -> "GOST-34.10-2012-256"- GOST_34_10_2012_512 -> "GOST-34.10-2012-512"- -- | An elliptic curve. type ECGroup = CBytes @@ -340,18 +316,6 @@ pattern Sm2p256v1 :: ECGroup pattern Sm2p256v1 = "sm2p256v1" --- | Discrete Logarithm-data DLType- = DH -- ^ Diffie-Hellman key exchange- | DSA -- ^ Digital Signature Algorithm- | ElGamal--dlToCBytes :: DLType -> CBytes-dlToCBytes = \ case- DH -> "DH"- DSA -> "DSA"- ElGamal -> "ElGamal"- -- | Discrete Logarithm Group type DLGroup = CBytes @@ -433,15 +397,16 @@ -- | Pass 'PrivKey' to FFI. withPrivKey :: HasCallStack => PrivKey -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withPrivKey #-} withPrivKey (PrivKey key) = withBotanStruct key -- | Creating a new key pair. ---newKeyPair ::- -- | Algorithm name and some algorithm specific arguments.- KeyType ->- RNG ->- IO (PrivKey, PubKey)+newKeyPair :: HasCallStack+ => KeyType -- ^ Algorithm name and some algorithm specific arguments.+ -> RNG+ -> IO (PrivKey, PubKey)+{-# INLINABLE newKeyPair #-} newKeyPair kt rng = do priv <- newPrivKey kt rng let !pub = privKeyToPubKey priv@@ -454,11 +419,11 @@ -- * a source of random numbers -- * some algorithm specific arguments that define the security level of the resulting key. ---newPrivKey ::- -- | Algorithm name and some algorithm specific arguments.- KeyType ->- RNG ->- IO PrivKey+newPrivKey :: HasCallStack+ => KeyType -- ^ Algorithm name and some algorithm specific arguments.+ -> RNG+ -> IO PrivKey+{-# INLINABLE newPrivKey #-} newPrivKey keyTyp rng = withRNG rng $ \ rng' -> CB.withCBytes algo $ \ algo' ->@@ -470,12 +435,13 @@ (algo, args) = keyTypeToCBytes keyTyp -- | Load a private key. If the key is encrypted, password will be used to attempt decryption.-loadPrivKey ::+loadPrivKey :: HasCallStack => RNG -> V.Bytes -> -- | Password. CBytes -> IO PrivKey+{-# INLINABLE loadPrivKey #-} loadPrivKey rng buf passwd = withRNG rng $ \ rng' -> withPrimVectorUnsafe buf $ \ buf' off len ->@@ -485,13 +451,14 @@ botan_privkey_destroy -- | Get the algorithm name of a private key.-privKeyAlgoName :: PrivKey -> IO V.Bytes+privKeyAlgoName :: PrivKey -> IO T.Text+{-# INLINABLE privKeyAlgoName #-} privKeyAlgoName key =- withPrivKey key $ allocBotanBufferUnsafe 16 . botan_privkey_algo_name+ withPrivKey key $ allocBotanBufferUTF8Unsafe 16 . botan_privkey_algo_name -- | Export a private key in DER binary format. exportPrivKeyDER :: HasCallStack => PrivKey -> V.Bytes-{-# INLINE exportPrivKeyDER #-}+{-# INLINABLE exportPrivKeyDER #-} exportPrivKeyDER key = unsafePerformIO $ withPrivKey key $ \ key' -> allocBotanBufferUnsafe V.smallChunkSize $ \ buf siz ->@@ -499,16 +466,18 @@ -- | Export a private key in PEM textual format. exportPrivKeyPEM :: HasCallStack => PrivKey -> T.Text-{-# INLINE exportPrivKeyPEM #-}+{-# INLINABLE exportPrivKeyPEM #-} exportPrivKeyPEM key = unsafePerformIO $ withPrivKey key $ \ key' -> allocBotanBufferUTF8Unsafe V.smallChunkSize $ \ buf siz -> botan_privkey_export key' buf siz 1 -- | Export a private key with password.-exportPrivKeyEncryptedDER :: PrivKey -> RNG+exportPrivKeyEncryptedDER :: HasCallStack+ => PrivKey -> RNG -> CBytes -- ^ password -> IO V.Bytes+{-# INLINABLE exportPrivKeyEncryptedDER #-} exportPrivKeyEncryptedDER key rng pwd = withPrivKey key $ \ key' -> withRNG rng $ \ rng' ->@@ -518,9 +487,11 @@ botan_privkey_export_encrypted key' buf siz rng' pwd' pbe' 0 -- | Export a private key with password in PEM textual format.-exportPrivKeyEncryptedPEM :: PrivKey -> RNG+exportPrivKeyEncryptedPEM :: HasCallStack+ => PrivKey -> RNG -> CBytes -- ^ password -> IO T.Text+{-# INLINABLE exportPrivKeyEncryptedPEM #-} exportPrivKeyEncryptedPEM key rng pwd = withPrivKey key $ \ key' -> withRNG rng $ \ rng' ->@@ -531,7 +502,7 @@ -- | Export a public key from a given key pair. privKeyToPubKey :: PrivKey -> PubKey-{-# INLINE privKeyToPubKey #-}+{-# INLINABLE privKeyToPubKey #-} privKeyToPubKey (PrivKey priv) = unsafePerformIO $ do withBotanStruct priv $ \ priv' -> PubKey <$> newBotanStruct (`botan_privkey_export_pubkey` priv') botan_privkey_destroy@@ -541,7 +512,7 @@ => PrivKey -- ^ key -> CBytes -- ^ field name -> MPI-{-# INLINE privKeyParam #-}+{-# INLINABLE privKeyParam #-} privKeyParam key name = unsafeNewMPI $ \ mp -> withPrivKey key $ \ key' -> do@@ -553,21 +524,20 @@ deriving anyclass T.Print -- | Pass 'PubKey' to FFI.-withPubKey :: HasCallStack- => PubKey -> (BotanStructT -> IO r) -> IO r+withPubKey :: PubKey -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withPubKey #-} withPubKey (PubKey key) = withBotanStruct key -- | Load a publickey.-loadPubKey :: HasCallStack- => V.Bytes -> IO PubKey-{-# INLINE loadPubKey #-}+loadPubKey :: HasCallStack => V.Bytes -> IO PubKey+{-# INLINABLE loadPubKey #-} loadPubKey buf = do withPrimVectorUnsafe buf $ \ buf' off len -> PubKey <$> newBotanStruct (\ pubKey -> hs_botan_pubkey_load pubKey buf' off len) botan_pubkey_destroy -- | Export a public key in DER binary format.. exportPubKeyDER :: HasCallStack => PubKey -> V.Bytes-{-# INLINE exportPubKeyDER #-}+{-# INLINABLE exportPubKeyDER #-} exportPubKeyDER pubKey = unsafePerformIO $ withPubKey pubKey $ \ pubKey' -> allocBotanBufferUnsafe V.smallChunkSize $ \ buf siz ->@@ -575,7 +545,7 @@ -- | Export a public key in PEM textual format. exportPubKeyPEM :: HasCallStack => PubKey -> T.Text-{-# INLINE exportPubKeyPEM #-}+{-# INLINABLE exportPubKeyPEM #-} exportPubKeyPEM pubKey = unsafePerformIO $ withPubKey pubKey $ \ pubKey' -> allocBotanBufferUTF8Unsafe V.smallChunkSize $ \ buf siz ->@@ -583,7 +553,7 @@ -- | Get the algorithm name of a public key. pubKeyAlgoName :: PubKey -> CBytes-{-# INLINE pubKeyAlgoName #-}+{-# INLINABLE pubKeyAlgoName #-} pubKeyAlgoName pubKey = unsafePerformIO $ withPubKey pubKey $ \ pubKey' -> CB.fromBytes <$> allocBotanBufferUnsafe 16@@ -591,7 +561,7 @@ -- | Estimate the strength of a public key. estStrength :: PubKey -> Int-{-# INLINE estStrength #-}+{-# INLINABLE estStrength #-} estStrength pubKey = unsafePerformIO $ withPubKey pubKey $ \ pubKey' -> do (a, _) <- allocPrimUnsafe @CSize $ \ est ->@@ -600,7 +570,7 @@ -- | Fingerprint a given publickey. fingerPrintPubKey :: PubKey -> HashType -> V.Bytes-{-# INLINE fingerPrintPubKey #-}+{-# INLINABLE fingerPrintPubKey #-} fingerPrintPubKey pubKey ht = unsafePerformIO $ withPubKey pubKey $ \ pubKey' -> CB.withCBytesUnsafe (hashTypeToCBytes ht) $ \ hash' ->@@ -608,10 +578,10 @@ botan_pubkey_fingerprint pubKey' hash' buf siz -- | Read an algorithm specific field from the public key object.-pubKeyParam :: HasCallStack- => PubKey -- ^ key- -> CBytes -- ^ field name- -> MPI+pubKeyParam :: PubKey -- ^ key+ -> CBytes -- ^ field name+ -> MPI+{-# INLINABLE pubKeyParam #-} pubKeyParam pubKey name = unsafeNewMPI $ \ mp -> withPubKey pubKey $ \ pubKey' -> do@@ -632,6 +602,7 @@ -- getRSAParams :: PrivKey -> (MPI, MPI, MPI, MPI, MPI) -- ^ (p, q, n, d, e)+{-# INLINABLE getRSAParams #-} getRSAParams key = (p, q, n, d, e) where !p = privKeyParam key "p"@@ -647,13 +618,15 @@ -- getRSAPubParams :: PubKey -> (MPI, MPI) -- ^ (n, e)+{-# INLINABLE getRSAPubParams #-} getRSAPubParams key = (n, e) where !n = pubKeyParam key "n" !e = pubKeyParam key "e" -- | Initialize a RSA key pair using arguments p, q, and e.-newRSAPrivKey :: MPI -> MPI -> MPI -> PrivKey+newRSAPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey+{-# INLINABLE newRSAPrivKey #-} newRSAPrivKey p q e = unsafeWithMPI p $ \ p' -> withMPI q $ \ q' ->@@ -663,7 +636,8 @@ botan_privkey_destroy -- | Initialize a public RSA key using arguments n and e.-newRSAPubKey :: MPI -> MPI -> PubKey+newRSAPubKey :: HasCallStack => MPI -> MPI -> PubKey+{-# INLINABLE newRSAPubKey #-} newRSAPubKey n e = do unsafeWithMPI n $ \ n' -> withMPI e $ \ e' ->@@ -679,7 +653,8 @@ -- * Set x to the private key -- getDSAPrivParams :: PrivKey- -> (MPI, MPI, MPI, MPI) -- ^ (p, q, g, x)+ -> (MPI, MPI, MPI, MPI) -- ^ (p, q, g, x)+{-# INLINABLE getDSAPrivParams #-} getDSAPrivParams key = (p, q, g, x) where !p = privKeyParam key "p"@@ -688,7 +663,8 @@ !x = privKeyParam key "x" -- | Initialize a DSA key pair using arguments p, q, g and x.-newDSAPrivKey :: MPI -> MPI -> MPI -> MPI -> PrivKey+newDSAPrivKey :: HasCallStack => MPI -> MPI -> MPI -> MPI -> PrivKey+{-# INLINABLE newDSAPrivKey #-} newDSAPrivKey p q g x = unsafeWithMPI p $ \ p' -> withMPI q $ \ q' ->@@ -705,6 +681,7 @@ -- getDSAPubParams :: PubKey -> (MPI, MPI, MPI, MPI) -- ^ (p, q, g, y)+{-# INLINABLE getDSAPubParams #-} getDSAPubParams key = (p, q, g, y) where !p = pubKeyParam key "p"@@ -713,7 +690,8 @@ !y = pubKeyParam key "y" -- | Initialize a DSA public key using arguments p, q, g and y.-newDSAPubKey :: MPI -> MPI -> MPI -> MPI -> PubKey+newDSAPubKey :: HasCallStack => MPI -> MPI -> MPI -> MPI -> PubKey+{-# INLINABLE newDSAPubKey #-} newDSAPubKey p q g y = unsafeWithMPI p $ \ p' -> withMPI q $ \ q' ->@@ -734,13 +712,15 @@ -- getElGamalPrivParams :: PrivKey -> (MPI, MPI, MPI) -- ^ (p, g, x)+{-# INLINABLE getElGamalPrivParams #-} getElGamalPrivParams key = (p, g, x) where !p = privKeyParam key "p" !g = privKeyParam key "g" !x = privKeyParam key "x" -newElGamalPrivKey :: MPI -> MPI -> MPI -> PrivKey+newElGamalPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey+{-# INLINABLE newElGamalPrivKey #-} newElGamalPrivKey p g x = unsafeWithMPI p $ \ p' -> withMPI g $ \ g' ->@@ -756,13 +736,15 @@ -- getElGamalPubParams :: PubKey -> (MPI, MPI, MPI) -- ^ (p, g, y)+{-# INLINABLE getElGamalPubParams #-} getElGamalPubParams key = (p, g, y) where !p = pubKeyParam key "p" !g = pubKeyParam key "g" !y = pubKeyParam key "y" -newElGamalPubKey :: MPI -> MPI -> MPI -> PubKey+newElGamalPubKey :: HasCallStack => MPI -> MPI -> MPI -> PubKey+{-# INLINABLE newElGamalPubKey #-} newElGamalPubKey p g y = unsafeWithMPI p $ \ p' -> withMPI g $ \ g' ->@@ -782,13 +764,15 @@ -- getDHPrivParams :: PrivKey -> (MPI, MPI, MPI) -- ^ (p, g, x)+{-# INLINABLE getDHPrivParams #-} getDHPrivParams key = (p, g, x) where !p = privKeyParam key "p" !g = privKeyParam key "g" !x = privKeyParam key "x" -newDHPrivKey :: MPI -> MPI -> MPI -> PrivKey+newDHPrivKey :: HasCallStack => MPI -> MPI -> MPI -> PrivKey+{-# INLINABLE newDHPrivKey #-} newDHPrivKey p g x = do unsafeWithMPI p $ \ p' -> withMPI g $ \ g' -> withMPI x $ \ x' -> PrivKey <$> newBotanStruct (\ key -> botan_privkey_load_dh key p' g' x') botan_privkey_destroy@@ -800,13 +784,15 @@ -- getDHPubParams :: PubKey -> (MPI, MPI, MPI) -- ^ (p, g, y)+{-# INLINABLE getDHPubParams #-} getDHPubParams key = (p, g, y) where !p = pubKeyParam key "p" !g = pubKeyParam key "g" !y = pubKeyParam key "y" -newDHPubKey :: MPI -> MPI -> MPI -> PubKey+newDHPubKey :: HasCallStack => MPI -> MPI -> MPI -> PubKey+{-# INLINABLE newDHPubKey #-} newDHPubKey p g y = do unsafeWithMPI p $ \ p' -> withMPI g $ \ g' ->@@ -828,6 +814,7 @@ | EME_OAEP' HashType HashType CBytes -- ^ hash, mask gen hash, labal emeToCBytes :: EMEPadding -> CBytes+{-# INLINABLE emeToCBytes #-} emeToCBytes EME_RAW = "Raw" emeToCBytes EME_PKCS1_v1'5 = "PKCS1v15" emeToCBytes (EME_OAEP ht label)@@ -842,19 +829,31 @@ -- | Encrypt a message, returning the ciphertext. ----- Though botan support DLIES and ECIES but only EME are exported via FFI, please use an algorithm that directly--- support encryption such as RSA and ElGamal.+-- Though botan support DLIES and ECIES but only EME are exported via FFI, please use an algorithm that directly support eme encryption such as RSA and ElGamal. ---pkEncrypt :: PubKey -> EMEPadding -> RNG+pkEncrypt :: HasCallStack+ => PubKey -> EMEPadding -> RNG -> V.Bytes -- ^ plaintext -> IO V.Bytes -- ^ ciphertext-pkEncrypt pubKey padding rng ptext = do- let paddingStr = emeToCBytes padding+{-# INLINABLE pkEncrypt #-}+pkEncrypt pubKey padding = encrypt_ pubKey (emeToCBytes padding)++-- | Encrypt a message using SM2, returning the ciphertext.+sm2Encrypt :: HasCallStack+ => PubKey -> HashType -> RNG+ -> V.Bytes -- ^ plaintext+ -> IO V.Bytes -- ^ ciphertext+{-# INLINABLE sm2Encrypt #-}+sm2Encrypt pubKey ht = encrypt_ pubKey (hashTypeToCBytes ht)++encrypt_ :: HasCallStack => PubKey -> CBytes -> RNG -> V.Bytes -> IO V.Bytes+{-# INLINABLE encrypt_ #-}+encrypt_ pubKey param rng ptext = do encryptor <- withPubKey pubKey $ \ pubKey' ->- CB.withCBytesUnsafe paddingStr $ \ padding' ->+ CB.withCBytesUnsafe param $ \ param' -> newBotanStruct- (\ op -> botan_pk_op_encrypt_create op pubKey' padding' 0) -- Flags should be 0 in this version.+ (\ op -> botan_pk_op_encrypt_create op pubKey' param' 0) -- Flags should be 0 in this version. botan_pk_op_encrypt_destroy withBotanStruct encryptor $ \ op -> do@@ -866,21 +865,31 @@ allocBotanBufferUnsafe (fromIntegral len) $ \ out len' -> hs_botan_pk_op_encrypt op rng' out len' ptext' ptextOff' ptextLen' --- | Decrypt a message, returning the ciphertext.+-- | Decrypt a message, returning the plaintext. ----- Though botan support DLIES and ECIES but only EME are exported via FFI, please use an algorithm that directly--- support decryption such as RSA and ElGamal.+-- Though botan support DLIES and ECIES but only EME are exported via FFI, please use an algorithm that directly support decryption such as 'RSA' and 'ElGamal'. ---pkDecrypt :: PrivKey -> EMEPadding+pkDecrypt :: HasCallStack => PrivKey -> EMEPadding -> V.Bytes -- ^ ciphertext -> V.Bytes -- ^ plaintext-pkDecrypt key padding ctext = unsafePerformIO $ do- let paddingStr = emeToCBytes padding+{-# INLINABLE pkDecrypt #-}+pkDecrypt pubKey padding = decrypt_ pubKey (emeToCBytes padding)++-- | Decrypt a message using SM2, returning the plaintext.+sm2Decrypt :: HasCallStack => PrivKey -> HashType+ -> V.Bytes -- ^ plaintext+ -> V.Bytes -- ^ ciphertext+{-# INLINABLE sm2Decrypt #-}+sm2Decrypt privKey ht = decrypt_ privKey (hashTypeToCBytes ht)++decrypt_ :: HasCallStack => PrivKey -> CBytes -> V.Bytes -> V.Bytes+{-# INLINABLE decrypt_ #-}+decrypt_ key param ctext = unsafePerformIO $ do decryptor <- withPrivKey key $ \ key' ->- CB.withCBytesUnsafe paddingStr $ \ padding' ->+ CB.withCBytesUnsafe param $ \ param' -> newBotanStruct- (\ op -> botan_pk_op_decrypt_create op key' padding' 0) -- Flags should be 0 in this version.+ (\ op -> botan_pk_op_decrypt_create op key' param' 0) -- Flags should be 0 in this version. botan_pk_op_decrypt_destroy withBotanStruct decryptor $ \ op -> do@@ -912,6 +921,7 @@ | EMSA_Raw emsaToCBytes :: EMSA -> CBytes+{-# INLINABLE emsaToCBytes #-} emsaToCBytes (EMSA1 ht) = CB.concat ["EMSA1(", hashTypeToCBytes ht, ")"] emsaToCBytes (EMSA3_RAW (Just ht)) = CB.concat ["EMSA3(Raw,", hashTypeToCBytes ht, ")"]@@ -946,6 +956,7 @@ deriving anyclass T.Print signFmtToFlag :: SignFmt -> Word32+{-# INLINABLE signFmtToFlag #-} signFmtToFlag DER_SEQUENCE = 1 signFmtToFlag IEEE_1363 = 0 @@ -958,7 +969,8 @@ deriving (Show, Generic) deriving anyclass T.Print -newSigner :: PrivKey -> EMSA -> SignFmt -> IO Signer+newSigner :: HasCallStack => PrivKey -> EMSA -> SignFmt -> IO Signer+{-# INLINABLE newSigner #-} newSigner key emsa fmt = do let name = emsaToCBytes emsa withPrivKey key $ \ key' ->@@ -971,7 +983,8 @@ throwBotanIfMinus_ $ botan_pk_op_sign_output_length op' siz') return (Signer op name fmt (fromIntegral siz)) -updateSigner :: Signer -> V.Bytes -> IO ()+updateSigner :: HasCallStack => Signer -> V.Bytes -> IO ()+{-# INLINABLE updateSigner #-} updateSigner (Signer op _ _ _) msg = withBotanStruct op $ \ op' -> withPrimVectorUnsafe msg $ \ m moff mlen ->@@ -979,7 +992,8 @@ -- | Produce a signature over all of the bytes passed to 'Signer'. -- Afterwards, the sign operator is reset and may be used to sign a new message.-finalSigner :: Signer -> RNG -> IO V.Bytes+finalSigner :: HasCallStack => Signer -> RNG -> IO V.Bytes+{-# INLINABLE finalSigner #-} finalSigner (Signer op _ _ siz) rng = withBotanStruct op $ \ op' -> withRNG rng $ \ rng' ->@@ -987,7 +1001,7 @@ -- | Trun 'Signer' to a 'V.Bytes' sink, update 'Signer' by write bytes to the sink. ---sinkToSigner :: HasCallStack => Signer -> Sink V.Bytes+sinkToSigner :: HasCallStack => HasCallStack => Signer -> Sink V.Bytes {-# INLINABLE sinkToSigner #-} sinkToSigner h = \ k mbs -> case mbs of Just bs -> updateSigner h bs@@ -1027,7 +1041,8 @@ deriving (Show, Generic) deriving anyclass T.Print -newVerifier :: PubKey -> EMSA -> SignFmt -> IO Verifier+newVerifier :: HasCallStack => PubKey -> EMSA -> SignFmt -> IO Verifier+{-# INLINABLE newVerifier #-} newVerifier pubKey emsa fmt = do let name = emsaToCBytes emsa withPubKey pubKey $ \ pubKey' ->@@ -1037,15 +1052,15 @@ botan_pk_op_verify_destroy return (Verifier op name fmt) -updateVerifier :: Verifier -> V.Bytes -> IO ()+updateVerifier :: HasCallStack => Verifier -> V.Bytes -> IO ()+{-# INLINABLE updateVerifier #-} updateVerifier (Verifier op _ _) msg = do withBotanStruct op $ \ op' -> withPrimVectorUnsafe msg $ \ msg' off len -> throwBotanIfMinus_ $ hs_botan_pk_op_verify_update op' msg' off len -finalVerifier :: Verifier- -> V.Bytes- -> IO Bool+finalVerifier :: HasCallStack => Verifier -> V.Bytes -> IO Bool+{-# INLINABLE finalVerifier #-} finalVerifier (Verifier op _ _) msg = withBotanStruct op $ \ op' -> withPrimVectorUnsafe msg $ \ msg' off len -> do@@ -1058,7 +1073,7 @@ -- | Trun 'Verifier' to a 'V.Bytes' sink, update 'Verifier' by write bytes to the sink. -- sinkToVerifier :: HasCallStack => Verifier -> Sink V.Bytes-{-# INLINABLE sinkToVerifier #-}+{-# INLINABLE sinkToVerifier #-} sinkToVerifier h = \ k mbs -> case mbs of Just bs -> updateVerifier h bs _ -> k EOF@@ -1081,7 +1096,7 @@ -> [V.Bytes] -> V.Bytes -- ^ signature -> Bool-{-# INLINABLE verifyChunks #-}+{-# INLINABLE verifyChunks #-} verifyChunks key emsa fmt inps sig = unsafePerformIO $ do m <- newVerifier key emsa fmt mapM_ (updateVerifier m) inps@@ -1101,15 +1116,10 @@ -- | Create a new key agreement operation with a given key pair and KDF algorithm. ----- Use a key type that support key agreement, such as 'DH' or 'ECDH',--- Botan implements the following key agreement methods:--- * ECDH over GF(p) Weierstrass curves--- * ECDH over x25519--- * DH over prime fields--- * McEliece--- * NewHope+-- Please use a key type that support key agreement, such as 'DH', 'ECDH', or 'Curve25519'. ---newKeyAgreement :: PrivKey -> KDFType -> IO KeyAgreement+newKeyAgreement :: HasCallStack => PrivKey -> KDFType -> IO KeyAgreement+{-# INLINABLE newKeyAgreement #-} newKeyAgreement key kdf = withPrivKey key $ \ key' -> CB.withCBytesUnsafe (kdfTypeToCBytes kdf) $ \ kdf' -> do@@ -1121,19 +1131,22 @@ throwBotanIfMinus_ $ botan_pk_op_key_agreement_size op' siz') return (KeyAgreement op (fromIntegral siz)) -exportKeyAgreementPublic :: PrivKey -> IO V.Bytes+exportKeyAgreementPublic :: HasCallStack => PrivKey -> IO V.Bytes+{-# INLINABLE exportKeyAgreementPublic #-} exportKeyAgreementPublic key = withPrivKey key $ \ key' -> allocBotanBufferUnsafe 128 $ botan_pk_op_key_agreement_export_public key' -- | How key agreement works is that you trade public values with some other party, and then each of you runs a computation with the other’s value and your key (this should return the same result to both parties). keyAgree ::+ HasCallStack => KeyAgreement -> -- | other key V.Bytes -> -- | salt V.Bytes -> IO V.Bytes+{-# INLINABLE keyAgree #-} keyAgree (KeyAgreement op siz) others salt = withBotanStruct op $ \ op' -> withPrimVectorUnsafe others $ \ others' others_off others_len ->
Z/Crypto/PwdHash.hs view
@@ -42,10 +42,12 @@ -- -- The bcrypt work factor must be at least 4 (though at this work factor bcrypt is not very secure). The bcrypt format allows up to 31, but Botan currently rejects all work factors greater than 18 since even that work factor requires roughly 15 seconds of computation on a fast machine. ---genBcrypt :: V.Bytes -- ^ password.+genBcrypt :: HasCallStack+ => V.Bytes -- ^ password. -> RNG -> Int -- ^ work factors (4 <= n <= 18). -> IO V.Bytes+{-# INLINABLE genBcrypt #-} genBcrypt pwd rng n = do withPrimVectorUnsafe pwd $ \ pwd_p pwd_off pwd_len -> withRNG rng $ \ rng_p -> do@@ -61,9 +63,11 @@ -- | Takes a password and a bcrypt output and returns true if the password is the same as the one that was used to generate the bcrypt hash. ---validBcrypt :: V.Bytes -- ^ password.+validBcrypt :: HasCallStack+ => V.Bytes -- ^ password. -> V.Bytes -- ^ hash generated by 'genBcrypt'. -> IO Bool+{-# INLINABLE validBcrypt #-} validBcrypt pwd hash = do withPrimVectorUnsafe pwd $ \ pwd_p pwd_off pwd_l -> withPrimVectorUnsafe hash $ \ hash_p hash_off hash_l -> do
Z/Crypto/RNG.hs view
@@ -45,7 +45,8 @@ deriving anyclass T.Print -- | Initialize a random number generator object from the given 'RNGType'-newRNG :: RNGType -> IO RNG+newRNG :: HasCallStack => RNGType -> IO RNG+{-# INLINABLE newRNG #-} newRNG typ = RNG <$> newBotanStruct (\ bts -> withCBytesUnsafe (rngTypeCBytes typ) (botan_rng_init bts)) botan_rng_destroy@@ -55,7 +56,8 @@ rngTypeCBytes ProcessorRNG = "hwrng" -- | Use RNG as a `botan_rng_t` object.-withRNG :: RNG -> (BotanStructT -> IO a) -> IO a+withRNG :: HasCallStack => RNG -> (BotanStructT -> IO a) -> IO a+{-# INLINABLE withRNG #-} withRNG (RNG rng) f = withBotanStruct rng f -- | Get an autoseeded RNG from a global RNG pool divide by haskell capability.@@ -63,7 +65,8 @@ -- Botan internal use a lock to protect user-space RNG, which may cause contention if shared. -- This function will fetch an autoseeded RNG from a global RNG pool, which is recommended under -- concurrent settings.-getRNG :: IO RNG+getRNG :: HasCallStack => IO RNG+{-# INLINABLE getRNG #-} getRNG = do (cap, _) <- threadCapability =<< myThreadId rngArray <- readIORef rngArrayRef@@ -80,19 +83,22 @@ newIORef irngArray -- | Get random bytes from a random number generator.-getRandom :: RNG -> Int -> IO V.Bytes+getRandom :: HasCallStack => RNG -> Int -> IO V.Bytes+{-# INLINABLE getRandom #-} getRandom r siz = withRNG r $ \ rng -> do (b, _) <- allocPrimVectorUnsafe siz $ \ buf -> throwBotanIfMinus_ (botan_rng_get rng buf (fromIntegral siz)) return b -- | Reseeds the random number generator with bits number of bits from the 'SystemRNG'.-reseedRNG :: RNG -> Int -> IO ()+reseedRNG :: HasCallStack => RNG -> Int -> IO ()+{-# INLINABLE reseedRNG #-} reseedRNG r siz = withRNG r $ \ rng -> do throwBotanIfMinus_ (botan_rng_reseed rng (fromIntegral siz)) -- | Reseeds the random number generator with bits number of bits from the given source RNG.-reseedRNGFromRNG :: RNG -> RNG -> Int -> IO ()+reseedRNGFromRNG :: HasCallStack => RNG -> RNG -> Int -> IO ()+{-# INLINABLE reseedRNGFromRNG #-} reseedRNGFromRNG r1 r2 siz = withRNG r1 $ \ rng1 -> do withRNG r2 $ \ rng2 -> do@@ -101,7 +107,8 @@ -- | Adds the provided seed material to the internal RNG state. -- -- This call may be ignored by certain RNG instances (such as 'ProcessorRNG' or, on some systems, the 'SystemRNG').-addEntropyRNG :: RNG -> V.Bytes -> IO ()+addEntropyRNG :: HasCallStack => RNG -> V.Bytes -> IO ()+{-# INLINABLE addEntropyRNG #-} addEntropyRNG r seed = withRNG r $ \ rng -> do withPrimVectorUnsafe seed $ \ pseed offseed lseed -> do
Z/Crypto/X509.hs view
@@ -39,6 +39,8 @@ , CertStore , withCertStore , loadCertStoreFile+ , mozillaCertStore+ , systemCertStore -- * constants , KeyUsageConstraint , pattern NO_CONSTRAINTS@@ -69,6 +71,7 @@ import Z.Foreign import Z.Foreign.CPtr import System.IO.Unsafe+import Paths_Z_Botan (getDataFileName) ------------------------ -- X.509 Certificates --@@ -85,10 +88,12 @@ deriving anyclass T.Print withCert :: HasCallStack => Cert -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withCert #-} withCert (Cert cert) = withBotanStruct cert -- | Load a certificate from the DER or PEM representation. loadCert :: HasCallStack => V.Bytes -> IO Cert+{-# INLINABLE loadCert #-} loadCert cert = do withPrimVectorUnsafe cert $ \ cert' off len -> Cert <$> newBotanStruct@@ -97,6 +102,7 @@ -- | Load a certificate from a file. loadCertFile :: HasCallStack => CBytes -> IO Cert+{-# INLINABLE loadCertFile #-} loadCertFile name = do CB.withCBytesUnsafe name $ \ name' -> Cert <$> newBotanStruct@@ -105,6 +111,7 @@ -- | Create a new object that refers to the same certificate. dupCert :: HasCallStack => Cert -> IO Cert+{-# INLINABLE dupCert #-} dupCert cert = do withCert cert $ \ cert' -> Cert <$> newBotanStruct@@ -135,18 +142,21 @@ -- | Return the time the certificate becomes valid, as a 'T.Text' in form “YYYYMMDDHHMMSSZ” where Z is a literal character reflecting that this time is relative to UTC. certStartText :: Cert -> IO T.Text+{-# INLINABLE certStartText #-} certStartText cert = withCert cert $ \ cert' -> allocBotanBufferUTF8Unsafe 16 (botan_x509_cert_get_time_starts cert') -- | Return the time the certificate expires, as a 'T.Text' in form “YYYYMMDDHHMMSSZ” where Z is a literal character reflecting that this time is relative to UTC. certExpireText :: Cert -> IO T.Text+{-# INLINABLE certExpireText #-} certExpireText cert = withCert cert $ \ cert' -> allocBotanBufferUTF8Unsafe 16 (botan_x509_cert_get_time_expires cert') -- | Return the time the certificate becomes valid, as seconds since epoch. certStart :: Cert -> IO Word64+{-# INLINABLE certStart #-} certStart cert = withCert cert $ \ cert' -> do (a, _) <- allocPrimUnsafe @Word64 $ botan_x509_cert_not_before cert'@@ -154,12 +164,14 @@ -- | Return the time the certificate becomes valid. certStart' :: Cert -> IO SystemTime+{-# INLINABLE certStart' #-} certStart' cert = do !r <- fromIntegral <$> certStart cert return (MkSystemTime r 0) -- | Return the time the certificate expires, as 'SystemTime'. certExpire :: Cert -> IO Word64+{-# INLINABLE certExpire #-} certExpire cert = withCert cert $ \ cert' -> do (a, _) <- allocPrimUnsafe @Word64 $ botan_x509_cert_not_after cert'@@ -167,12 +179,14 @@ -- | Return the time the certificate expires, as 'SystemTime'. certExpire' :: Cert -> IO SystemTime+{-# INLINABLE certExpire' #-} certExpire' cert = do !r <- fromIntegral <$> certExpire cert return (MkSystemTime r 0) -- | Return the finger print of the certificate. certFingerPrint :: Cert -> HashType -> IO T.Text+{-# INLINABLE certFingerPrint #-} certFingerPrint cert ht = withCert cert $ \ cert' -> CB.withCBytesUnsafe (hashTypeToCBytes ht) $ \ ht' ->@@ -181,6 +195,7 @@ -- | Return the serial number of the certificate. certSerial :: Cert -> IO V.Bytes+{-# INLINABLE certSerial #-} certSerial cert = withCert cert $ \ cert' -> allocBotanBufferUnsafe 64 $@@ -188,6 +203,7 @@ -- | Return the authority key ID set in the certificate, which may be empty. certIDAuthority :: Cert -> IO V.Bytes+{-# INLINABLE certIDAuthority #-} certIDAuthority cert = withCert cert $ \ cert' -> allocBotanBufferUnsafe 64 $@@ -195,6 +211,7 @@ -- | Return the subject key ID set in the certificate, which may be empty. certIDSubject :: Cert -> IO V.Bytes+{-# INLINABLE certIDSubject #-} certIDSubject cert = withCert cert $ \ cert' -> allocBotanBufferUnsafe 64 $@@ -202,6 +219,7 @@ -- | Get the serialized representation of the public key included in this certificate. certPubBits :: Cert -> IO V.Bytes+{-# INLINABLE certPubBits #-} certPubBits cert = withCert cert $ \ cert' -> allocBotanBufferUnsafe V.smallChunkSize $@@ -209,34 +227,39 @@ -- | Get the public key included in this certificate. certPubKey :: Cert -> IO PubKey+{-# INLINABLE certPubKey #-} certPubKey cert = do withCert cert $ \ cert' -> PubKey <$> newBotanStruct (cert' `botan_x509_cert_get_public_key`) botan_pubkey_destroy --- | Get a value from the issuer DN field.+-- | Get a value from the issuer DN field, throw exception if not exists. certDNIssuer ::+ HasCallStack => Cert -> -- | key CBytes -> -- | index Int -> IO T.Text+{-# INLINABLE certDNIssuer #-} certDNIssuer cert key ix = withCert cert $ \ cert' -> CB.withCBytesUnsafe key $ \ key' -> do allocBotanBufferUTF8Unsafe 64 $ botan_x509_cert_get_issuer_dn cert' key' ix --- | Get a value from the subject DN field.+-- | Get a value from the subject DN field, throw exception if not exists. certDNSubject ::- Cert ->- -- | key- CBytes ->- -- | index- Int ->- IO T.Text+ HasCallStack =>+ Cert ->+ -- | key+ CBytes ->+ -- | index+ Int ->+ IO T.Text+{-# INLINABLE certDNSubject #-} certDNSubject cert key ix = withCert cert $ \ cert' -> CB.withCBytesUnsafe key $ \ key' ->@@ -244,14 +267,16 @@ botan_x509_cert_get_subject_dn cert' key' ix -- | Format the certificate as a free-form string.-certToText :: Cert -> IO T.Text+certToText :: HasCallStack => Cert -> IO T.Text+{-# INLINABLE certToText #-} certToText cert = withCert cert $ \ cert' -> T.Text . V.unsafeInit <$> allocBotanBufferUnsafe V.smallChunkSize (botan_x509_cert_to_string cert') -- | Change cert's 'KeyUsageConstraint'.-certUsage :: Cert -> KeyUsageConstraint -> IO ()+certUsage :: HasCallStack => Cert -> KeyUsageConstraint -> IO ()+{-# INLINABLE certUsage #-} certUsage cert usage = withCert cert $ \ cert' -> throwBotanIfMinus_ $ botan_x509_cert_allowed_usage cert' usage@@ -259,6 +284,7 @@ -- Verify a certificate. Returns 'Nothing' if validation was successful, 'Just reason' if unsuccessful. -- verifyCert ::+ HasCallStack => -- | Intermediate certificates, set to @[]@ if not needed. [Cert] -> -- | Trusted certificates, set to @[]@ if not needed.@@ -272,6 +298,7 @@ -- | The certificate to be verified. Cert -> IO (Maybe CBytes)+{-# INLINABLE verifyCert #-} verifyCert intermediates trusted strength hostname refTime cert = withCert cert $ \ cert' -> withCPtrsUnsafe (map certStruct intermediates) $ \ intermediates' intermediatesLen ->@@ -288,6 +315,7 @@ -- | Return a (statically allocated) CString associated with the verification result. certValidateStatus :: CInt -> CBytes+{-# INLINABLE certValidateStatus #-} certValidateStatus r = unsafeDupablePerformIO $ CB.fromCString =<< botan_x509_cert_validation_status r @@ -296,6 +324,7 @@ -- Verify a certificate. Returns 'Nothing' if validation was successful, 'Just reason' if unsuccessful. -- verifyCertCRL ::+ HasCallStack => -- | Intermediate certificates, set to @[]@ if not needed. [Cert] -> -- | Trusted certificates, set to @[]@ if not needed.@@ -311,6 +340,7 @@ -- | The certificate to be verified. Cert -> IO (Maybe CBytes)+{-# INLINABLE verifyCertCRL #-} verifyCertCRL intermediates trusted crls strength hostname refTime cert = withCert cert $ \ cert' -> withCPtrsUnsafe (map certStruct intermediates) $ \ intermediates' intermediatesLen ->@@ -332,6 +362,7 @@ -- Verify a certificate. Returns 'Nothing' if validation was successful, 'Just reason' if unsuccessful. -- verifyCertCRL' ::+ HasCallStack => -- | Intermediate certificates, set to @[]@ if not needed. [Cert] -> -- | Trusted certificates in 'CertStore'@@ -347,6 +378,7 @@ -- | The certificate to be verified. Cert -> IO (Maybe CBytes)+{-# INLINABLE verifyCertCRL' #-} verifyCertCRL' intermediates store crls strength hostname refTime cert = withCert cert $ \ cert' -> withCertStore store $ \ store' ->@@ -380,10 +412,12 @@ deriving anyclass T.Print withCRL :: HasCallStack => CRL -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withCRL #-} withCRL (CRL crl) = withBotanStruct crl -- | Load a CRL from the DER or PEM representation.-loadCRL :: V.Bytes -> IO CRL+loadCRL :: HasCallStack => V.Bytes -> IO CRL+{-# INLINABLE loadCRL #-} loadCRL src = withPrimVectorUnsafe src $ \ src' off len -> CRL <$> newBotanStruct@@ -391,7 +425,8 @@ botan_x509_crl_destroy -- | Load a CRL from a file.-loadCRLFile :: CBytes -> IO CRL+loadCRLFile :: HasCallStack => CBytes -> IO CRL+{-# INLINABLE loadCRLFile #-} loadCRLFile src = CB.withCBytesUnsafe src $ \ src' -> CRL <$> newBotanStruct@@ -400,6 +435,7 @@ -- | Check whether a given crl contains a given cert. Return True when the certificate is revoked, False otherwise. isRevokedX509 :: HasCallStack => CRL -> Cert -> IO Bool+{-# INLINABLE isRevokedX509 #-} isRevokedX509 crl cert = withCRL crl $ \ crl' -> withCert cert $ \ cert' -> do@@ -421,12 +457,32 @@ -- | Use 'CertStore' as a 'botan_x509_certstore_t'. withCertStore :: HasCallStack => CertStore -> (BotanStructT -> IO r) -> IO r+{-# INLINABLE withCertStore #-} withCertStore (CertStore c) = withBotanStruct c -- | Load a CertStore from a file.-loadCertStoreFile :: CBytes -> IO CertStore+loadCertStoreFile :: HasCallStack => CBytes -> IO CertStore+{-# INLINABLE loadCertStoreFile #-} loadCertStoreFile src = CB.withCBytesUnsafe src $ \ src' -> CertStore <$> newBotanStruct (`botan_x509_certstore_load_file` src')+ botan_x509_certstore_destroy++-- | The built-in mozilla CA 'CertStore'.+--+-- This is a certstore extracted from Mozilla, see <https://curl.se/docs/caextract.html>.+mozillaCertStore :: CertStore+{-# NOINLINE mozillaCertStore #-}+mozillaCertStore = unsafePerformIO $ do+ f <- getDataFileName "third_party/cacert.pem"+ loadCertStoreFile (CB.pack f)++-- | The CA 'CertStore' on your system.+--+systemCertStore :: CertStore+{-# NOINLINE systemCertStore #-}+systemCertStore = unsafePerformIO $ do+ CertStore <$> newBotanStruct+ botan_x509_certstore_load_system botan_x509_certstore_destroy
third_party/botan/botan_all.cpp view
file too large to diff
+ third_party/botan/doc/abi.rst view
@@ -0,0 +1,21 @@++ABI Stability+====================++Botan uses semantic versioning for the API; if API features are added the minor+version increases, whereas if API compatibility breaks occur the major version+is increased.++However no guarantees about ABI are made between releases. Maintaining an ABI+compatible release in a complex C++ API is exceedingly expensive in development+time; just adding a single member variable or virtual function is enough to+cause ABI issues.++If ABI changes, the soname revision will increase to prevent applications from+linking against a potentially incompatible version at runtime.++If you are concerned about long-term ABI issues, considering using the C API+instead; this subset *is* ABI stable.++You can review a report on ABI changes to Botan at+https://abi-laboratory.pro/tracker/timeline/botan/
+ third_party/botan/doc/api_ref/bigint.rst view
@@ -0,0 +1,279 @@+BigInt+========================================++``BigInt`` is Botan's implementation of a multiple-precision integer. Thanks to+C++'s operator overloading features, using ``BigInt`` is often quite similar to+using a native integer type. The number of functions related to ``BigInt`` is+quite large, and not all of them are documented here. You can find the complete+declarations in ``botan/bigint.h`` and ``botan/numthry.h``.++.. cpp:class:: BigInt++ .. cpp:function:: BigInt()++ Create a BigInt with value zero++ .. cpp:function:: BigInt(uint64_t n)++ Create a BigInt with value *n*++ .. cpp:function:: BigInt(const std::string& str)++ Create a BigInt from a string. By default decimal is expected. With an 0x+ prefix instead it is treated as hexadecimal.++ .. cpp:function:: BigInt(const uint8_t buf[], size_t length)++ Create a BigInt from a binary array (big-endian encoding).++ .. cpp:function:: BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true)++ Create a random BigInt of the specified size.++ .. cpp:function:: BigInt operator+(const BigInt& x, const BigInt& y)++ Add ``x`` and ``y`` and return result.++ .. cpp:function:: BigInt operator+(const BigInt& x, word y)++ Add ``x`` and ``y`` and return result.++ .. cpp:function:: BigInt operator+(word x, const BigInt& y)++ Add ``x`` and ``y`` and return result.++ .. cpp:function:: BigInt operator-(const BigInt& x, const BigInt& y)++ Subtract ``y`` from ``x`` and return result.++ .. cpp:function:: BigInt operator-(const BigInt& x, word y)++ Subtract ``y`` from ``x`` and return result.++ .. cpp:function:: BigInt operator*(const BigInt& x, const BigInt& y)++ Multiply ``x`` and ``y`` and return result.++ .. cpp:function:: BigInt operator/(const BigInt& x, const BigInt& y)++ Divide ``x`` by ``y`` and return result.++ .. cpp:function:: BigInt operator%(const BigInt& x, const BigInt& y)++ Divide ``x`` by ``y`` and return remainder.++ .. cpp:function:: word operator%(const BigInt& x, word y)++ Divide ``x`` by ``y`` and return remainder.++ .. cpp:function:: word operator<<(const BigInt& x, size_t n)++ Left shift ``x`` by ``n`` and return result.++ .. cpp:function:: word operator>>(const BigInt& x, size_t n)++ Right shift ``x`` by ``n`` and return result.++ .. cpp:function:: BigInt& operator+=(const BigInt& y)++ Add y to ``*this``++ .. cpp:function:: BigInt& operator+=(word y)++ Add y to ``*this``++ .. cpp:function:: BigInt& operator-=(const BigInt& y)++ Subtract y from ``*this``++ .. cpp:function:: BigInt& operator-=(word y)++ Subtract y from ``*this``++ .. cpp:function:: BigInt& operator*=(const BigInt& y)++ Multiply ``*this`` with y++ .. cpp:function:: BigInt& operator*=(word y)++ Multiply ``*this`` with y++ .. cpp:function:: BigInt& operator/=(const BigInt& y)++ Divide ``*this`` by y++ .. cpp:function:: BigInt& operator%=(const BigInt& y)++ Divide ``*this`` by y and set ``*this`` to the remainder.++ .. cpp:function:: word operator%=(word y)++ Divide ``*this`` by y and set ``*this`` to the remainder.++ .. cpp:function:: word operator<<=(size_t shift)++ Left shift ``*this`` by *shift* bits++ .. cpp:function:: word operator>>=(size_t shift)++ Right shift ``*this`` by *shift* bits++ .. cpp:function:: BigInt& operator++()++ Increment ``*this`` by 1++ .. cpp:function:: BigInt& operator--()++ Decrement ``*this`` by 1++ .. cpp:function:: BigInt operator++(int)++ Postfix increment ``*this`` by 1++ .. cpp:function:: BigInt operator--(int)++ Postfix decrement ``*this`` by 1++ .. cpp:function:: BigInt operator-() const++ Negation operator++ .. cpp:function:: bool operator !() const++ Return true unless ``*this`` is zero++ .. cpp:function:: void clear()++ Set ``*this`` to zero++ .. cpp:function:: size_t bytes() const++ Return number of bytes need to represent value of ``*this``++ .. cpp:function:: size_t bits() const++ Return number of bits need to represent value of ``*this``++ .. cpp:function:: bool is_even() const++ Return true if ``*this`` is even++ .. cpp:function:: bool is_odd() const++ Return true if ``*this`` is odd++ .. cpp:function:: bool is_nonzero() const++ Return true if ``*this`` is not zero++ .. cpp:function:: bool is_zero() const++ Return true if ``*this`` is zero++ .. cpp:function:: void set_bit(size_t n)++ Set bit *n* of ``*this``++ .. cpp:function:: void clear_bit(size_t n)++ Clear bit *n* of ``*this``++ .. cpp:function:: bool get_bit(size_t n) const++ Get bit *n* of ``*this``++ .. cpp:function:: uint32_t to_u32bit() const++ Return value of ``*this`` as a 32-bit integer, if possible.+ If the integer is negative or not in range, an exception is thrown.++ .. cpp:function:: bool is_negative() const++ Return true if ``*this`` is negative++ .. cpp:function:: bool is_positive() const++ Return true if ``*this`` is negative++ .. cpp:function:: BigInt abs() const++ Return absolute value of ``*this``++ .. cpp:function:: void binary_encode(uint8_t buf[]) const++ Encode this BigInt as a big-endian integer. The sign is ignored.++ .. cpp:function:: void binary_encode(uint8_t buf[], size_t len) const++ Encode this BigInt as a big-endian integer. The sign is ignored.+ If ``len`` is less than ``bytes()`` then only the low ``len``+ bytes are output. If ``len`` is greater than ``bytes()`` then+ the output is padded with leading zeros.++ .. cpp:function:: void binary_decode(uint8_t buf[])++ Decode this BigInt as a big-endian integer.++ .. cpp:function:: std::string to_dec_string() const++ Encode the integer as a decimal string.++ .. cpp:function:: std::string to_hex_string() const++ Encode the integer as a hexadecimal string.++Number Theory+----------------------------------------++Number theoretic functions available include:++.. cpp:function:: BigInt gcd(BigInt x, BigInt y)++ Returns the greatest common divisor of x and y++.. cpp:function:: BigInt lcm(BigInt x, BigInt y)++ Returns an integer z which is the smallest integer such that z % x+ == 0 and z % y == 0++.. cpp:function:: BigInt jacobi(BigInt a, BigInt n)++ Return Jacobi symbol of (a|n).++.. cpp:function:: BigInt inverse_mod(BigInt x, BigInt m)++ Returns the modular inverse of x modulo m, that is, an integer+ y such that (x*y) % m == 1. If no such y exists, returns zero.++.. cpp:function:: BigInt power_mod(BigInt b, BigInt x, BigInt m)++ Returns b to the xth power modulo m. If you are doing many+ exponentiations with a single fixed modulus, it is faster to use a+ ``Power_Mod`` implementation.++.. cpp:function:: BigInt ressol(BigInt x, BigInt p)++ Returns the square root modulo a prime, that is, returns a number y+ such that (y*y) % p == x. Returns -1 if no such integer exists.++.. cpp:function:: bool is_prime(BigInt n, RandomNumberGenerator& rng, \+ size_t prob = 56, double is_random = false)++ Test *n* for primality using a probabilistic algorithm (Miller-Rabin). With+ this algorithm, there is some non-zero probability that true will be returned+ even if *n* is actually composite. Modifying *prob* allows you to decrease the+ chance of such a false positive, at the cost of increased runtime. Sufficient+ tests will be run such that the chance *n* is composite is no more than 1 in+ 2\ :sup:`prob`. Set *is_random* to true if (and only if) *n* was randomly+ chosen (ie, there is no danger it was chosen maliciously) as far fewer tests+ are needed in that case.++.. 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+ ``equiv_mod``.
+ third_party/botan/doc/api_ref/block_cipher.rst view
@@ -0,0 +1,361 @@+Block Ciphers+=======================++Block ciphers are a n-bit permutation for some small n, typically 64 or 128+bits. They are a cryptographic primitive used to generate higher level+operations such as authenticated encryption.++.. warning::++ In almost all cases, a bare block cipher is not what you should be using.+ You probably want an authenticated cipher mode instead (see :ref:`cipher_modes`)+ This interface is used to build higher level operations (such as cipher+ modes or MACs), or in the very rare situation where ECB is required,+ eg for compatibility with an existing system.++.. cpp:class:: BlockCipher++ .. cpp:function:: static std::unique_ptr<BlockCipher> create(const std::string& algo_spec, \+ const std::string& provider = "")++ Create a new block cipher object, or else return null.++ .. cpp:function:: static std::unique_ptr<BlockCipher> create_or_throw(const std::string& algo_spec, \+ const std::string& provider = "")++ Like ``create``, except instead of returning null an exception is thrown+ if the cipher is not known.++ .. cpp:function:: void set_key(const uint8_t* key, size_t length)++ This sets the key to the value specified. Most algorithms only accept keys+ of certain lengths. If you attempt to call ``set_key`` with a key length+ that is not supported, the exception ``Invalid_Key_Length`` will be+ thrown.++ In all cases, ``set_key`` must be called on an object before any data+ processing (encryption, decryption, etc) is done by that object. If this+ is not done, an exception will be thrown.+ thrown.++ .. cpp:function:: bool valid_keylength(size_t length) const++ This function returns true if and only if *length* is a valid keylength for+ this algorithm.++ .. cpp:function:: size_t minimum_keylength() const++ Return the smallest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: size_t maximum_keylength() const++ Return the largest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: std::string name() const++ Return a human readable name for this algorithm. This is guaranteed to round-trip with+ ``create`` and ``create_or_throw`` calls, ie create("Foo")->name() == "Foo"++ .. cpp:function:: void clear()++ Zero out the key. The key must be reset before the cipher object can be used.++ .. cpp:function:: BlockCipher* clone() const++ Return a newly allocated BlockCipher object of the same type as this one.++ .. cpp:function:: size_t block_size() const++ Return the size (in *bytes*) of the cipher.++ .. cpp:function:: size_t parallelism() const++ Return the parallelism underlying this implementation of the cipher. This+ value can vary across versions and machines. A return value of N means that+ encrypting or decrypting with N blocks can operate in parallel.++ .. cpp:function:: size_t parallel_bytes() const++ Returns ``parallelism`` multiplied by the block size as well as a small+ fudge factor. That's because even ciphers that have no implicit parallelism+ typically see a small speedup for being called with several blocks due to+ caching effects.++ .. cpp:function:: std::string provider() const++ Return the provider type. Default value is "base" but can be any arbitrary string.+ Other example values are "sse2", "avx2", "openssl".++ .. cpp:function:: void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const++ Encrypt *blocks* blocks of data, taking the input from the array *in* and+ placing the ciphertext into *out*. The two pointers may be identical, but+ should not overlap ranges.++ .. cpp:function:: void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const++ Decrypt *blocks* blocks of data, taking the input from the array *in* and+ placing the plaintext into *out*. The two pointers may be identical, but+ should not overlap ranges.++ .. cpp:function:: void encrypt(const uint8_t in[], uint8_t out[]) const++ Encrypt a single block. Equivalent to :cpp:func:`encrypt_n`\ (in, out, 1).++ .. cpp:function:: void encrypt(uint8_t block[]) const++ Encrypt a single block. Equivalent to :cpp:func:`encrypt_n`\ (block, block, 1)++ .. cpp:function:: void decrypt(const uint8_t in[], uint8_t out[]) const++ Decrypt a single block. Equivalent to :cpp:func:`decrypt_n`\ (in, out, 1)++ .. cpp:function:: void decrypt(uint8_t block[]) const++ Decrypt a single block. Equivalent to :cpp:func:`decrypt_n`\ (block, block, 1)++ .. cpp:function:: template<typename Alloc> void encrypt(std::vector<uint8_t, Alloc>& block) const++ Assumes ``block`` is of a multiple of the block size.++ .. cpp:function:: template<typename Alloc> void decrypt(std::vector<uint8_t, Alloc>& block) const++ Assumes ``block`` is of a multiple of the block size.++Code Example+-----------------++For sheer demonstrative purposes, the following code encrypts a provided single+block of plaintext with AES-256 using two different keys.++.. code-block:: cpp++ #include <botan/block_cipher.h>+ #include <botan/hex.h>+ #include <iostream>+ int main ()+ {+ std::vector<uint8_t> key = Botan::hex_decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");+ std::vector<uint8_t> block = Botan::hex_decode("00112233445566778899AABBCCDDEEFF");+ std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create("AES-256"));+ cipher->set_key(key);+ cipher->encrypt(block);+ std::cout << std::endl <<cipher->name() << "single block encrypt: " << Botan::hex_encode(block);++ //clear cipher for 2nd encryption with other key+ cipher->clear();+ key = Botan::hex_decode("1337133713371337133713371337133713371337133713371337133713371337");+ cipher->set_key(key);+ cipher->encrypt(block);++ std::cout << std::endl << cipher->name() << "single block encrypt: " << Botan::hex_encode(block);+ return 0;+ }++Available Ciphers+---------------------++Botan includes a number of block ciphers that are specific to particular countries, as+well as a few that are included mostly due to their use in specific protocols such as PGP+but not widely used elsewhere. If you are developing new code and have no particular+opinion, use AES-256. If you desire an alternative to AES, consider Serpent, SHACAL2 or+Threefish.++.. warning:: Avoid any 64-bit block cipher in new designs. There are+ combinatoric issues that affect any 64-bit cipher that render it+ insecure when large amounts of data are processed.++AES+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Comes in three variants, AES-128, AES-192, and AES-256.++The standard 128-bit block cipher. Many modern platforms offer hardware+acceleration. However, on platforms without hardware support, AES+implementations typically are vulnerable to side channel attacks. For x86+systems with SSSE3 but without AES-NI, Botan has an implementation which avoids+known side channels.++Available if ``BOTAN_HAS_AES`` is defined.++ARIA+~~~~~~++South Korean cipher used in industry there. No reason to use it otherwise.++Available if ``BOTAN_HAS_ARIA`` is defined.++Blowfish+~~~~~~~~~++A 64-bit cipher popular in the pre-AES era. Very slow key setup. Also used (with+bcrypt) for password hashing.++Available if ``BOTAN_HAS_BLOWFISH`` is defined.++CAST-128+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 64-bit cipher, commonly used in OpenPGP.++Available if ``BOTAN_HAS_CAST128`` is defined.++CAST-256+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 128-bit cipher that was a contestant in the NIST AES competition.+Almost never used in practice. Prefer AES or Serpent.++Available if ``BOTAN_HAS_CAST256`` is defined.++.. warning::+ Support for CAST-256 is deprecated and will be removed in a future major release.++Camellia+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Comes in three variants, Camellia-128, Camellia-192, and Camellia-256.++A Japanese design standardized by ISO, NESSIE and CRYPTREC.+Rarely used outside of Japan.++Available if ``BOTAN_HAS_CAMELLIA`` is defined.++Cascade+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Creates a block cipher cascade, where each block is encrypted by two ciphers+with independent keys. Useful if you're very paranoid. In practice any single+good cipher (such as Serpent, SHACAL2, or AES-256) is more than sufficient.++Available if ``BOTAN_HAS_CASCADE`` is defined.++DES, 3DES, DESX+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Originally designed by IBM and NSA in the 1970s. Today, DES's 56-bit key renders+it insecure to any well-resourced attacker. DESX and 3DES extend the key length,+and are still thought to be secure, modulo the limitation of a 64-bit block.+All are somewhat common in some industries such as finance. Avoid in new code.++.. warning::+ Support for DESX is deprecated and it will be removed in a future major release.++Available if ``BOTAN_HAS_DES`` is defined.++GOST-28147-89+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Aka "Magma". An old 64-bit Russian cipher. Possible security issues, avoid+unless compatibility is needed.++Available if ``BOTAN_HAS_GOST_28147_89`` is defined.++.. warning::+ Support for this cipher is deprecated and will be removed in a future major release.++IDEA+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++An older but still unbroken 64-bit cipher with a 128-bit key. Somewhat common+due to its use in PGP. Avoid in new designs.++Available if ``BOTAN_HAS_IDEA`` is defined.++Kasumi+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 64-bit cipher used in 3GPP mobile phone protocols. There is no reason to use+it outside of this context.++Available if ``BOTAN_HAS_KASUMI`` is defined.++.. warning::+ Support for Kasumi is deprecated and will be removed in a future major release.++Lion+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A "block cipher construction" which can encrypt blocks of nearly arbitrary+length. Built from a stream cipher and a hash function. Useful in certain+protocols where being able to encrypt large or arbitrary length blocks is+necessary.++Available if ``BOTAN_HAS_LION`` is defined.++MISTY1+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 64-bit Japanese cipher standardized by NESSIE and ISO. Seemingly secure, but+quite slow and saw little adoption. No reason to use it in new code.++Available if ``BOTAN_HAS_MISTY1`` is defined.++.. warning::+ Support for MISTY1 is deprecated and will be removed in a future major release.++Noekeon+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A fast 128-bit cipher by the designers of AES. Easily secured against side+channels.++Available if ``BOTAN_HAS_NOEKEON`` is defined.++SEED+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A older South Korean cipher, widely used in industry there. No reason to choose it otherwise.++Available if ``BOTAN_HAS_SEED`` is defined.++SHACAL2+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++The 256-bit block cipher used inside SHA-256. Accepts up to a 512-bit key.+Fast, especially when SIMD or SHA-2 acceleration instructions are available.+Standardized by NESSIE but otherwise obscure.++Available if ``BOTAN_HAS_SHACAL2`` is defined.++SM4+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 128-bit Chinese national cipher, required for use in certain commercial+applications in China. Quite slow. Probably no reason to use it outside of legal+requirements.++Available if ``BOTAN_HAS_SM4`` is defined.++Serpent+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++An AES contender. Widely considered the most conservative design. Fairly slow+unless SIMD instructions are available.++Available if ``BOTAN_HAS_SERPENT`` is defined.++Threefish-512+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 512-bit tweakable block cipher that was used in the Skein hash function.+Very fast on 64-bit processors.++Available if ``BOTAN_HAS_THREEFISH_512`` is defined.++Twofish+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 128-bit block cipher that was one of the AES finalists. Has a somewhat complicated key+setup and a "kitchen sink" design.++Available if ``BOTAN_HAS_TWOFISH`` is defined.++XTEA+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++A 64-bit cipher popular for its simple implementation. Avoid in new code.++Available if ``BOTAN_HAS_XTEA`` is defined.
+ third_party/botan/doc/api_ref/cipher_modes.rst view
@@ -0,0 +1,384 @@+.. _cipher_modes:++Cipher Modes+=====================++A block cipher by itself, is only able to securely encrypt a single data block.+To be able to securely encrypt data of arbitrary length, a mode of operation+applies the block cipher's single block operation repeatedly to encrypt+an entire message.++All cipher mode implementations are are derived from the base class+:cpp:class:`Cipher_Mode`, which is declared in ``botan/cipher_mode.h``.++.. warning::+ Using an unauthenticted cipher mode without combining it with a+ :ref:`mac` is insecure. Prefer using an :ref:`aead`.++.. cpp:class:: Cipher_Mode++ .. cpp:function:: void set_key(const uint8_t* key, size_t length)++ Set the symmetric key to be used.++ .. cpp:function:: bool valid_keylength(size_t length) const++ This function returns true if and only if *length* is a valid+ keylength for the algorithm.++ .. cpp:function:: size_t minimum_keylength() const++ Return the smallest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: size_t maximum_keylength() const++ Return the largest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: size_t default_nonce_length() const++ Return the default (preferable) nonce size for this cipher mode.++ .. cpp:function:: bool valid_nonce_length(size_t nonce_len) const++ Return true if *nonce_len* is a valid length for a nonce with this+ algorithm.++ .. cpp:function:: bool authenticated() const++ Return true if this cipher mode is authenticated++ .. cpp:function:: size_t tag_size() const++ Return the length in bytes of the authentication tag this algorithm+ generates. If the mode is not authenticated, this will return 0. If the mode+ is authenticated, it will return some positive value (typically somewhere+ between 8 and 16).++ .. cpp:function:: void clear()++ Clear all internal state. The object will act exactly like one which was+ just allocated.++ .. cpp:function:: void reset()++ Reset all message state. For example if you called :cpp:func:`start_msg`,+ then :cpp:func:`process` to process some ciphertext, but then encounter an+ IO error and must abandon the current message, you can call `reset`. The+ object will retain the key (unlike calling :cpp:func:`clear` which also+ resets the key) but the nonce and current message state will be erased.++ .. cpp:function:: void start_msg(const uint8_t* nonce, size_t nonce_len)++ Set up for processing a new message. This function must be called with a new+ random value for each message. For almost all modes (excepting SIV), if the+ same nonce is ever used twice with the same key, the encryption scheme loses+ its confidentiality and/or authenticity properties.++ .. cpp:function:: void start(const std::vector<uint8_t> nonce)++ Acts like :cpp:func:`start_msg`\ (nonce.data(), nonce.size()).++ .. cpp:function:: void start(const uint8_t* nonce, size_t nonce_len)++ Acts like :cpp:func:`start_msg`\ (nonce, nonce_len).++ .. cpp:function:: virtual size_t update_granularity() const++ The :cpp:class:`Cipher_Mode` interface requires message processing in multiples of the block size.+ Returns size of required blocks to update and 1, if the mode can process messages of any length.++ .. cpp:function:: virtual size_t process(uint8_t* msg, size_t msg_len)++ Process msg in place and returns the number of bytes written. *msg* must+ be a multiple of :cpp:func:`update_granularity`.++ .. cpp:function:: void update(secure_vector<uint8_t>& buffer, size_t offset = 0)++ Continue processing a message in the buffer in place. The passed buffer's+ size must be a multiple of :cpp:func:`update_granularity`. The first+ *offset* bytes of the buffer will be ignored.++ .. cpp:function:: size_t minimum_final_size() const++ Returns the minimum size needed for :cpp:func:`finish`.++ .. cpp:function:: void finish(secure_vector<uint8_t>& final_block, size_t offset = 0)++ Finalize the message processing with a final block of at least :cpp:func:`minimum_final_size` size.+ The first *offset* bytes of the passed final block will be ignored.++Code Example+---------------------++The following code encrypts the specified plaintext using AES-128/CBC+with PKCS#7 padding.++.. warning::+ This example ignores the requirement to authenticate the ciphertext++.. note::+ Simply replacing the string "AES-128/CBC/PKCS7" string in the example below+ with "AES-128/GCM" suffices to use authenticated encryption.++.. code-block:: cpp++ #include <botan/rng.h>+ #include <botan/auto_rng.h>+ #include <botan/cipher_mode.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ Botan::AutoSeeded_RNG rng;++ const std::string plaintext("Your great-grandfather gave this watch to your granddad for good luck. Unfortunately, Dane's luck wasn't as good as his old man's.");+ const std::vector<uint8_t> key = Botan::hex_decode("2B7E151628AED2A6ABF7158809CF4F3C");++ std::unique_ptr<Botan::Cipher_Mode> enc = Botan::Cipher_Mode::create("AES-128/CBC/PKCS7", Botan::ENCRYPTION);+ enc->set_key(key);++ //generate fresh nonce (IV)+ Botan::secure_vector<uint8_t> iv = rng.random_vec(enc->default_nonce_length());++ // Copy input data to a buffer that will be encrypted+ Botan::secure_vector<uint8_t> pt(plaintext.data(), plaintext.data()+plaintext.length());++ enc->start(iv);+ enc->finish(pt);++ std::cout << enc->name() << " with iv " << Botan::hex_encode(iv) << " " << Botan::hex_encode(pt) << "\n";+ return 0;+ }+++Available Unauthenticated Cipher Modes+-----------------------------------------++.. note::+ CTR and OFB modes are also implemented, but these are treated as+ :cpp:class:`Stream_Cipher`\s instead.++CBC+~~~~~~~~~~~~++Available if ``BOTAN_HAS_MODE_CBC`` is defined.++CBC requires the plaintext be padded using a reversible rule. The following+padding schemes are implemented++PKCS#7 (RFC5652)+ The last byte in the padded block defines the padding length p, the remaining padding bytes are set to p as well.+ANSI X9.23+ The last byte in the padded block defines the padding length, the remaining padding is filled with 0x00.+OneAndZeros (ISO/IEC 7816-4)+ The first padding byte is set to 0x80, the remaining padding bytes are set to 0x00.++Ciphertext stealing (CTS) is also implemented. This scheme allows the+ciphertext to have the same length as the plaintext, however using CTS+requires the input be at least one full block plus one byte. It is+also less commonly implemented.++CFB+~~~~~~~~~~~~++Available if ``BOTAN_HAS_MODE_CFB`` is defined.++CFB uses a block cipher to create a self-synchronizing stream cipher. It is used+for example in the OpenPGP protocol. There is no reason to prefer it, as it has+worse performance characteristics than modes such as CTR or CBC.++XTS+~~~~~~~~~++Available if ``BOTAN_HAS_MODE_XTS`` is defined.++XTS is a mode specialized for encrypting disk or database storage+where ciphertext expansion is not possible. XTS requires all inputs be+at least one full block (16 bytes for AES), however for any acceptable+input length, there is no ciphertext expansion.++.. _aead:++AEAD Mode+---------------------------++AEAD (Authenticated Encryption with Associated Data) modes provide message+encryption, message authentication, and the ability to authenticate additional+data that is not included in the ciphertext (such as a sequence number or+header). It is a subclass of :cpp:class:`Cipher_Mode`.++.. cpp:class:: AEAD_Mode++ .. cpp:function:: void set_key(const SymmetricKey& key)++ Set the key++ .. cpp:function:: Key_Length_Specification key_spec() const++ Return the key length specification++ .. cpp:function:: void set_associated_data(const uint8_t ad[], size_t ad_len)++ Set any associated data for this message. For maximum portability between+ different modes, this must be called after :cpp:func:`set_key` and before+ :cpp:func:`start`.++ If the associated data does not change, it is not necessary to call this+ function more than once, even across multiple calls to :cpp:func:`start`+ and :cpp:func:`finish`.++ .. cpp:function:: void start(const uint8_t nonce[], size_t nonce_len)++ Start processing a message, using *nonce* as the unique per-message+ value. It does not need to be random, simply unique (per key).++ .. warning::+ With almost all AEADs, if the same nonce is ever used to encrypt two+ different messages under the same key, all security is lost. If+ reliably generating unique nonces is difficult in your environment,+ use SIV mode which retains security even if nonces are repeated.++ .. cpp:function:: void update(secure_vector<uint8_t>& buffer, size_t offset = 0)++ Continue processing a message. The *buffer* is an in/out parameter and+ may be resized. In particular, some modes require that all input be+ consumed before any output is produced; with these modes, *buffer* will+ be returned empty.++ On input, the buffer must be sized in blocks of size+ :cpp:func:`update_granularity`. For instance if the update granularity+ was 64, then *buffer* could be 64, 128, 192, ... bytes.++ The first *offset* bytes of *buffer* will be ignored (this allows in+ place processing of a buffer that contains an initial plaintext header)++ .. cpp:function:: void finish(secure_vector<uint8_t>& buffer, size_t offset = 0)++ Complete processing a message with a final input of *buffer*, which is+ treated the same as with :cpp:func:`update`. It must contain at least+ :cpp:func:`final_minimum_size` bytes.++ Note that if you have the entire message in hand, calling finish without+ ever calling update is both efficient and convenient.++ .. note::++ During decryption, if the supplied authentication tag does not+ validate, finish will throw an instance of Invalid_Authentication_Tag+ (aka Integrity_Failure, which was the name for this exception in+ versions before 2.10, a typedef is included for compatability).++ If this occurs, all plaintext previously output via calls to update+ must be destroyed and not used in any way that an attacker could+ observe the effects of. This could be anything from echoing the+ plaintext back (perhaps in an error message), or by making an external+ RPC whose destination or contents depend on the plaintext. The only+ thing you can do is buffer it, and in the event of an invalid tag,+ erase the previously decrypted content from memory.++ One simply way to assure this could never happen is to never+ call update, and instead always marshal the entire message+ into a single buffer and call finish on it when decrypting.++ .. cpp:function:: size_t update_granularity() const++ The AEAD interface requires :cpp:func:`update` be called with blocks of+ this size. This will be 1, if the mode can process any length inputs.++ .. cpp:function:: size_t final_minimum_size() const++ The AEAD interface requires :cpp:func:`finish` be called with at least+ this many bytes (which may be zero, or greater than+ :cpp:func:`update_granularity`)++ .. cpp:function:: bool valid_nonce_length(size_t nonce_len) const++ Returns true if *nonce_len* is a valid nonce length for this scheme. For+ EAX and GCM, any length nonces are allowed. OCB allows any value between+ 8 and 15 bytes.++ .. cpp:function:: size_t default_nonce_length() const++ Returns a reasonable length for the nonce, typically either 96+ bits, or the only supported length for modes which don't+ support 96 bit nonces.+++Available AEAD Modes+-------------------------++If in doubt about what to use, pick ChaCha20Poly1305, AES-256/GCM, or AES-256/SIV.+Both ChaCha20Poly1305 and AES with GCM are widely implemented. SIV is somewhat+more obscure (and is slower than either GCM or ChaCha20Poly1305), but has+excellent security properties.++ChaCha20Poly1305+~~~~~~~~~~~~~~~~~~++Available if ``BOTAN_HAS_AEAD_CHACHA20_POLY1305`` is defined.++Unlike the other AEADs which are based on block ciphers, this mode is based on+the ChaCha stream cipher and the Poly1305 authentication code. It is very fast+on all modern platforms.++ChaCha20Poly1305 supports 64-bit, 96-bit, and (since 2.8) 192-bit nonces. 64-bit nonces+are the "classic" ChaCha20Poly1305 design. 96-bit nonces are used by the IETF standard+version of ChaCha20Poly1305. And 192-bit nonces is the XChaCha20Poly1305 construction,+which is somewhat less common.++For best interop use the IETF version with 96-bit nonces. However 96 bits is small enough+that it can be dangerous to generate nonces randomly if more than ~ 2^32 messages are+encrypted under a single key, since if a nonce is ever reused ChaCha20Poly1305 becomes+insecure. It is better to use a counter for the nonce in this case.++If you are encrypting many messages under a single key and cannot maintain a counter for+the nonce, prefer XChaCha20Poly1305 since a 192 bit nonce is large enough that randomly+chosen nonces are extremely unlikely to repeat.++GCM+~~~~~++Available if ``BOTAN_HAS_AEAD_GCM`` is defined.++NIST standard, commonly used. Requires a 128-bit block cipher. Fairly slow,+unless hardware support for carryless multiplies is available.++OCB+~~~~~++Available if ``BOTAN_HAS_AEAD_OCB`` is defined.++A block cipher based AEAD. Supports 128-bit, 256-bit and 512-bit block ciphers.+This mode is very fast and easily secured against side channels. Adoption has+been poor because it is patented in the United States, though a license is+available allowing it to be freely used by open source software.++EAX+~~~~~++Available if ``BOTAN_HAS_AEAD_EAX`` is defined.++A secure composition of CTR mode and CMAC. Supports 128-bit, 256-bit and 512-bit+block ciphers.++SIV+~~~~~~++Available if ``BOTAN_HAS_AEAD_SIV`` is defined.++Requires a 128-bit block cipher. Unlike other AEADs, SIV is "misuse resistant";+if a nonce is repeated, SIV retains security, with the exception that if the+same nonce is used to encrypt the same message multiple times, an attacker can+detect the fact that the message was duplicated (this is simply because if both+the nonce and the message are reused, SIV will output identical ciphertexts).++CCM+~~~~~++Available if ``BOTAN_HAS_AEAD_CCM`` is defined.++A composition of CTR mode and CBC-MAC. Requires a 128-bit block cipher. This is+a NIST standard mode, but that is about all to recommend it. Prefer EAX.
+ third_party/botan/doc/api_ref/compression.rst view
@@ -0,0 +1,90 @@+Lossless Data Compression+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Some lossless data compression algorithms are available in botan, currently all+via third party libraries - these include zlib (including deflate and gzip+formats), bzip2, and lzma. Support for these must be enabled at build time;+you can check for them using the macros ``BOTAN_HAS_ZLIB``, ``BOTAN_HAS_BZIP2``,+and ``BOTAN_HAS_LZMA``.++.. note::+ You should always compress *before* you encrypt, because encryption seeks to+ hide the redundancy that compression is supposed to try to find and remove.++Compression is done through the ``Compression_Algorithm`` and+``Decompression_Algorithm`` classes, both defined in `compression.h`++Compression and decompression both work in three stages: starting a+message (``start``), continuing to process it (``update``), and then+finally completing processing the stream (``finish``).++.. cpp:class:: Compression_Algorithm++ .. cpp:function:: void start(size_t level)++ Initialize the compression engine. This must be done before calling+ ``update`` or ``finish``. The meaning of the `level` parameter varies by+ the algorithm but generally takes a value between 1 and 9, with higher+ values implying typically better compression from and more memory and/or+ CPU time consumed by the compression process. The decompressor can always+ handle input from any compressor.++ .. cpp:function:: void update(secure_vector<uint8_t>& buf, \+ size_t offset = 0, bool flush = false)++ Compress the material in the in/out parameter ``buf``. The leading+ ``offset`` bytes of ``buf`` are ignored and remain untouched; this can be+ useful for ignoring packet headers. If ``flush`` is true, the+ compression state is flushed, allowing the decompressor to recover the+ entire message up to this point without having the see the rest of the+ compressed stream.++ .. cpp::function:: void finish(secure_vector<uint8_t>& buf, size_t offset = 0)++ Finish compressing a message. The ``buf`` and ``offset`` parameters are+ treated as in ``update``. It is acceptable to call ``start`` followed by+ ``finish`` with the entire message, without any intervening call to+ ``update``.++.. cpp:class:: Decompression_Algorithm++ .. cpp:function:: void start()++ Initialize the decompression engine. This must be done before calling+ ``update`` or ``finish``. No level is provided here; the decompressor+ can accept input generated by any compression parameters.++ .. cpp:function:: void update(secure_vector<uint8_t>& buf, \+ size_t offset = 0)++ Decompress the material in the in/out parameter ``buf``. The leading+ ``offset`` bytes of ``buf`` are ignored and remain untouched; this can be+ useful for ignoring packet headers.++ This function may throw if the data seems to be invalid.++ .. cpp::function:: void finish(secure_vector<uint8_t>& buf, size_t offset = 0)++ Finish decompressing a message. The ``buf`` and ``offset`` parameters are+ treated as in ``update``. It is acceptable to call ``start`` followed by+ ``finish`` with the entire message, without any intervening call to+ ``update``.++ This function may throw if the data seems to be invalid.++The easiest way to get a compressor is via the functions++.. cpp:function:: Compression_Algorithm* make_compressor(std::string type)+.. cpp:function:: Decompression_Algorithm* make_decompressor(std::string type)++Supported values for `type` include `zlib` (raw zlib with no checksum),+`deflate` (zlib's deflate format), `gzip`, `bz2`, and `lzma`. A null pointer+will be returned if the algorithm is unavailable.++To use a compression algorithm in a `Pipe` use the adapter types+`Compression_Filter` and `Decompression_Filter` from `comp_filter.h`. The+constructors of both filters take a `std::string` argument (passed to+`make_compressor` or `make_decompressor`), the compression filter also takes a+`level` parameter. Finally both constructors have a parameter `buf_sz` which+specifies the size of the internal buffer that will be used - inputs will be+broken into blocks of this size. The default is 4096.
+ third_party/botan/doc/api_ref/contents.rst view
@@ -0,0 +1,39 @@++API Reference+===================++.. toctree::+ :maxdepth: 1++ versions+ secmem+ rng+ hash+ block_cipher+ stream_ciphers+ message_auth_codes+ cipher_modes+ pubkey+ x509+ tls+ credentials_manager+ bigint+ kdf+ pbkdf+ keywrap+ passhash+ cryptobox+ srp+ psk_db+ filters+ fpe+ tss+ ecc+ compression+ pkcs11+ tpm+ otp+ roughtime+ ffi+ env_vars+ python
+ third_party/botan/doc/api_ref/credentials_manager.rst view
@@ -0,0 +1,186 @@++Credentials Manager+==================================================++A ``Credentials_Manager`` is a way to abstract how the application+stores credentials. The main user is the :doc:`tls` implementation.++.. cpp:class:: Credentials_Manager++ .. cpp:function:: std::vector<Certificate_Store*> \+ trusted_certificate_authorities( \+ const std::string& type, \+ const std::string& context)++ Return the list of certificate stores, each of which is assumed+ to contain (only) trusted certificate authorities. The+ ``Credentials_Manager`` retains ownership of the+ Certificate_Store pointers.++ .. note::++ It would have been a better API to return a vector of+ ``shared_ptr`` here. This may change in a future major release.++ When *type* is "tls-client", *context* will be the hostname of+ the server, or empty if the hostname is not known. This allows+ using a different set of certificate stores in different contexts,+ for example using the system certificate store unless contacting+ one particular server which uses a cert issued by an internal CA.++ When *type* is "tls-server", the *context* will again be the+ hostname of the server, or empty if the client did not send a+ server name indicator. For TLS servers, these CAs are the ones+ trusted for signing of client certificates. If you do not want+ the TLS server to ask for a client cert,+ ``trusted_certificate_authorities`` should return an empty list+ for *type* "tls-server".++ The default implementation returns an empty list.++ .. cpp:function:: std::vector<X509_Certificate> find_cert_chain( \+ const std::vector<std::string>& cert_key_types, \+ const std::vector<X509_DN>& acceptable_CAs, \+ const std::string& type, \+ const std::string& context)++ Return the certificate chain to use to identify ourselves. The+ ``acceptable_CAs`` parameter gives a list of CAs the peer trusts.+ This may be empty.++ .. warning::+ If this function returns a certificate that is not one of the+ types given in ``cert_key_types`` confusing handshake+ failures will result.++ .. cpp:function:: std::vector<X509_Certificate> cert_chain( \+ const std::vector<std::string>& cert_key_types, \+ const std::string& type, \+ const std::string& context)++ Return the certificate chain to use to identify ourselves. Starting in+ 2.5, prefer ``find_cert_chain`` which additionally provides the CA list.++ .. cpp:function:: std::vector<X509_Certificate> cert_chain_single_type( \+ const std::string& cert_key_type, \+ const std::string& type, \+ const std::string& context)++ Return the certificate chain to use to identifier ourselves, if+ we have one of type *cert_key_type* and we would like to use a+ certificate in this *type*/*context*.++ .. cpp:function:: Private_Key* private_key_for(const X509_Certificate& cert, \+ const std::string& type, \+ const std::string& context)++ Return the private key for this certificate. The *cert* will be+ the leaf cert of a chain returned previously by ``cert_chain``+ or ``cert_chain_single_type``.++In versions before 1.11.34, there was an additional function on `Credentials_Manager`++ .. cpp::function:: void verify_certificate_chain( \+ const std::string& type, \+ const std::string& hostname, \+ const std::vector<X509_Certificate>& cert_chain)++This function has been replaced by `TLS::Callbacks::tls_verify_cert_chain`.++SRP Authentication+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++``Credentials_Manager`` contains the hooks used by TLS clients and+servers for SRP authentication.++.. note::++ Support for TLS-SRP is deprecated, and will be removed in a future+ major release. When that occurs these APIs will be removed. Prefer+ instead performing a standard TLS handshake, then perform a PAKE+ authentication inside of (and cryptographically bound to) the TLS+ channel.++.. cpp:function:: bool attempt_srp(const std::string& type, \+ const std::string& context)++ Returns if we should consider using SRP for authentication++.. cpp:function:: std::string srp_identifier(const std::string& type, \+ const std::string& context)++ Returns the SRP identifier we'd like to use (used by client)++.. cpp:function:: std::string srp_password(const std::string& type, \+ const std::string& context, \+ const std::string& identifier)++ Returns the password for *identifier* (used by client)++.. cpp:function:: bool srp_verifier(const std::string& type, \+ const std::string& context, \+ const std::string& identifier, \+ std::string& group_name, \+ BigInt& verifier, \+ std::vector<uint8_t>& salt, \+ bool generate_fake_on_unknown)++ Returns the SRP verifier information for *identifier* (used by server)++Preshared Keys+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++TLS supports the use of pre shared keys for authentication.++.. cpp:function:: SymmetricKey psk(const std::string& type, \+ const std::string& context, \+ const std::string& identity)++ Return a symmetric key for use with *identity*++ One important special case for ``psk`` is where *type* is+ "tls-server", *context* is "session-ticket" and *identity* is an+ empty string. If a key is returned for this case, a TLS server+ will offer session tickets to clients who can use them, and the+ returned key will be used to encrypt the ticket. The server is+ allowed to change the key at any time (though changing the key+ means old session tickets can no longer be used for resumption,+ forcing a full re-handshake when the client next connects). One+ simple approach to add support for session tickets in your server+ is to generate a random key the first time ``psk`` is called to+ retrieve the session ticket key, cache it for later use in the+ ``Credentials_Manager``, and simply let it be thrown away when the+ process terminates. See :rfc:`4507` for more information about TLS+ session tickets.++ A similar special case exists for DTLS cookie verification. In+ this case *type* will be "tls-server" and *context* is+ "dtls-cookie-secret". If no key is returned, then DTLS cookies are+ not used. Similar to the session ticket key, the DTLS cookie+ secret can be chosen during server startup and rotated at any time+ with no ill effect.++ .. warning::++ If DTLS cookies are not used then the server is prone to be+ abused as a DoS amplifier, where the attacker sends a+ relatively small client hello in a UDP packet with a forged+ return address, and then the server replies to the victim with+ several messages that are larger. This not only hides the+ attackers address from the victim, but increases their+ effective bandwidth. This is not an issue when using DTLS over+ SCTP or TCP.++.. cpp:function:: std::string psk_identity_hint(const std::string& type, \+ const std::string& context)++ Returns an identity hint which may be provided to the client. This+ can help a client understand what PSK to use.++.. cpp:function:: std::string psk_identity(const std::string& type, \+ const std::string& context, \+ const std::string& identity_hint)++ Returns the identity we would like to use given this *type* and+ *context* and the optional *identity_hint*. Not all servers or+ protocols will provide a hint.
+ third_party/botan/doc/api_ref/cryptobox.rst view
@@ -0,0 +1,32 @@++Cryptobox+========================================++Encryption using a passphrase+----------------------------------------++.. versionadded:: 1.8.6++This is a set of simple routines that encrypt some data using a+passphrase. There are defined in the header `cryptobox.h`, inside+namespace `Botan::CryptoBox`.++It generates cipher and MAC keys using 8192 iterations of PBKDF2 with+HMAC(SHA-512), then encrypts using Serpent in CTR mode and authenticates using a+HMAC(SHA-512) mac of the ciphertext, truncated to 160 bits.++ .. cpp:function:: std::string encrypt(const uint8_t input[], size_t input_len, \+ const std::string& passphrase, \+ RandomNumberGenerator& rng)++ Encrypt the contents using *passphrase*.++ .. cpp:function:: std::string decrypt(const uint8_t input[], size_t input_len, \+ const std::string& passphrase)++ Decrypts something encrypted with encrypt.++ .. cpp:function:: std::string decrypt(const std::string& input, \+ const std::string& passphrase)++ Decrypts something encrypted with encrypt.
+ third_party/botan/doc/api_ref/ecc.rst view
@@ -0,0 +1,284 @@+Elliptic Curve Operations+============================++In addition to high level operations for signatures, key agreement,+and message encryption using elliptic curve cryptography, the library+contains lower level interfaces for performing operations such as+elliptic curve point multiplication.++Only curves over prime fields are supported.++Many of these functions take a workspace, either a vector of words or+a vector of BigInts. These are used to minimize memory allocations+during common operations.++.. warning::+ You should only use these interfaces if you know what you are doing.++.. cpp:class:: EC_Group++ .. cpp:function:: EC_Group(const OID& oid)++ Initialize an ``EC_Group`` using an OID referencing the curve+ parameters.++ .. cpp:function:: EC_Group(const std::string& name)++ Initialize an ``EC_Group`` using a name or OID (for example+ "secp256r1", or "1.2.840.10045.3.1.7")++ .. cpp:function:: EC_Group(const BigInt& p, \+ const BigInt& a, \+ const BigInt& b, \+ const BigInt& base_x, \+ const BigInt& base_y, \+ const BigInt& order, \+ const BigInt& cofactor, \+ const OID& oid = OID())++ Initialize an elliptic curve group from the relevant parameters. This+ is used for example to create custom (application-specific) curves.++ .. cpp:function:: EC_Group(const std::vector<uint8_t>& ber_encoding)++ Initialize an ``EC_Group`` by decoding a DER encoded parameter block.++ .. cpp:function:: std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const++ Return the DER encoding of this group.++ .. cpp:function:: std::string PEM_encode() const++ Return the PEM encoding of this group (base64 of DER encoding plus+ header/trailer).++ .. cpp:function:: bool a_is_minus_3() const++ Return true if the ``a`` parameter is congruent to -3 mod p.++ .. cpp:function:: bool a_is_zero() const++ Return true if the ``a`` parameter is congruent to 0 mod p.++ .. cpp:function:: size_t get_p_bits() const++ Return size of the prime in bits.++ .. cpp:function:: size_t get_p_bytes() const++ Return size of the prime in bytes.++ .. cpp:function:: size_t get_order_bits() const++ Return size of the group order in bits.++ .. cpp:function:: size_t get_order_bytes() const++ Return size of the group order in bytes.++ .. cpp:function:: const BigInt& get_p() const++ Return the prime modulus.++ .. cpp:function:: const BigInt& get_a() const++ Return the ``a`` parameter of the elliptic curve equation.++ .. cpp:function:: const BigInt& get_b() const++ Return the ``b`` parameter of the elliptic curve equation.++ .. cpp:function:: const PointGFp& get_base_point() const++ Return the groups base point element.++ .. cpp:function:: const BigInt& get_g_x() const++ Return the x coordinate of the base point element.++ .. cpp:function:: const BigInt& get_g_y() const++ Return the y coordinate of the base point element.++ .. cpp:function:: const BigInt& get_order() const++ Return the order of the group generated by the base point.++ .. cpp:function:: const BigInt& get_cofactor() const++ Return the cofactor of the curve. In most cases this will be 1.++ .. cpp:function:: BigInt mod_order(const BigInt& x) const++ Reduce argument ``x`` modulo the curve order.++ .. cpp:function:: BigInt inverse_mod_order(const BigInt& x) const++ Return inverse of argument ``x`` modulo the curve order.++ .. cpp:function:: BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const++ Multiply ``x`` and ``y`` and reduce the result modulo the curve order.++ .. cpp:function:: bool verify_public_element(const PointGFp& y) const++ Return true if ``y`` seems to be a valid group element.++ .. cpp:function:: const OID& get_curve_oid() const++ Return the OID used to identify the curve. May be empty.++ .. cpp:function:: PointGFp point(const BigInt& x, const BigInt& y) const++ Create and return a point with affine elements ``x`` and ``y``. Note+ this function *does not* verify that ``x`` and ``y`` satisfy the curve+ equation.++ .. cpp:function:: PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const++ Multi-exponentiation. Returns base_point*x + pt*y. Not constant time.+ (Ordinarily used for signature verification.)++ .. cpp:function:: PointGFp blinded_base_point_multiply(const BigInt& k, \+ RandomNumberGenerator& rng, \+ std::vector<BigInt>& ws) const++ Return ``base_point*k`` in a way that attempts to resist side channels.++ .. cpp:function:: BigInt blinded_base_point_multiply_x(const BigInt& k, \+ RandomNumberGenerator& rng, \+ std::vector<BigInt>& ws) const++ Like `blinded_base_point_multiply` but returns only the x coordinate.++ .. cpp:function:: PointGFp blinded_var_point_multiply(const PointGFp& point, \+ const BigInt& k, \+ RandomNumberGenerator& rng, \+ std::vector<BigInt>& ws) const++ Return ``point*k`` in a way that attempts to resist side channels.++ .. cpp:function:: BigInt random_scalar(RandomNumberGenerator& rng) const++ Return a random scalar (ie an integer between 1 and the group order).++ .. cpp:function:: PointGFp zero_point() const++ Return the zero point (aka the point at infinity).++ .. cpp:function:: PointGFp OS2ECP(const uint8_t bits[], size_t len) const++ Decode a point from the binary encoding. This function verifies that+ the decoded point is a valid element on the curve.++ .. cpp:function:: bool verify_group(RandomNumberGenerator& rng, bool strong = false) const++ Attempt to verify the group seems valid.++ .. cpp:function:: static const std::set<std::string>& known_named_groups()++ Return a list of known groups, ie groups for which ``EC_Group(name)``+ will succeed.++.. cpp:class:: PointGFp++ Stores elliptic curve points in Jacobian representation.++ .. cpp:function:: std::vector<uint8_t> encode(PointGFp::Compression_Type format) const++ Encode a point in a way that can later be decoded with `EC_Group::OS2ECP`.++ .. cpp:function:: PointGFp& operator+=(const PointGFp& rhs)++ Point addition.++ .. cpp:function:: PointGFp& operator-=(const PointGFp& rhs)++ Point subtraction.++ .. cpp:function:: PointGFp& operator*=(const BigInt& scalar)++ Point multiplication using Montgomery ladder.++ .. warning::+ Prefer the blinded functions in ``EC_Group``++ .. cpp:function:: PointGFp& negate()++ Negate this point.++ .. cpp:function:: BigInt get_affine_x() const++ Return the affine ``x`` coordinate of the point.++ .. cpp:function:: BigInt get_affine_y() const++ Return the affine ``y`` coordinate of the point.++ .. cpp:function:: void force_affine()++ Convert the point to its equivalent affine coordinates. Throws+ if this is the point at infinity.++ .. cpp:function:: static void force_all_affine(std::vector<PointGFp>& points, \+ secure_vector<word>& ws)++ Force several points to be affine at once. Uses Montgomery's+ trick to reduce number of inversions required, so this is much+ faster than calling ``force_affine`` on each point in sequence.++ .. cpp:function:: bool is_affine() const++ Return true if this point is in affine coordinates.++ .. cpp:function:: bool is_zero() const++ Return true if this point is zero (aka point at infinity).++ .. cpp:function:: bool on_the_curve() const++ Return true if this point is on the curve.++ .. cpp:function:: void randomize_repr(RandomNumberGenerator& rng)++ Randomize the point representation.++ .. cpp:function:: bool operator==(const PointGFp& other) const++ Point equality. This compares the affine representations.++ .. cpp:function:: void add(const PointGFp& other, std::vector<BigInt>& workspace)++ Point addition, taking a workspace.++ .. cpp:function:: void add_affine(const PointGFp& other, std::vector<BigInt>& workspace)++ Mixed (Jacobian+affine) addition, taking a workspace.++ .. warning::++ This function assumes that ``other`` is affine, if this is+ not correct the result will be invalid.++ .. cpp:function:: void mult2(std::vector<BigInt>& workspace)++ Point doubling.++ .. cpp:function:: void mult2i(size_t i, std::vector<BigInt>& workspace)++ Repeated point doubling.++ .. cpp:function:: PointGFp plus(const PointGFp& other, std::vector<BigInt>& workspace) const++ Point addition, returning the result.++ .. cpp:function:: PointGFp double_of(std::vector<BigInt>& workspace) const++ Point doubling, returning the result.++ .. cpp:function:: PointGFp zero() const++ Return the point at infinity+++
+ third_party/botan/doc/api_ref/env_vars.rst view
@@ -0,0 +1,20 @@+Environment Variables+======================++Certain environment variables can affect or tune the behavior of the+library. The variables and their behavior are described here.++* ``BOTAN_THREAD_POOL_SIZE`` controls the number of threads which will be+ created for a thread pool used for some purposes within the library. If not+ set then it defaults to the number of CPUs available on the system.++* ``BOTAN_MLOCK_POOL_SIZE`` controls the total amount of memory which will be+ locked in memory using ``mlock`` or ``VirtualLock`` and managed in a memory+ pool. If set to ``0`` (or indeed any value smaller than the system page size),+ then the memory pool is disabled.++* ``BOTAN_FFI_PRINT_EXCEPTIONS`` if this variable is set (to any value), then+ if an exception is caught by the FFI layer, before returning an error code, it+ will print the text message of the exception to stderr. This is primarily+ intended for debugging.+
+ third_party/botan/doc/api_ref/ffi.rst view
@@ -0,0 +1,1203 @@++FFI (C Binding)+========================================++.. versionadded:: 1.11.14++Botan's ffi module provides a C89 binding intended to be easily usable with other+language's foreign function interface (FFI) libraries. For instance the included+Python wrapper uses Python's ``ctypes`` module and the C89 API. This API is of+course also useful for programs written directly in C.++Code examples can be found in+`the tests <https://github.com/randombit/botan/blob/master/src/tests/test_ffi.cpp>`_.++Return Codes+---------------++Almost all functions in the Botan C interface return an ``int`` error code. The+only exceptions are a handful of functions (like+:cpp:func:`botan_ffi_api_version`) which cannot fail in any circumstances.++The FFI functions return a non-negative integer (usually 0) to indicate success,+or a negative integer to represent an error. A few functions (like+:cpp:func:`botan_block_cipher_block_size`) return positive integers instead of+zero on success.++The error codes returned in certain error situations may change over time. This+especially applies to very generic errors like+:cpp:enumerator:`BOTAN_FFI_ERROR_EXCEPTION_THROWN` and+:cpp:enumerator:`BOTAN_FFI_ERROR_UNKNOWN_ERROR`. For instance, before 2.8, setting+an invalid key length resulted in :cpp:enumerator:`BOTAN_FFI_ERROR_EXCEPTION_THROWN`+but now this is specially handled and returns+:cpp:enumerator:`BOTAN_FFI_ERROR_INVALID_KEY_LENGTH` instead.++The following enum values are defined in the FFI header:++.. cpp:enumerator:: BOTAN_FFI_SUCCESS = 0++ Generally returned to indicate success++.. cpp:enumerator:: BOTAN_FFI_INVALID_VERIFIER = 1++ Note this value is positive, but still represents an error condition. In+ indicates that the function completed successfully, but the value provided+ was not correct. For example :cpp:func:`botan_bcrypt_is_valid` returns this+ value if the password did not match the hash.++.. cpp:enumerator:: BOTAN_FFI_ERROR_INVALID_INPUT = -1++ The input was invalid. (Currently this error return is not used.)++.. cpp:enumerator:: BOTAN_FFI_ERROR_BAD_MAC = -2++ While decrypting in an AEAD mode, the tag failed to verify.++.. cpp:enumerator:: BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE = -10++ Functions which write a variable amount of space return this if the indicated+ buffer length was insufficient to write the data. In that case, the output+ length parameter is set to the size that is required.++.. cpp:enumerator:: BOTAN_FFI_ERROR_EXCEPTION_THROWN = -20++ An exception was thrown while processing this request, but no further+ details are available.++ .. note::++ If the environment variable ``BOTAN_FFI_PRINT_EXCEPTIONS`` is set to any+ non-empty value, then any exception which is caught by the FFI layer will+ first print the exception message to stderr before returning an+ error. This is sometimes useful for debugging.++.. cpp:enumerator:: BOTAN_FFI_ERROR_OUT_OF_MEMORY = -21++ Memory allocation failed++.. cpp:enumerator:: BOTAN_FFI_ERROR_BAD_FLAG = -30++ A value provided in a `flag` variable was unknown.++.. cpp:enumerator:: BOTAN_FFI_ERROR_NULL_POINTER = -31++ A null pointer was provided as an argument where that is not allowed.++.. cpp:enumerator:: BOTAN_FFI_ERROR_BAD_PARAMETER = -32++ An argument did not match the function.++.. cpp:enumerator:: BOTAN_FFI_ERROR_KEY_NOT_SET = -33++ An object that requires a key normally must be keyed before use (eg before+ encrypting or MACing data). If this is not done, the operation will fail and+ return this error code.++.. cpp:enumerator:: BOTAN_FFI_ERROR_INVALID_KEY_LENGTH = -34++ An invalid key length was provided with a call to ``x_set_key``.++.. cpp:enumerator:: BOTAN_FFI_ERROR_NOT_IMPLEMENTED = -40++ This is returned if the functionality is not available for some reason. For+ example if you call :cpp:func:`botan_hash_init` with a named hash function+ which is not enabled, this error is returned.++.. cpp:enumerator:: BOTAN_FFI_ERROR_INVALID_OBJECT = -50++ This is used if an object provided did not match the function. For example+ calling :cpp:func:`botan_hash_destroy` on a ``botan_rng_t`` object will cause+ this return.++.. cpp:enumerator:: BOTAN_FFI_ERROR_UNKNOWN_ERROR = -100++ Something bad happened, but we are not sure why or how.++Versioning+----------------------------------------++.. cpp:function:: uint32_t botan_ffi_api_version()++ Returns the version of the currently supported FFI API. This is+ expressed in the form YYYYMMDD of the release date of this version+ of the API.++.. cpp:function:: int botan_ffi_supports_api(uint32_t version)++ Returns 0 iff the FFI version specified is supported by this+ library. Otherwise returns -1. The expression+ botan_ffi_supports_api(botan_ffi_api_version()) will always+ evaluate to 0. A particular version of the library may also support+ other (older) versions of the FFI API.++.. cpp:function:: const char* botan_version_string()++ Returns a free-form string describing the version. The return+ value is a statically allocated string.++.. cpp:function:: uint32_t botan_version_major()++ Returns the major version of the library++.. cpp:function:: uint32_t botan_version_minor()++ Returns the minor version of the library++.. cpp:function:: uint32_t botan_version_patch()++ Returns the patch version of the library++.. cpp:function:: uint32_t botan_version_datestamp()++ Returns the date this version was released as an integer YYYYMMDD,+ or 0 if an unreleased version+++FFI Versions+^^^^^^^^^^^^^++This maps the FFI API version to the first version of the library that+supported it.++============== ===================+FFI Version Supported Starting+============== ===================+20191214 2.13.0+20180713 2.8.0+20170815 2.3.0+20170327 2.1.0+20150515 2.0.0+============== ===================++Utility Functions+----------------------------------------++.. const char* botan_error_description(int err)++ Return a string representation of the provided error code. If the error code+ is unknown, returns the string "Unknown error". The return values are static+ constant strings and should not be freed.++.. cpp:function:: int botan_same_mem(const uint8_t* x, const uint8_t* y, size_t len)++ Returns 0 if `x[0..len] == y[0..len]`, -1 otherwise.++.. cpp:function:: int botan_hex_encode(const uint8_t* x, size_t len, char* out, uint32_t flags)++ Performs hex encoding of binary data in *x* of size *len* bytes.+ The output buffer *out* must be of at least *x*2* bytes in size.+ If *flags* contains ``BOTAN_FFI_HEX_LOWER_CASE``, hex encoding+ will only contain lower-case letters, upper-case letters otherwise.+ Returns 0 on success, 1 otherwise.++.. cpp:function:: int botan_hex_decode(const char* hex_str, size_t in_len, uint8_t* out, size_t* out_len)++ Hex decode some data++Random Number Generators+----------------------------------------++.. cpp:type:: opaque* botan_rng_t++ An opaque data type for a random number generator. Don't mess with it.++.. cpp:function:: int botan_rng_init(botan_rng_t* rng, const char* rng_type)++ Initialize a random number generator object from the given+ *rng_type*: "system" (or ``nullptr``): ``System_RNG``,+ "user": ``AutoSeeded_RNG``,+ "user-threadsafe": serialized ``AutoSeeded_RNG``,+ "null": ``Null_RNG`` (always fails),+ "hwrnd" or "rdrand": ``Processor_RNG`` (if available)++.. cpp:function:: int botan_rng_get(botan_rng_t rng, uint8_t* out, size_t out_len)++ Get random bytes from a random number generator.++.. cpp:function:: int botan_rng_reseed(botan_rng_t rng, size_t bits)++ Reseeds the random number generator with *bits* number of bits+ from the `System_RNG`.++.. cpp:function:: int botan_rng_reseed_from_rng(botan_rng_t rng, botan_rng_t src, size_t bits)++ Reseeds the random number generator with *bits* number of bits+ taken from the given source RNG.++.. cpp:function:: int botan_rng_add_entropy(botan_rng_t rng, const uint8_t seed[], size_t len)++ Adds the provided seed material to the internal RNG state.++ This call may be ignored by certain RNG instances (such as RDRAND+ or, on some systems, the system RNG).++.. cpp:function:: int botan_rng_destroy(botan_rng_t rng)++ Destroy the object created by :cpp:func:`botan_rng_init`.++Block Ciphers+----------------------------------------++.. versionadded:: 2.1.0++This is a 'raw' interface to ECB mode block ciphers. Most applications+want the higher level cipher API which provides authenticated+encryption. This API exists as an escape hatch for applications which+need to implement custom primitives using a PRP.++.. cpp:type:: opaque* botan_block_cipher_t++ An opaque data type for a block cipher. Don't mess with it.++.. cpp:function:: int botan_block_cipher_init(botan_block_cipher_t* bc, const char* cipher_name)++ Create a new cipher mode object, `cipher_name` should be for example "AES-128" or "Threefish-512"++.. cpp:function:: int botan_block_cipher_block_size(botan_block_cipher_t bc)++ Return the block size of this cipher.++.. cpp:function:: int botan_block_cipher_name(botan_block_cipher_t cipher, \+ char* name, size_t* name_len)++ Return the name of this block cipher algorithm, which may nor may not exactly+ match what was passed to :cpp:func:`botan_block_cipher_init`.++.. cpp:function:: int botan_block_cipher_get_keyspec(botan_block_cipher_t cipher, \+ size_t* out_minimum_keylength, \+ size_t* out_maximum_keylength, \+ size_t* out_keylength_modulo)++ Return the limits on the key which can be provided to this cipher. If any of the+ parameters are null, no output is written to that field. This allows retrieving only+ (say) the maximum supported keylength, if that is the only information needed.++.. cpp:function:: int botan_block_cipher_clear(botan_block_cipher_t bc)++ Clear the internal state (such as keys) of this cipher object, but do not deallocate it.++.. cpp:function:: int botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t key[], size_t key_len)++ Set the cipher key, which is required before encrypting or decrypting.++.. cpp:function:: int botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc, const uint8_t in[], uint8_t out[], size_t blocks)++ The key must have been set first with :cpp:func:`botan_block_cipher_set_key`.+ Encrypt *blocks* blocks of data stored in *in* and place the ciphertext into *out*.+ The two parameters may be the same buffer, but must not overlap.++.. cpp:function:: int botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc, const uint8_t in[], uint8_t out[], size_t blocks)++ The key must have been set first with :cpp:func:`botan_block_cipher_set_key`.+ Decrypt *blocks* blocks of data stored in *in* and place the ciphertext into *out*.+ The two parameters may be the same buffer, but must not overlap.++.. cpp:function:: int botan_block_cipher_destroy(botan_block_cipher_t rng)++ Destroy the object created by :cpp:func:`botan_block_cipher_init`.+++Hash Functions+----------------------------------------++.. cpp:type:: opaque* botan_hash_t++ An opaque data type for a hash. Don't mess with it.++.. cpp:function:: botan_hash_t botan_hash_init(const char* hash, uint32_t flags)++ Creates a hash of the given name, e.g., "SHA-384".+ Returns null on failure. Flags should always be zero in this version of the API.++.. cpp:function:: int botan_hash_destroy(botan_hash_t hash)++ Destroy the object created by :cpp:func:`botan_hash_init`.++.. cpp:function:: int botan_hash_name(botan_hash_t hash, char* name, size_t* name_len)++ Write the name of the hash function to the provided buffer.++.. cpp:function:: int botan_hash_copy_state(botan_hash_t* dest, const botan_hash_t source)++ Copies the state of the hash object to a new hash object.++.. cpp:function:: int botan_hash_clear(botan_hash_t hash)++ Reset the state of this object back to clean, as if no input has+ been supplied.++.. cpp:function:: size_t botan_hash_output_length(botan_hash_t hash)++ Return the output length of the hash function.++.. cpp:function:: int botan_hash_update(botan_hash_t hash, const uint8_t* input, size_t len)++ Add input to the hash computation.++.. cpp:function:: int botan_hash_final(botan_hash_t hash, uint8_t out[])++ Finalize the hash and place the output in out. Exactly+ :cpp:func:`botan_hash_output_length` bytes will be written.++Message Authentication Codes+----------------------------------------+.. 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.++.. cpp:function:: botan_mac_t botan_mac_init(const char* mac, uint32_t flags)++ Creates a MAC of the given name, e.g., "HMAC(SHA-384)".+ Returns null on failure. Flags should always be zero in this version of the API.++.. cpp:function:: int botan_mac_destroy(botan_mac_t mac)++ Destroy the object created by :cpp:func:`botan_mac_init`.++.. cpp:function:: int botan_mac_clear(botan_mac_t mac)++ Reset the state of this object back to clean, as if no key and input have+ been supplied.++.. cpp:function:: size_t botan_mac_output_length(botan_mac_t mac)++ Return the output length of the MAC.++.. cpp:function:: int botan_mac_set_key(botan_mac_t mac, const uint8_t* key, size_t key_len)++ Set the random key.++.. cpp:function:: int botan_mac_update(botan_mac_t mac, uint8_t buf[], size_t len)++ Add input to the MAC computation.++.. cpp:function:: int botan_mac_final(botan_mac_t mac, uint8_t out[], size_t* out_len)++ Finalize the MAC and place the output in out. Exactly+ :cpp:func:`botan_mac_output_length` bytes will be written.++Symmetric Ciphers+----------------------------------------++.. cpp:type:: opaque* botan_cipher_t++ An opaque data type for a symmetric cipher object. Don't mess with it, but do remember+ to set a random key first. And please use an AEAD.++.. cpp:function:: botan_cipher_t botan_cipher_init(const char* cipher_name, uint32_t flags)++ Create a cipher object from a name such as "AES-256/GCM" or "Serpent/OCB".++ Flags is a bitfield; the low bitof ``flags`` specifies if encrypt or decrypt,+ ie use 0 for encryption and 1 for decryption.++.. cpp:function:: int botan_cipher_destroy(botan_cipher_t cipher)++.. 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_is_authenticated(botan_cipher_t cipher)++.. cpp:function:: size_t botan_cipher_get_tag_length(botan_cipher_t cipher, size_t* tag_len)++ Write the tag length of the cipher to ``tag_len``. This will be zero for non-authenticated+ ciphers.++.. cpp:function:: int botan_cipher_valid_nonce_length(botan_cipher_t cipher, size_t nl)++ Returns 1 if the nonce length is valid, or 0 otherwise. Returns -1 on error (such as+ the cipher object being invalid).++.. cpp:function:: size_t botan_cipher_get_default_nonce_length(botan_cipher_t cipher, size_t* nl)++ Return the default nonce length++.. cpp:function:: int botan_cipher_set_associated_data(botan_cipher_t cipher, \+ const uint8_t* ad, size_t ad_len)++ Set associated data. Will fail unless the cipher is an AEAD.++.. cpp:function:: int botan_cipher_start(botan_cipher_t cipher, \+ const uint8_t* nonce, size_t nonce_len)++ Start processing a message using the provided nonce.++.. cpp:function:: int botan_cipher_update(botan_cipher_t cipher, \+ uint32_t flags, \+ uint8_t output[], \+ size_t output_size, \+ size_t* output_written, \+ const uint8_t input_bytes[], \+ size_t input_size, \+ size_t* input_consumed)++ Encrypt or decrypt data.++PBKDF+----------------------------------------++.. cpp:function:: int botan_pbkdf(const char* pbkdf_algo, \+ uint8_t out[], size_t out_len, \+ const char* passphrase, \+ const uint8_t salt[], size_t salt_len, \+ size_t iterations)++ Derive a key from a passphrase for a number of iterations+ using the given PBKDF algorithm, e.g., "PBKDF2".++.. cpp:function:: int botan_pbkdf_timed(const char* pbkdf_algo, \+ uint8_t out[], size_t out_len, \+ const char* passphrase, \+ const uint8_t salt[], size_t salt_len, \+ size_t milliseconds_to_run, \+ size_t* out_iterations_used)++ Derive a key from a passphrase using the given PBKDF algorithm,+ e.g., "PBKDF2". If *out_iterations_used* is zero, instead the+ PBKDF is run until *milliseconds_to_run* milliseconds have passed.+ In this case, the number of iterations run will be written to+ *out_iterations_used*.++KDF+----------------------------------------++.. cpp:function:: int botan_kdf(const char* kdf_algo, \+ uint8_t out[], size_t out_len, \+ const uint8_t secret[], size_t secret_len, \+ const uint8_t salt[], size_t salt_len, \+ const uint8_t label[], size_t label_len)++ Derive a key using the given KDF algorithm, e.g., "SP800-56C".+ The derived key of length *out_len* bytes will be placed in *out*.++Multiple Precision Integers+----------------------------------------++.. versionadded: 2.1.0++.. cpp:type:: opaque* botan_mp_t++ An opaque data type for a multiple precision integer. Don't mess with it.++.. cpp:function:: int botan_mp_init(botan_mp_t* mp)++ Initialize a ``botan_mp_t``. Initial value is zero, use `botan_mp_set_X` to load a value.++.. cpp:function:: int botan_mp_destroy(botan_mp_t mp)++ Free a ``botan_mp_t``++.. cpp:function:: int botan_mp_to_hex(botan_mp_t mp, char* out)++ Writes exactly ``botan_mp_num_bytes(mp)*2 + 1`` bytes to out++.. cpp:function:: int botan_mp_to_str(botan_mp_t mp, uint8_t base, char* out, size_t* out_len)++ Base can be either 10 or 16.++.. cpp:function:: int botan_mp_set_from_int(botan_mp_t mp, int initial_value)++ Set ``botan_mp_t`` from an integer value.++.. cpp:function:: int botan_mp_set_from_mp(botan_mp_t dest, botan_mp_t source)++ Set ``botan_mp_t`` from another MP.++.. cpp:function:: int botan_mp_set_from_str(botan_mp_t dest, const char* str)++ Set ``botan_mp_t`` from a string. Leading prefix of "0x" is accepted.++.. cpp:function:: int botan_mp_num_bits(botan_mp_t n, size_t* bits)++ Return the size of ``n`` in bits.++.. cpp:function:: int botan_mp_num_bytes(botan_mp_t n, size_t* uint8_ts)++ Return the size of ``n`` in bytes.++.. cpp:function:: int botan_mp_to_bin(botan_mp_t mp, uint8_t vec[])++ Writes exactly ``botan_mp_num_bytes(mp)`` to ``vec``.++.. cpp:function:: int botan_mp_from_bin(botan_mp_t mp, const uint8_t vec[], size_t vec_len)++ Loads ``botan_mp_t`` from a binary vector (as produced by ``botan_mp_to_bin``).++.. cpp:function:: int botan_mp_is_negative(botan_mp_t mp)++ Return 1 if ``mp`` is negative, otherwise 0.++.. cpp:function:: int botan_mp_flip_sign(botan_mp_t mp)++ Flip the sign of ``mp``.++.. cpp:function:: int botan_mp_add(botan_mp_t result, botan_mp_t x, botan_mp_t y)++ Add two ``botan_mp_t`` and store the output in ``result``.++.. cpp:function:: int botan_mp_sub(botan_mp_t result, botan_mp_t x, botan_mp_t y)++ Subtract two ``botan_mp_t`` and store the output in ``result``.++.. cpp:function:: int botan_mp_mul(botan_mp_t result, botan_mp_t x, botan_mp_t y)++ Multiply two ``botan_mp_t`` and store the output in ``result``.++.. cpp:function:: int botan_mp_div(botan_mp_t quotient, botan_mp_t remainder, \+ botan_mp_t x, botan_mp_t y)++ Divide ``x`` by ``y`` and store the output in ``quotient`` and ``remainder``.++.. cpp:function:: int botan_mp_mod_mul(botan_mp_t result, botan_mp_t x, botan_mp_t y, botan_mp_t mod)++ Set ``result`` to ``x`` times ``y`` modulo ``mod``.++.. cpp:function:: int botan_mp_equal(botan_mp_t x, botan_mp_t y)++ Return 1 if ``x`` is equal to ``y``, 0 if ``x`` is not equal to ``y``++.. cpp:function:: int botan_mp_is_zero(const botan_mp_t x)++ Return 1 if ``x`` is equal to zero, otherwise 0.++.. cpp:function:: int botan_mp_is_odd(const botan_mp_t x)++ Return 1 if ``x`` is odd, otherwise 0.++.. cpp:function:: int botan_mp_is_even(const botan_mp_t x)++ Return 1 if ``x`` is even, otherwise 0.++.. cpp:function:: int botan_mp_is_positive(const botan_mp_t x)++ Return 1 if ``x`` is greater than or equal to zero.++.. cpp:function:: int botan_mp_is_negative(const botan_mp_t x)++ Return 1 if ``x`` is less than zero.++.. cpp:function:: int botan_mp_to_uint32(const botan_mp_t x, uint32_t* val)++ If x fits in a 32-bit integer, set val to it and return 0. If x is out of+ range an error is returned.++.. cpp:function:: int botan_mp_cmp(int* result, botan_mp_t x, botan_mp_t y)++ Three way comparison: set result to -1 if ``x`` is less than ``y``,+ 0 if ``x`` is equal to ``y``, and 1 if ``x`` is greater than ``y``.++.. cpp:function:: int botan_mp_swap(botan_mp_t x, botan_mp_t y)++ Swap two ``botan_mp_t`` values.++.. cpp:function:: int botan_mp_powmod(botan_mp_t out, botan_mp_t base, botan_mp_t exponent, botan_mp_t modulus)++ Modular exponentiation.++.. cpp:function:: int botan_mp_lshift(botan_mp_t out, botan_mp_t in, size_t shift)++ Left shift by specified bit count, place result in ``out``.++.. cpp:function:: int botan_mp_rshift(botan_mp_t out, botan_mp_t in, size_t shift)++ Right shift by specified bit count, place result in ``out``.++.. cpp:function:: int botan_mp_mod_inverse(botan_mp_t out, botan_mp_t in, botan_mp_t modulus)++ Compute modular inverse. If no modular inverse exists (for instance because ``in`` and+ ``modulus`` are not relatively prime), then sets ``out`` to -1.++.. cpp:function:: int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)++ Create a random ``botan_mp_t`` of the specified bit size.++.. cpp:function:: int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng, \+ botan_mp_t lower_bound, botan_mp_t upper_bound)++ Create a random ``botan_mp_t`` within the provided range.++.. cpp:function:: int botan_mp_gcd(botan_mp_t out, botan_mp_t x, botan_mp_t y)++ Compute the greatest common divisor of ``x`` and ``y``.++.. cpp:function:: int botan_mp_is_prime(botan_mp_t n, botan_rng_t rng, size_t test_prob)++ Test if ``n`` is prime. The algorithm used (Miller-Rabin) is probabilistic,+ set ``test_prob`` to the desired assurance level. For example if+ ``test_prob`` is 64, then sufficient Miller-Rabin iterations will run to+ assure there is at most a ``1/2**64`` chance that ``n`` is composite.++.. cpp:function:: int botan_mp_get_bit(botan_mp_t n, size_t bit)++ Returns 0 if the specified bit of ``n`` is not set, 1 if it is set.++.. cpp:function:: int botan_mp_set_bit(botan_mp_t n, size_t bit)++ Set the specified bit of ``n``++.. cpp:function:: int botan_mp_clear_bit(botan_mp_t n, size_t bit)++ Clears the specified bit of ``n``+++Password Hashing+----------------------------------------++.. cpp:function:: int botan_bcrypt_generate(uint8_t* out, size_t* out_len, \+ const char* password, \+ botan_rng_t rng, \+ size_t work_factor, \+ uint32_t flags)++ Create a password hash using Bcrypt.+ The output buffer *out* should be of length 64 bytes.+ The output is formatted bcrypt $2a$...++.. cpp:function:: int botan_bcrypt_is_valid(const char* pass, const char* hash)++ Check a previously created password hash. Returns+ :cpp:enumerator:`BOTAN_SUCCESS` if if this password/hash+ combination is valid, :cpp:enumerator:`BOTAN_FFI_INVALID_VERIFIER`+ if the combination is not valid (but otherwise well formed),+ negative on error.++Public Key Creation, Import and Export+----------------------------------------++.. cpp:type:: opaque* botan_privkey_t++ An opaque data type for a private key. Don't mess with it.++.. cpp:function:: int botan_privkey_create(botan_privkey_t* key, \+ const char* algo_name, \+ const char* algo_params, \+ botan_rng_t rng)++.. cpp:function:: int botan_privkey_create_rsa(botan_privkey_t* key, botan_rng_t rng, size_t n_bits)++ Create an RSA key of the given size++.. cpp:function:: int botan_privkey_create_ecdsa(botan_privkey_t* key, botan_rng_t rng, const char* curve)++ Create a ECDSA key of using a named curve++.. cpp:function:: int botan_privkey_create_ecdh(botan_privkey_t* key, botan_rng_t rng, const char* curve)++ Create a ECDH key of using a named curve++.. cpp:function:: int botan_privkey_create_mceliece(botan_privkey_t* key, botan_rng_t rng, size_t n, size_t t)++ Create a McEliece key using the specified parameters. See+ :ref:`mceliece` for details on choosing parameters.++.. cpp:function:: int botan_privkey_create_dh(botan_privkey_t* key, botan_rng_t rng, const char* params)++ Create a finite field Diffie-Hellman key using the specified named group, for example+ "modp/ietf/3072".++.. cpp:function:: int botan_privkey_load(botan_privkey_t* key, botan_rng_t rng, \+ const uint8_t bits[], size_t len, \+ const char* password)++ Load a private key. If the key is encrypted, ``password`` will be+ used to attempt decryption.++.. cpp:function:: int botan_privkey_destroy(botan_privkey_t key)++ Destroy the object.++.. cpp:function:: int botan_privkey_export(botan_privkey_t key, \+ uint8_t out[], size_t* out_len, \+ uint32_t flags)++ Export a public key. If flags is 1 then PEM format is used.++.. cpp:function:: int botan_privkey_export_encrypted(botan_privkey_t key, \+ uint8_t out[], size_t* out_len, \+ botan_rng_t rng, \+ const char* passphrase, \+ const char* encryption_algo, \+ uint32_t flags)++ Deprecated, use ``botan_privkey_export_encrypted_msec`` or ``botan_privkey_export_encrypted_iter``++.. cpp::function:: int botan_privkey_export_encrypted_pbkdf_msec(botan_privkey_t key,+ uint8_t out[], size_t* out_len, \+ botan_rng_t rng, \+ const char* passphrase, \+ uint32_t pbkdf_msec_runtime, \+ size_t* pbkdf_iterations_out, \+ const char* cipher_algo, \+ const char* pbkdf_algo, \+ uint32_t flags);++ Encrypt a key, running the key derivation function for ``pbkdf_msec_runtime`` milliseconds.+ Returns the number of iterations used in ``pbkdf_iterations_out``.++ ``cipher_algo`` must specify a CBC mode cipher (such as "AES-128/CBC") or as+ a Botan-specific extension a GCM mode may be used.++.. cpp::function:: int botan_privkey_export_encrypted_pbkdf_iter(botan_privkey_t key, \+ uint8_t out[], size_t* out_len, \+ botan_rng_t rng, \+ const char* passphrase, \+ size_t pbkdf_iterations, \+ const char* cipher_algo, \+ const char* pbkdf_algo, \+ uint32_t flags);++ Encrypt a private key. The PBKDF function runs for the specified number of iterations.+ At least 100,000 is recommended.++.. cpp:function:: int botan_privkey_export_pubkey(botan_pubkey_t* out, botan_privkey_t in)++.. cpp:function:: int botan_privkey_get_field(botan_mp_t output, \+ botan_privkey_t key, \+ const char* field_name)++ Read an algorithm specific field from the private key object, placing it into output.+ For example "p" or "q" for RSA keys, or "x" for DSA keys or ECC keys.++.. cpp:type:: opaque* botan_pubkey_t++ An opaque data type for a public key. Don't mess with it.++.. cpp:function:: int botan_pubkey_load(botan_pubkey_t* key, const uint8_t bits[], size_t len)++.. cpp:function:: int botan_pubkey_export(botan_pubkey_t key, uint8_t out[], size_t* out_len, uint32_t flags)++.. cpp:function:: int botan_pubkey_algo_name(botan_pubkey_t key, char out[], size_t* out_len)++.. cpp:function:: int botan_pubkey_estimated_strength(botan_pubkey_t key, size_t* estimate)++.. cpp:function:: int botan_pubkey_fingerprint(botan_pubkey_t key, const char* hash, \+ uint8_t out[], size_t* out_len)++.. cpp:function:: int botan_pubkey_destroy(botan_pubkey_t key)++.. cpp:function:: int botan_pubkey_get_field(botan_mp_t output, \+ botan_pubkey_t key, \+ const char* field_name)++ Read an algorithm specific field from the public key object, placing it into output.+ For example "n" or "e" for RSA keys or "p", "q", "g", and "y" for DSA keys.++RSA specific functions+----------------------------------------++.. cpp:function:: int botan_privkey_rsa_get_p(botan_mp_t p, botan_privkey_t rsa_key)++ Set ``p`` to the first RSA prime.++.. cpp:function:: int botan_privkey_rsa_get_q(botan_mp_t q, botan_privkey_t rsa_key)++ Set ``q`` to the second RSA prime.++.. cpp:function:: int botan_privkey_rsa_get_d(botan_mp_t d, botan_privkey_t rsa_key)++ Set ``d`` to the RSA private exponent.++.. cpp:function:: int botan_privkey_rsa_get_n(botan_mp_t n, botan_privkey_t rsa_key)++ Set ``n`` to the RSA modulus.++.. cpp:function:: int botan_privkey_rsa_get_e(botan_mp_t e, botan_privkey_t rsa_key)++ Set ``e`` to the RSA public exponent.++.. cpp:function:: int botan_pubkey_rsa_get_e(botan_mp_t e, botan_pubkey_t rsa_key)++ Set ``e`` to the RSA public exponent.++.. cpp:function:: int botan_pubkey_rsa_get_n(botan_mp_t n, botan_pubkey_t rsa_key)++ Set ``n`` to the RSA modulus.++.. cpp:function:: int botan_privkey_load_rsa(botan_privkey_t* key, \+ botan_mp_t p, botan_mp_t q, botan_mp_t e)++ Initialize a private RSA key using parameters p, q, and e.++.. cpp:function:: int botan_pubkey_load_rsa(botan_pubkey_t* key, \+ botan_mp_t n, botan_mp_t e)++ Initialize a public RSA key using parameters n and e.++DSA specific functions+----------------------------------------++.. cpp:function:: int botan_privkey_load_dsa(botan_privkey_t* key, \+ botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t x)++ Initialize a private DSA key using group parameters p, q, and g and private key x.++.. cpp:function:: int botan_pubkey_load_dsa(botan_pubkey_t* key, \+ botan_mp_t p, botan_mp_t q, botan_mp_t g, botan_mp_t y)++ Initialize a private DSA key using group parameters p, q, and g and public key y.++ElGamal specific functions+----------------------------------------++.. cpp:function:: int botan_privkey_load_elgamal(botan_privkey_t* key, \+ botan_mp_t p, botan_mp_t g, botan_mp_t x)++ Initialize a private ElGamal key using group parameters p and g and private key x.++.. cpp:function:: int botan_pubkey_load_elgamal(botan_pubkey_t* key, \+ botan_mp_t p, botan_mp_t g, botan_mp_t y)++ Initialize a public ElGamal key using group parameters p and g and public key y.++Diffie-Hellman specific functions+----------------------------------------++.. cpp:function:: int botan_privkey_load_dh(botan_privkey_t* key, \+ botan_mp_t p, botan_mp_t g, botan_mp_t x)++ Initialize a private Diffie-Hellman key using group parameters p and g and private key x.++.. cpp:function:: int botan_pubkey_load_dh(botan_pubkey_t* key, \+ botan_mp_t p, botan_mp_t g, botan_mp_t y)++ Initialize a public Diffie-Hellman key using group parameters p and g and public key y.++Public Key Encryption/Decryption+----------------------------------------++.. cpp:type:: opaque* botan_pk_op_encrypt_t++ An opaque data type for an encryption operation. Don't mess with it.++.. cpp:function:: int botan_pk_op_encrypt_create(botan_pk_op_encrypt_t* op, \+ botan_pubkey_t key, \+ const char* padding, \+ uint32_t flags)++ Create a new operation object which can be used to encrypt using the provided+ key and the specified padding scheme (such as "OAEP(SHA-256)" for use with+ RSA). Flags should be 0 in this version.++.. cpp:function:: int botan_pk_op_encrypt_destroy(botan_pk_op_encrypt_t op)++ Destroy the object.++.. cpp:function:: int botan_pk_op_encrypt_output_length(botan_pk_op_encrypt_t op, \+ size_t ptext_len, size_t* ctext_len)++ Returns an upper bound on the output length if a plaintext of length ``ptext_len``+ is encrypted with this key/parameter setting. This allows correctly sizing the+ buffer that is passed to :cpp:func:`botan_pk_op_encrypt`.++.. cpp:function:: int botan_pk_op_encrypt(botan_pk_op_encrypt_t op, \+ botan_rng_t rng, \+ uint8_t out[], size_t* out_len, \+ const uint8_t plaintext[], size_t plaintext_len)++ Encrypt the provided data using the key, placing the output in `out`. If+ `out` is NULL, writes the length of what the ciphertext would have been to+ `*out_len`. However this is computationally expensive (the encryption+ actually occurs, then the result is discarded), so it is better to use+ :cpp:func:`botan_pk_op_encrypt_output_length` to correctly size the buffer.++.. cpp:type:: opaque* botan_pk_op_decrypt_t++ An opaque data type for a decryption operation. Don't mess with it.++.. cpp:function:: int botan_pk_op_decrypt_create(botan_pk_op_decrypt_t* op, \+ botan_privkey_t key, \+ const char* padding, \+ uint32_t flags)++.. cpp:function:: int botan_pk_op_decrypt_destroy(botan_pk_op_decrypt_t op)++.. cpp:function:: int botan_pk_op_decrypt_output_length(botan_pk_op_decrypt_t op, \+ size_t ctext_len, size_t* ptext_len)++ For a given ciphertext length, returns the upper bound on the size of the+ plaintext that might be enclosed. This allows properly sizing the output+ buffer passed to :cpp:func:`botan_pk_op_decrypt`.++.. cpp:function:: int botan_pk_op_decrypt(botan_pk_op_decrypt_t op, \+ uint8_t out[], size_t* out_len, \+ uint8_t ciphertext[], size_t ciphertext_len)++Signature Generation+----------------------------------------++.. cpp:type:: opaque* botan_pk_op_sign_t++ An opaque data type for a signature generation operation. Don't mess with it.++.. cpp:function:: int botan_pk_op_sign_create(botan_pk_op_sign_t* op, \+ botan_privkey_t key, \+ const char* hash_and_padding, \+ uint32_t flags)++ Create a signature operator for the provided key. The padding string+ specifies what hash function and padding should be used, for example+ "PKCS1v15(SHA-256)" or "EMSA1(SHA-384)".++.. cpp:function:: int botan_pk_op_sign_destroy(botan_pk_op_sign_t op)++ Destroy an object created by :cpp:func:`botan_pk_op_sign_create`.++.. cpp:function:: int botan_pk_op_sign_output_length(botan_pk_op_sign_t op, size_t* sig_len)++ Writes the length of the signatures that this signer will produce. This+ allows properly sizing the buffer passed to+ :cpp:func:`botan_pk_op_sign_finish`.++.. cpp:function:: int botan_pk_op_sign_update(botan_pk_op_sign_t op, \+ const uint8_t in[], size_t in_len)++ Add bytes of the message to be signed.++.. cpp:function:: int botan_pk_op_sign_finish(botan_pk_op_sign_t op, botan_rng_t rng, \+ uint8_t sig[], size_t* sig_len)++ Produce a signature over all of the bytes passed to :cpp:func:`botan_pk_op_sign_update`.+ Afterwards, the sign operator is reset and may be used to sign a new message.++Signature Verification+----------------------------------------++.. cpp:type:: opaque* botan_pk_op_verify_t++ An opaque data type for a signature verification operation. Don't mess with it.++.. cpp:function:: int botan_pk_op_verify_create(botan_pk_op_verify_t* op, \+ botan_pubkey_t key, \+ const char* hash_and_padding, \+ uint32_t flags)++.. cpp:function:: int botan_pk_op_verify_destroy(botan_pk_op_verify_t op)++.. cpp:function:: int botan_pk_op_verify_update(botan_pk_op_verify_t op, \+ const uint8_t in[], size_t in_len)++ Add bytes of the message to be verified++.. cpp:function:: int botan_pk_op_verify_finish(botan_pk_op_verify_t op, \+ const uint8_t sig[], size_t sig_len)++ Verify if the signature provided matches with the message provided as calls+ to :cpp:func:`botan_pk_op_verify_update`.++Key Agreement+----------------------------------------++.. cpp:type:: opaque* botan_pk_op_ka_t++ An opaque data type for a key agreement operation. Don't mess with it.++.. cpp:function:: int botan_pk_op_key_agreement_create(botan_pk_op_ka_t* op, \+ botan_privkey_t key, \+ const char* kdf, \+ uint32_t flags)++.. cpp:function:: int botan_pk_op_key_agreement_destroy(botan_pk_op_ka_t op)++.. cpp:function:: int botan_pk_op_key_agreement_export_public(botan_privkey_t key, \+ uint8_t out[], size_t* out_len)++.. cpp:function:: int botan_pk_op_key_agreement(botan_pk_op_ka_t op, \+ uint8_t out[], size_t* out_len, \+ const uint8_t other_key[], size_t other_key_len, \+ const uint8_t salt[], size_t salt_len)++.. cpp:function:: int botan_mceies_encrypt(botan_pubkey_t mce_key, \+ botan_rng_t rng, \+ const char* aead, \+ const uint8_t pt[], size_t pt_len, \+ const uint8_t ad[], size_t ad_len, \+ uint8_t ct[], size_t* ct_len)++.. cpp:function:: int botan_mceies_decrypt(botan_privkey_t mce_key, \+ const char* aead, \+ const uint8_t ct[], size_t ct_len, \+ const uint8_t ad[], size_t ad_len, \+ uint8_t pt[], size_t* pt_len)++X.509 Certificates+----------------------------------------++.. cpp:type:: opaque* botan_x509_cert_t++ An opaque data type for an X.509 certificate. Don't mess with it.++.. cpp:function:: int botan_x509_cert_load(botan_x509_cert_t* cert_obj, \+ const uint8_t cert[], size_t cert_len)++ Load a certificate from the DER or PEM representation++.. cpp:function:: int botan_x509_cert_load_file(botan_x509_cert_t* cert_obj, const char* filename)++ Load a certificate from a file.++.. cpp:function:: int botan_x509_cert_dup(botan_x509_cert_t* cert_obj, botan_x509_cert_t cert)++ Create a new object that refers to the same certificate.++.. cpp:function:: int botan_x509_cert_destroy(botan_x509_cert_t cert)++ Destroy the certificate object++.. cpp:function:: int botan_x509_cert_gen_selfsigned(botan_x509_cert_t* cert, \+ botan_privkey_t key, \+ botan_rng_t rng, \+ const char* common_name, \+ const char* org_name)++.. cpp:function:: int botan_x509_cert_get_time_starts(botan_x509_cert_t cert, char out[], size_t* out_len)++ Return the time the certificate becomes valid, as a string in form+ "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is+ relative to UTC. Prefer :cpp:func:`botan_x509_cert_not_before`.++.. cpp:function:: int botan_x509_cert_get_time_expires(botan_x509_cert_t cert, char out[], size_t* out_len)++ Return the time the certificate expires, as a string in form+ "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is+ relative to UTC. Prefer :cpp:func:`botan_x509_cert_not_after`.++.. cpp:function:: int botan_x509_cert_not_before(botan_x509_cert_t cert, uint64_t* time_since_epoch)++ Return the time the certificate becomes valid, as seconds since epoch.++.. cpp:function:: int botan_x509_cert_not_after(botan_x509_cert_t cert, uint64_t* time_since_epoch)++ Return the time the certificate expires, as seconds since epoch.++.. cpp:function:: int botan_x509_cert_get_fingerprint(botan_x509_cert_t cert, const char* hash, uint8_t out[], size_t* out_len)++.. cpp:function:: int botan_x509_cert_get_serial_number(botan_x509_cert_t cert, uint8_t out[], size_t* out_len)++ Return the serial number of the certificate.++.. cpp:function:: int botan_x509_cert_get_authority_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len)++ Return the authority key ID set in the certificate, which may be empty.++.. cpp:function:: int botan_x509_cert_get_subject_key_id(botan_x509_cert_t cert, uint8_t out[], size_t* out_len)++ Return the subject key ID set in the certificate, which may be empty.++.. cpp:function:: int botan_x509_cert_get_public_key_bits(botan_x509_cert_t cert, \+ uint8_t out[], size_t* out_len)++ Get the serialized representation of the public key included in this certificate++.. cpp:function:: int botan_x509_cert_get_public_key(botan_x509_cert_t cert, botan_pubkey_t* key)++ Get the public key included in this certificate as a newly allocated object++.. cpp:function:: int botan_x509_cert_get_issuer_dn(botan_x509_cert_t cert, \+ const char* key, size_t index, \+ uint8_t out[], size_t* out_len)++ Get a value from the issuer DN field.++.. cpp:function:: int botan_x509_cert_get_subject_dn(botan_x509_cert_t cert, \+ const char* key, size_t index, \+ uint8_t out[], size_t* out_len)++ Get a value from the subject DN field.++.. cpp:function:: int botan_x509_cert_to_string(botan_x509_cert_t cert, char out[], size_t* out_len)++ Format the certificate as a free-form string.++.. cpp:enum:: botan_x509_cert_key_constraints++ Certificate key usage constraints. Allowed values: `NO_CONSTRAINTS`,+ `DIGITAL_SIGNATURE`, `NON_REPUDIATION`, `KEY_ENCIPHERMENT`,+ `DATA_ENCIPHERMENT`, `KEY_AGREEMENT`, `KEY_CERT_SIGN`,+ `CRL_SIGN`, `ENCIPHER_ONLY`, `DECIPHER_ONLY`.++.. cpp:function:: int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage)+++.. cpp:function:: int botan_x509_cert_verify(int* validation_result, \+ botan_x509_cert_t cert, \+ const botan_x509_cert_t* intermediates, \+ size_t intermediates_len, \+ const botan_x509_cert_t* trusted, \+ size_t trusted_len, \+ const char* trusted_path, \+ size_t required_strength, \+ const char* hostname, \+ uint64_t reference_time)++ Verify a certificate. Returns 0 if validation was successful, 1 if+ unsuccessful, or negative on error.++ Sets ``validation_result`` to a code that provides more information.++ If not needed, set ``intermediates`` to NULL and ``intermediates_len`` to+ zero.++ If not needed, set ``trusted`` to NULL and ``trusted_len`` to zero.++ The ``trusted_path`` refers to a directory where one or more trusted CA+ certificates are stored. It may be NULL if not needed.++ Set ``required_strength`` to indicate the minimum key and hash strength+ that is allowed. For instance setting to 80 allows 1024-bit RSA and SHA-1.+ Setting to 110 requires 2048-bit RSA and SHA-256 or higher. Set to zero+ to accept a default.++ Set ``reference_time`` to be the time which the certificate chain is+ validated against. Use zero to use the current system clock.++.. cpp:function:: int botan_x509_cert_verify_with_crl(int* validation_result, \+ botan_x509_cert_t cert, \+ const botan_x509_cert_t* intermediates, \+ size_t intermediates_len, \+ const botan_x509_cert_t* trusted, \+ size_t trusted_len, \+ const botan_x509_crl_t* crls, \+ size_t crls_len, \+ const char* trusted_path, \+ size_t required_strength, \+ const char* hostname, \+ uint64_t reference_time)++ Certificate path validation supporting Certificate Revocation Lists.++ Works the same as ``botan_x509_cert_cerify``.++ ``crls`` is an array of ``botan_x509_crl_t`` objects, ``crls_len`` is its length.++.. cpp:function:: const char* botan_x509_cert_validation_status(int code)++ Return a (statically allocated) string associated with the verification+ result.++X.509 Certificate Revocation Lists+----------------------------------------++.. cpp:type:: opaque* botan_x509_crl_t++ An opaque data type for an X.509 CRL.++.. cpp:function:: int botan_x509_crl_load(botan_x509_crl_t* crl_obj, \+ const uint8_t crl[], size_t crl_len)++ Load a CRL from the DER or PEM representation.++.. cpp:function:: int botan_x509_crl_load_file(botan_x509_crl_t* crl_obj, const char* filename)++ Load a CRL from a file.++.. cpp:function:: int botan_x509_crl_destroy(botan_x509_crl_t crl)++ Destroy the CRL object.++.. cpp:function:: int botan_x509_is_revoked(botan_x509_crl_t crl, botan_x509_cert_t cert)++ Check whether a given ``crl`` contains a given ``cert``.+ Return ``0`` when the certificate is revoked, ``-1`` otherwise.
+ third_party/botan/doc/api_ref/filters.rst view
@@ -0,0 +1,733 @@++Pipe/Filter Message Processing+========================================++.. note::++ The system described below provides a message processing system with a+ straightforward API. However it makes many extra memory copies and+ allocations than would otherwise be required, and also tends to make+ applications using it somewhat opaque because it is not obvious what this or+ that Pipe& object actually does (type of operation, number of messages+ output (if any!), and so on), whereas using say a HashFunction or AEAD_Mode+ provides a much better idea in the code of what operation is occurring.++ This filter interface is no longer used within the library itself+ (outside a few dusty corners) and will likely not see any further major+ development. However it will remain included because the API is often+ convenient and many applications use it.++Many common uses of cryptography involve processing one or more+streams of data. Botan provides services that make setting up data+flows through various operations, such as compression, encryption, and+base64 encoding. Each of these operations is implemented in what are+called *filters* in Botan. A set of filters are created and placed into+a *pipe*, and information "flows" through the pipe until it reaches+the end, where the output is collected for retrieval. If you're+familiar with the Unix shell environment, this design will sound quite+familiar.++Here is an example that uses a pipe to base64 encode some strings::++ Pipe pipe(new Base64_Encoder); // pipe owns the pointer+ pipe.start_msg();+ pipe.write("message 1");+ pipe.end_msg(); // flushes buffers, increments message number++ // process_msg(x) is start_msg() && write(x) && end_msg()+ pipe.process_msg("message2");++ std::string m1 = pipe.read_all_as_string(0); // "message1"+ std::string m2 = pipe.read_all_as_string(1); // "message2"++Byte streams in the pipe are grouped into messages; blocks of data that+are processed in an identical fashion (ie, with the same sequence of+filter operations). Messages are delimited by calls to ``start_msg``+and ``end_msg``. Each message in a pipe has its own identifier, which+currently is an integer that increments up from zero.++The ``Base64_Encoder`` was allocated using ``new``; but where was it+deallocated? When a filter object is passed to a ``Pipe``, the pipe+takes ownership of the object, and will deallocate it when it is no+longer needed.++There are two different ways to make use of messages. One is to send+several messages through a ``Pipe`` without changing the ``Pipe``+configuration, so you end up with a sequence of messages; one use of+this would be to send a sequence of identically encrypted UDP packets,+for example (note that the *data* need not be identical; it is just+that each is encrypted, encoded, signed, etc in an identical+fashion). Another is to change the filters that are used in the+``Pipe`` between each message, by adding or removing filters;+functions that let you do this are documented in the Pipe API section.++Botan has about 40 filters that perform different operations on data.+Here's code that uses one of them to encrypt a string with AES::++ AutoSeeded_RNG rng,+ SymmetricKey key(rng, 16); // a random 128-bit key+ InitializationVector iv(rng, 16); // a random 128-bit IV++ // The algorithm we want is specified by a string+ Pipe pipe(get_cipher("AES-128/CBC", key, iv, ENCRYPTION));++ pipe.process_msg("secrets");+ pipe.process_msg("more secrets");++ secure_vector<uint8_t> c1 = pipe.read_all(0);++ uint8_t c2[4096] = { 0 };+ size_t got_out = pipe.read(c2, sizeof(c2), 1);+ // use c2[0...got_out]++Note the use of ``AutoSeeded_RNG``, which is a random number+generator. If you want to, you can explicitly set up the random number+generators and entropy sources you want to, however for 99% of cases+``AutoSeeded_RNG`` is preferable.++``Pipe`` also has convenience methods for dealing with ``std::iostream``.+Here is an example of this, using the bzip2 compression filter::++ std::ifstream in("data.bin", std::ios::binary)+ std::ofstream out("data.bin.bz2", std::ios::binary)++ Pipe pipe(new Compression_Filter("bzip2", 9));++ pipe.start_msg();+ in >> pipe;+ pipe.end_msg();+ out << pipe;++However there is a hitch to the code above; the complete contents of+the compressed data will be held in memory until the entire message+has been compressed, at which time the statement ``out << pipe`` is+executed, and the data is freed as it is read from the pipe and+written to the file. But if the file is very large, we might not have+enough physical memory (or even enough virtual memory!) for that to be+practical. So instead of storing the compressed data in the pipe for+reading it out later, we divert it directly to the file::++ std::ifstream in("data.bin", std::ios::binary)+ std::ofstream out("data.bin.bz2", std::ios::binary)++ Pipe pipe(new Compression_Filter("bzip2", 9), new DataSink_Stream(out));++ pipe.start_msg();+ in >> pipe;+ pipe.end_msg();++This is the first code we've seen so far that uses more than one+filter in a pipe. The output of the compressor is sent to the+``DataSink_Stream``. Anything written to a ``DataSink_Stream`` is+written to a file; the filter produces no output. As soon as the+compression algorithm finishes up a block of data, it will send it+along to the sink filter, which will immediately write it to the+stream; if you were to call ``pipe.read_all()`` after+``pipe.end_msg()``, you'd get an empty vector out. This is+particularly useful for cases where you are processing a large amount+of data, as it means you don't have to store everything in memory at+once.++Here's an example using two computational filters::++ AutoSeeded_RNG rng,+ SymmetricKey key(rng, 32);+ InitializationVector iv(rng, 16);++ Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, ENCRYPTION),+ new Base64_Encoder);++ encryptor.start_msg();+ file >> encryptor;+ encryptor.end_msg(); // flush buffers, complete computations+ std::cout << encryptor;++You can read from a pipe while you are still writing to it, which+allows you to bound the amount of memory that is in use at any one+time. A common idiom for this is::++ pipe.start_msg();+ std::vector<uint8_t> buffer(4096); // arbitrary size+ while(infile.good())+ {+ infile.read((char*)&buffer[0], buffer.size());+ const size_t got_from_infile = infile.gcount();+ pipe.write(buffer, got_from_infile);++ if(infile.eof())+ pipe.end_msg();++ while(pipe.remaining() > 0)+ {+ const size_t buffered = pipe.read(buffer, buffer.size());+ outfile.write((const char*)&buffer[0], buffered);+ }+ }+ if(infile.bad() || (infile.fail() && !infile.eof()))+ throw Some_Exception();++Fork+---------------------------------++It is common that you might receive some data and want to perform more+than one operation on it (ie, encrypt it with Serpent and calculate+the SHA-256 hash of the plaintext at the same time). That's where+``Fork`` comes in. ``Fork`` is a filter that takes input and passes it+on to *one or more* filters that are attached to it. ``Fork`` changes+the nature of the pipe system completely: instead of being a linked+list, it becomes a tree or acyclic graph.++Each filter in the fork is given its own output buffer, and thus its+own message. For example, if you had previously written two messages+into a pipe, then you start a new one with a fork that has three+paths of filter's inside it, you add three new messages to the+pipe. The data you put into the pipe is duplicated and sent+into each set of filter and the eventual output is placed into a+dedicated message slot in the pipe.++Messages in the pipe are allocated in a depth-first manner. This is only+interesting if you are using more than one fork in a single pipe.+As an example, consider the following::++ Pipe pipe(new Fork(+ new Fork(+ new Base64_Encoder,+ new Fork(+ NULL,+ new Base64_Encoder+ )+ ),+ new Hex_Encoder+ )+ );++In this case, message 0 will be the output of the first+``Base64_Encoder``, message 1 will be a copy of the input (see below+for how fork interprets NULL pointers), message 2 will be the output+of the second ``Base64_Encoder``, and message 3 will be the output of+the ``Hex_Encoder``. This results in message numbers being allocated+in a top to bottom fashion, when looked at on the screen. However,+note that there could be potential for bugs if this is not+anticipated. For example, if your code is passed a filter, and you+assume it is a "normal" one that only uses one message, your message+offsets would be wrong, leading to some confusion during output.++If Fork's first argument is a null pointer, but a later argument is+not, then Fork will feed a copy of its input directly through. Here's+a case where that is useful::++ // have std::string ciphertext, auth_code, key, iv, mac_key;++ Pipe pipe(new Base64_Decoder,+ get_cipher("AES-128", key, iv, DECRYPTION),+ new Fork(+ 0, // this message gets plaintext+ new MAC_Filter("HMAC(SHA-1)", mac_key)+ )+ );++ pipe.process_msg(ciphertext);+ std::string plaintext = pipe.read_all_as_string(0);+ secure_vector<uint8_t> mac = pipe.read_all(1);++ if(mac != auth_code)+ error();++Here we wanted to not only decrypt the message, but send the decrypted+text through an additional computation, in order to compute the+authentication code.++Any filters that are attached to the pipe after the fork are+implicitly attached onto the first branch created by the fork. For+example, let's say you created this pipe::++ Pipe pipe(new Fork(new Hash_Filter("SHA-256"),+ new Hash_Filter("SHA-512")),+ new Hex_Encoder);++And then called ``start_msg``, inserted some data, then+``end_msg``. Then ``pipe`` would contain two messages. The first one+(message number 0) would contain the SHA-256 sum of the input in hex+encoded form, and the other would contain the SHA-512 sum of the input+in raw binary. In many situations you'll want to perform a sequence of+operations on multiple branches of the fork; in which case, use+the filter described in :ref:`chain`.++There is also a ``Threaded_Fork`` which acts the same as ``Fork``,+except it runs each of the filters in its own thread.++.. _chain:++Chain+---------------------------------++A ``Chain`` filter creates a chain of filters and encapsulates them+inside a single filter (itself). This allows a sequence of filters to+become a single filter, to be passed into or out of a function, or to+a ``Fork`` constructor.++You can call ``Chain``'s constructor with up to four ``Filter``+pointers (they will be added in order), or with an array of filter+pointers and a ``size_t`` that tells ``Chain`` how many filters are in+the array (again, they will be attached in order). Here's the example+from the last section, using chain instead of relying on the implicit+pass through the other version used::++ Pipe pipe(new Fork(+ new Chain(new Hash_Filter("SHA-256"), new Hex_Encoder),+ new Hash_Filter("SHA-512")+ )+ );++Sources and Sinks+----------------------------------------++Data Sources+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A ``DataSource`` is a simple abstraction for a thing that stores+bytes. This type is used heavily in the areas of the API related to+ASN.1 encoding/decoding. The following types are ``DataSource``:+``Pipe``, ``SecureQueue``, and a couple of special purpose ones:+``DataSource_Memory`` and ``DataSource_Stream``.++You can create a ``DataSource_Memory`` with an array of bytes and a+length field. The object will make a copy of the data, so you don't+have to worry about keeping that memory allocated. This is mostly for+internal use, but if it comes in handy, feel free to use it.++A ``DataSource_Stream`` is probably more useful than the memory based+one. Its constructors take either a ``std::istream`` or a+``std::string``. If it's a stream, the data source will use the+``istream`` to satisfy read requests (this is particularly useful to+use with ``std::cin``). If the string version is used, it will attempt+to open up a file with that name and read from it.++Data Sinks+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A ``DataSink`` (in ``data_snk.h``) is a ``Filter`` that takes+arbitrary amounts of input, and produces no output. This means it's+doing something with the data outside the realm of what+``Filter``/``Pipe`` can handle, for example, writing it to a file+(which is what the ``DataSink_Stream`` does). There is no need for+``DataSink``s that write to a ``std::string`` or memory buffer,+because ``Pipe`` can handle that by itself.++Here's a quick example of using a ``DataSink``, which encrypts+``in.txt`` and sends the output to ``out.txt``. There is+no explicit output operation; the writing of ``out.txt`` is+implicit::++ DataSource_Stream in("in.txt");+ Pipe pipe(get_cipher("AES-128/CTR-BE", key, iv),+ new DataSink_Stream("out.txt"));+ pipe.process_msg(in);++A real advantage of this is that even if "in.txt" is large, only as+much memory is needed for internal I/O buffers will be used.++The Pipe API+---------------------------------++Initializing Pipe+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++By default, ``Pipe`` will do nothing at all; any input placed into the+``Pipe`` will be read back unchanged. Obviously, this has limited+utility, and presumably you want to use one or more filters to somehow+process the data. First, you can choose a set of filters to initialize+the ``Pipe`` via the constructor. You can pass it either a set of up+to four filter pointers, or a pre-defined array and a length::++ Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),+ new Filter3(/*args*/), new Filter4(/*args*/));+ Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));++ Filter* filters[5] = {+ new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),+ new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */+ };+ Pipe pipe3(filters, 5);++This is by far the most common way to initialize a ``Pipe``. However,+occasionally a more flexible initialization strategy is necessary;+this is supported by 4 member functions. These functions may only be+used while the pipe in question is not in use; that is, either before+calling ``start_msg``, or after ``end_msg`` has been called (and no+new calls to ``start_msg`` have been made yet).++.. cpp:function:: void Pipe::prepend(Filter* filter)++ Calling ``prepend`` will put the passed filter first in the list of+ transformations. For example, if you prepend a filter implementing+ encryption, and the pipe already had a filter that hex encoded the+ input, then the next message processed would be first encrypted,+ and *then* hex encoded.++.. cpp:function:: void Pipe::append(Filter* filter)++ Like ``prepend``, but places the filter at the end of the message+ flow. This doesn't always do what you expect if there is a fork.++.. cpp:function:: void Pipe::pop()++ Removes the first filter in the flow.++.. cpp:function:: void Pipe::reset()++ Removes all the filters that the pipe currently holds - it is reset+ to an empty/no-op state. Any data that is being retained by the+ pipe is retained after a ``reset``, and ``reset`` does not affect+ message numbers (discussed later).++Giving Data to a Pipe+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Input to a ``Pipe`` is delimited into messages, which can be read from+independently (ie, you can read 5 bytes from one message, and then all of+another message, without either read affecting any other messages).++.. cpp:function:: void Pipe::start_msg()++ Starts a new message; if a message was already running, an exception is+ thrown. After this function returns, you can call ``write``.++.. cpp:function:: void Pipe::write(const uint8_t* input, size_t length)++.. cpp:function:: void Pipe::write(const std::vector<uint8_t>& input)++.. cpp:function:: void Pipe::write(const std::string& input)++.. cpp:function:: void Pipe::write(DataSource& input)++.. cpp:function:: void Pipe::write(uint8_t input)++ All versions of ``write`` write the input into the filter sequence.+ If a message is not currently active, an exception is thrown.++.. cpp:function:: void Pipe::end_msg()++ End the currently active message++Sometimes, you may want to do only a single write per message. In this+case, you can use the ``process_msg`` series of functions, which start+a message, write their argument into the pipe, and then end the+message. In this case you would not make any explicit calls to+``start_msg``/``end_msg``.++Pipes can also be used with the ``>>`` operator, and will accept a+``std::istream``, or on Unix systems with the ``fd_unix`` module, a+Unix file descriptor. In either case, the entire contents of the file+will be read into the pipe.++Getting Output from a Pipe+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Retrieving the processed data from a pipe is a bit more complicated,+for various reasons. The pipe will separate each message into a+separate buffer, and you have to retrieve data from each message+independently. Each of the reader functions has a final parameter that+specifies what message to read from. If this parameter is set to+``Pipe::DEFAULT_MESSAGE``, it will read the current default message+(``DEFAULT_MESSAGE`` is also the default value of this parameter).++Functions in ``Pipe`` related to reading include:++.. cpp:function:: size_t Pipe::read(uint8_t* out, size_t len)++ Reads up to ``len`` bytes into ``out``, and returns the number of+ bytes actually read.++.. cpp:function:: size_t Pipe::peek(uint8_t* out, size_t len)++ Acts exactly like `read`, except the data is not actually read; the+ next read will return the same data.++.. cpp:function:: secure_vector<uint8_t> Pipe::read_all()++ Reads the entire message into a buffer and returns it++.. cpp:function:: std::string Pipe::read_all_as_string()++ Like ``read_all``, but it returns the data as a ``std::string``.+ No encoding is done; if the message contains raw binary, so will+ the string.++.. cpp:function:: size_t Pipe::remaining()++ Returns how many bytes are left in the message++.. cpp:function:: Pipe::message_id Pipe::default_msg()++ Returns the current default message number++.. cpp:function:: Pipe::message_id Pipe::message_count()++ Returns the total number of messages currently in the pipe++.. cpp:function:: Pipe::set_default_msg(Pipe::message_id msgno)++ Sets the default message number (which must be a valid message+ number for that pipe). The ability to set the default message number+ is particularly important in the case of using the file output+ operations (``<<`` with a ``std::ostream`` or Unix file descriptor),+ because there is no way to specify the message explicitly when using+ the output operator.++Pipe I/O for Unix File Descriptors+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++This is a minor feature, but it comes in handy sometimes. In all+installations of the library, Botan's ``Pipe`` object overloads the+``<<`` and ``>>`` operators for C++ iostream objects,+which is usually more than sufficient for doing I/O.++However, there are cases where the iostream hierarchy does not map well to+local 'file types', so there is also the ability to do I/O directly with Unix+file descriptors. This is most useful when you want to read from or write to+something like a TCP or Unix-domain socket, or a pipe, since for simple file+access it's usually easier to just use C++'s file streams.++If ``BOTAN_EXT_PIPE_UNIXFD_IO`` is defined, then you can use the+overloaded I/O operators with Unix file descriptors. For an example of this,+check out the ``hash_fd`` example, included in the Botan distribution.++Filter Catalog+---------------------------------++This section documents most of the useful filters included in the+library.++Keyed Filters+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A few sections ago, it was mentioned that ``Pipe`` can process+multiple messages, treating each of them the same. Well, that was a+bit of a lie. There are some algorithms (in particular, block ciphers+not in ECB mode, and all stream ciphers) that change their state as+data is put through them.++Naturally, you might well want to reset the keys or (in the case of+block cipher modes) IVs used by such filters, so multiple messages can+be processed using completely different keys, or new IVs, or new keys+and IVs, or whatever. And in fact, even for a MAC or an ECB block+cipher, you might well want to change the key used from message to+message.++Enter ``Keyed_Filter``, which acts as an abstract interface for any+filter that is uses keys: block cipher modes, stream ciphers, MACs,+and so on. It has two functions, ``set_key`` and ``set_iv``. Calling+``set_key`` will set (or reset) the key used by the algorithm. Setting+the IV only makes sense in certain algorithms -- a call to ``set_iv``+on an object that doesn't support IVs will cause an exception. You+must call ``set_key`` *before* calling ``set_iv``.++Here's a example::++ Keyed_Filter *aes, *hmac;+ Pipe pipe(new Base64_Decoder,+ // Note the assignments to the cast and hmac variables+ aes = get_cipher("AES-128/CBC", aes_key, iv),+ new Fork(+ 0, // Read the section 'Fork' to understand this+ new Chain(+ hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),+ new Base64_Encoder+ )+ )+ );+ pipe.start_msg();+ // use pipe for a while, decrypt some stuff, derive new keys and IVs+ pipe.end_msg();++ aes->set_key(aes_key2);+ aes->set_iv(iv2);+ hmac->set_key(mac_key2);++ pipe.start_msg();+ // use pipe for some other things+ pipe.end_msg();++There are some requirements to using ``Keyed_Filter`` that you must+follow. If you call ``set_key`` or ``set_iv`` on a filter that is+owned by a ``Pipe``, you must do so while the ``Pipe`` is+"unlocked". This refers to the times when no messages are being+processed by ``Pipe`` -- either before ``Pipe``'s ``start_msg`` is+called, or after ``end_msg`` is called (and no new call to+``start_msg`` has happened yet). Doing otherwise will result in+undefined behavior, probably silently getting invalid output.++And remember: if you're resetting both values, reset the key *first*.++Cipher Filters+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Getting a hold of a ``Filter`` implementing a cipher is very+easy. Make sure you're including the header ``lookup.h``, and+then call ``get_cipher``. You will pass the return value+directly into a ``Pipe``. There are a couple different functions+which do varying levels of initialization:++.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, \+ SymmetricKey key, InitializationVector iv, Cipher_Dir dir)++.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, \+ SymmetricKey key, Cipher_Dir dir)++The version that doesn't take an IV is useful for things that don't+use them, like block ciphers in ECB mode, or most stream ciphers. If+you specify a cipher spec that does want a IV, and you use the version+that doesn't take one, an exception will be thrown. The ``dir``+argument can be either ``ENCRYPTION`` or ``DECRYPTION``.++The cipher_spec is a string that specifies what cipher is to be+used. The general syntax for "cipher_spec" is "STREAM_CIPHER",+"BLOCK_CIPHER/MODE", or "BLOCK_CIPHER/MODE/PADDING". In the case of+stream ciphers, no mode is necessary, so just the name is+sufficient. A block cipher requires a mode of some sort, which can be+"ECB", "CBC", "CFB(n)", "OFB", "CTR-BE", or "EAX(n)". The argument to+CFB mode is how many bits of feedback should be used. If you just use+"CFB" with no argument, it will default to using a feedback equal to+the block size of the cipher. EAX mode also takes an optional bit+argument, which tells EAX how large a tag size to use~--~generally+this is the size of the block size of the cipher, which is the default+if you don't specify any argument.++In the case of the ECB and CBC modes, a padding method can also be+specified. If it is not supplied, ECB defaults to not padding, and CBC+defaults to using PKCS #5/#7 compatible padding. The padding methods+currently available are "NoPadding", "PKCS7", "OneAndZeros", and+"CTS". CTS padding is currently only available for CBC mode, but the+others can also be used in ECB mode.++Some example "cipher_spec arguments are: "AES-128/CBC",+"Blowfish/CTR-BE", "Serpent/XTS", and "AES-256/EAX".++"CTR-BE" refers to counter mode where the counter is incremented as if+it were a big-endian encoded integer. This is compatible with most+other implementations, but it is possible some will use the+incompatible little endian convention. This version would be denoted+as "CTR-LE" if it were supported.++"EAX" is a new cipher mode designed by Wagner, Rogaway, and+Bellare. It is an authenticated cipher mode (that is, no separate+authentication is needed), has provable security, and is free from+patent entanglements. It runs about half as fast as most of the other+cipher modes (like CBC, OFB, or CTR), which is not bad considering you+don't need to use an authentication code.++Hashes and MACs+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Hash functions and MACs don't need anything special when it comes to+filters. Both just take their input and produce no output until+``end_msg`` is called, at which time they complete the hash or MAC and+send that as output.++These filters take a string naming the type to be used. If for some+reason you name something that doesn't exist, an exception will be thrown.++.. cpp:function:: Hash_Filter::Hash_Filter(std::string hash, size_t outlen = 0)++ This constructor creates a filter that hashes its input with+ ``hash``. When ``end_msg`` is called on the owning pipe, the hash is+ completed and the digest is sent on to the next filter in the+ pipeline. The parameter ``outlen`` specifies how many bytes of the+ hash output will be passed along to the next filter when ``end_msg``+ is called. By default, it will pass the entire hash.++ Examples of names for ``Hash_Filter`` are "SHA-1" and "Whirlpool".++.. cpp:function:: MAC_Filter::MAC_Filter(std::string mac, SymmetricKey key, size_t outlen = 0)++ This constructor takes a name for a mac, such as "HMAC(SHA-1)" or+ "CMAC(AES-128)", along with a key to use. The optional ``outlen``+ works the same as in ``Hash_Filter``.++Encoders+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Often you want your data to be in some form of text (for sending over+channels that aren't 8-bit clean, printing it, etc). The filters+``Hex_Encoder`` and ``Base64_Encoder`` will convert arbitrary binary+data into hex or base64 formats. Not surprisingly, you can use+``Hex_Decoder`` and ``Base64_Decoder`` to convert it back into its+original form.++Both of the encoders can take a few options about how the data should+be formatted (all of which have defaults). The first is a ``bool``+which says if the encoder should insert line breaks. This defaults to+false. Line breaks don't matter either way to the decoder, but it+makes the output a bit more appealing to the human eye, and a few+transport mechanisms (notably some email systems) limit the maximum+line length.++The second encoder option is an integer specifying how long such lines+will be (obviously this will be ignored if line-breaking isn't being+used). The default tends to be in the range of 60-80 characters, but+is not specified. If you want a specific value, set it. Otherwise the+default should be fine.++Lastly, ``Hex_Encoder`` takes an argument of type ``Case``, which can+be ``Uppercase`` or ``Lowercase`` (default is ``Uppercase``). This+specifies what case the characters A-F should be output as. The base64+encoder has no such option, because it uses both upper and lower case+letters for its output.++You can find the declarations for these types in ``hex_filt.h`` and+``b64_filt.h``.++Writing New Filters+---------------------------------++The system of filters and pipes was designed in an attempt to make it+as simple as possible to write new filter types. There are four+functions that need to be implemented by a class deriving from+``Filter``:++.. cpp:function:: std::string Filter::name() const++ This should just return a useful decription of the filter object.++.. cpp:function:: void Filter::write(const uint8_t* input, size_t length)++ This function is what is called when a filter receives input for it+ to process. The filter is not required to process the data right+ away; many filters buffer their input before producing any output. A+ filter will usually have ``write`` called many times during its+ lifetime.++.. cpp:function:: void Filter::send(uint8_t* output, size_t length)++ Eventually, a filter will want to produce some output to send along+ to the next filter in the pipeline. It does so by calling ``send``+ with whatever it wants to send along to the next filter. There is+ also a version of ``send`` taking a single byte argument, as a+ convenience.++ .. note::++ Normally a filter does not need to override ``send``, though it+ can for special handling. It does however need to call this+ function whenever it wants to produce output.++.. cpp:function:: void Filter::start_msg()++ Implementing this function is optional. Implement it if your filter+ would like to do some processing or setup at the start of each+ message, such as allocating a data structure.++.. cpp:function:: void Filter::end_msg()++ Implementing this function is optional. It is called when it has+ been requested that filters finish up their computations. The filter+ should finish up with whatever computation it is working on (for+ example, a compressing filter would flush the compressor and+ ``send`` the final block), and empty any buffers in preparation for+ processing a fresh new set of input.++Additionally, if necessary, filters can define a constructor that+takes any needed arguments, and a destructor to deal with deallocating+memory, closing files, etc.+
+ third_party/botan/doc/api_ref/fpe.rst view
@@ -0,0 +1,98 @@+Format Preserving Encryption+========================================++Format preserving encryption (FPE) refers to a set of techniques for+encrypting data such that the ciphertext has the same format as the+plaintext. For instance, you can use FPE to encrypt credit card+numbers with valid checksums such that the ciphertext is also an+credit card number with a valid checksum, or similarly for bank+account numbers, US Social Security numbers, or even more general+mappings like English words onto other English words.++The scheme currently implemented in botan is called FE1, and described+in the paper `Format Preserving Encryption+<https://eprint.iacr.org/2009/251>`_ by Mihir Bellare, Thomas+Ristenpart, Phillip Rogaway, and Till Stegers. FPE is an area of+ongoing standardization and it is likely that other schemes will be+included in the future.++To encrypt an arbitrary value using FE1, you need to use a ranking+method. Basically, the idea is to assign an integer to every value you+might encrypt. For instance, a 16 digit credit card number consists of+a 15 digit code plus a 1 digit checksum. So to encrypt a credit card+number, you first remove the checksum, encrypt the 15 digit value+modulo 10\ :sup:`15`, and then calculate what the checksum is for the+new (ciphertext) number. Or, if you were encrypting words in a+dictionary, you could rank the words by their lexicographical order,+and choose the modulus to be the number of words in the dictionary.++The interfaces for FE1 are defined in the header ``fpe_fe1.h``:++.. versionadded:: 2.5.0++.. cpp:class:: FPE_FE1++ .. cpp:function:: FPE_FE1(const BigInt& n, size_t rounds = 5, \+ bool compat_mode = false, \+ std::string mac_algo = "HMAC(SHA-256)")++ Initialize an FPE operation to encrypt/decrypt integers less+ than *n*. It is expected that *n* is trivially factorable into+ small integers. Common usage would be n to be a power of 10.++ Note that the default parameters to this constructor are+ **incompatible** with the ``fe1_encrypt`` and ``fe1_decrypt``+ function originally added in 1.9.17. For compatibility, use+ 3 rounds and set ``compat_mode`` to true.++ .. cpp:function:: BigInt encrypt(const BigInt& x, const uint8_t tweak[], size_t tweak_len) const++ Encrypts the value *x* modulo the value *n* using the *key* and *tweak*+ specified. Returns an integer less than *n*. The *tweak* is a value that+ does not need to be secret that parameterizes the encryption function. For+ instance, if you were encrypting a database column with a single key, you+ could use a per-row-unique integer index value as the tweak. The same+ tweak value must be used during decryption.++ .. cpp:function:: BigInt decrypt(const BigInt& x, const uint8_t tweak[], size_t tweak_len) const++ Decrypts an FE1 ciphertext. The *tweak* must be the same as that provided+ to the encryption function. Returns the plaintext integer.++ Note that there is not any implicit authentication or checking of data in+ FE1, so if you provide an incorrect key or tweak the result is simply a+ random integer.++ .. cpp:function:: BigInt encrypt(const BigInt& x, uint64_t tweak)++ Convenience version of encrypt taking an integer tweak.++ .. cpp:function:: BigInt decrypt(const BigInt& x, uint64_t tweak)++ Convenience version of decrypt taking an integer tweak.++There are two functions that handle the entire FE1 encrypt/decrypt operation.+These are the original interface to FE1, first added in 1.9.17. However because+they do the entire setup cost for each operation, they are significantly slower+than the class-based API presented above.++.. warning:: These functions are hardcoded to use 3 rounds, which may be+ insufficient depending on the chosen modulus.++.. cpp:function:: BigInt FPE::fe1_encrypt(const BigInt& n, const BigInt& X, \+ const SymmetricKey& key, const std::vector<uint8_t>& tweak)++ This creates an FPE_FE1 object, sets the key, and encrypts *X* using+ the provided tweak.++.. cpp:function:: BigInt FPE::fe1_decrypt(const BigInt& n, const BigInt& X, \+ const SymmetricKey& key, const std::vector<uint8_t>& tweak)++ This creates an FPE_FE1 object, sets the key, and decrypts *X* using+ the provided tweak.++This example encrypts a credit card number with a valid `Luhn checksum+<https://en.wikipedia.org/wiki/Luhn_algorithm>`_ to another number with the same+format, including a correct checksum.++.. literalinclude:: ../../src/cli/cc_enc.cpp
+ third_party/botan/doc/api_ref/hash.rst view
@@ -0,0 +1,348 @@+Hash Functions and Checksums+=============================++Hash functions are one-way functions, which map data of arbitrary size to a+fixed output length. Most of the hash functions in Botan are designed to be+cryptographically secure, which means that it is computationally infeasible to+create a collision (finding two inputs with the same hash) or preimages (given a+hash output, generating an arbitrary input with the same hash). But note that+not all such hash functions meet their goals, in particular MD4 and MD5 are+trivially broken. However they are still included due to their wide adoption in+various protocols.++The class :cpp:class:`HashFunction` is defined in `botan/hash.h`.++Using a hash function is typically split into three stages: initialization,+update, and finalization (often referred to as a IUF interface). The+initialization stage is implicit: after creating a hash function object, it is+ready to process data. Then update is called one or more times. Calling update+several times is equivalent to calling it once with all of the arguments+concatenated. After completing a hash computation (eg using ``final``), the+internal state is reset to begin hashing a new message.++.. cpp:class:: HashFunction++ .. cpp:function:: static std::unique_ptr<HashFunction> create(const std::string& name)++ Return a newly allocated hash function object, or nullptr if the+ name is not recognized.++ .. cpp:function:: static std::unique_ptr<HashFunction> create_or_throw(const std::string& name)++ Like ``create`` except that it will throw an exception instead of+ returning nullptr.++ .. cpp:function:: size_t output_length()++ Return the size (in *bytes*) of the output of this function.++ .. cpp:function:: void update(const uint8_t* input, size_t length)++ Updates the computation with *input*.++ .. cpp:function:: void update(uint8_t input)++ Updates the computation with *input*.++ .. cpp:function:: void update(const std::vector<uint8_t>& input)++ Updates the computation with *input*.++ .. cpp:function:: void update(const std::string& input)++ Updates the computation with *input*.++ .. cpp:function:: void final(uint8_t* out)++ Finalize the calculation and place the result into ``out``.+ For the argument taking an array, exactly ``output_length`` bytes will+ be written. After you call ``final``, the algorithm is reset to+ its initial state, so it may be reused immediately.++ .. cpp:function:: secure_vector<uint8_t> final()++ Similar to the other function of the same name, except it returns+ the result in a newly allocated vector.++ .. cpp:function:: secure_vector<uint8_t> process(const uint8_t in[], size_t length)++ Equivalent to calling ``update`` followed by ``final``.++ .. cpp:function:: secure_vector<uint8_t> process(const std::string& in)++ Equivalent to calling ``update`` followed by ``final``.++Code Example+------------++Assume we want to calculate the SHA-256, SHA-384, and SHA-3 hash digests of the STDIN stream using the Botan library.++.. code-block:: cpp++ #include <botan/hash.h>+ #include <botan/hex.h>+ #include <iostream>+ int main ()+ {+ std::unique_ptr<Botan::HashFunction> hash1(Botan::HashFunction::create("SHA-256"));+ std::unique_ptr<Botan::HashFunction> hash2(Botan::HashFunction::create("SHA-384"));+ std::unique_ptr<Botan::HashFunction> hash3(Botan::HashFunction::create("SHA-3"));+ std::vector<uint8_t> buf(2048);++ while(std::cin.good())+ {+ //read STDIN to buffer+ std::cin.read(reinterpret_cast<char*>(buf.data()), buf.size());+ size_t readcount = std::cin.gcount();+ //update hash computations with read data+ hash1->update(buf.data(),readcount);+ hash2->update(buf.data(),readcount);+ hash3->update(buf.data(),readcount);+ }+ std::cout << "SHA-256: " << Botan::hex_encode(hash1->final()) << std::endl;+ std::cout << "SHA-384: " << Botan::hex_encode(hash2->final()) << std::endl;+ std::cout << "SHA-3: " << Botan::hex_encode(hash3->final()) << std::endl;+ return 0;+ }++Available Hash Functions+------------------------------++The following cryptographic hash functions are implemented. If in doubt,+any of SHA-384, SHA-3, or BLAKE2b are fine choices.++BLAKE2b+^^^^^^^^^++Available if ``BOTAN_HAS_BLAKE2B`` is defined.++A recently designed hash function. Very fast on 64-bit processors. Can output a+hash of any length between 1 and 64 bytes, this is specified by passing a value+to the constructor with the desired length.++Named like "Blake2b" which selects default 512-bit output, or as+"Blake2b(256)" to select 256 bits of output.++GOST-34.11+^^^^^^^^^^^^^^^++.. deprecated:: 2.11++Available if ``BOTAN_HAS_GOST_34_11`` is defined.++Russian national standard hash. It is old, slow, and has some weaknesses. Avoid+it unless you must.++.. warning::+ As this hash function is no longer approved by the latest Russian standards,+ support for GOST 34.11 hash is deprecated and will be removed in a future+ major release.++Keccak-1600+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_KECCAK`` is defined.++An older (and incompatible) variant of SHA-3, but sometimes used. Prefer SHA-3 in+new code.++MD4+^^^^^^^^^++Available if ``BOTAN_HAS_MD4`` is defined.++An old hash function that is now known to be trivially breakable. It is very+fast, and may still be suitable as a (non-cryptographic) checksum.++MD5+^^^^^^^^^++Available if ``BOTAN_HAS_MD5`` is defined.++Widely used, now known to be broken.++RIPEMD-160+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_RIPEMD160`` is defined.++A 160 bit hash function, quite old but still thought to be secure (up to the+limit of 2**80 computation required for a collision which is possible with any+160 bit hash function). Somewhat deprecated these days.++SHA-1+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SHA1`` is defined.++Widely adopted NSA designed hash function. Starting to show significant signs of+weakness, and collisions can now be generated. Avoid in new designs.++SHA-256+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SHA2_32`` is defined.++Relatively fast 256 bit hash function, thought to be secure.++Also includes the variant SHA-224. There is no real reason to use SHA-224.++SHA-512+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SHA2_64`` is defined.++SHA-512 is faster than SHA-256 on 64-bit processors. Also includes the+truncated variants SHA-384 and SHA-512/256, which have the advantage+of avoiding message extension attacks.++SHA-3+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SHA3`` is defined.++The new NIST standard hash. Fairly slow.++Supports 224, 256, 384 or 512 bit outputs. SHA-3 is faster with+smaller outputs. Use as "SHA-3(256)" or "SHA-3(512)". Plain "SHA-3"+selects default 512 bit output.++SHAKE (SHAKE-128, SHAKE-256)+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SHAKE`` is defined.++These are actually XOFs (extensible output functions) based on SHA-3, which can+output a value of any byte length. For example "SHAKE-128(1024)" will produce+1024 bits of output. The specified length must be a multiple of 8. Not+specifying an output length, "SHAKE-128" defaults to a 128-bit output and+"SHAKE-256" defaults to a 256-bit output.++.. warning::+ In the case of SHAKE-128, the default output length in insufficient+ to ensure security. The choice of default lengths was a bug which is+ currently retained for compatability; they should have been 256 and+ 512 bits resp to match SHAKE's security level. Using the default+ lengths with SHAKE is deprecated and will be removed in a future major+ release. Instead, always specify the desired output length.++SM3+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SM3`` is defined.++Chinese national hash function, 256 bit output. Widely used in industry there.+Fast and seemingly secure, but no reason to prefer it over SHA-2 or SHA-3 unless+required.++Skein-512+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_SKEIN_512`` is defined.++A contender for the NIST SHA-3 competition. Very fast on 64-bit systems. Can+output a hash of any length between 1 and 64 bytes. It also accepts an optional+"personalization string" which can create variants of the hash. This is useful+for domain separation.++To set a personalization string set the second param to any value,+typically ASCII strings are used. Examples "Skein-512(256)" or+"Skein-512(384,personalization_string)".++Streebog (Streebog-256, Streebog-512)+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_STREEBOG`` is defined.++Newly designed Russian national hash function. Due to use of input-dependent+table lookups, it is vulnerable to side channels. There is no reason to use it+unless compatibility is needed.++.. warning::+ The Streebog Sbox has recently been revealed to have a hidden structure which+ interacts with its linear layer in a way which may provide a backdoor when+ used in certain ways. Avoid Streebog if at all possible.++Tiger+^^^^^^^^^^^^^^^++.. deprecated:: 2.15++Available if ``BOTAN_HAS_TIGER`` is defined.++An older 192-bit hash function, optimized for 64-bit systems. Possibly+vulnerable to side channels due to its use of table lookups.++Tiger supports variable length output (16, 20 or 24 bytes) and+variable rounds (which must be at least 3). Default is 24 byte output+and 3 rounds. Specify with names like "Tiger" or "Tiger(20,5)".++.. warning::+ There are documented (albeit impractical) attacks on the full Tiger+ hash leading to preimage attacks. This indicates possibility of a+ serious weakness in the hash and for this reason it is deprecated+ and will be removed in a future major release of the library.++Whirlpool+^^^^^^^^^^^^^^^++Available if ``BOTAN_HAS_WHIRLPOOL`` is defined.++A 512-bit hash function standardized by ISO and NESSIE. Relatively slow, and due+to the table based implementation it is potentially vulnerable to cache based+side channels.++Hash Function Combiners+---------------------------++These are functions which combine multiple hash functions to create a new hash+function. They are typically only used in specialized applications.++Parallel+^^^^^^^^^^^^^++Available if ``BOTAN_HAS_PARALLEL_HASH`` is defined.++Parallel simply concatenates multiple hash functions. For example+"Parallel(SHA-256,SHA-512)" outputs a 256+512 bit hash created by hashing the+input with both SHA-256 and SHA-512 and concatenating the outputs.++Note that due to the "multicollision attack" it turns out that generating a+collision for multiple parallel hash functions is no harder than generating a+collision for the strongest hash function.++Comp4P+^^^^^^^^^^^^^++Available if ``BOTAN_HAS_COMB4P`` is defined.++This combines two cryptographic hashes in such a way that preimage and collision+attacks are provably at least as hard as a preimage or collision attack on the+strongest hash.++Checksums+----------------++.. note:: Checksums are not suitable for cryptographic use, but can be used for+ error checking purposes.++Adler32+^^^^^^^^^^^++Available if ``BOTAN_HAS_ADLER32`` is defined.++The Adler32 checksum is used in the zlib format. 32 bit output.++CRC24+^^^^^^^^^^^++Available if ``BOTAN_HAS_CRC24`` is defined.++This is the CRC function used in OpenPGP. 24 bit output.++CRC32+^^^^^^^^^^^++Available if ``BOTAN_HAS_CRC32`` is defined.++This is the 32-bit CRC used in protocols such as Ethernet, gzip, PNG, etc.
+ third_party/botan/doc/api_ref/kdf.rst view
@@ -0,0 +1,106 @@++.. _key_derivation_function:++Key Derivation Functions+========================================++Key derivation functions are used to turn some amount of shared secret+material into uniform random keys suitable for use with symmetric+algorithms. An example of an input which is useful for a KDF is a+shared secret created using Diffie-Hellman key agreement.++.. cpp:class:: KDF++ .. cpp:function:: secure_vector<uint8_t> derive_key( \+ size_t key_len, const std::vector<uint8_t>& secret, \+ const std::string& salt = "") const++ .. cpp:function:: secure_vector<uint8_t> derive_key( \+ size_t key_len, const std::vector<uint8_t>& secret, \+ const std::vector<uint8_t>& salt) const++ .. cpp:function:: secure_vector<uint8_t> derive_key( \+ size_t key_len, const std::vector<uint8_t>& secret, \+ const uint8_t* salt, size_t salt_len) const++ .. cpp:function:: secure_vector<uint8_t> derive_key( \+ size_t key_len, const uint8_t* secret, size_t secret_len, \+ const std::string& salt) const++ All variations on the same theme. Deterministically creates a+ uniform random value from *secret* and *salt*. Typically *salt* is+ a label or identifier, such as a session id.++You can create a :cpp:class:`KDF` using++.. cpp:function:: KDF* get_kdf(const std::string& algo_spec)+++Available KDFs+-------------------++Botan includes many different KDFs simply because different protocols and+standards have created subtly different approaches to this problem. For new+code, use HKDF which is conservative, well studied, widely implemented and NIST+approved.++HKDF+~~~~~++Defined in RFC 5869, HKDF uses HMAC to process inputs. Also available+are variants HKDF-Extract and HKDF-Expand. HKDF is the combined+Extract+Expand operation. Use the combined HKDF unless you need+compatibility with some other system.++Available if ``BOTAN_HAS_HKDF`` is defined.++KDF2+~~~~~++KDF2 comes from IEEE 1363. It uses a hash function.++Available if ``BOTAN_HAS_KDF2`` is defined.++KDF1-18033+~~~~~~~~~~~~++KDF1 from ISO 18033-2. Very similar to (but incompatible with) KDF2.++Available if ``BOTAN_HAS_KDF1_18033`` is defined.++KDF1+~~~~~~++KDF1 from IEEE 1363. It can only produce an output at most the length+of the hash function used.++Available if ``BOTAN_HAS_KDF1`` is defined.++X9.42 PRF+~~~~~~~~~~++A KDF from ANSI X9.42. Sometimes used for Diffie-Hellman.++Available if ``BOTAN_HAS_X942_PRF`` is defined.++SP800-108+~~~~~~~~~~++KDFs from NIST SP 800-108. Variants include "SP800-108-Counter",+"SP800-108-Feedback" and "SP800-108-Pipeline".++Available if ``BOTAN_HAS_SP800_108`` is defined.++SP800-56A+~~~~~~~~~~++KDF from NIST SP 800-56A.++Available if ``BOTAN_HAS_SP800_56A`` is defined.++SP800-56C+~~~~~~~~~~++KDF from NIST SP 800-56C.++Available if ``BOTAN_HAS_SP800_56C`` is defined.
+ third_party/botan/doc/api_ref/keywrap.rst view
@@ -0,0 +1,60 @@+AES Key Wrapping+=================================++NIST specifies two mechanisms for wrapping (encrypting) symmetric keys using+another key. The first (and older, more widely supported) method requires the+input be a multiple of 8 bytes long. The other allows any length input, though+only up to 2**32 bytes.++These algorithms are described in NIST SP 800-38F, and RFCs 3394 and 5649.++This API, defined in ``nist_keywrap.h``, first became available in version 2.4.0++These functions take an arbitrary 128-bit block cipher object, which must+already have been keyed with the key encryption key. NIST only allows these+functions with AES, but any 128-bit cipher will do and some other implementations+(such as in OpenSSL) do also allow other ciphers. Use AES for best interop.++.. cpp:function:: std::vector<uint8_t> nist_key_wrap(const uint8_t input[], \+ size_t input_len, const BlockCipher& bc)++ This performs KW (key wrap) mode. The input must be a multiple of 8 bytes long.++.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap(const uint8_t input[], \+ size_t input_len, const BlockCipher& bc)++ This unwraps the result of nist_key_wrap, or throw Invalid_Authentication_Tag on error.++.. cpp:function:: std::vector<uint8_t> nist_key_wrap_padded(const uint8_t input[], \+ size_t input_len, const BlockCipher& bc)++ This performs KWP (key wrap with padding) mode. The input can be any length.++.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap_padded(const uint8_t input[], \+ size_t input_len, const BlockCipher& bc)++ This unwraps the result of nist_key_wrap_padded, or throws Invalid_Authentication_Tag+ on error.++RFC 3394 Interface+-----------------------------++This is an older interface that was first available (with slight changes) in+1.10, and available in its current form since 2.0 release. It uses a 128-bit,+192-bit, or 256-bit key to encrypt an input key. AES is always used. The input+must be a multiple of 8 bytes; if not an exception is thrown.++This interface is defined in ``rfc3394.h``.++.. cpp:function:: secure_vector<uint8_t> rfc3394_keywrap(const secure_vector<uint8_t>& key, \+ const SymmetricKey& kek)++ Wrap the input key using kek (the key encryption key), and return the result. It will+ be 8 bytes longer than the input key.++.. cpp:function:: secure_vector<uint8_t> rfc3394_keyunwrap(const secure_vector<uint8_t>& key, \+ const SymmetricKey& kek)++ Unwrap a key wrapped with rfc3394_keywrap.++
+ third_party/botan/doc/api_ref/message_auth_codes.rst view
@@ -0,0 +1,268 @@++.. _mac:++Message Authentication Codes (MAC)+===================================++A Message Authentication Code algorithm computes a tag over a message utilizing+a shared secret key. Thus a valid tag confirms the authenticity and integrity of+the message. Only entities in possession of the shared secret key are able to+verify the tag.++.. note::++ When combining a MAC with unauthenticated encryption mode, prefer to first+ encrypt the message and then MAC the ciphertext. The alternative is to MAC+ the plaintext, which depending on exact usage can suffer serious security+ issues. For a detailed discussion of this issue see the paper "The Order of+ Encryption and Authentication for Protecting Communications" by Hugo+ Krawczyk++The Botan MAC computation is split into five stages.++#. Instantiate the MAC algorithm.+#. Set the secret key.+#. Process IV.+#. Process data.+#. Finalize the MAC computation.++.. cpp:class:: MessageAuthenticationCode++ .. cpp:function:: std::string name() const++ Returns a human-readable string of the name of this algorithm.++ .. cpp:function:: void clear()++ Clear the key.++ .. cpp:function:: MessageAuthenticationCode* clone() const++ Return a newly allocated object of the same type as this one.++ .. cpp:function:: void set_key(const uint8_t* key, size_t length)++ Set the shared MAC key for the calculation. This function has to be called before the data is processed.++ .. cpp:function:: bool valid_keylength(size_t length) const++ This function returns true if and only if *length* is a valid+ keylength for the algorithm.++ .. cpp:function:: size_t minimum_keylength() const++ Return the smallest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: size_t maximum_keylength() const++ Return the largest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: void start(const uint8_t* nonce, size_t nonce_len)++ Set the IV for the MAC calculation. Note that not all MAC algorithms require an IV.+ If an IV is required, the function has to be called before the data is processed.+ For algorithms that don't require it, the call can be omitted, or else called+ with ``nonce_len`` of zero.++ .. cpp:function:: void update(const uint8_t* input, size_t length)++ Process the passed data.++ .. cpp:function:: void update(const secure_vector<uint8_t>& in)++ Process the passed data.++ .. cpp:function:: void update(uint8_t in)++ Process a single byte.++ .. cpp:function:: void final(uint8_t* out)++ Complete the MAC computation and write the calculated tag to the passed byte array.++ .. cpp:function:: secure_vector<uint8_t> final()++ Complete the MAC computation and return the calculated tag.++ .. cpp:function:: bool verify_mac(const uint8_t* mac, size_t length)++ Finalize the current MAC computation and compare the result to the passed+ ``mac``. Returns ``true``, if the verification is successful and false+ otherwise.+++Code Examples+------------------------++The following example computes an HMAC with a random key then verifies the tag.++ #include <botan/mac.h>+ #include <botan/hex.h>+ #include <botan/system_rng.h>+ #include <assert.h>++ std::string compute_mac(const std::string& msg, const Botan::secure_vector<uint8_t>& key)+ {+ auto hmac = Botan::MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");++ hmac->set_key(key);+ hmac->update(msg);++ return Botan::hex_encode(hmac->final());+ }++ int main()+ {+ Botan::System_RNG rng;++ const auto key = rng.random_vec(32); // 256 bit random key++ // "Message" != "Mussage" so tags will also not match+ std::string tag1 = compute_mac("Message", key);+ std::string tag2 = compute_mac("Mussage", key);+ assert(tag1 != tag2);++ // Recomputing with original input message results in identical tag+ std::string tag3 = compute_mac("Message", key);+ assert(tag1 == tag3);+ }+++The following example code computes a AES-256 GMAC and subsequently verifies the+tag. Unlike most other MACs, GMAC requires a nonce *which must not repeat or+all security is lost*.++.. code-block:: cpp++ #include <botan/mac.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ const std::vector<uint8_t> key = Botan::hex_decode("1337133713371337133713371337133713371337133713371337133713371337");+ const std::vector<uint8_t> nonce = Botan::hex_decode("FFFFFFFFFFFFFFFFFFFFFFFF");+ const std::vector<uint8_t> data = Botan::hex_decode("6BC1BEE22E409F96E93D7E117393172A");+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create("GMAC(AES-256)"));+ if(!mac)+ return 1;+ mac->set_key(key);+ mac->start(nonce);+ mac->update(data);+ Botan::secure_vector<uint8_t> tag = mac->final();+ std::cout << mac->name() << ": " << Botan::hex_encode(tag) << std::endl;++ //Verify created MAC+ mac->start(nonce);+ mac->update(data);+ std::cout << "Verification: " << (mac->verify_mac(tag) ? "success" : "failure");+ return 0;+ }++The following example code computes a valid AES-128 CMAC tag and modifies the+data to demonstrate a MAC verification failure.++.. code-block:: cpp++ #include <botan/mac.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ const std::vector<uint8_t> key = Botan::hex_decode("2B7E151628AED2A6ABF7158809CF4F3C");+ std::vector<uint8_t> data = Botan::hex_decode("6BC1BEE22E409F96E93D7E117393172A");+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create("CMAC(AES-128)"));+ if(!mac)+ return 1;+ mac->set_key(key);+ mac->update(data);+ Botan::secure_vector<uint8_t> tag = mac->final();+ //Corrupting data+ data.back()++;+ //Verify with corrupted data+ mac->update(data);+ std::cout << "Verification with malformed data: " << (mac->verify_mac(tag) ? "success" : "failure");+ return 0;+ }++Available MACs+------------------------------------------++Currently the following MAC algorithms are available in Botan. In new code,+default to HMAC with a strong hash like SHA-256 or SHA-384.++CBC-MAC+~~~~~~~~~~~~++An older authentication code based on a block cipher. Serious security problems,+in particular **insecure** if messages of several different lengths are+authenticated. Avoid unless required for compatibility.++Available if ``BOTAN_HAS_CBC_MAC`` is defined.++.. warning::+ CBC-MAC support is deprecated and will be removed in a future major release.++CMAC+~~~~~~~~~~~~++A modern CBC-MAC variant that avoids the security problems of plain CBC-MAC.+Approved by NIST. Also sometimes called OMAC.++Available if ``BOTAN_HAS_CMAC`` is defined.++GMAC+~~~~~~~~~~~~++GMAC is related to the GCM authenticated cipher mode. It is quite slow unless+hardware support for carryless multiplications is available. A new nonce+must be used with **each** message authenticated, or otherwise all security is+lost.++Available if ``BOTAN_HAS_GMAC`` is defined.++.. warning::+ Due to the nonce requirement, GMAC is exceptionally fragile. Avoid it unless+ absolutely required.++HMAC+~~~~~~~~~~~~++A message authentication code based on a hash function. Very commonly used.++Available if ``BOTAN_HAS_HMAC`` is defined.++Poly1305+~~~~~~~~~~~~++A polynomial mac (similar to GMAC). Very fast, but tricky to use safely. Forms+part of the ChaCha20Poly1305 AEAD mode. A new key must be used for **each**+message, or all security is lost.++Available if ``BOTAN_HAS_POLY1305`` is defined.++.. warning::+ Due to the nonce requirement, Poly1305 is exceptionally fragile. Avoid it unless+ absolutely required.++SipHash+~~~~~~~~~~~~++A modern and very fast PRF. Produces only a 64-bit output. Defaults to+"SipHash(2,4)" which is the recommended configuration, using 2 rounds for each+input block and 4 rounds for finalization.++Available if ``BOTAN_HAS_SIPHASH`` is defined.++X9.19-MAC+~~~~~~~~~~~~++A CBC-MAC variant sometimes used in finance. Always uses DES.+Sometimes called the "DES retail MAC", also standardized in ISO 9797-1.++It is slow and has known attacks. Avoid unless required.++Available if ``BOTAN_HAS_X919_MAC`` is defined.
+ third_party/botan/doc/api_ref/otp.rst view
@@ -0,0 +1,98 @@+One Time Passwords+========================++.. versionadded:: 2.2.0++One time password schemes are a user authentication method that relies on a+fixed secret key which is used to derive a sequence of short passwords, each of+which is accepted only once. Commonly this is used to implement two-factor+authentication (2FA), where the user authenticates using both a conventional+password (or a public key signature) and an OTP generated by a small device such+as a mobile phone.++Botan implements the HOTP and TOTP schemes from RFC 4226 and 6238.++Since the range of possible OTPs is quite small, applications must rate limit+OTP authentication attempts to some small number per second. Otherwise an attacker+could quickly try all 1000000 6-digit OTPs in a brief amount of time.++HOTP+^^^^^^++HOTP generates OTPs that are a short numeric sequence, between 6 and 8 digits+(most applications use 6 digits), created using the HMAC of a 64-bit counter+value. If the counter ever repeats the OTP will also repeat, thus both parties+must assure the counter only increments and is never repeated or+decremented. Thus both client and server must keep track of the next counter+expected.++Anyone with access to the client-specific secret key can authenticate as that+client, so it should be treated with the same security consideration as would be+given to any other symmetric key or plaintext password.++.. cpp:class:: HOTP++ Implement counter-based OTP++ .. cpp:function:: HOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", size_t digits = 6)++ Initialize an HOTP instance with a secret key (specific to each client),+ a hash algorithm (must be SHA-1, SHA-256, or SHA-512), and the number of+ digits with each OTP (must be 6, 7, or 8).++ In RFC 4226, HOTP is only defined with SHA-1, but many HOTP+ implementations support SHA-256 as an extension. The collision attacks+ on SHA-1 do not have any known effect on HOTP's security.++ .. cpp:function:: uint32_t generate_hotp(uint64_t counter)++ Return the OTP associated with a specific counter value.++ .. cpp:function:: std::pair<bool,uint64_t> verify_hotp(uint32_t otp, \+ uint64_t starting_counter, size_t resync_range = 0)++ Check if a provided OTP matches the one that should be generated for+ the specified counter.++ The *starting_counter* should be the counter of the last successful+ authentication plus 1. If *resync_resync* is greater than 0, some number+ of counter values above *starting_counter* will also be checked if+ necessary. This is useful for instance when a client mistypes an OTP on+ entry; the authentication will fail so the server will not update its+ counter, but the client device will subsequently show the OTP for the+ next counter. Depending on the environment a *resync_range* of 3 to 10+ might be appropriate.++ Returns a pair of (is_valid,next_counter_to_use). If the OTP is invalid+ then always returns (false,starting_counter), since the last successful+ authentication counter has not changed.+++TOTP+^^^^^^^^^^++TOTP is based on the same algorithm as HOTP, but instead of a counter a+timestamp is used.++.. cpp:class:: TOTP++ .. cpp:function:: TOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", \+ size_t digits = 6, size_t time_step = 30)++ Setup to perform TOTP authentication using secret key *key*.++ .. cpp:function:: uint32_t generate_totp(std::chrono::system_clock::time_point time_point)++ .. cpp:function:: uint32_t generate_totp(uint64_t unix_time)++ Generate and return a TOTP code based on a timestamp.++ .. cpp:function:: bool verify_totp(uint32_t otp, std::chrono::system_clock::time_point time, \+ size_t clock_drift_accepted = 0)++ .. cpp:function:: bool verify_totp(uint32_t otp, uint64_t unix_time, \+ size_t clock_drift_accepted = 0)++ Return true if the provided OTP code is correct for the provided+ timestamp. If required, use *clock_drift_accepted* to deal with+ the client and server having slightly different clocks.
+ third_party/botan/doc/api_ref/passhash.rst view
@@ -0,0 +1,219 @@+Password Hashing+========================================++Storing passwords for user authentication purposes in plaintext is the+simplest but least secure method; when an attacker compromises the+database in which the passwords are stored, they immediately gain+access to all of them. Often passwords are reused among multiple+services or machines, meaning once a password to a single service is+known an attacker has a substantial head start on attacking other+machines.++The general approach is to store, instead of the password, the output+of a one way function of the password. Upon receiving an+authentication request, the authenticating party can recompute the one way+function and compare the value just computed with the one that was+stored. If they match, then the authentication request succeeds. But+when an attacker gains access to the database, they only have the+output of the one way function, not the original password.++Common hash functions such as SHA-256 are one way, but used alone they+have problems for this purpose. What an attacker can do, upon gaining+access to such a stored password database, is hash common dictionary+words and other possible passwords, storing them in a list. Then he+can search through his list; if a stored hash and an entry in his list+match, then he has found the password. Even worse, this can happen+*offline*: an attacker can begin hashing common passwords days,+months, or years before ever gaining access to the database. In+addition, if two users choose the same password, the one way function+output will be the same for both of them, which will be visible upon+inspection of the database.++There are two solutions to these problems: salting and+iteration. Salting refers to including, along with the password, a+randomly chosen value which perturbs the one way function. Salting can+reduce the effectiveness of offline dictionary generation, because for+each potential password, an attacker would have to compute the one way+function output for all possible salts. It also prevents the same+password from producing the same output, as long as the salts do not+collide. Choosing n-bit salts randomly, salt collisions become likely+only after about 2\ :sup:\ `(n/2)` salts have been generated. Choosing a+large salt (say 80 to 128 bits) ensures this is very unlikely. Note+that in password hashing salt collisions are unfortunate, but not+fatal - it simply allows the attacker to attack those two passwords in+parallel easier than they would otherwise be able to.++The other approach, iteration, refers to the general technique of+forcing multiple one way function evaluations when computing the+output, to slow down the operation. For instance if hashing a single+password requires running SHA-256 100,000 times instead of just once,+that will slow down user authentication by a factor of 100,000, but+user authentication happens quite rarely, and usually there are more+expensive operations that need to occur anyway (network and database+I/O, etc). On the other hand, an attacker who is attempting to break a+database full of stolen password hashes will be seriously+inconvenienced by a factor of 100,000 slowdown; they will be able to+only test at a rate of .0001% of what they would without iterations+(or, equivalently, will require 100,000 times as many zombie botnet+hosts).++Memory usage while checking a password is also a consideration; if the+computation requires using a certain minimum amount of memory, then an+attacker can become memory-bound, which may in particular make+customized cracking hardware more expensive. Some password hashing+designs, such as scrypt, explicitly attempt to provide this. The+bcrypt approach requires over 4 KiB of RAM (for the Blowfish key+schedule) and may also make some hardware attacks more expensive.++Botan provides three techniques for password hashing: Argon2, bcrypt, and+passhash9 (based on PBKDF2).++Argon2+----------------------------------------++.. versionadded:: 2.11.0++Argon2 is the winner of the PHC (Password Hashing Competition) and provides+a tunable memory hard password hash. It has a standard string encoding, which looks like::++ "$argon2i$v=19$m=8192,t=10,p=3$YWFhYWFhYWE$itkWB9ODqTd85wUsoib7pfpVTNGMOu0ZJan1odl25V8"++Argon2 has three tunable parameters: ``M``, ``p``, and ``t``. ``M`` gives the+total memory consumption of the algorithm in kilobytes. Increasing ``p``+increases the available parallelism of the computation. The ``t`` parameter+gives the number of passes which are made over the data.++.. note::+ Currently Botan does not make use of ``p`` > 1, so it is best to set it to 1+ to minimize any advantage to highly parallel cracking attempts.++There are three variants of Argon2, namely Argon2d, Argon2i and Argon2id.+Argon2d uses data dependent table lookups with may leak information about the+password via side channel attacks, and is **not recommended** for password+hashing. Argon2i uses data independent table lookups and is immune to these+attacks, but at the cost of requiring higher ``t`` for security. Argon2id uses a+hybrid approach which is thought to be highly secure. The algorithm designers+recommend using Argon2id with ``t`` and ``p`` both equal to 1 and ``M`` set to+the largest amount of memory usable in your environment.++.. cpp:function:: std::string argon2_generate_pwhash(const char* password, size_t password_len, \+ RandomNumberGenerator& rng, \+ size_t p, size_t M, size_t t, \+ size_t y = 2, size_t salt_len = 16, size_t output_len = 32)++ Generate an Argon2 hash of the specified password. The ``y`` parameter specifies+ the variant: 0 for Argon2d, 1 for Argon2i, and 2 for Argon2id.++.. cpp:function:: bool argon2_check_pwhash(const char* password, size_t password_len, \+ const std::string& hash)++ Verify an Argon2 password hash against the provided password. Returns false if+ the input hash seems malformed or if the computed hash does not match.++Bcrypt+----------------------------------------++`Bcrypt <https://www.usenix.org/legacy/event/usenix99/provos/provos.pdf>`_ is a+password hashing scheme originally designed for use in OpenBSD, but numerous+other implementations exist. It is made available by including ``bcrypt.h``.++It has the advantage that it requires a small amount (4K) of fast RAM+to compute, which can make hardware password cracking somewhat more+expensive.++Bcrypt provides outputs that look like this::++ "$2a$12$7KIYdyv8Bp32WAvc.7YvI.wvRlyVn0HP/EhPmmOyMQA4YKxINO0p2"++.. note::++ Due to the design of bcrypt, the password is effectively truncated at 72+ characters; further characters are ignored and do not change the hash. To+ support longer passwords, one common approach is to pre-hash the password+ with SHA-256, then run bcrypt using the hex or base64 encoding of the hash as+ the password. (Many bcrypt implementations truncate the password at the first+ NULL character, so hashing the raw binary SHA-256 may cause problems. Botan's+ bcrypt implementation will hash whatever values are given in the+ ``std::string`` including any embedded NULLs so this is not an issue, but+ might cause interop problems if another library needs to validate the+ password hashes.)++.. cpp:function:: std::string generate_bcrypt(const std::string& password, \+ RandomNumberGenerator& rng, \+ uint16_t work_factor = 12, \+ char bcrypt_version = "a")++ Takes the password to hash, a rng, and a work factor.+ The resulting password hash is returned as a string.++ Higher work factors increase the amount of time the algorithm runs,+ increasing the cost of cracking attempts. The increase is exponential, so a+ work factor of 12 takes roughly twice as long as work factor 11. The default+ work factor was set to 10 up until the 2.8.0 release.++ It is recommended to set the work factor as high as your system can tolerate+ (from a performance and latency perspective) since higher work factors greatly+ improve the security against GPU-based attacks. For example, for protecting+ high value administrator passwords, consider using work factor 15 or 16; at+ these work factors each bcrypt computation takes several seconds. Since admin+ logins will be relatively uncommon, it might be acceptable for each login+ attempt to take some time. As of 2018, a good password cracking rig (with 8+ NVIDIA 1080 cards) can attempt about 1 billion bcrypt computations per month+ for work factor 13. For work factor 12, it can do twice as many. For work+ factor 15, it can do only one quarter as many attempts.++ Due to bugs affecting various implementations of bcrypt, several different+ variants of the algorithm are defined. As of 2.7.0 Botan supports generating+ (or checking) the 2a, 2b, and 2y variants. Since Botan has never been+ affected by any of the bugs which necessitated these version upgrades, all+ three versions are identical beyond the version identifier. Which variant to+ use is controlled by the ``bcrypt_version`` argument.++ The bcrypt work factor must be at least 4 (though at this work factor bcrypt+ is not very secure). The bcrypt format allows up to 31, but Botan currently+ rejects all work factors greater than 18 since even that work factor requires+ roughly 15 seconds of computation on a fast machine.++.. cpp:function:: bool check_bcrypt(const std::string& password, \+ const std::string& hash)++ Takes a password and a bcrypt output and returns true if the+ password is the same as the one that was used to generate the+ bcrypt hash.++.. _passhash9:++Passhash9+----------------------------------------++Botan also provides a password hashing technique called passhash9, in+``passhash9.h``, which is based on PBKDF2.++Passhash9 hashes look like::++ "$9$AAAKxwMGNPSdPkOKJS07Xutm3+1Cr3ytmbnkjO6LjHzCMcMQXvcT"++This function should be secure with the proper parameters, and will remain in+the library for the foreseeable future, but it is specific to Botan rather than+being a widely used password hash. Prefer bcrypt or Argon2.++.. warning::++ This password format string ("$9$") conflicts with the format used+ for scrypt password hashes on Cisco systems.++.. cpp:function:: std::string generate_passhash9(const std::string& password, \+ RandomNumberGenerator& rng, uint16_t work_factor = 15, uint8_t alg_id = 4)++ Functions much like ``generate_bcrypt``. The last parameter,+ ``alg_id``, specifies which PRF to use. Currently defined values are+ 0: HMAC(SHA-1), 1: HMAC(SHA-256), 2: CMAC(Blowfish), 3: HMAC(SHA-384), 4: HMAC(SHA-512)++ The work factor must be greater than zero and less than 512. This performs+ 10000 * ``work_factor`` PBKDF2 iterations, using 96 bits of salt taken from+ ``rng``. Using work factor of 10 or more is recommended.++.. cpp:function:: bool check_passhash9(const std::string& password, \+ const std::string& hash)++ Functions much like ``check_bcrypt``
+ third_party/botan/doc/api_ref/pbkdf.rst view
@@ -0,0 +1,190 @@++.. _pbkdf:++Password Based Key Derivation+========================================++Often one needs to convert a human readable password into a cryptographic+key. It is useful to slow down the computation of these computations in order to+reduce the speed of brute force search, thus they are parameterized in some+way which allows their required computation to be tuned.++PBKDF+---------++:cpp:class:`PBKDF` is the older API for this functionality, presented in header+``pbkdf.h``. It does not support Scrypt, nor will it be able to support other+future hashes (such as Argon2) that may be added in the future. In addition,+this API requires the passphrase be entered as a ``std::string``, which means+the secret will be stored in memory that will not be zeroed.++.. cpp:class:: PBKDF++ .. cpp:function:: void pbkdf_iterations(uint8_t out[], size_t out_len, \+ const std::string& passphrase, \+ const uint8_t salt[], size_t salt_len, \+ size_t iterations) const++ Run the PBKDF algorithm for the specified number of iterations,+ with the given salt, and write output to the buffer.++ .. cpp:function:: void pbkdf_timed(uint8_t out[], size_t out_len, \+ const std::string& passphrase, \+ const uint8_t salt[], size_t salt_len, \+ std::chrono::milliseconds msec, \+ size_t& iterations) const++ Choose (via short run-time benchmark) how many iterations to perform+ in order to run for roughly msec milliseconds. Writes the number+ of iterations used to reference argument.++ .. cpp:function:: OctetString derive_key( \+ size_t output_len, const std::string& passphrase, \+ const uint8_t* salt, size_t salt_len, \+ size_t iterations) const++ Computes a key from *passphrase* and the *salt* (of length+ *salt_len* bytes) using an algorithm-specific interpretation of+ *iterations*, producing a key of length *output_len*.++ Use an iteration count of at least 10000. The salt should be+ randomly chosen by a good random number generator (see+ :ref:`random_number_generators` for how), or at the very least+ unique to this usage of the passphrase.++ If you call this function again with the same parameters, you will+ get the same key.++PasswordHash+--------------++.. versionadded:: 2.8.0++This API has two classes, one representing the algorithm (such as+"PBKDF2(SHA-256)", or "Scrypt") and the other representing a specific instance+of the problem which is fully specified (say "Scrypt" with N=8192,r=64,p=8).++.. cpp:class:: PasswordHash++ .. cpp:function:: void derive_key(uint8_t out[], size_t out_len, \+ const char* password, const size_t password_len, \+ const uint8_t salt[], size_t salt_len) const++ Derive a key, placing it into output++ .. cpp:function:: std::string to_string() const++ Return a descriptive string including the parameters (iteration count, etc)++The ``PasswordHashFamily`` creates specific instances of ``PasswordHash``:++.. cpp:class:: PasswordHashFamily++ .. cpp:function:: static std::unique_ptr<PasswordHashFamily> create(const std::string& what)++ For example "PBKDF2(SHA-256)", "Scrypt", "OpenPGP-S2K(SHA-384)". Returns+ null if not available.++ .. cpp:function:: std::unique_ptr<PasswordHash> default_params() const++ Create a default instance of the password hashing algorithm. Be warned the+ value returned here may change from release to release.++ .. cpp:function:: std::unique_ptr<PasswordHash> tune(size_t output_len, std::chrono::milliseconds msec) const++ Return a password hash instance tuned to run for approximately ``msec``+ milliseconds when producing an output of length ``output_len``. (Accuracy+ may vary, use the command line utility ``botan pbkdf_tune`` to check.)++ .. cpp:function:: std::unique_ptr<PasswordHash> from_params( \+ size_t i1, size_t i2 = 0, size_t i3 = 0) const+ + Create a password hash using some scheme specific format.+ Eg PBKDF2 and PGP-S2K set iterations in i1+ Scrypt uses N,r,p in i{1-3}+ Bcrypt-PBKDF just has iterations+ Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3}, and Argon2 type is part of the family.+ + Values not needed should be set to 0.++Available Schemes+----------------------++PBKDF2+^^^^^^^^^^^^++PBKDF2 is the "standard" password derivation scheme, widely implemented in many+different libraries. It uses HMAC internally.++Scrypt+^^^^^^^^^^++Scrypt is a relatively newer design which is "memory hard" - in+addition to requiring large amounts of CPU power it uses a large block+of memory to compute the hash. This makes brute force attacks using+ASICs substantially more expensive.++Scrypt is not supported through :cpp:class:`PBKDF`, only :cpp:class:`PasswordHash`,+starting in 2.8.0. In addition, starting in version 2.7.0, scrypt is available+with this function:++.. cpp:function:: void scrypt(uint8_t output[], size_t output_len, \+ const std::string& password, \+ const uint8_t salt[], size_t salt_len, \+ size_t N, size_t r, size_t p)++ Computes the Scrypt using the password and salt, and produces an output+ of arbitrary length.++ The N, r, p parameters control how much work and memory Scrypt+ uses. N is the primary control of the workfactor, and must be a+ power of 2. For interactive logins use 32768, for protection of+ secret keys or backups use 1048576.++ The r parameter controls how 'wide' the internal hashing operation+ is. It also increases the amount of memory that is used. Values+ from 1 to 8 are reasonable.++ Setting p parameter to greater than one splits up the work in a way+ that up to p processors can work in parallel.++ As a general recommendation, use N=32768, r=8, p=1++Argon2+^^^^^^^^^^++.. versionadded:: 2.11.0++Argon2 is the winner of the PHC (Password Hashing Competition) and+provides a tunable memory hard PBKDF.++OpenPGP S2K+^^^^^^^^^^^^++.. warning::++ The OpenPGP algorithm is weak and strange, and should be avoided unless+ implementing OpenPGP.++There are some oddities about OpenPGP's S2K algorithms that are documented+here. For one thing, it uses the iteration count in a strange manner; instead of+specifying how many times to iterate the hash, it tells how many *bytes* should+be hashed in total (including the salt). So the exact iteration count will+depend on the size of the salt (which is fixed at 8 bytes by the OpenPGP+standard, though the implementation will allow any salt size) and the size of+the passphrase.++To get what OpenPGP calls "Simple S2K", set iterations to 0, and do not specify+a salt. To get "Salted S2K", again leave the iteration count at 0, but give an+8-byte salt. "Salted and Iterated S2K" requires an 8-byte salt and some+iteration count (this should be significantly larger than the size of the+longest passphrase that might reasonably be used; somewhere from 1024 to 65536+would probably be about right). Using both a reasonably sized salt and a large+iteration count is highly recommended to prevent password guessing attempts.++PBKDF1+^^^^^^^^^^^^++PBKDF1 is an old scheme that can only produce an output length at most+as long as the hash function. It is deprecated and will be removed in+a future release. It is not supported through :cpp:class:`PasswordHash`.
+ third_party/botan/doc/api_ref/pkcs11.rst view
@@ -0,0 +1,1419 @@+.. _pkcs11:++PKCS#11+========================================++.. versionadded:: 1.11.31++|++PKCS#11 is a platform-independent interface for accessing smart cards and+hardware security modules (HSM). Vendors of PKCS#11 compatible devices usually+provide a so called middleware or "PKCS#11 module" which implements the PKCS#11+standard. This middleware translates calls from the platform-independent PKCS#11+API to device specific calls. So application developers don't have to write smart card+or HSM specific code for each device they want to support.++ .. note::++ The Botan PKCS#11 interface is implemented against version v2.40 of the standard.++Botan wraps the C PKCS#11 API to provide a C++ PKCS#11 interface. This is done+in two levels of abstraction: a low level API (see :ref:`pkcs11_low_level`) and+a high level API (see :ref:`pkcs11_high_level`). The low level API provides+access to all functions that are specified by the standard. The high level API+represents an object oriented approach to use PKCS#11 compatible devices but+only provides a subset of the functions described in the standard.++To use the PKCS#11 implementation the ``pkcs11`` module has to be enabled.++ .. note::++ Both PKCS#11 APIs live in the namespace ``Botan::PKCS11``++.. _pkcs11_low_level:++Low Level API+----------------------------------------++The PKCS#11 standards committee provides header files (``pkcs11.h``, ``pkcs11f.h`` and+``pkcs11t.h``) which define the PKCS#11 API in the C programming language. These+header files could be used directly to access PKCS#11 compatible smart cards or+HSMs. The external header files are shipped with Botan in version v2.4 of the standard. The PKCS#11 low+level API wraps the original PKCS#11 API, but still allows to access all functions described in the+standard and has the advantage that it is a C++ interface with features like RAII, exceptions+and automatic memory management.++The low level API is implemented by the :cpp:class:`LowLevel` class and can be accessed by+including the header ``botan/p11.h``.++Preface+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++All constants that belong together in the PKCS#11 standard are grouped into C+++enum classes. For example the different user types are grouped in the+:cpp:enum:`UserType` enumeration:++.. cpp:enum-class:: UserType : CK_USER_TYPE++ .. cpp:enumerator:: UserType::SO = CKU_SO+ .. cpp:enumerator:: UserType::User = CKU_USER+ .. cpp:enumerator:: UserType::ContextSpecific = CKU_CONTEXT_SPECIFIC++Additionally, all types that are used by the low or high level API are mapped by+type aliases to more C++ like names. For instance:++.. cpp:type:: FunctionListPtr = CK_FUNCTION_LIST_PTR++.. rubric:: C-API Wrapping++There is at least one method in the :cpp:class:`LowLevel` class that corresponds to a PKCS#11+function. For example the :cpp:func:`C_GetSlotList` method in the :cpp:class:`LowLevel` class is defined as follows:++.. cpp:class:: LowLevel++ .. cpp:function:: bool C_GetSlotList(Bbool token_present, SlotId* slot_list_ptr, Ulong* count_ptr, ReturnValue* return_value = ThrowException) const++The :cpp:class:`LowLevel` class calls the PKCS#11 function from the function list of the PKCS#11 module:++ .. code-block:: c++ CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,+ CK_ULONG_PTR pulCount )++Where it makes sense there is also an overload of the :cpp:class:`LowLevel` method to make usage easier and safer:++ .. cpp:function:: bool C_GetSlotList( bool token_present, std::vector<SlotId>& slot_ids, ReturnValue* return_value = ThrowException ) const++With this overload the user of this API just has to pass a vector of :cpp:type:`SlotId` instead of pointers+to preallocated memory for the slot list and the number of elements. Additionally, there is no need+to call the method twice in order to determine the number of elements first.++Another example is the :cpp:func:`C_InitPIN` overload:++ .. cpp:function:: template<typename Talloc> bool C_InitPIN( SessionHandle session, const std::vector<uint8_t, TAlloc>& pin, ReturnValue* return_value = ThrowException ) const++The templated ``pin`` parameter allows to pass the PIN as a ``std::vector<uint8_t>`` or a ``secure_vector<uint8_t>``.+If used with a ``secure_vector`` it is assured that the memory is securely erased when the ``pin`` object is no longer needed.++Error Handling+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++All possible PKCS#11 return values are represented by the enum class:++.. cpp:enum-class:: ReturnValue : CK_RV++All methods of the :cpp:class:`LowLevel` class have a default parameter ``ReturnValue* return_value = ThrowException``.+This parameter controls the error handling of all :cpp:class:`LowLevel` methods. The default+behavior ``return_value = ThrowException`` is to throw an exception if the method does+not complete successfully. If a non-``NULL`` pointer is passed, ``return_value`` receives the+return value of the PKCS#11 function and no exception is thrown. In case ``nullptr`` is+passed as ``return_value``, the exact return value is ignored and the method just returns+``true`` if the function succeeds and ``false`` otherwise.++Getting started+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++An object of this class can be instantiated by providing a :cpp:type:`FunctionListPtr` to the :cpp:class:`LowLevel` constructor:++ .. cpp:function:: explicit LowLevel(FunctionListPtr ptr)++The :cpp:class:`LowLevel` class provides a static method to retrieve a :cpp:type:`FunctionListPtr`+from a PKCS#11 module file:++ .. cpp:function:: static bool C_GetFunctionList(Dynamically_Loaded_Library& pkcs11_module, FunctionListPtr* function_list_ptr_ptr, ReturnValue* return_value = ThrowException)++----------++Code Example: Object Instantiation++ .. code-block:: cpp++ Botan::Dynamically_Loaded_Library pkcs11_module( "C:\\pkcs11-middleware\\library.dll" );+ Botan::PKCS11::FunctionListPtr func_list = nullptr;+ Botan::PKCS11::LowLevel::C_GetFunctionList( pkcs11_module, &func_list );+ Botan::PKCS11::LowLevel p11_low_level( func_list );++----------++Code Example: PKCS#11 Module Initialization++ .. code-block:: cpp++ Botan::PKCS11::LowLevel p11_low_level(func_list);++ Botan::PKCS11::C_InitializeArgs init_args = { nullptr, nullptr, nullptr, nullptr,+ static_cast<CK_FLAGS>(Botan::PKCS11::Flag::OsLockingOk), nullptr };++ p11_low_level.C_Initialize(&init_args);++ // work with the token++ p11_low_level.C_Finalize(nullptr);++More code examples can be found in the test suite in the ``test_pkcs11_low_level.cpp`` file.++.. _pkcs11_high_level:++High Level API+----------------------------------------++The high level API provides access to the most commonly used PKCS#11 functionality in an+object oriented manner. Functionality of the high level API includes:++* Loading/unloading of PKCS#11 modules+* Initialization of tokens+* Change of PIN/SO-PIN+* Session management+* Random number generation+* Enumeration of objects on the token (certificates, public keys, private keys)+* Import/export/deletion of certificates+* Generation/import/export/deletion of RSA and EC public and private keys+* Encryption/decryption using RSA with support for OAEP and PKCS1-v1_5 (and raw)+* Signature generation/verification using RSA with support for PSS and PKCS1-v1_5 (and raw)+* Signature generation/verification using ECDSA+* Key derivation using ECDH++Module+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The :cpp:class:`Module` class represents a PKCS#11 shared library (module) and is defined in+``botan/p11_module.h``.++It is constructed from a a file path to a PKCS#11 module and optional :cpp:type:`C_InitializeArgs`:++.. cpp:class:: Module++ .. code-block:: cpp++ Module(const std::string& file_path, C_InitializeArgs init_args =+ { nullptr, nullptr, nullptr, nullptr, static_cast<CK_FLAGS>(Flag::OsLockingOk), nullptr })++ It loads the shared library and calls :cpp:func:`C_Initialize` with the provided :cpp:type:`C_InitializeArgs`.+ On destruction of the object :cpp:func:`C_Finalize` is called.++There are two more methods in this class. One is for reloading the shared library+and reinitializing the PKCS#11 module:++ .. code-block:: cpp++ void reload(C_InitializeArgs init_args =+ { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });++The other one is for getting general information about the PKCS#11 module:++ .. cpp:function:: Info get_info() const++ This function calls :cpp:func:`C_GetInfo` internally.++----------++Code example:++ .. code-block:: cpp++ Botan::PKCS11::Module module( "C:\\pkcs11-middleware\\library.dll" );++ // Sometimes useful if a newly connected token is not detected by the PKCS#11 module+ module.reload();++ Botan::PKCS11::Info info = module.get_info();++ // print library version+ std::cout << std::to_string( info.libraryVersion.major ) << "."+ << std::to_string( info.libraryVersion.minor ) << std::endl;++Slot+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The :cpp:class:`Slot` class represents a PKCS#11 slot and is defined in+``botan/p11_slot.h``.++A PKCS#11 slot is usually a smart card reader that potentially contains a token.++.. cpp:class:: Slot++ .. cpp:function:: Slot(Module& module, SlotId slot_id)++ To instantiate this class a reference to a :cpp:class:`Module` object and a ``slot_id`` have to be passed+ to the constructor.++ .. cpp:function:: static std::vector<SlotId> get_available_slots(Module& module, bool token_present)++ Retrieve available slot ids by calling this static method.++ The parameter ``token_present`` controls whether all slots or only slots with a+ token attached are returned by this method. This method calls :cpp:func:`C_GetSlotList()`.++ .. cpp:function:: SlotInfo get_slot_info() const++ Returns information about the slot. Calls :cpp:func:`C_GetSlotInfo`.++ .. cpp:function:: TokenInfo get_token_info() const++ Obtains information about a particular token in the system. Calls :cpp:func:`C_GetTokenInfo`.++ .. cpp:function:: std::vector<MechanismType> get_mechanism_list() const++ Obtains a list of mechanism types supported by the slot. Calls :cpp:func:`C_GetMechanismList`.++ .. cpp:function:: MechanismInfo get_mechanism_info(MechanismType mechanism_type) const++ Obtains information about a particular mechanism possibly supported by a slot.+ Calls :cpp:func:`C_GetMechanismInfo`.++ .. cpp:function:: void initialize(const std::string& label, const secure_string& so_pin) const++ Calls :cpp:func:`C_InitToken` to initialize the token. The ``label`` must not exceed 32 bytes.+ The current PIN of the security officer must be passed in ``so_pin`` if the token+ is reinitialized or if it's a factory new token, the ``so_pin`` that is passed will initially be set.++----------++Code example:++ .. code-block:: cpp++ // only slots with connected token+ std::vector<Botan::PKCS11::SlotId> slots = Botan::PKCS11::Slot::get_available_slots( module, true );++ // use first slot+ Botan::PKCS11::Slot slot( module, slots.at( 0 ) );++ // print firmware version of the slot+ Botan::PKCS11::SlotInfo slot_info = slot.get_slot_info();+ std::cout << std::to_string( slot_info.firmwareVersion.major ) << "."+ << std::to_string( slot_info.firmwareVersion.minor ) << std::endl;++ // print firmware version of the token+ Botan::PKCS11::TokenInfo token_info = slot.get_token_info();+ std::cout << std::to_string( token_info.firmwareVersion.major ) << "."+ << std::to_string( token_info.firmwareVersion.minor ) << std::endl;++ // retrieve all mechanisms supported by the token+ std::vector<Botan::PKCS11::MechanismType> mechanisms = slot.get_mechanism_list();++ // retrieve information about a particular mechanism+ Botan::PKCS11::MechanismInfo mech_info =+ slot.get_mechanism_info( Botan::PKCS11::MechanismType::RsaPkcsOaep );++ // maximum RSA key length supported:+ std::cout << mech_info.ulMaxKeySize << std::endl;++ // initialize the token+ Botan::PKCS11::secure_string so_pin( 8, '0' );+ slot.initialize( "Botan PKCS11 documentation test label", so_pin );++Session+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The :cpp:class:`Session` class represents a PKCS#11 session and is defined in ``botan/p11_session.h``.++A session is a logical connection between an application and a token.++.. cpp:class:: Session++ There are two constructors to create a new session and one constructor to+ take ownership of an existing session. The destructor calls+ :cpp:func:`C_Logout` if a user is logged in to this session and always+ :cpp:func:`C_CloseSession`.++ .. cpp:function:: Session(Slot& slot, bool read_only)++ To initialize a session object a :cpp:class:`Slot` has to be specified on which the session+ should operate. ``read_only`` specifies whether the session should be read only or read write.+ Calls :cpp:func:`C_OpenSession`.++ .. cpp:function:: Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback)++ Creates a new session by passing a :cpp:class:`Slot`, session ``flags``, ``callback_data`` and a+ ``notify_callback``. Calls :cpp:func:`C_OpenSession`.++ .. cpp:function:: Session(Slot& slot, SessionHandle handle)++ Takes ownership of an existing session by passing :cpp:class:`Slot` and a session ``handle``.++ .. cpp:function:: SessionHandle release()++ Returns the released :cpp:type:`SessionHandle`++ .. cpp:function:: void login(UserType userType, const secure_string& pin)++ Login to this session by passing :cpp:enum:`UserType` and ``pin``. Calls :cpp:func:`C_Login`.++ .. cpp:function:: void logoff()++ Logout from this session. Not mandatory because on destruction of the :cpp:class:`Session` object+ this is done automatically.++ .. cpp:function:: SessionInfo get_info() const++ Returns information about this session. Calls :cpp:func:`C_GetSessionInfo`.++ .. cpp:function:: void set_pin(const secure_string& old_pin, const secure_string& new_pin) const++ Calls :cpp:func:`C_SetPIN` to change the PIN of the logged in user using the ``old_pin``.++ .. cpp:function:: void init_pin(const secure_string& new_pin)++ Calls :cpp:func:`C_InitPIN` to change or initialize the PIN using the SO_PIN (requires a logged in session).++----------++Code example:++ .. code-block:: cpp++ // open read only session+ {+ Botan::PKCS11::Session read_only_session( slot, true );+ }++ // open read write session+ {+ Botan::PKCS11::Session read_write_session( slot, false );+ }++ // open read write session by passing flags+ {+ Botan::PKCS11::Flags flags =+ Botan::PKCS11::flags( Botan::PKCS11::Flag::SerialSession | Botan::PKCS11::Flag::RwSession );++ Botan::PKCS11::Session read_write_session( slot, flags, nullptr, nullptr );+ }++ // move ownership of a session+ {+ Botan::PKCS11::Session session( slot, false );+ Botan::PKCS11::SessionHandle handle = session.release();++ Botan::PKCS11::Session session2( slot, handle );+ }++ Botan::PKCS11::Session session( slot, false );++ // get session info+ Botan::PKCS11::SessionInfo info = session.get_info();+ std::cout << info.slotID << std::endl;++ // login+ Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };+ session.login( Botan::PKCS11::UserType::User, pin );++ // set pin+ Botan::PKCS11::secure_string new_pin = { '6', '5', '4', '3', '2', '1' };+ session.set_pin( pin, new_pin );++ // logoff+ session.logoff();++ // log in as security officer+ Botan::PKCS11::secure_string so_pin = { '0', '0', '0', '0', '0', '0', '0', '0' };+ session.login( Botan::PKCS11::UserType::SO, so_pin );++ // change pin to old pin+ session.init_pin( pin );++Objects+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++PKCS#11 objects consist of various attributes (:c:type:`CK_ATTRIBUTE`). For example :c:macro:`CKA_TOKEN`+describes if a PKCS#11 object is a session object or a token object. The helper class :cpp:class:`AttributeContainer`+helps with storing these attributes. The class is defined in ``botan/p11_object.h``.++.. cpp:class:: AttributeContainer++Attributes can be set in an :cpp:class:`AttributeContainer` by various ``add_`` methods:++ .. cpp:function:: void add_class(ObjectClass object_class)++ Add a class attribute (:c:macro:`CKA_CLASS` / :cpp:enumerator:`AttributeType::Class`)++ .. cpp:function:: void add_string(AttributeType attribute, const std::string& value)++ Add a string attribute (e.g. :c:macro:`CKA_LABEL` / :cpp:enumerator:`AttributeType::Label`).++ .. cpp:function:: void AttributeContainer::add_binary(AttributeType attribute, const uint8_t* value, size_t length)++ Add a binary attribute (e.g. :c:macro:`CKA_ID` / :cpp:enumerator:`AttributeType::Id`).++ .. cpp:function:: template<typename TAlloc> void AttributeContainer::add_binary(AttributeType attribute, const std::vector<uint8_t, TAlloc>& binary)++ Add a binary attribute by passing a ``vector``/``secure_vector`` (e.g. :c:macro:`CKA_ID` / :cpp:enumerator:`AttributeType::Id`).++ .. cpp:function:: void AttributeContainer::add_bool(AttributeType attribute, bool value)++ Add a bool attribute (e.g. :c:macro:`CKA_SENSITIVE` / :cpp:enumerator:`AttributeType::Sensitive`).++ .. cpp:function:: template<typename T> void AttributeContainer::add_numeric(AttributeType attribute, T value)++ Add a numeric attribute (e.g. :c:macro:`CKA_MODULUS_BITS` / :cpp:enumerator:`AttributeType::ModulusBits`).++.. rubric:: Object Properties++The PKCS#11 standard defines the mandatory and optional attributes for each object class.+The mandatory and optional attribute requirements are mapped in so called property classes.+Mandatory attributes are set in the constructor, optional attributes can be set via ``set_`` methods.++In the top hierarchy is the :cpp:class:`ObjectProperties` class which inherits from the :cpp:class:`AttributeContainer`.+This class represents the common attributes of all PKCS#11 objects.++.. cpp:class:: ObjectProperties : public AttributeContainer++The constructor is defined as follows:++ .. cpp:function:: ObjectProperties(ObjectClass object_class)++ Every PKCS#11 object needs an object class attribute.++The next level defines the :cpp:class:`StorageObjectProperties` class which inherits from+:cpp:class:`ObjectProperties`.++.. cpp:class:: StorageObjectProperties : public ObjectProperties++The only mandatory attribute is the object class, so the constructor is+defined as follows:++ .. cpp:function:: StorageObjectProperties(ObjectClass object_class)++But in contrast to the :cpp:class:`ObjectProperties` class there are various setter methods. For example to+set the :cpp:enumerator:`AttributeType::Label`:++ .. cpp:function:: void set_label(const std::string& label)++ Sets the label description of the object (RFC2279 string).++The remaining hierarchy is defined as follows:++* :cpp:class:`DataObjectProperties` inherits from :cpp:class:`StorageObjectProperties`+* :cpp:class:`CertificateProperties` inherits from :cpp:class:`StorageObjectProperties`+* :cpp:class:`DomainParameterProperties` inherits from :cpp:class:`StorageObjectProperties`+* :cpp:class:`KeyProperties` inherits from :cpp:class:`StorageObjectProperties`+* :cpp:class:`PublicKeyProperties` inherits from :cpp:class:`KeyProperties`+* :cpp:class:`PrivateKeyProperties` inherits from :cpp:class:`KeyProperties`+* :cpp:class:`SecretKeyProperties` inherits from :cpp:class:`KeyProperties`++PKCS#11 objects themselves are represented by the :cpp:class:`Object` class.++.. cpp:class:: Object++Following constructors are defined:++ .. cpp:function:: Object(Session& session, ObjectHandle handle)++ Takes ownership over an existing object.++ .. cpp:function:: Object(Session& session, const ObjectProperties& obj_props)++ Creates a new object with the :cpp:class:`ObjectProperties` provided in ``obj_props``.++The other methods are:++ .. cpp:function:: secure_vector<uint8_t> get_attribute_value(AttributeType attribute) const++ Returns the value of the given attribute (using :cpp:func:`C_GetAttributeValue`)++ .. cpp:function:: void set_attribute_value(AttributeType attribute, const secure_vector<uint8_t>& value) const++ Sets the given value for the attribute (using :cpp:func:`C_SetAttributeValue`)++ .. cpp:function:: void destroy() const++ Destroys the object.++ .. cpp:function:: ObjectHandle copy(const AttributeContainer& modified_attributes) const++ Allows to copy the object with modified attributes.++And static methods to search for objects:++ .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::vector<Attribute>& search_template)++ Searches for all objects of the given type that match ``search_template``.++ .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::string& label)++ Searches for all objects of the given type using the label (:c:macro:`CKA_LABEL`).++ .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::vector<uint8_t>& id)++ Searches for all objects of the given type using the id (:c:macro:`CKA_ID`).++ .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::string& label, const std::vector<uint8_t>& id)++ Searches for all objects of the given type using the label (:c:macro:`CKA_LABEL`) and id (:c:macro:`CKA_ID`).++ .. cpp:function:: template<typename T> static std::vector<T> search(Session& session)++ Searches for all objects of the given type.++.. rubric:: The ObjectFinder++Another way for searching objects is to use the :cpp:class:`ObjectFinder` class. This class+manages calls to the ``C_FindObjects*`` functions: :cpp:func:`C_FindObjectsInit`, :cpp:func:`C_FindObjects`+and :cpp:func:`C_FindObjectsFinal`.++.. cpp:class:: ObjectFinder++The constructor has the following signature:++ .. cpp:function:: ObjectFinder(Session& session, const std::vector<Attribute>& search_template)++ A search can be prepared with an :cpp:class:`ObjectSearcher` by passing a :cpp:class:`Session` and a ``search_template``.++The actual search operation is started by calling the :cpp:func:`find` method:++ .. cpp:function:: std::vector<ObjectHandle> find(std::uint32_t max_count = 100) const++ Starts or continues a search for token and session objects that match a template. ``max_count``+ specifies the maximum number of search results (object handles) that are returned.++ .. cpp:function:: void finish()++ Finishes the search operation manually to allow a new :cpp:class:`ObjectFinder` to exist.+ Otherwise the search is finished by the destructor.++----------++Code example:++ .. code-block:: cpp++ // create an simple data object+ Botan::secure_vector<uint8_t> value = { 0x00, 0x01 ,0x02, 0x03 };+ std::size_t id = 1337;+ std::string label = "test data object";++ // set properties of the new object+ Botan::PKCS11::DataObjectProperties data_obj_props;+ data_obj_props.set_label( label );+ data_obj_props.set_value( value );+ data_obj_props.set_token( true );+ data_obj_props.set_modifiable( true );+ data_obj_props.set_object_id( Botan::DER_Encoder().encode( id ).get_contents_unlocked() );++ // create the object+ Botan::PKCS11::Object data_obj( session, data_obj_props );++ // get label of this object+ Botan::PKCS11::secure_string retrieved_label =+ data_obj.get_attribute_value( Botan::PKCS11::AttributeType::Label );++ // set a new label+ Botan::PKCS11::secure_string new_label = { 'B', 'o', 't', 'a', 'n' };+ data_obj.set_attribute_value( Botan::PKCS11::AttributeType::Label, new_label );++ // copy the object+ Botan::PKCS11::AttributeContainer copy_attributes;+ copy_attributes.add_string( Botan::PKCS11::AttributeType::Label, "copied object" );+ Botan::PKCS11::ObjectHandle copied_obj_handle = data_obj.copy( copy_attributes );++ // search for an object+ Botan::PKCS11::AttributeContainer search_template;+ search_template.add_string( Botan::PKCS11::AttributeType::Label, "Botan" );+ auto found_objs =+ Botan::PKCS11::Object::search<Botan::PKCS11::Object>( session, search_template.attributes() );++ // destroy the object+ data_obj.destroy();++RSA+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++PKCS#11 RSA support is implemented in ``<botan/p11_rsa.h>``.++.. rubric:: RSA Public Keys++PKCS#11 RSA public keys are provided by the class :cpp:class:`PKCS11_RSA_PublicKey`. This class+inherits from :cpp:class:`RSA_PublicKey` and :cpp:class:`Object`. Furthermore there are two property classes defined+to generate and import RSA public keys analogous to the other property classes described+before: :cpp:class:`RSA_PublicKeyGenerationProperties` and :cpp:class:`RSA_PublicKeyImportProperties`.++.. cpp:class:: PKCS11_RSA_PublicKey : public RSA_PublicKey, public Object++ .. cpp:function:: PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 RSA public keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props)++ This constructor can be used to import an existing RSA public key with the :cpp:class:`RSA_PublicKeyImportProperties`+ passed in ``pubkey_props`` to the token.++.. rubric:: RSA Private Keys++The support for PKCS#11 RSA private keys is implemented in a similar way. There are two property+classes: :cpp:class:`RSA_PrivateKeyGenerationProperties` and :cpp:class:`RSA_PrivateKeyImportProperties`. The :cpp:class:`PKCS11_RSA_PrivateKey`+class implements the actual support for PKCS#11 RSA private keys. This class inherits from :cpp:class:`Private_Key`,+:cpp:class:`RSA_PublicKey` and :cpp:class:`Object`. In contrast to the public key class there is a third constructor+to generate private keys directly on the token or in the session and one method to export private keys.++.. cpp:class:: PKCS11_RSA_PrivateKey : public Private_Key, public RSA_PublicKey, public Object++ .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 RSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props)++ This constructor can be used to import an existing RSA private key with the :cpp:class:`RSA_PrivateKeyImportProperties`+ passed in ``priv_key_props`` to the token.++ .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, uint32_t bits, const RSA_PrivateKeyGenerationProperties& priv_key_props)++ Generates a new PKCS#11 RSA private key with bit length provided in ``bits`` and the :cpp:class:`RSA_PrivateKeyGenerationProperties`+ passed in ``priv_key_props``.++ .. cpp:function:: RSA_PrivateKey export_key() const++ Returns the exported :cpp:class:`RSA_PrivateKey`.++PKCS#11 RSA key pairs can be generated with the following free function:++ .. cpp:function:: PKCS11_RSA_KeyPair PKCS11::generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props, const RSA_PrivateKeyGenerationProperties& priv_props)++----------++Code example:++ .. code-block:: cpp++ Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };+ session.login( Botan::PKCS11::UserType::User, pin );++ /************ import RSA private key *************/++ // create private key in software+ Botan::AutoSeeded_RNG rng;+ Botan::RSA_PrivateKey priv_key_sw( rng, 2048 );++ // set the private key import properties+ Botan::PKCS11::RSA_PrivateKeyImportProperties+ priv_import_props( priv_key_sw.get_n(), priv_key_sw.get_d() );++ priv_import_props.set_pub_exponent( priv_key_sw.get_e() );+ priv_import_props.set_prime_1( priv_key_sw.get_p() );+ priv_import_props.set_prime_2( priv_key_sw.get_q() );+ priv_import_props.set_coefficient( priv_key_sw.get_c() );+ priv_import_props.set_exponent_1( priv_key_sw.get_d1() );+ priv_import_props.set_exponent_2( priv_key_sw.get_d2() );++ priv_import_props.set_token( true );+ priv_import_props.set_private( true );+ priv_import_props.set_decrypt( true );+ priv_import_props.set_sign( true );++ // import+ Botan::PKCS11::PKCS11_RSA_PrivateKey priv_key( session, priv_import_props );++ /************ export PKCS#11 RSA private key *************/+ Botan::RSA_PrivateKey exported = priv_key.export_key();++ /************ import RSA public key *************/++ // set the public key import properties+ Botan::PKCS11::RSA_PublicKeyImportProperties pub_import_props( priv_key.get_n(), priv_key.get_e() );+ pub_import_props.set_token( true );+ pub_import_props.set_encrypt( true );+ pub_import_props.set_private( false );++ // import+ Botan::PKCS11::PKCS11_RSA_PublicKey public_key( session, pub_import_props );++ /************ generate RSA private key *************/++ Botan::PKCS11::RSA_PrivateKeyGenerationProperties priv_generate_props;+ priv_generate_props.set_token( true );+ priv_generate_props.set_private( true );+ priv_generate_props.set_sign( true );+ priv_generate_props.set_decrypt( true );+ priv_generate_props.set_label( "BOTAN_TEST_RSA_PRIV_KEY" );++ Botan::PKCS11::PKCS11_RSA_PrivateKey private_key2( session, 2048, priv_generate_props );++ /************ generate RSA key pair *************/++ Botan::PKCS11::RSA_PublicKeyGenerationProperties pub_generate_props( 2048UL );+ pub_generate_props.set_pub_exponent();+ pub_generate_props.set_label( "BOTAN_TEST_RSA_PUB_KEY" );+ pub_generate_props.set_token( true );+ pub_generate_props.set_encrypt( true );+ pub_generate_props.set_verify( true );+ pub_generate_props.set_private( false );++ Botan::PKCS11::PKCS11_RSA_KeyPair rsa_keypair =+ Botan::PKCS11::generate_rsa_keypair( session, pub_generate_props, priv_generate_props );++ /************ RSA encrypt *************/++ Botan::secure_vector<uint8_t> plaintext = { 0x00, 0x01, 0x02, 0x03 };+ Botan::PK_Encryptor_EME encryptor( rsa_keypair.first, rng, "Raw" );+ auto ciphertext = encryptor.encrypt( plaintext, rng );++ /************ RSA decrypt *************/++ Botan::PK_Decryptor_EME decryptor( rsa_keypair.second, rng, "Raw" );+ plaintext = decryptor.decrypt( ciphertext );++ /************ RSA sign *************/++ Botan::PK_Signer signer( rsa_keypair.second, rng, "EMSA4(SHA-256)", Botan::IEEE_1363 );+ auto signature = signer.sign_message( plaintext, rng );++ /************ RSA verify *************/++ Botan::PK_Verifier verifier( rsa_keypair.first, "EMSA4(SHA-256)", Botan::IEEE_1363 );+ auto ok = verifier.verify_message( plaintext, signature );++ECDSA+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++PKCS#11 ECDSA support is implemented in ``<botan/p11_ecdsa.h>``.++.. rubric:: ECDSA Public Keys++PKCS#11 ECDSA public keys are provided by the class :cpp:class:`PKCS11_ECDSA_PublicKey`. This class+inherits from :cpp:class:`PKCS11_EC_PublicKey` and :cpp:class:`ECDSA_PublicKey`. The necessary property classes+are defined in ``<botan/p11_ecc_key.h>``. For public keys there are :cpp:class:`EC_PublicKeyGenerationProperties`+and :cpp:class:`EC_PublicKeyImportProperties`.++.. cpp:class:: PKCS11_ECDSA_PublicKey : public PKCS11_EC_PublicKey, public virtual ECDSA_PublicKey++ .. cpp:function:: PKCS11_ECDSA_PublicKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 ECDSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_ECDSA_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)++ This constructor can be used to import an existing ECDSA public key with the :cpp:class:`EC_PublicKeyImportProperties`+ passed in ``props`` to the token.++ .. cpp:function:: ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key() const++ Returns the exported :cpp:class:`ECDSA_PublicKey`.++.. rubric:: ECDSA Private Keys++The class :cpp:class:`PKCS11_ECDSA_PrivateKey` inherits from :cpp:class:`PKCS11_EC_PrivateKey` and implements support+for PKCS#11 ECDSA private keys. There are two property classes for key generation+and import: :cpp:class:`EC_PrivateKeyGenerationProperties` and :cpp:class:`EC_PrivateKeyImportProperties`.++.. cpp:class:: PKCS11_ECDSA_PrivateKey : public PKCS11_EC_PrivateKey++ .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 ECDSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)++ This constructor can be used to import an existing ECDSA private key with the :cpp:class:`EC_PrivateKeyImportProperties`+ passed in ``props`` to the token.++ .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params, const EC_PrivateKeyGenerationProperties& props)++ This constructor can be used to generate a new ECDSA private key with the :cpp:class:`EC_PrivateKeyGenerationProperties`+ passed in ``props`` on the token. The ``ec_params`` parameter is the DER-encoding of an+ ANSI X9.62 Parameters value.++ .. cpp:function:: ECDSA_PrivateKey export_key() const++ Returns the exported :cpp:class:`ECDSA_PrivateKey`.++PKCS#11 ECDSA key pairs can be generated with the following free function:++ .. cpp:function:: PKCS11_ECDSA_KeyPair PKCS11::generate_ecdsa_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props)++----------++Code example:++ .. code-block:: cpp++ Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };+ session.login( Botan::PKCS11::UserType::User, pin );++ /************ import ECDSA private key *************/++ // create private key in software+ Botan::AutoSeeded_RNG rng;++ Botan::ECDSA_PrivateKey priv_key_sw( rng, Botan::EC_Group( "secp256r1" ) );+ priv_key_sw.set_parameter_encoding( Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID );++ // set the private key import properties+ Botan::PKCS11::EC_PrivateKeyImportProperties priv_import_props(+ priv_key_sw.DER_domain(), priv_key_sw.private_value() );++ priv_import_props.set_token( true );+ priv_import_props.set_private( true );+ priv_import_props.set_sign( true );+ priv_import_props.set_extractable( true );++ // label+ std::string label = "test ECDSA key";+ priv_import_props.set_label( label );++ // import to card+ Botan::PKCS11::PKCS11_ECDSA_PrivateKey priv_key( session, priv_import_props );++ /************ export PKCS#11 ECDSA private key *************/+ Botan::ECDSA_PrivateKey priv_exported = priv_key.export_key();++ /************ import ECDSA public key *************/++ // import to card+ Botan::PKCS11::EC_PublicKeyImportProperties pub_import_props( priv_key_sw.DER_domain(),+ Botan::DER_Encoder().encode( EC2OSP( priv_key_sw.public_point(), Botan::PointGFp::UNCOMPRESSED ),+ Botan::OCTET_STRING ).get_contents_unlocked() );++ pub_import_props.set_token( true );+ pub_import_props.set_verify( true );+ pub_import_props.set_private( false );++ // label+ label = "test ECDSA pub key";+ pub_import_props.set_label( label );++ Botan::PKCS11::PKCS11_ECDSA_PublicKey public_key( session, pub_import_props );++ /************ export PKCS#11 ECDSA public key *************/+ Botan::ECDSA_PublicKey pub_exported = public_key.export_key();++ /************ generate PKCS#11 ECDSA private key *************/+ Botan::PKCS11::EC_PrivateKeyGenerationProperties priv_generate_props;+ priv_generate_props.set_token( true );+ priv_generate_props.set_private( true );+ priv_generate_props.set_sign( true );++ Botan::PKCS11::PKCS11_ECDSA_PrivateKey pk( session,+ Botan::EC_Group( "secp256r1" ).DER_encode( Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID ),+ priv_generate_props );++ /************ generate PKCS#11 ECDSA key pair *************/++ Botan::PKCS11::EC_PublicKeyGenerationProperties pub_generate_props(+ Botan::EC_Group( "secp256r1" ).DER_encode(Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID ) );++ pub_generate_props.set_label( "BOTAN_TEST_ECDSA_PUB_KEY" );+ pub_generate_props.set_token( true );+ pub_generate_props.set_verify( true );+ pub_generate_props.set_private( false );+ pub_generate_props.set_modifiable( true );++ Botan::PKCS11::PKCS11_ECDSA_KeyPair key_pair = Botan::PKCS11::generate_ecdsa_keypair( session,+ pub_generate_props, priv_generate_props );++ /************ PKCS#11 ECDSA sign and verify *************/++ std::vector<uint8_t> plaintext( 20, 0x01 );++ Botan::PK_Signer signer( key_pair.second, rng, "Raw", Botan::IEEE_1363, "pkcs11" );+ auto signature = signer.sign_message( plaintext, rng );++ Botan::PK_Verifier token_verifier( key_pair.first, "Raw", Botan::IEEE_1363, "pkcs11" );+ bool ecdsa_ok = token_verifier.verify_message( plaintext, signature );++ECDH+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++PKCS#11 ECDH support is implemented in ``<botan/p11_ecdh.h>``.++.. rubric:: ECDH Public Keys++PKCS#11 ECDH public keys are provided by the class :cpp:class:`PKCS11_ECDH_PublicKey`. This class+inherits from :cpp:class:`PKCS11_EC_PublicKey`. The necessary property classes+are defined in ``<botan/p11_ecc_key.h>``. For public keys there are :cpp:class:`EC_PublicKeyGenerationProperties`+and :cpp:class:`EC_PublicKeyImportProperties`.++.. cpp:class:: PKCS11_ECDH_PublicKey : public PKCS11_EC_PublicKey++ .. cpp:function:: PKCS11_ECDH_PublicKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 ECDH private keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_ECDH_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)++ This constructor can be used to import an existing ECDH public key with the :cpp:class:`EC_PublicKeyImportProperties`+ passed in ``props`` to the token.++ .. cpp:function:: ECDH_PublicKey export_key() const++ Returns the exported :cpp:class:`ECDH_PublicKey`.++.. rubric:: ECDH Private Keys++The class :cpp:class:`PKCS11_ECDH_PrivateKey` inherits from :cpp:class:`PKCS11_EC_PrivateKey` and :cpp:class:`PK_Key_Agreement_Key`+and implements support for PKCS#11 ECDH private keys. There are two+property classes. One for key generation and one for import: :cpp:class:`EC_PrivateKeyGenerationProperties` and+:cpp:class:`EC_PrivateKeyImportProperties`.++.. cpp:class:: PKCS11_ECDH_PrivateKey : public virtual PKCS11_EC_PrivateKey, public virtual PK_Key_Agreement_Key++ .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, ObjectHandle handle)++ Existing PKCS#11 ECDH private keys can be used by providing an :cpp:type:`ObjectHandle` to the+ constructor.++ .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)++ This constructor can be used to import an existing ECDH private key with the :cpp:class:`EC_PrivateKeyImportProperties`+ passed in ``props`` to the token.++ .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params, const EC_PrivateKeyGenerationProperties& props)++ This constructor can be used to generate a new ECDH private key with the :cpp:class:`EC_PrivateKeyGenerationProperties`+ passed in ``props`` on the token. The ``ec_params`` parameter is the DER-encoding of an+ ANSI X9.62 Parameters value.++ .. cpp:function:: ECDH_PrivateKey export_key() const++ Returns the exported :cpp:class:`ECDH_PrivateKey`.++PKCS#11 ECDH key pairs can be generated with the following free function:++.. cpp:function:: PKCS11_ECDH_KeyPair PKCS11::generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props)++----------++Code example:++ .. code-block:: cpp++ Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };+ session.login( Botan::PKCS11::UserType::User, pin );++ /************ import ECDH private key *************/++ Botan::AutoSeeded_RNG rng;++ // create private key in software+ Botan::ECDH_PrivateKey priv_key_sw( rng, Botan::EC_Group( "secp256r1" ) );+ priv_key_sw.set_parameter_encoding( Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID );++ // set import properties+ Botan::PKCS11::EC_PrivateKeyImportProperties priv_import_props(+ priv_key_sw.DER_domain(), priv_key_sw.private_value() );++ priv_import_props.set_token( true );+ priv_import_props.set_private( true );+ priv_import_props.set_derive( true );+ priv_import_props.set_extractable( true );++ // label+ std::string label = "test ECDH key";+ priv_import_props.set_label( label );++ // import to card+ Botan::PKCS11::PKCS11_ECDH_PrivateKey priv_key( session, priv_import_props );++ /************ export ECDH private key *************/+ Botan::ECDH_PrivateKey exported = priv_key.export_key();++ /************ import ECDH public key *************/++ // set import properties+ Botan::PKCS11::EC_PublicKeyImportProperties pub_import_props( priv_key_sw.DER_domain(),+ Botan::DER_Encoder().encode( EC2OSP( priv_key_sw.public_point(), Botan::PointGFp::UNCOMPRESSED ),+ Botan::OCTET_STRING ).get_contents_unlocked() );++ pub_import_props.set_token( true );+ pub_import_props.set_private( false );+ pub_import_props.set_derive( true );++ // label+ label = "test ECDH pub key";+ pub_import_props.set_label( label );++ // import+ Botan::PKCS11::PKCS11_ECDH_PublicKey pub_key( session, pub_import_props );++ /************ export ECDH private key *************/+ Botan::ECDH_PublicKey exported_pub = pub_key.export_key();++ /************ generate ECDH private key *************/++ Botan::PKCS11::EC_PrivateKeyGenerationProperties priv_generate_props;+ priv_generate_props.set_token( true );+ priv_generate_props.set_private( true );+ priv_generate_props.set_derive( true );++ Botan::PKCS11::PKCS11_ECDH_PrivateKey priv_key2( session,+ Botan::EC_Group( "secp256r1" ).DER_encode( Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID ),+ priv_generate_props );++ /************ generate ECDH key pair *************/++ Botan::PKCS11::EC_PublicKeyGenerationProperties pub_generate_props(+ Botan::EC_Group( "secp256r1" ).DER_encode( Botan::EC_Group_Encoding::EC_DOMPAR_ENC_OID ) );++ pub_generate_props.set_label( label + "_PUB_KEY" );+ pub_generate_props.set_token( true );+ pub_generate_props.set_derive( true );+ pub_generate_props.set_private( false );+ pub_generate_props.set_modifiable( true );++ Botan::PKCS11::PKCS11_ECDH_KeyPair key_pair = Botan::PKCS11::generate_ecdh_keypair(+ session, pub_generate_props, priv_generate_props );++ /************ ECDH derive *************/++ Botan::PKCS11::PKCS11_ECDH_KeyPair key_pair_other = Botan::PKCS11::generate_ecdh_keypair(+ session, pub_generate_props, priv_generate_props );++ Botan::PK_Key_Agreement ka( key_pair.second, rng, "Raw", "pkcs11" );+ Botan::PK_Key_Agreement kb( key_pair_other.second, rng, "Raw", "pkcs11" );++ Botan::SymmetricKey alice_key = ka.derive_key( 32,+ Botan::unlock( Botan::EC2OSP( key_pair_other.first.public_point(),+ Botan::PointGFp::UNCOMPRESSED ) ) );++ Botan::SymmetricKey bob_key = kb.derive_key( 32,+ Botan::unlock( Botan::EC2OSP( key_pair.first.public_point(),+ Botan::PointGFp::UNCOMPRESSED ) ) );++ bool eq = alice_key == bob_key;++RNG+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The PKCS#11 RNG is defined in ``<botan/p11_randomgenerator.h>``. The class :cpp:class:`PKCS11_RNG`+implements the :cpp:class:`Hardware_RNG` interface.++.. cpp:class:: PKCS11_RNG : public Hardware_RNG++ .. cpp:function:: PKCS11_RNG(Session& session)++ A PKCS#11 :cpp:class:`Session` must be passed to instantiate a ``PKCS11_RNG``.++ .. cpp:function:: void randomize(uint8_t output[], std::size_t length) override++ Calls :cpp:func:`C_GenerateRandom` to generate random data.++ .. cpp:function:: void add_entropy(const uint8_t in[], std::size_t length) override++ Calls :cpp:func:`C_SeedRandom` to add entropy to the random generation function of the token/middleware.++----------++Code example:++ .. code-block:: cpp++ Botan::PKCS11::PKCS11_RNG p11_rng( session );++ /************ generate random data *************/+ std::vector<uint8_t> random( 20 );+ p11_rng.randomize( random.data(), random.size() );++ /************ add entropy *************/+ Botan::AutoSeeded_RNG auto_rng;+ auto auto_rng_random = auto_rng.random_vec( 20 );+ p11_rng.add_entropy( auto_rng_random.data(), auto_rng_random.size() );++ /************ use PKCS#11 RNG to seed HMAC_DRBG *************/+ Botan::HMAC_DRBG drbg( Botan::MessageAuthenticationCode::create( "HMAC(SHA-512)" ), p11_rng );+ drbg.randomize( random.data(), random.size() );++Token Management Functions+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The header file ``<botan/p11.h>`` also defines some free functions for token management:++ .. cpp:function:: void initialize_token(Slot& slot, const std::string& label, const secure_string& so_pin, const secure_string& pin)++ Initializes a token by passing a :cpp:class:`Slot`, a ``label`` and the ``so_pin`` of the security officer.++ .. cpp:function:: void change_pin(Slot& slot, const secure_string& old_pin, const secure_string& new_pin)++ Change PIN with ``old_pin`` to ``new_pin``.++ .. cpp:function:: void change_so_pin(Slot& slot, const secure_string& old_so_pin, const secure_string& new_so_pin)++ Change SO_PIN with ``old_so_pin`` to new ``new_so_pin``.++ .. cpp:function:: void set_pin(Slot& slot, const secure_string& so_pin, const secure_string& pin)++ Sets user ``pin`` with ``so_pin``.++----------++Code example:++ .. code-block:: cpp++ /************ set pin *************/++ Botan::PKCS11::Module module( Middleware_path );++ // only slots with connected token+ std::vector<Botan::PKCS11::SlotId> slots = Botan::PKCS11::Slot::get_available_slots( module, true );++ // use first slot+ Botan::PKCS11::Slot slot( module, slots.at( 0 ) );++ Botan::PKCS11::secure_string so_pin = { '1', '2', '3', '4', '5', '6', '7', '8' };+ Botan::PKCS11::secure_string pin = { '1', '2', '3', '4', '5', '6' };+ Botan::PKCS11::secure_string test_pin = { '6', '5', '4', '3', '2', '1' };++ // set pin+ Botan::PKCS11::set_pin( slot, so_pin, test_pin );++ // change back+ Botan::PKCS11::set_pin( slot, so_pin, pin );++ /************ initialize *************/+ Botan::PKCS11::initialize_token( slot, "Botan handbook example", so_pin, pin );++ /************ change pin *************/+ Botan::PKCS11::change_pin( slot, pin, test_pin );++ // change back+ Botan::PKCS11::change_pin( slot, test_pin, pin );++ /************ change security officer pin *************/+ Botan::PKCS11::change_so_pin( slot, so_pin, test_pin );++ // change back+ Botan::PKCS11::change_so_pin( slot, test_pin, so_pin );++X.509+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The header file ``<botan/p11_x509.h>`` defines the property class :cpp:class:`X509_CertificateProperties`+and the class :cpp:class:`PKCS11_X509_Certificate`.++.. cpp:class:: PKCS11_X509_Certificate : public Object, public X509_Certificate++ .. cpp:function:: PKCS11_X509_Certificate(Session& session, ObjectHandle handle)++ Allows to use existing certificates on the token by passing a valid :cpp:type:`ObjectHandle`.++ .. cpp:function:: PKCS11_X509_Certificate(Session& session, const X509_CertificateProperties& props)++ Allows to import an existing X.509 certificate to the token with the :cpp:class:`X509_CertificateProperties`+ passed in ``props``.++----------++Code example:++ .. code-block:: cpp++ // load existing certificate+ Botan::X509_Certificate root( "test.crt" );++ // set props+ Botan::PKCS11::X509_CertificateProperties props(+ Botan::DER_Encoder().encode( root.subject_dn() ).get_contents_unlocked(), root.BER_encode() );++ props.set_label( "Botan PKCS#11 test certificate" );+ props.set_private( false );+ props.set_token( true );++ // import+ Botan::PKCS11::PKCS11_X509_Certificate pkcs11_cert( session, props );++ // load by handle+ Botan::PKCS11::PKCS11_X509_Certificate pkcs11_cert2( session, pkcs11_cert.handle() );++Tests+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The PKCS#11 tests are not executed automatically because the depend on an external+PKCS#11 module/middleware. The test tool has to be executed with ``--pkcs11-lib=``+followed with the path of the PKCS#11 module and a second argument which controls the+PKCS#11 tests that are executed. Passing ``pkcs11`` will execute all PKCS#11 tests but it's+also possible to execute only a subset with the following arguments:++- pkcs11-ecdh+- pkcs11-ecdsa+- pkcs11-lowlevel+- pkcs11-manage+- pkcs11-module+- pkcs11-object+- pkcs11-rng+- pkcs11-rsa+- pkcs11-session+- pkcs11-slot+- pkcs11-x509++The following PIN and SO-PIN/PUK values are used in tests:++- PIN 123456+- SO-PIN/PUK 12345678++ .. warning::++ Unlike the CardOS (4.4, 5.0, 5.3), the aforementioned SO-PIN/PUK is+ inappropriate for Gemalto (IDPrime MD 3840) cards, as it must be a byte array+ of length 24. For this reason some of the tests for Gemalto card involving+ SO-PIN will fail. You run into a risk of exceding login attempts and as a+ result locking your card! Currently, specifying pin via command-line option+ is not implemented, and therefore the desired PIN must be modified in the+ header src/tests/test_pkcs11.h:++ .. code-block:: cpp++ // SO PIN is expected to be set to "12345678" prior to running the tests+ const std::string SO_PIN = "12345678";+ const auto SO_PIN_SECVEC = Botan::PKCS11::secure_string(SO_PIN.begin(), SO_PIN.end());+++Tested/Supported Smartcards+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++You are very welcome to contribute your own test results for other testing environments or other cards.+++Test results+++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| Smartcard | Status | OS | Midleware | Botan | Errors |++=====================================+===========================================+===================================================+===================================================+===================================================+===================================================++| CardOS 4.4 | mostly works | Windows 10, 64-bit, version 1709 | API Version 5.4.9.77 (Cryptoki v2.11) | 2.4.0, Cryptoki v2.40 | [50]_ |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| CardOS 5.0 | mostly works | Windows 10, 64-bit, version 1709 | API Version 5.4.9.77 (Cryptoki v2.11) | 2.4.0, Cryptoki v2.40 | [51]_ |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| CardOS 5.3 | mostly works | Windows 10, 64-bit, version 1709 | API Version 5.4.9.77 (Cryptoki v2.11) | 2.4.0, Cryptoki v2.40 | [52]_ |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| CardOS 5.3 | mostly works | Windows 10, 64-bit, version 1903 | API Version 5.5.1 (Cryptoki v2.11) | 2.12.0 unreleased, Cryptoki v2.40 | [53]_ |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| Gemalto IDPrime MD 3840 | mostly works | Windows 10, 64-bit, version 1709 | IDGo 800, v1.2.4 (Cryptoki v2.20) | 2.4.0, Cryptoki v2.40 | [54]_ |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| SoftHSM 2.3.0 (OpenSSL 1.0.2g) | works | Windows 10, 64-bit, version 1709 | Cryptoki v2.40 | 2.4.0, Cryptoki v2.40 | |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------++| SoftHSM 2.5.0 (OpenSSL 1.1.1) | works | Windows 10, 64-bit, version 1803 | Cryptoki v2.40 | 2.11.0, Cryptoki v2.40 | |++-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+++.. [50] Failing operations for CardOS 4.4:++ - object_copy [20]_++ - rsa_privkey_export [21]_+ - rsa_generate_private_key [22]_+ - rsa_sign_verify [23]_++ - ecdh_privkey_import [3]_+ - ecdh_privkey_export [2]_+ - ecdh_pubkey_import [4]_+ - ecdh_pubkey_export [4]_+ - ecdh_generate_private_key [3]_+ - ecdh_generate_keypair [3]_+ - ecdh_derive [3]_++ - ecdsa_privkey_import [3]_+ - ecdsa_privkey_export [2]_+ - ecdsa_pubkey_import [4]_+ - ecdsa_pubkey_export [4]_+ - ecdsa_generate_private_key [3]_+ - ecdsa_generate_keypair [3]_+ - ecdsa_sign_verify [3]_++ - rng_add_entropy [5]_+++.. [51] Failing operations for CardOS 5.0++ - object_copy [20]_++ - rsa_privkey_export [21]_+ - rsa_generate_private_key [22]_+ - rsa_sign_verify [23]_++ - ecdh_privkey_export [2]_+ - ecdh_pubkey_import [4]_+ - ecdh_generate_private_key [32]_+ - ecdh_generate_keypair [3]_+ - ecdh_derive [33]_++ - ecdsa_privkey_export [2]_+ - ecdsa_generate_private_key [30]_+ - ecdsa_generate_keypair [30]_+ - ecdsa_sign_verify [30]_++ - rng_add_entropy [5]_++.. [52] Failing operations for CardOS 5.3++ - object_copy [20]_++ - rsa_privkey_export [21]_+ - rsa_generate_private_key [22]_+ - rsa_sign_verify [23]_++ - ecdh_privkey_export [2]_+ - ecdh_pubkey_import [6]_+ - ecdh_pubkey_export [6]_+ - ecdh_generate_private_key [30]_+ - ecdh_generate_keypair [31]_+ - ecdh_derive [30]_++ - ecdsa_privkey_export [2]_+ - ecdsa_pubkey_import [6]_+ - ecdsa_pubkey_export [6]_+ - ecdsa_generate_private_key [31]_+ - ecdsa_generate_keypair [31]_+ - ecdsa_sign_verify [34]_++ - rng_add_entropy [5]_++.. [53] Failing operations for CardOS 5.3 (middelware 5.5.1)++ - ecdh_privkey_export [2]_+ - ecdh_generate_private_key [35]_+ - ecdsa_privkey_export [2]_+ - ecdsa_generate_private_key [36]_+ - c_copy_object [4]_++ - object_copy [4]_++ - rng_add_entropy [5]_++ - rsa_sign_verify [3]_+ - rsa_privkey_export [2]_+ - rsa_generate_private_key [9]_++.. [54] Failing operations for Gemalto IDPrime MD 3840++ - session_login_logout [2]_+ - session_info [2]_+ - set_pin [2]_+ - initialize [2]_+ - change_so_pin [2]_++ - object_copy [20]_++ - rsa_generate_private_key [7]_+ - rsa_encrypt_decrypt [8]_+ - rsa_sign_verify [2]_++ - rng_add_entropy [5]_++Error descriptions++.. [2] CKR_ARGUMENTS_BAD (0x7=7)+.. [3] CKR_MECHANISM_INVALID (0x70=112)+.. [4] CKR_FUNCTION_NOT_SUPPORTED (0x54=84)+.. [5] CKR_RANDOM_SEED_NOT_SUPPORTED (0x120=288)+.. [6] CKM_X9_42_DH_KEY_PAIR_GEN | CKR_DEVICE_ERROR (0x30=48)+.. [7] CKR_TEMPLATE_INCONSISTENT (0xD1=209)+.. [8] CKR_ENCRYPTED_DATA_INVALID | CKM_SHA256_RSA_PKCS (0x40=64)+.. [9] CKR_TEMPLATE_INCOMPLETE (0xD0=208)++.. [20] Test fails due to unsupported copy function (CKR_FUNCTION_NOT_SUPPORTED)+.. [21] Generating private key for extraction with property extractable fails (CKR_ARGUMENTS_BAD)+.. [22] Generate rsa private key operation fails (CKR_TEMPLATE_INCOMPLETE)+.. [23] Raw RSA sign-verify fails (CKR_MECHANISM_INVALID)++.. [30] Invalid argument Decoding error: BER: Value truncated+.. [31] Invalid argument Decoding error: BER: Length field is to large+.. [32] Invalid argument OS2ECP: Unknown format type 155+.. [33] Invalid argument OS2ECP: Unknown format type 92+.. [34] Invalid argument OS2ECP: Unknown format type 57+.. [35] Invalid argument OS2ECP: Unknown format type 82+.. [36] Invalid argument OS2ECP: Unknown format type 102
+ third_party/botan/doc/api_ref/psk_db.rst view
@@ -0,0 +1,108 @@+PSK Database+======================++.. versionadded:: 2.4.0++Many applications need to store pre-shared keys (hereafter PSKs) for+authentication purposes.++An abstract interface to PSK stores is provided in ``psk_db.h``++.. cpp:class:: PSK_Database++ .. cpp:function:: bool is_encrypted() const++ Returns true if (at least) the PSKs themselves are encrypted. Returns+ false if PSKs are stored in plaintext.++ .. cpp:function:: std::set<std::string> list_names() const++ Return the set of valid names stored in the database, ie values for which+ ``get`` will return a value.++ .. cpp:function:: void set(const std::string& name, const uint8_t psk[], size_t psk_len)++ Save a PSK. If ``name`` already exists, the current value will be+ overwritten.++ .. cpp:function:: secure_vector<uint8_t> get(const std::string& name) const++ Return a value saved with ``set``. Throws an exception if ``name`` doesn't+ exist.++ .. cpp:function:: void remove(const std::string& name)++ Remove ``name`` from the database. If ``name`` doesn't exist, ignores the request.++ .. cpp::function:: std::string get_str(const std::string& name) const++ Like ``get`` but casts the return value to a string.++ .. cpp:function:: void set_str(const std::string& name, const std::string& psk)++ Like ``set`` but accepts the psk as a string (eg for a password).++ .. cpp:function:: template<typename Alloc> void set_vec(const std::string& name, \+ const std::vector<uint8_t, Alloc>& psk)++ Like ``set`` but accepting a vector.++The same header also provides a specific instantiation of ``PSK_Database`` which+encrypts both names and PSKs. It must be subclassed to provide the storage.++.. cpp:class:: Encrypted_PSK_Database : public PSK_Database++ .. cpp:function:: Encrypted_PSK_Database(const secure_vector<uint8_t>& master_key)++ Initializes or opens a PSK database. The master key is used the secure the+ contents. It may be of any length. If encrypting PSKs under a passphrase,+ use a suitable key derivation scheme (such as PBKDF2) to derive the secret+ key. If the master key is lost, all PSKs stored are unrecoverable.++ Both names and values are encrypted using NIST key wrapping (see NIST+ SP800-38F) with AES-256. First the master key is used with HMAC(SHA-256)+ to derive two 256-bit keys, one for encrypting all names and the other to+ key an instance of HMAC(SHA-256). Values are each encrypted under an+ individual key created by hashing the encrypted name with HMAC. This+ associates the encrypted key with the name, and prevents an attacker with+ write access to the data store from taking an encrypted key associated+ with one entity and copying it to another entity.++ Names and PSKs are both padded to the next multiple of 8 bytes, providing+ some obfuscation of the length.++ One artifact of the names being encrypted is that is is possible to use+ multiple different master keys with the same underlying storage. Each+ master key will be responsible for a subset of the keys. An attacker who+ knows one of the keys will be able to tell there are other values+ encrypted under another key.++ .. cpp:function:: virtual void kv_set(const std::string& index, const std::string& value) = 0++ Save an encrypted value. Both ``index`` and ``value`` will be non-empty+ base64 encoded strings.++ .. cpp:function:: virtual std::string kv_get(const std::string& index) const = 0++ Return a value saved with ``kv_set``, or return the empty string.++ .. cpp:function:: virtual void kv_del(const std::string& index) = 0++ Remove a value saved with ``kv_set``.++ .. cpp:function:: virtual std::set<std::string> kv_get_all() const = 0++ Return all active names (ie values for which ``kv_get`` will return a+ non-empty string).++A subclass of ``Encrypted_PSK_Database`` which stores data in a SQL database+is also available. This class is declared in ``psk_db_sql.h``:++.. cpp:class:: Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database++ .. cpp:function:: Encrypted_PSK_Database_SQL(const secure_vector<uint8_t>& master_key, \+ std::shared_ptr<SQL_Database> db, \+ const std::string& table_name)++ Creates or uses the named table in ``db``. The SQL schema of the table is+ ``(psk_name TEXT PRIMARY KEY, psk_value TEXT)``.
+ third_party/botan/doc/api_ref/pubkey.rst view
@@ -0,0 +1,954 @@+Public Key Cryptography+=================================++Public key cryptography (also called asymmetric cryptography) is a collection+of techniques allowing for encryption, signatures, and key agreement.++Key Objects+----------------------------------------++Public and private keys are represented by classes ``Public_Key`` and it's+subclass ``Private_Key``. The use of inheritance here means that a+``Private_Key`` can be converted into a reference to a public key.++None of the functions on ``Public_Key`` and ``Private_Key`` itself are+particularly useful for users of the library, because 'bare' public key+operations are *very insecure*. The only purpose of these functions is to+provide a clean interface that higher level operations can be built on. So+really the only thing you need to know is that when a function takes a+reference to a ``Public_Key``, it can take any public key or private key, and+similarly for ``Private_Key``.++Types of ``Public_Key`` include ``RSA_PublicKey``, ``DSA_PublicKey``,+``ECDSA_PublicKey``, ``ECKCDSA_PublicKey``, ``ECGDSA_PublicKey``, ``DH_PublicKey``, ``ECDH_PublicKey``,+``Curve25519_PublicKey``, ``ElGamal_PublicKey``, ``McEliece_PublicKey``, ``XMSS_PublicKey``+and ``GOST_3410_PublicKey``. There are corresponding ``Private_Key`` classes for each of these algorithms.++.. _creating_new_private_keys:++Creating New Private Keys+----------------------------------------++Creating a new private key requires two things: a source of random numbers+(see :ref:`random_number_generators`) and some algorithm specific parameters+that define the *security level* of the resulting key. For instance, the+security level of an RSA key is (at least in part) defined by the length of+the public key modulus in bits. So to create a new RSA private key, you would+call++.. cpp:function:: RSA_PrivateKey::RSA_PrivateKey(RandomNumberGenerator& rng, size_t bits)++ A constructor that creates a new random RSA private key with a modulus+ of length *bits*.++ RSA key generation is relatively slow, and can take an unpredictable+ amount of time. Generating a 2048 bit RSA key might take 5 to 10+ seconds on a slow machine like a Raspberry Pi 2. Even on a fast+ desktop it might take up to half a second. In a GUI blocking for+ that long can be a problem. The usual approach is to perform key+ generation in a new thread, with a animated modal UI element so the+ user knows the application is still alive. If you wish to provide a+ progress estimate things get a bit complicated but some library+ users documented their approach in+ `a blog post <https://medium.com/nexenio/indicating-progress-of-rsa-key-pair-generation-the-practical-approach-a049ba829dbe>`_.++Algorithms based on the discrete-logarithm problem use what is called a+*group*; a group can safely be used with many keys, and for some operations,+like key agreement, the two keys *must* use the same group. There are+currently two kinds of discrete logarithm groups supported in botan: the+integers modulo a prime, represented by :ref:`dl_group`, and elliptic curves+in GF(p), represented by :ref:`ec_group`. A rough generalization is that the+larger the group is, the more secure the algorithm is, but correspondingly the+slower the operations will be.++Given a ``DL_Group``, you can create new DSA, Diffie-Hellman and ElGamal key pairs with++.. cpp:function:: DSA_PrivateKey::DSA_PrivateKey(RandomNumberGenerator& rng, \+ const DL_Group& group, const BigInt& x = 0)++.. cpp:function:: DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, \+ const DL_Group& group, const BigInt& x = 0)++.. cpp:function:: ElGamal_PrivateKey::ElGamal_PrivateKey(RandomNumberGenerator& rng, \+ const DL_Group& group, const BigInt& x = 0)++ 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+ leave the value as zero, letting the class generate a new random key.++Finally, given an ``EC_Group`` object, you can create a new ECDSA, ECKCDSA, ECGDSA,+ECDH, or GOST 34.10-2001 private key with++.. cpp:function:: ECDSA_PrivateKey::ECDSA_PrivateKey(RandomNumberGenerator& rng, \+ const EC_Group& domain, const BigInt& x = 0)++.. cpp:function:: ECKCDSA_PrivateKey::ECKCDSA_PrivateKey(RandomNumberGenerator& rng, \+ const EC_Group& domain, const BigInt& x = 0)++.. cpp:function:: ECGDSA_PrivateKey::ECGDSA_PrivateKey(RandomNumberGenerator& rng, \+ const EC_Group& domain, const BigInt& x = 0)++.. cpp:function:: ECDH_PrivateKey::ECDH_PrivateKey(RandomNumberGenerator& rng, \+ const EC_Group& domain, const BigInt& x = 0)++.. cpp:function:: GOST_3410_PrivateKey::GOST_3410_PrivateKey(RandomNumberGenerator& rng, \+ const EC_Group& domain, const BigInt& x = 0)++.. _serializing_private_keys:++Serializing Private Keys Using PKCS #8+----------------------------------------++The standard format for serializing a private key is PKCS #8, the operations+for which are defined in ``pkcs8.h``. It supports both unencrypted and+encrypted storage.++.. cpp:function:: secure_vector<uint8_t> PKCS8::BER_encode(const Private_Key& key, \+ RandomNumberGenerator& rng, const std::string& password, const std::string& pbe_algo = "")++ Takes any private key object, serializes it, encrypts it using+ *password*, and returns a binary structure representing the private+ key.++ The final (optional) argument, *pbe_algo*, specifies a particular+ password based encryption (or PBE) algorithm. If you don't specify a+ PBE, a sensible default will be used.++ The currently supported PBE is PBES2 from PKCS5. Format is as follows:+ ``PBE-PKCS5v20(CIPHER,PBKDF)``. Since 2.8.0, ``PBES2(CIPHER,PBKDF)`` also works.+ Cipher can be any block cipher with /CBC or /GCM appended, for example+ "AES-128/CBC" or "Camellia-256/GCM". For best interop with other systems, use+ AES in CBC mode. The PBKDF can be either the name of a hash function (in which+ case PBKDF2 is used with that hash) or "Scrypt", which causes the scrypt+ memory hard password hashing function to be used. Scrypt is supported since+ version 2.7.0.++ Use `PBE-PKCS5v20(AES-256/CBC,SHA-256)` if you want to ensure the keys can+ be imported by different software packages. Use+ `PBE-PKCS5v20(AES-256/GCM,Scrypt)` for best security assuming you do not+ care about interop.++ For ciphers you can use anything which has an OID defined for CBC, GCM or SIV+ modes. Currently this includes AES, Camellia, Serpent, Twofish, and SM4. Most+ other libraries only support CBC mode for private key encryption. GCM has+ been supported in PBES2 since 1.11.10. SIV has been supported since 2.8.++.. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key, \+ RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = "")++ This formats the key in the same manner as ``BER_encode``, but additionally+ encodes it into a text format with identifying headers. Using PEM encoding+ is *highly* recommended for many reasons, including compatibility with other+ software, for transmission over 8-bit unclean channels, because it can be+ identified by a human without special tools, and because it sometimes allows+ more sane behavior of tools that process the data.++Unencrypted serialization is also supported.++.. warning::++ In most situations, using unencrypted private key storage is a bad idea,+ because anyone can come along and grab the private key without having to+ know any passwords or other secrets. Unless you have very particular+ security requirements, always use the versions that encrypt the key based on+ a passphrase, described above.++.. cpp:function:: secure_vector<uint8_t> PKCS8::BER_encode(const Private_Key& key)++ Serializes the private key and returns the result.++.. cpp:function:: std::string PKCS8::PEM_encode(const Private_Key& key)++ Serializes the private key, base64 encodes it, and returns the+ result.++Last but not least, there are some functions that will load (and+decrypt, if necessary) a PKCS #8 private key:++.. cpp:function:: Private_Key* PKCS8::load_key(DataSource& in, \+ RandomNumberGenerator& rng, const User_Interface& ui)++.. cpp:function:: Private_Key* PKCS8::load_key(DataSource& in, \+ RandomNumberGenerator& rng, std::string passphrase = "")++.. cpp:function:: Private_Key* PKCS8::load_key(const std::string& filename, \+ RandomNumberGenerator& rng, const User_Interface& ui)++.. cpp:function:: Private_Key* PKCS8::load_key(const std::string& filename, \+ RandomNumberGenerator& rng, const std::string& passphrase = "")++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+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+functions that take either a filename or a memory buffer and create the+appropriate ``DataSource``.++The versions taking a ``std::string`` attempt to decrypt using the password+given (if the key is encrypted; if it is not, the passphase value will be+ignored). If the passphrase does not decrypt the key, an exception will be+thrown.++The ones taking a ``User_Interface`` provide a simple callback interface which+makes handling incorrect passphrases and such a bit simpler. A+``User_Interface`` has very little to do with talking to users; it's just a+way to glue together Botan and whatever user interface you happen to be using.++.. note::++ In a future version, it is likely that ``User_Interface`` will be+ replaced by a simple callback using ``std::function``.++To use ``User_Interface``, derive a subclass and implement:++.. cpp:function:: std::string User_Interface::get_passphrase(const std::string& what, \+ const std::string& source, UI_Result& result) const++ The ``what`` argument specifies what the passphrase is needed for (for+ example, PKCS #8 key loading passes ``what`` as "PKCS #8 private key"). This+ lets you provide the user with some indication of *why* your application is+ asking for a passphrase; feel free to pass the string through ``gettext(3)``+ or moral equivalent for i18n purposes. Similarly, ``source`` specifies where+ the data in question came from, if available (for example, a file name). If+ the source is not available for whatever reason, then ``source`` will be an+ empty string; be sure to account for this possibility.++ The function returns the passphrase as the return value, and a status code+ in ``result`` (either ``OK`` or ``CANCEL_ACTION``). If ``CANCEL_ACTION`` is+ returned in ``result``, then the return value will be ignored, and the+ caller will take whatever action is necessary (typically, throwing an+ exception stating that the passphrase couldn't be determined). In the+ specific case of PKCS #8 key decryption, a ``Decoding_Error`` exception will+ be thrown; your UI should assume this can happen, and provide appropriate+ error handling (such as putting up a dialog box informing the user of the+ situation, and canceling the operation in progress).++.. _serializing_public_keys:++Serializing Public Keys+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++To import and export public keys, use:++.. cpp:function:: std::vector<uint8_t> X509::BER_encode(const Public_Key& key)++.. cpp:function:: std::string X509::PEM_encode(const Public_Key& key)++.. cpp:function:: Public_Key* X509::load_key(DataSource& in)++.. cpp:function:: Public_Key* X509::load_key(const secure_vector<uint8_t>& buffer)++.. cpp:function:: Public_Key* X509::load_key(const std::string& filename)++ These functions operate in the same way as the ones described in+ :ref:`serializing_private_keys`, except that no encryption option is+ available.++.. _dl_group:++DL_Group+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++As described in :ref:`creating_new_private_keys`, a discrete logarithm group+can be shared among many keys, even keys created by users who do not trust+each other. However, it is necessary to trust the entity who created the+group; that is why organization like NIST use algorithms which generate groups+in a deterministic way such that creating a bogus group would require breaking+some trusted cryptographic primitive like SHA-2.++Instantiating a ``DL_Group`` simply requires calling++.. cpp:function:: DL_Group::DL_Group(const std::string& name)++ The *name* parameter is a specially formatted string that consists of three+ things, the type of the group ("modp" or "dsa"), the creator of the group,+ and the size of the group in bits, all delimited by '/' characters.++ Currently all "modp" groups included in botan are ones defined by the+ Internet Engineering Task Force, so the provider is "ietf", and the strings+ look like "modp/ietf/N" where N can be any of 1024, 1536, 2048, 3072,+ 4096, 6144, or 8192. This group type is used for Diffie-Hellman and ElGamal+ algorithms.++ The other type, "dsa" is used for DSA keys. They can also be used with+ Diffie-Hellman and ElGamal, but this is less common. The currently available+ groups are "dsa/jce/1024" and "dsa/botan/N" with N being 2048 or 3072. The+ "jce" groups are the standard DSA groups used in the Java Cryptography+ Extensions, while the "botan" groups were randomly generated using the+ FIPS 186-3 algorithm by the library maintainers.++You can generate a new random group using++.. cpp:function:: DL_Group::DL_Group(RandomNumberGenerator& rng, \+ PrimeType type, size_t pbits, size_t qbits = 0)++ The *type* can be either ``Strong``, ``Prime_Subgroup``, or+ ``DSA_Kosherizer``. *pbits* specifies the size of the prime in+ bits. If the *type* is ``Prime_Subgroup`` or ``DSA_Kosherizer``,+ then *qbits* specifies the size of the subgroup.++You can serialize a ``DL_Group`` using++.. cpp:function:: secure_vector<uint8_t> DL_Group::DER_Encode(Format format)++or++.. cpp:function:: std::string DL_Group::PEM_encode(Format format)++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 compatibility.++You can reload a serialized group using++.. cpp:function:: void DL_Group::BER_decode(DataSource& source, Format format)++.. cpp:function:: void DL_Group::PEM_decode(DataSource& source)++Code Example+"""""""""""""""""+The example below creates a new 2048 bit ``DL_Group``, prints the generated+parameters and ANSI_X9_42 encodes the created group for further usage with DH.++.. code-block:: cpp++ #include <botan/dl_group.h>+ #include <botan/auto_rng.h>+ #include <botan/rng.h>+ #include <iostream>++ int main()+ {+ std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);+ std::unique_ptr<Botan::DL_Group> group(new Botan::DL_Group(*rng.get(), Botan::DL_Group::Strong, 2048));+ std::cout << std::endl << "p: " << group->get_p();+ std::cout << std::endl << "q: " << group->get_q();+ std::cout << std::endl << "g: " << group->get_q();+ std::cout << std::endl << "ANSI_X9_42: " << std::endl << group->PEM_encode(Botan::DL_Group::ANSI_X9_42);++ return 0;+ }+++.. _ec_group:++EC_Group+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++An ``EC_Group`` is initialized by passing the name of the+group to be used to the constructor. These groups have+semi-standardized names like "secp256r1" and "brainpool512r1".++Key Checking+---------------------------------++Most public key algorithms have limitations or restrictions on their+parameters. For example RSA requires an odd exponent, and algorithms+based on the discrete logarithm problem need a generator > 1.++Each public key type has a function++.. cpp:function:: bool Public_Key::check_key(RandomNumberGenerator& rng, bool strong)++ This function performs a number of algorithm-specific tests that the key+ seems to be mathematically valid and consistent, and returns true if all of+ the tests pass.++ It does not have anything to do with the validity of the key for any+ particular use, nor does it have anything to do with certificates that link+ a key (which, after all, is just some numbers) with a user or other+ entity. If *strong* is ``true``, then it does "strong" checking, which+ includes expensive operations like primality checking.++As key checks are not automatically performed they must be called+manually after loading keys from untrusted sources. If a key from an untrusted source+is not checked, the implementation might be vulnerable to algorithm specific attacks.++The following example loads the Subject Public Key from the x509 certificate ``cert.pem`` and checks the+loaded key. If the key check fails a respective error is thrown.++.. code-block:: cpp++ #include <botan/x509cert.h>+ #include <botan/auto_rng.h>+ #include <botan/rng.h>++ int main()+ {+ Botan::X509_Certificate cert("cert.pem");+ std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);+ std::unique_ptr<Botan::Public_Key> key(cert.subject_public_key());+ if(!key->check_key(*rng.get(), false))+ {+ throw std::invalid_argument("Loaded key is invalid");+ }+ }++Encryption+---------------------------------++Safe public key encryption requires the use of a padding scheme which hides+the underlying mathematical properties of the algorithm. Additionally, they+will add randomness, so encrypting the same plaintext twice produces two+different ciphertexts.++The primary interface for encryption is++.. cpp:class:: PK_Encryptor++ .. cpp:function:: secure_vector<uint8_t> encrypt( \+ const uint8_t* in, size_t length, RandomNumberGenerator& rng) const++ .. cpp:function:: secure_vector<uint8_t> encrypt( \+ const std::vector<uint8_t>& in, RandomNumberGenerator& rng) const++ These encrypt a message, returning the ciphertext.++ .. cpp:function:: size_t maximum_input_size() const++ Returns the maximum size of the message that can be processed, in+ bytes. If you call :cpp:func:`PK_Encryptor::encrypt` with a value larger+ than this the operation will fail with an exception.++:cpp:class:`PK_Encryptor` is only an interface - to actually encrypt you have+to create an implementation, of which there are currently three available in the+library, :cpp:class:`PK_Encryptor_EME`, :cpp:class:`DLIES_Encryptor` and+:cpp:class:`ECIES_Encryptor`. DLIES is a hybrid encryption scheme (from+IEEE 1363) that uses the DH key agreement technique in combination with a KDF, a+MAC and a symmetric encryption algorithm to perform message encryption. ECIES is+similar to DLIES, but uses ECDH for the key agreement. Normally, public key+encryption is done using algorithms which support it directly, such as RSA or+ElGamal; these use the EME class:++.. cpp:class:: PK_Encryptor_EME++ .. cpp:function:: PK_Encryptor_EME(const Public_Key& key, std::string eme)++ With *key* being the key you want to encrypt messages to. The padding+ method to use is specified in *eme*.++ The recommended values for *eme* is "EME1(SHA-1)" or "EME1(SHA-256)". If+ you need compatibility with protocols using the PKCS #1 v1.5 standard,+ you can also use "EME-PKCS1-v1_5".++.. cpp:class:: DLIES_Encryptor++ Available in the header ``dlies.h``++ .. cpp:function:: DLIES_Encryptor(const DH_PrivateKey& own_priv_key, \+ RandomNumberGenerator& rng, KDF* kdf, MessageAuthenticationCode* mac, \+ size_t mac_key_len = 20)++ Where *kdf* is a key derivation function (see+ :ref:`key_derivation_function`) and *mac* is a+ MessageAuthenticationCode. The encryption is performed by XORing the+ message with a stream of bytes provided by the KDF.++ .. cpp:function:: DLIES_Encryptor(const DH_PrivateKey& own_priv_key, \+ RandomNumberGenerator& rng, KDF* kdf, Cipher_Mode* cipher, \+ size_t cipher_key_len, MessageAuthenticationCode* mac, \+ size_t mac_key_len = 20)++ Instead of XORing the message a block cipher can be specified.++.. cpp:class:: ECIES_Encryptor++ Available in the header ``ecies.h``.++ Parameters for encryption and decryption are set by the+ :cpp:class:`ECIES_System_Params` class which stores the EC domain parameters,+ the KDF (see :ref:`key_derivation_function`), the cipher (see+ :ref:`cipher_modes`) and the MAC.++ .. cpp:function:: ECIES_Encryptor(const PK_Key_Agreement_Key& private_key, \+ const ECIES_System_Params& ecies_params, \+ RandomNumberGenerator& rng)++ Where *private_key* is the key to use for the key agreement. The system+ parameters are specified in *ecies_params* and the RNG to use is passed in+ *rng*.++ .. cpp:function:: ECIES_Encryptor(RandomNumberGenerator& rng, \+ const ECIES_System_Params& ecies_params)++ Creates an ephemeral private key which is used for the key agreement.++The decryption classes are named :cpp:class:`PK_Decryptor`,+:cpp:class:`PK_Decryptor_EME`, :cpp:class:`DLIES_Decryptor` and+:cpp:class:`ECIES_Decryptor`. They are created in the exact same way, except+they take the private key, and the processing function is named ``decrypt``.+++Botan implements the following encryption algorithms and padding schemes:++1. RSA+ - "PKCS1v15" || "EME-PKCS1-v1_5"+ - "OAEP" || "EME-OAEP" || "EME1" || "EME1(SHA-1)" || "EME1(SHA-256)"+#. DLIES+#. ECIES+#. SM2++Code Example+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+The following Code sample reads a PKCS #8 keypair from the passed location and+subsequently encrypts a fixed plaintext with the included public key, using EME1+with SHA-256. For the sake of completeness, the ciphertext is then decrypted using+the private key.++.. code-block:: cpp++ #include <botan/pkcs8.h>+ #include <botan/hex.h>+ #include <botan/pk_keys.h>+ #include <botan/pubkey.h>+ #include <botan/auto_rng.h>+ #include <botan/rng.h>+ #include <iostream>+ int main (int argc, char* argv[])+ {+ if(argc!=2)+ return 1;+ std::string plaintext("Your great-grandfather gave this watch to your granddad for good luck. Unfortunately, Dane's luck wasn't as good as his old man's.");+ std::vector<uint8_t> pt(plaintext.data(),plaintext.data()+plaintext.length());+ std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);++ //load keypair+ std::unique_ptr<Botan::Private_Key> kp(Botan::PKCS8::load_key(argv[1],*rng.get()));++ //encrypt with pk+ Botan::PK_Encryptor_EME enc(*kp,*rng.get(), "EME1(SHA-256)");+ std::vector<uint8_t> ct = enc.encrypt(pt,*rng.get());++ //decrypt with sk+ Botan::PK_Decryptor_EME dec(*kp,*rng.get(), "EME1(SHA-256)");+ std::cout << std::endl << "enc: " << Botan::hex_encode(ct) << std::endl << "dec: "<< Botan::hex_encode(dec.decrypt(ct));++ return 0;+ }+++Signatures+---------------------------------++Signature generation is performed using++.. cpp:class:: PK_Signer++ .. cpp:function:: PK_Signer(const Private_Key& key, \+ const std::string& emsa, \+ Signature_Format format = IEEE_1363)++ Constructs a new signer object for the private key *key* using the+ signature format *emsa*. The key must support signature operations. In+ the current version of the library, this includes RSA, DSA, ECDSA, ECKCDSA,+ ECGDSA, GOST 34.10-2001. Other signature schemes may be supported in the future.++ .. note::++ Botan both supports non-deterministic and deterministic (as per RFC+ 6979) DSA and ECDSA signatures. Deterministic signatures are compatible+ in the way that they can be verified with a non-deterministic implementation.+ If the ``rfc6979`` module is enabled, deterministic DSA and ECDSA signatures+ will be generated.++ Currently available values for *emsa* include EMSA1, EMSA2, EMSA3, EMSA4,+ and Raw. All of them, except Raw, take a parameter naming a message+ digest function to hash the message with. The Raw encoding signs the+ input directly; if the message is too big, the signing operation will+ 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 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, ECKCDSA, ECGDSA and+ GOST 34.10-2001 you should use EMSA1.++ The *format* defaults to ``IEEE_1363`` which is the only available+ format for RSA. For DSA, ECDSA, ECGDSA and ECKCDSA you can also use+ ``DER_SEQUENCE``, which will format the signature as an ASN.1+ SEQUENCE value.++ .. cpp:function:: void update(const uint8_t* in, size_t length)+ .. cpp:function:: void update(const std::vector<uint8_t>& in)+ .. cpp:function:: void update(uint8_t in)++ These add more data to be included in the signature+ computation. Typically, the input will be provided directly to a+ hash function.++ .. cpp:function:: secure_vector<uint8_t> signature(RandomNumberGenerator& rng)++ Creates the signature and returns it++ .. cpp:function:: secure_vector<uint8_t> sign_message( \+ const uint8_t* in, size_t length, RandomNumberGenerator& rng)++ .. cpp:function:: secure_vector<uint8_t> sign_message( \+ const std::vector<uint8_t>& in, RandomNumberGenerator& rng)++ These functions are equivalent to calling+ :cpp:func:`PK_Signer::update` and then+ :cpp:func:`PK_Signer::signature`. Any data previously provided+ using ``update`` will be included.++Signatures are verified using++.. cpp:class:: PK_Verifier++ .. cpp:function:: PK_Verifier(const Public_Key& pub_key, \+ const std::string& emsa, Signature_Format format = IEEE_1363)++ Construct a new verifier for signatures associated with public+ key *pub_key*. The *emsa* and *format* should be the same as+ that used by the signer.++ .. cpp:function:: void update(const uint8_t* in, size_t length)+ .. cpp:function:: void update(const std::vector<uint8_t>& in)+ .. cpp:function:: void update(uint8_t in)++ Add further message data that is purportedly associated with the+ signature that will be checked.++ .. cpp:function:: bool check_signature(const uint8_t* sig, size_t length)+ .. cpp:function:: bool check_signature(const std::vector<uint8_t>& sig)++ Check to see if *sig* is a valid signature for the message data+ that was written in. Return true if so. This function clears the+ internal message state, so after this call you can call+ :cpp:func:`PK_Verifier::update` to start verifying another+ message.++ .. cpp:function:: bool verify_message(const uint8_t* msg, size_t msg_length, \+ const uint8_t* sig, size_t sig_length)++ .. cpp:function:: bool verify_message(const std::vector<uint8_t>& msg, \+ const std::vector<uint8_t>& sig)++ These are equivalent to calling :cpp:func:`PK_Verifier::update`+ on *msg* and then calling :cpp:func:`PK_Verifier::check_signature`+ on *sig*.+++Botan implements the following signature algorithms:++1. RSA+#. DSA+#. ECDSA+#. ECGDSA+#. ECKDSA+#. GOST 34.10-2001+#. Ed25519+#. SM2++Code Example+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The following sample program below demonstrates the generation of a new ECDSA keypair over the curve secp512r1+and a ECDSA signature using EMSA1 with SHA-256. Subsequently the computed signature is validated.++.. code-block:: cpp++ #include <botan/auto_rng.h>+ #include <botan/ecdsa.h>+ #include <botan/ec_group.h>+ #include <botan/pubkey.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ Botan::AutoSeeded_RNG rng;+ // Generate ECDSA keypair+ Botan::ECDSA_PrivateKey key(rng, Botan::EC_Group("secp521r1"));++ std::string text("This is a tasty burger!");+ std::vector<uint8_t> data(text.data(),text.data()+text.length());+ // sign data+ Botan::PK_Signer signer(key, rng, "EMSA1(SHA-256)");+ signer.update(data);+ std::vector<uint8_t> signature = signer.signature(rng);+ std::cout << "Signature:" << std::endl << Botan::hex_encode(signature);+ // verify signature+ Botan::PK_Verifier verifier(key, "EMSA1(SHA-256)");+ verifier.update(data);+ std::cout << std::endl << "is " << (verifier.check_signature(signature)? "valid" : "invalid");+ return 0;+ }+++Ed25519 Variants+^^^^^^^^^^^^^^^^^^++Most signature schemes in Botan follow a hash-then-sign paradigm. That is, the+entire message is digested to a fixed length representative using a collision+resistant hash function, and then the digest is signed. Ed25519 instead signs+the message directly. This is beneficial, in that the Ed25519 design should+remain secure even in the (extremely unlikely) event that a collision attack on+SHA-512 is found. However it means the entire message must be buffered in+memory, which can be a problem for many applications which might need to sign+large inputs. To use this variety of Ed25519, use a padding name of "Pure".++Ed25519ph (pre-hashed) instead hashes the message with SHA-512 and then signs+the digest plus a special prefix specified in RFC 8032. To use it, specify+padding name "Ed25519ph".++Another variant of pre-hashing is used by GnuPG. There the message is digested+with any hash function, then the digest is signed. To use it, specify any valid+hash function. Even if SHA-512 is used, this variant is not compatible with+Ed25519ph.++For best interop with other systems, prefer "Ed25519ph".++Key Agreement+---------------------------------++You can get a hold of a ``PK_Key_Agreement_Scheme`` object by calling+``get_pk_kas`` with a key that is of a type that supports key+agreement (such as a Diffie-Hellman key stored in a ``DH_PrivateKey``+object), and the name of a key derivation function. This can be "Raw",+meaning the output of the primitive itself is returned as the key, or+"KDF1(hash)" or "KDF2(hash)" where "hash" is any string you happen to+like (hopefully you like strings like "SHA-256" or "RIPEMD-160"), or+"X9.42-PRF(keywrap)", which uses the PRF specified in ANSI X9.42. It+takes the name or OID of the key wrap algorithm that will be used to+encrypt a content encryption key.++How key agreement works is that you trade public values with some+other party, and then each of you runs a computation with the other's+value and your key (this should return the same result to both+parties). This computation can be called by using+``derive_key`` with either a byte array/length pair, or a+``secure_vector<uint8_t>`` than holds the public value of the other+party. The last argument to either call is a number that specifies how+long a key you want.++Depending on the KDF you're using, you *might not* get back a key+of the size you requested. In particular "Raw" will return a number+about the size of the Diffie-Hellman modulus, and KDF1 can only return+a key that is the same size as the output of the hash. KDF2, on the+other hand, will always give you a key exactly as long as you request,+regardless of the underlying hash used with it. The key returned is a+``SymmetricKey``, ready to pass to a block cipher, MAC, or other+symmetric algorithm.++The public value that should be used can be obtained by calling+``public_data``, which exists for any key that is associated with a+key agreement algorithm. It returns a ``secure_vector<uint8_t>``.++"KDF2(SHA-256)" is by far the preferred algorithm for key derivation+in new applications. The X9.42 algorithm may be useful in some+circumstances, but unless you need X9.42 compatibility, KDF2 is easier+to use.+++Botan implements the following key agreement methods:++1. ECDH over GF(p) Weierstrass curves+#. ECDH over x25519+#. DH over prime fields+#. McEliece+#. NewHope++Code Example+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The code below performs an unauthenticated ECDH key agreement using the secp521r elliptic curve and+applies the key derivation function KDF2(SHA-256) with 256 bit output length to the computed shared secret.++.. code-block:: cpp++ #include <botan/auto_rng.h>+ #include <botan/ecdh.h>+ #include <botan/ec_group.h>+ #include <botan/pubkey.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ Botan::AutoSeeded_RNG rng;+ // ec domain and+ Botan::EC_Group domain("secp521r1");+ std::string kdf = "KDF2(SHA-256)";+ // generate ECDH keys+ Botan::ECDH_PrivateKey keyA(rng, domain);+ Botan::ECDH_PrivateKey keyB(rng, domain);+ // Construct key agreements+ Botan::PK_Key_Agreement ecdhA(keyA,rng,kdf);+ Botan::PK_Key_Agreement ecdhB(keyB,rng,kdf);+ // Agree on shared secret and derive symmetric key of 256 bit length+ Botan::secure_vector<uint8_t> sA = ecdhA.derive_key(32,keyB.public_value()).bits_of();+ Botan::secure_vector<uint8_t> sB = ecdhB.derive_key(32,keyA.public_value()).bits_of();++ if(sA != sB)+ return 1;++ std::cout << "agreed key: " << std::endl << Botan::hex_encode(sA);+ return 0;+ }+++.. _mceliece:++McEliece+--------------------------++McEliece is a cryptographic scheme based on error correcting codes which is+thought to be resistant to quantum computers. First proposed in 1978, it is fast+and patent-free. Variants have been proposed and broken, but with suitable+parameters the original scheme remains secure. However the public keys are quite+large, which has hindered deployment in the past.++The implementation of McEliece in Botan was contributed by cryptosource GmbH. It+is based on the implementation HyMES, with the kind permission of Nicolas+Sendrier and INRIA to release a C++ adaption of their original C code under the+Botan license. It was then modified by Falko Strenzke to add side channel and+fault attack countermeasures. You can read more about the implementation at+http://www.cryptosource.de/docs/mceliece_in_botan.pdf++Encryption in the McEliece scheme consists of choosing a message block of size+`n`, encoding it in the error correcting code which is the public key, then+adding `t` bit errors. The code is created such that knowing only the public+key, decoding `t` errors is intractable, but with the additional knowledge of+the secret structure of the code a fast decoding technique exists.++The McEliece implementation in HyMES, and also in Botan, uses an optimization to+reduce the public key size, by converting the public key into a systemic code.+This means a portion of the public key is a identity matrix, and can be excluded+from the published public key. However it also means that in McEliece the+plaintext is represented directly in the ciphertext, with only a small number of+bit errors. Thus it is absolutely essential to only use McEliece with a CCA2+secure scheme.++One such scheme, KEM, is provided in Botan currently. It it a somewhat unusual+scheme in that it outputs two values, a symmetric key for use with an AEAD, and+an encrypted key. It does this by choosing a random plaintext (n - log2(n)*t+bits) using ``McEliece_PublicKey::random_plaintext_element``. Then a random+error mask is chosen and the message is coded and masked. The symmetric key is+SHA-512(plaintext || error_mask). As long as the resulting key is used with a+secure AEAD scheme (which can be used for transporting arbitrary amounts of+data), CCA2 security is provided.++In ``mcies.h`` there are functions for this combination:++.. cpp:function:: secure_vector<uint8_t> mceies_encrypt(const McEliece_PublicKey& pubkey, \+ const secure_vector<uint8_t>& pt, \+ uint8_t ad[], size_t ad_len, \+ RandomNumberGenerator& rng, \+ const std::string& aead = "AES-256/OCB")++.. cpp:function:: secure_vector<uint8_t> mceies_decrypt(const McEliece_PrivateKey& privkey, \+ const secure_vector<uint8_t>& ct, \+ uint8_t ad[], size_t ad_len, \+ const std::string& aead = "AES-256/OCB")++For a given security level (SL) a McEliece key would use+parameters n and t, and have the corresponding key sizes listed:+++-----+------+-----+---------------+----------------++| SL | n | t | public key KB | private key KB |++=====+======+=====+===============+================++| 80 | 1632 | 33 | 59 | 140 |++-----+------+-----+---------------+----------------++| 107 | 2280 | 45 | 128 | 300 |++-----+------+-----+---------------+----------------++| 128 | 2960 | 57 | 195 | 459 |++-----+------+-----+---------------+----------------++| 147 | 3408 | 67 | 265 | 622 |++-----+------+-----+---------------+----------------++| 191 | 4624 | 95 | 516 | 1234 |++-----+------+-----+---------------+----------------++| 256 | 6624 | 115 | 942 | 2184 |++-----+------+-----+---------------+----------------+++You can check the speed of McEliece with the suggested parameters above+using ``botan speed McEliece``+++eXtended Merkle Signature Scheme (XMSS)+----------------------------------------++Botan implements the single tree version of the eXtended Merkle Signature+Scheme (XMSS) using Winternitz One Time Signatures+ (WOTS+). The implementation+is based on `RFC 8391 "XMSS: eXtended Merkle Signature Scheme"+<https://tools.ietf.org/html/rfc8391>`_.++XMSS uses the Botan interfaces for public key cryptography.+The following algorithms are implemented:++1. XMSS-SHA2_10_256+# XMSS-SHA2_16_256+# XMSS-SHA2_20_256+# XMSS-SHA2_10_512+# XMSS-SHA2_16_512+# XMSS-SHA2_20_512+# XMSS-SHAKE_10_256+# XMSS-SHAKE_16_256+# XMSS-SHAKE_20_256+# XMSS-SHAKE_10_512+# XMSS-SHAKE_16_512+# XMSS-SHAKE_20_512++The algorithm name contains the hash function name, tree height and digest+width defined by the corresponding parameter set. Choosing `XMSS-SHA2_10_256`+for instance will use the SHA2-256 hash function to generate a tree of height+ten.++Code Example+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The following code snippet shows a minimum example on how to create an XMSS+public/private key pair and how to use these keys to create and verify a+signature:++.. code-block:: cpp++ #include <iostream>+ #include <botan/secmem.h>+ #include <botan/auto_rng.h>+ #include <botan/xmss.h>++ int main()+ {+ // Create a random number generator used for key generation.+ Botan::AutoSeeded_RNG rng;++ // create a new public/private key pair using SHA2 256 as hash+ // function and a tree height of 10.+ Botan::XMSS_PrivateKey private_key(+ Botan::XMSS_Parameters::xmss_algorithm_t::XMSS_SHA2_10_256,+ rng);+ Botan::XMSS_PublicKey public_key(private_key);++ // create signature operation using the private key.+ std::unique_ptr<Botan::PK_Ops::Signature> sig_op =+ private_key.create_signature_op(rng, "", "");++ // create and sign a message using the signature operation.+ Botan::secure_vector<uint8_t> msg { 0x01, 0x02, 0x03, 0x04 };+ sig_op->update(msg.data(), msg.size());+ Botan::secure_vector<uint8_t> sig = sig_op->sign(rng);++ // create verification operation using the public key+ std::unique_ptr<Botan::PK_Ops::Verification> ver_op =+ public_key.create_verification_op("", "");++ // verify the signature for the previously generated message.+ ver_op->update(msg.data(), msg.size());+ if(ver_op->is_valid_signature(sig.data(), sig.size()))+ {+ std::cout << "Success." << std::endl;+ }+ else+ {+ std::cout << "Error." << std::endl;+ }+ }
+ third_party/botan/doc/api_ref/python.rst view
@@ -0,0 +1,668 @@++Python Binding+========================================++.. versionadded:: 1.11.14++.. highlight:: python++.. py:module:: botan++The Python binding is based on the `ffi` module of botan and the+`ctypes` module of the Python standard library.++Starting in 2.8, the class names were renamed to match Python standard+conventions. However aliases are defined which allow older code to+continue to work; the older names are mentioned as "previously X".+These aliases will be removed in a future major release.++Versioning+----------------------------------------+.. py:function:: version_major()++ Returns the major number of the library version.++.. py:function:: version_minor()++ Returns the minor number of the library version.++.. py:function:: version_patch()++ Returns the patch number of the library version.++.. py:function:: version_string()++ Returns a free form version string for the library++Random Number Generators+----------------------------------------++.. py:class:: RandomNumberGenerator(rng_type = 'system')++ Previously ``rng``++ Type 'user' also allowed (userspace HMAC_DRBG seeded from system+ rng). The system RNG is very cheap to create, as just a single file+ handle or CSP handle is kept open, from first use until shutdown,+ no matter how many 'system' rng instances are created. Thus it is+ easy to use the RNG in a one-off way, with `botan.RandomNumberGenerator().get(32)`.++ .. py:method:: get(length)++ Return some bytes++ .. py:method:: reseed(bits = 256)++ Meaningless on system RNG, on userspace RNG causes a reseed/rekey++ .. py:method:: reseed_from_rng(source_rng, bits = 256)++ Take bits from the source RNG and use it to seed ``self``++ .. py:method:: add_entropy(seed)++ Add some unpredictable seed data to the RNG++Hash Functions+----------------------------------------++.. py:class:: HashFunction(algo)++ Previously ``hash_function``++ The ``algo`` param is a string (eg 'SHA-1', 'SHA-384', 'BLAKE2b')++ .. py:method:: algo_name()++ Returns the name of this algorithm++ .. py:method:: clear()++ Clear state++ .. py:method:: output_length()++ Return output length in bytes++ .. py:method:: update(x)++ Add some input++ .. py:method:: final()++ Returns the hash of all input provided, resets+ for another message.++Message Authentication Codes+----------------------------------------++.. py:class:: MsgAuthCode(algo)++ Previously ``message_authentication_code``++ Algo is a string (eg 'HMAC(SHA-256)', 'Poly1305', 'CMAC(AES-256)')++ .. py:method:: algo_name()++ Returns the name of this algorithm++ .. py:method:: clear()++ Clear internal state including the key++ .. py:method:: output_length()++ Return the output length in bytes++ .. py:method:: set_key(key)++ Set the key++ .. py:method:: update(x)++ Add some input++ .. py:method:: final()++ Returns the MAC of all input provided, resets+ for another message with the same key.++Ciphers+----------------------------------------++.. py:class:: SymmetricCipher(object, algo, encrypt = True)++ Previously ``cipher``++ The algorithm is spcified as a string (eg 'AES-128/GCM',+ 'Serpent/OCB(12)', 'Threefish-512/EAX').++ Set the second param to False for decryption++ .. py:method:: algo_name()++ Returns the name of this algorithm++ .. py:method:: tag_length()++ Returns the tag length (0 for unauthenticated modes)++ .. py:method:: default_nonce_length()++ Returns default nonce length++ .. py:method:: update_granularity()++ Returns update block size. Call to update() must provide input+ of exactly this many bytes++ .. py:method:: is_authenticated()++ Returns True if this is an AEAD mode++ .. py:method:: valid_nonce_length(nonce_len)++ Returns True if nonce_len is a valid nonce len for this mode++ .. py:method:: clear()++ Resets all state++ .. py:method:: set_key(key)++ Set the key++ .. py:method:: set_assoc_data(ad)++ Sets the associated data. Fails if this is not an AEAD mode++ .. py:method:: start(nonce)++ Start processing a message using nonce++ .. py:method:: update(txt)++ Consumes input text and returns output. Input text must be of+ update_granularity() length. Alternately, always call finish+ with the entire message, avoiding calls to update entirely++ .. py:method:: finish(txt = None)++ Finish processing (with an optional final input). May throw if+ message authentication checks fail, in which case all plaintext+ previously processed must be discarded. You may call finish()+ with the entire message++Bcrypt+----------------------------------------++.. py:function:: bcrypt(passwd, rng, work_factor = 10)++ Provided the password and an RNG object, returns a bcrypt string++.. py:function:: check_bcrypt(passwd, bcrypt)++ Check a bcrypt hash against the provided password, returning True+ iff the password matches.++PBKDF+----------------------------------------++.. py:function:: pbkdf(algo, password, out_len, iterations = 100000, salt = None)++ Runs a PBKDF2 algo specified as a string (eg 'PBKDF2(SHA-256)',+ 'PBKDF2(CMAC(Blowfish))'). Runs with specified iterations, with+ meaning depending on the algorithm. The salt can be provided or+ otherwise is randomly chosen. In any case it is returned from the+ call.++ Returns out_len bytes of output (or potentially less depending on+ the algorithm and the size of the request).++ Returns tuple of salt, iterations, and psk++.. py:function:: pbkdf_timed(algo, password, out_len, ms_to_run = 300, salt = rng().get(12))++ Runs for as many iterations as needed to consumed ms_to_run+ milliseconds on whatever we're running on. Returns tuple of salt,+ iterations, and psk++Scrypt+---------------++.. versionadded:: 2.8.0++.. py:function:: scrypt(out_len, password, salt, N=1024, r=8, p=8)++ Runs Scrypt key derivation function over the specified password+ and salt using Scrypt parameters N, r, p.++KDF+----------------------------------------++.. py:function:: kdf(algo, secret, out_len, salt)++ Performs a key derviation function (such as "HKDF(SHA-384)") over+ the provided secret and salt values. Returns a value of the+ specified length.++Public Key+----------------------------------------++.. py:class:: PublicKey(object)++ Previously ``public_key``++ .. py:classmethod:: load(val)++ Load a public key. The value should be a PEM or DER blob.++ .. py:classmethod:: load_rsa(n, e)++ Load an RSA public key giving the modulus and public exponent+ as integers.++ .. py:classmethod:: load_dsa(p, q, g, y)++ Load an DSA public key giving the parameters and public value+ as integers.++ .. py:classmethod:: load_dh(p, g, y)++ Load an Diffie-Hellman public key giving the parameters and+ public value as integers.++ .. py:classmethod:: load_elgamal(p, q, g, y)++ Load an ElGamal public key giving the parameters and+ public value as integers.++ .. py:classmethod:: load_ecdsa(curve, pub_x, pub_y)++ Load an ECDSA public key giving the curve as a string+ (like "secp256r1") and the public point as a pair of+ integers giving the affine coordinates.++ .. py:classmethod:: load_ecdh(curve, pub_x, pub_y)++ Load an ECDH public key giving the curve as a string+ (like "secp256r1") and the public point as a pair of+ integers giving the affine coordinates.++ .. py:classmethod:: load_sm2(curve, pub_x, pub_y)++ Load a SM2 public key giving the curve as a string (like+ "sm2p256v1") and the public point as a pair of integers giving+ the affine coordinates.++ .. py:method:: check_key(rng_obj, strong=True):++ Test the key for consistency. If ``strong`` is ``True`` then+ more expensive tests are performed.++ .. py:method:: export(pem=False)++ Exports the public key using the usual X.509 SPKI representation.+ If ``pem`` is True, the result is a PEM encoded string. Otherwise+ it is a binary DER value.++ .. py:method:: to_der()++ Like ``self.export(False)``++ .. py:method:: to_pem()++ Like ``self.export(True)``++ .. py:method:: get_field(field_name)++ Return an integer field related to the public key. The valid field names+ vary depending on the algorithm. For example RSA public modulus can be+ extracted with ``rsa_key.get_field("n")``.++ .. py:method:: fingerprint(hash = 'SHA-256')++ Returns a hash of the public key++ .. py:method:: algo_name()++ Returns the algorithm name++ .. py:method:: estimated_strength()++ Returns the estimated strength of this key against known attacks+ (NFS, Pollard's rho, etc)++Private Key+----------------------------------------++.. py:class:: PrivateKey++ Previously ``private_key``++ .. py:classmethod:: create(algo, param, rng)++ 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+ "curve25519" (which is actually a completely distinct key type+ with a non-standard encoding).++ .. py:classmethod:: load(val, passphrase="")++ Return a private key (DER or PEM formats accepted)++ .. py:classmethod:: load_rsa(p, q, e)++ Return a private RSA key++ .. py:classmethod:: load_dsa(p, q, g, x)++ Return a private DSA key++ .. py:classmethod:: load_dh(p, g, x)++ Return a private DH key++ .. py:classmethod:: load_elgamal(p, q, g, x)++ Return a private ElGamal key++ .. py:classmethod:: load_ecdsa(curve, x)++ Return a private ECDSA key++ .. py:classmethod:: load_ecdh(curve, x)++ Return a private ECDH key++ .. py:classmethod:: load_sm2(curve, x)++ Return a private SM2 key++ .. py:method:: get_public_key()++ Return a public_key object++ .. py:method:: to_pem()++ Return the PEM encoded private key (unencrypted). Like ``self.export(True)``++ .. py:method:: to_der()++ Return the PEM encoded private key (unencrypted). Like ``self.export(False)``++ .. py:method:: check_key(rng_obj, strong=True):++ Test the key for consistency. If ``strong`` is ``True`` then+ more expensive tests are performed.++ .. py:method:: algo_name()++ Returns the algorithm name++ .. py:method:: export(pem=False)++ Exports the private key in PKCS8 format. If ``pem`` is True, the+ result is a PEM encoded string. Otherwise it is a binary DER+ value. The key will not be encrypted.++ .. py:method:: export_encrypted(passphrase, rng, pem=False, msec=300, cipher=None, pbkdf=None)++ Exports the private key in PKCS8 format, encrypted using the+ provided passphrase. If ``pem`` is True, the result is a PEM+ encoded string. Otherwise it is a binary DER value.++ .. py:method:: get_field(field_name)++ Return an integer field related to the public key. The valid field names+ vary depending on the algorithm. For example first RSA secret prime can be+ extracted with ``rsa_key.get_field("p")``. This function can also be+ used to extract the public parameters.++Public Key Operations+----------------------------------------++.. py:class:: PKEncrypt(pubkey, padding)++ Previously ``pk_op_encrypt``++ .. py:method:: encrypt(msg, rng)++.. py:class:: PKDecrypt(privkey, padding)++ Previously ``pk_op_decrypt``++ .. py:method:: decrypt(msg)++.. py:class:: PKSign(privkey, hash_w_padding)++ Previously ``pk_op_sign``++ .. py:method:: update(msg)+ .. py:method:: finish(rng)++.. py:class:: PKVerify(pubkey, hash_w_padding)++ Previously ``pk_op_verify``++ .. py:method:: update(msg)+ .. py:method:: check_signature(signature)++.. py:class:: PKKeyAgreement(privkey, kdf)++ Previously ``pk_op_key_agreement``++ .. py:method:: public_value()++ Returns the public value to be passed to the other party++ .. py:method:: agree(other, key_len, salt)++ Returns a key derived by the KDF.++Multiple Precision Integers (MPI)+-------------------------------------+.. versionadded:: 2.8.0++.. py:class:: MPI(initial_value=None, radix=None)++ Initialize an MPI object with specified value, left as zero otherwise. The+ ``initial_value`` should be an ``int``, ``str``, or ``MPI``.+ The ``radix`` value should be set to 16 when initializing from a base 16 `str` value.+++ Most of the usual arithmetic operators (``__add__``, ``__mul__``, etc) are+ defined.++ .. py:method:: inverse_mod(modulus)++ Return the inverse of ``self`` modulo ``modulus``, or zero if no inverse exists++ .. py:method:: is_prime(rng, prob=128)++ Test if ``self`` is prime++ .. py:method:: pow_mod(exponent, modulus):++ Return ``self`` to the ``exponent`` power modulo ``modulus``++ .. py:method:: mod_mul(other, modulus):++ Return the multiplication product of ``self`` and ``other`` modulo ``modulus``++ .. py:method:: gcd(other):++ Return the greatest common divisor of ``self`` and ``other``+++Format Preserving Encryption (FE1 scheme)+-----------------------------------------+.. versionadded:: 2.8.0++.. py:class:: FormatPreservingEncryptionFE1(modulus, key, rounds=5, compat_mode=False)++ Initialize an instance for format preserving encryption++ .. py:method:: encrypt(msg, tweak)++ The msg should be a botan2.MPI or an object which can be converted to one++ .. py:method:: decrypt(msg, tweak)++ The msg should be a botan2.MPI or an object which can be converted to one++HOTP+-----------------------------------------+.. versionadded:: 2.8.0++.. py:class:: HOTP(key, hash="SHA-1", digits=6)++ .. py:method:: generate(counter)++ Generate an HOTP code for the provided counter++ .. py:method:: check(code, counter, resync_range=0)++ Check if provided ``code`` is the correct code for ``counter``.+ If ``resync_range`` is greater than zero, HOTP also checks+ up to ``resync_range`` following counter values.++ Returns a tuple of (bool,int) where the boolean indicates if the+ code was valid, and the int indicates the next counter value+ that should be used. If the code did not verify, the next+ counter value is always identical to the counter that was passed+ in. If the code did verify and resync_range was zero, then the+ next counter will always be counter+1.++X509Cert+-----------------------------------------++.. py:class:: X509Cert(filename=None, buf=None) ++ .. py:method:: time_starts()++ Return the time the certificate becomes valid, as a string in form+ "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is+ relative to UTC.++ .. py:method:: time_expires()++ Return the time the certificate expires, as a string in form+ "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is+ relative to UTC. ++ .. py:method:: to_string()++ Format the certificate as a free-form string.++ .. py:method:: fingerprint(hash_algo='SHA-256')++ Return a fingerprint for the certificate, which is basically just a hash+ of the binary contents. Normally SHA-1 or SHA-256 is used, but any hash+ function is allowed.++ .. py:method:: serial_number()++ Return the serial number of the certificate.++ .. py:method:: authority_key_id()++ Return the authority key ID set in the certificate, which may be empty.++ .. py:method:: subject_key_id()++ Return the subject key ID set in the certificate, which may be empty.++ .. py:method:: subject_public_key_bits()++ Get the serialized representation of the public key included in this certificate.++ .. py:method:: subject_public_key()++ Get the public key included in this certificate as an object of class ``PublicKey``.++ .. py:method:: subject_dn(key, index)++ Get a value from the subject DN field.++ ``key`` specifies a value to get, for instance ``"Name"`` or `"Country"`. ++ .. py:method:: issuer_dn(key, index)++ Get a value from the issuer DN field.++ ``key`` specifies a value to get, for instance ``"Name"`` or `"Country"`.++ .. py:method:: hostname_match(hostname)++ Return True if the Common Name (CN) field of the certificate matches a given ``hostname``.++ .. py:method:: not_before()++ Return the time the certificate becomes valid, as seconds since epoch. ++ .. py:method:: not_after()++ Return the time the certificate expires, as seconds since epoch.++ .. py:method:: allowed_usage(usage_list)++ Return True if the certificates Key Usage extension contains all constraints given in ``usage_list``.+ Also return True if the certificate doesn't have this extension.+ Example usage constraints are: ``"DIGITAL_SIGNATURE"``, ``"KEY_CERT_SIGN"``, ``"CRL_SIGN"``.++ .. py:method:: verify(intermediates=None, \+ trusted=None, \+ trusted_path=None, \+ required_strength=0, \+ hostname=None, \+ reference_time=0 \+ crls=None)++ Verify a certificate. Returns 0 if validation was successful, returns a positive error code + if the validation was unsuccesful.++ ``intermediates`` is a list of untrusted subauthorities.++ ``trusted`` is a list of trusted root CAs.++ The `trusted_path` refers to a directory where one or more trusted CA+ certificates are stored.++ Set ``required_strength`` to indicate the minimum key and hash strength+ that is allowed. For instance setting to 80 allows 1024-bit RSA and SHA-1.+ Setting to 110 requires 2048-bit RSA and SHA-256 or higher. Set to zero+ to accept a default.++ If ``hostname`` is given, it will be checked against the certificates CN field.++ Set ``reference_time`` to be the time which the certificate chain is+ validated against. Use zero (default) to use the current system clock.++ ``crls`` is a list of CRLs issued by either trusted or untrusted authorities.++ .. py:classmethod:: validation_status(error_code)++ Return an informative string associated with the verification return code.++ .. py:method:: is_revoked(self, crl)++ Check if the certificate (``self``) is revoked on the given ``crl``.++X509CRL+-----------------------------------------++.. py:class:: X509CRL(filename=None, buf=None)++ Class representing an X.509 Certificate Revocation List.++ A CRL in PEM or DER format can be loaded from a file, with the ``filename`` argument,+ or from a bytestring, with the ``buf`` argument.++++++
+ third_party/botan/doc/api_ref/rng.rst view
@@ -0,0 +1,281 @@+.. _random_number_generators:++Random Number Generators+========================================++.. cpp:class:: RandomNumberGenerator++ The base class for all RNG objects, is declared in ``rng.h``.++ .. cpp:function:: void randomize(uint8_t* output_array, size_t length)++ Places *length* random bytes into the provided buffer.++ .. cpp:function:: void randomize_with_input(uint8_t* data, size_t length, \+ const uint8_t* extra_input, size_t extra_input_len)++ Like randomize, but first incorporates the additional input field into the+ state of the RNG. The additional input could be anything which+ parameterizes this request. Not all RNG types accept additional inputs,+ the value will be silently ignored when not supported.++ .. cpp:function:: void randomize_with_ts_input(uint8_t* data, size_t length)++ Creates a buffer with some timestamp values and calls ``randomize_with_input``++ .. note::++ When RDRAND is enabled and available at runtime, instead of timestamps+ the output of RDRAND is used as the additional data.++ .. cpp:function:: uint8_t next_byte()++ Generates a single random byte and returns it. Note that calling this+ function several times is much slower than calling ``randomize`` once to+ produce multiple bytes at a time.++ .. cpp:function:: void add_entropy(const uint8_t* data, size_t length)++ Incorporates provided data into the state of the PRNG, if at all possible.+ This works for most RNG types, including the system and TPM RNGs. But if+ the RNG doesn't support this operation, the data is dropped, no error is+ indicated.++ .. cpp:function:: bool accepts_input() const++ This function returns ``false`` if it is known that this RNG object cannot+ accept external inputs. In this case, any calls to+ :cpp:func:`RandomNumberGenerator::add_entropy` will be ignored.++ .. cpp:function:: void reseed_from_rng(RandomNumberGenerator& rng, \+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS)++ Reseed by calling ``rng`` to acquire ``poll_bits`` data.+++RNG Types+----------------------------------------++Several different RNG types are implemented. Some access hardware RNGs, which+are only available on certain platforms. Others are mostly useful in specific+situations.++Generally prefer using the system RNG, or if not available use ``AutoSeeded_RNG``+which is intended to provide best possible behavior in a userspace PRNG.++System_RNG+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++On systems which support it, in ``system_rng.h`` you can access a shared+reference to a process global instance of the system PRNG (using interfaces such+as ``/dev/urandom``, ``getrandom``, ``arc4random``, or ``RtlGenRandom``):++.. cpp:function:: RandomNumberGenerator& system_rng()++ Returns a reference to the system RNG++There is also a wrapper class ``System_RNG`` which simply invokes on+the return value of ``system_rng()``. This is useful in situations where+you may sometimes want to use the system RNG and a userspace RNG in others,+for example::++ std::unique_ptr<Botan::RandomNumberGenerator> rng;+ #if defined(BOTAN_HAS_SYSTEM_RNG)+ rng.reset(new System_RNG);+ #else+ rng.reset(new AutoSeeded_RNG);+ #endif++Unlike nearly any other object in Botan it is acceptable to share a single+instance of ``System_RNG`` between threads, because the underlying RNG is itself+thread safe due to being serialized by a mutex in the kernel itself.++AutoSeeded_RNG+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++AutoSeeded_RNG is type naming a 'best available' userspace PRNG. The+exact definition of this has changed over time and may change in the+future, fortunately there is no compatibility concerns when changing+any RNG since the only expectation is it produces bits+indistinguishable from random.++.. note:: Starting in 2.16.0, AutoSeeded_RNG uses an internal lock and so is+ safe to share among threads. However if possible it is still better to+ use a RNG per thread as otherwise the RNG object needlessly creates a+ point of contention. In previous versions, the RNG does not have an+ internal lock and all access to it must be serialized.++The current version uses HMAC_DRBG with either SHA-384 or SHA-256. The+initial seed is generated either by the system PRNG (if available) or+a default set of entropy sources. These are also used for periodic+reseeding of the RNG state.++HMAC_DRBG+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++HMAC DRBG is a random number generator designed by NIST and specified+in SP 800-90A. It seems to be the most conservative generator of the+NIST approved options.++It can be instantiated with any HMAC but is typically used with+SHA-256, SHA-384, or SHA-512, as these are the hash functions approved+for this use by NIST.++HMAC_DRBG's constructors are:++.. cpp:class:: HMAC_DRBG++ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \+ RandomNumberGenerator& underlying_rng, \+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \+ size_t max_number_of_bytes_per_request = 64 * 1024)++ Creates a DRBG which will automatically reseed as required by making+ calls to ``underlying_rng`` either after being invoked+ ``reseed_interval`` times, or if use of ``fork`` system call is+ detected.++ You can disable automatic reseeding by setting ``reseed_interval`` to+ zero, in which case ``underlying_rng`` will only be invoked in the case+ of ``fork``.++ The specification of HMAC DRBG requires that each invocation produce no+ more than 64 kibibytes of data. However, the RNG interface allows+ producing arbitrary amounts of data in a single request. To accommodate+ this, ``HMAC_DRBG`` treats requests for more data as if they were+ multiple requests each of (at most) the maximum size. You can specify a+ smaller maximum size with ``max_number_of_bytes_per_request``. There is+ normally no reason to do this.++ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \+ Entropy_Sources& entropy_sources, \+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \+ size_t max_number_of_bytes_per_request = 64 * 1024)++ Like above function, but instead of an RNG taking a set of entropy+ sources to seed from as required.++ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \+ RandomNumberGenerator& underlying_rng, \+ Entropy_Sources& entropy_sources, \+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \+ size_t max_number_of_bytes_per_request = 64 * 1024)++ Like above function, but taking both an RNG and a set of entropy+ sources to seed from as required.++ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf)++ Creates an unseeded DRBG. You must explicitly provide seed data later+ on in order to use this RNG. This is primarily useful for deterministic+ key generation.++ Since no source of data is available to automatically reseed, automatic+ reseeding is disabled when this constructor is used. If the RNG object+ detects that ``fork`` system call was used without it being+ subsequently reseeded, it will throw an exception.++ .. cpp:function:: HMAC_DRBG(const std::string& hmac_hash)++ Like the constructor just taking a PRF, except instead of a PRF object,+ a string specifying what hash to use with HMAC is provided.++ChaCha_RNG+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++This is a very fast userspace PRNG based on ChaCha20 and HMAC(SHA-256). The key+for ChaCha is derived by hashing entropy inputs with HMAC. Then the ChaCha+keystream generator is run, first to generate the new HMAC key (used for any+future entropy additions), then the desired RNG outputs.++This RNG composes two primitives thought to be secure (ChaCha and HMAC) in a+simple and well studied way (the extract-then-expand paradigm), but is still an+ad-hoc and non-standard construction. It is included because it is roughly 20x+faster then HMAC_DRBG (basically running as fast as ChaCha can generate+keystream bits), and certain applications need access to a very fast RNG.++One thing applications using ``ChaCha_RNG`` need to be aware of is that for+performance reasons, no backtracking resistance is implemented in the RNG+design. An attacker who recovers the ``ChaCha_RNG`` state can recover the output+backwards in time to the last rekey and forwards to the next rekey.++An explicit reseeding (:cpp:func:`RandomNumberGenerator::add_entropy`) or+providing any input to the RNG+(:cpp:func:`RandomNumberGenerator::randomize_with_ts_input`,+:cpp:func:`RandomNumberGenerator::randomize_with_input`) is sufficient to cause+a reseeding. Or, if a RNG or entropy source was provided to the ``ChaCha_RNG``+constructor, then reseeding will be performed automatically after a certain+interval of requests.++Processor_RNG+^^^^^^^^^^^^^^^^^++This RNG type directly invokes a CPU instruction capable of generating+a cryptographically secure random number. On x86 it uses ``rdrand``,+on POWER ``darn``. If the relevant instruction is not available, the+constructor of the class will throw at runtime. You can test+beforehand by checking the result of ``Processor_RNG::available()``.++TPM_RNG+^^^^^^^^^^^^^^^^^++This RNG type allows using the RNG exported from a TPM chip.++PKCS11_RNG+^^^^^^^^^^^^^^^^^++This RNG type allows using the RNG exported from a hardware token accessed via PKCS11.++Entropy Sources+---------------------------------++An ``EntropySource`` is an abstract representation of some method of+gather "real" entropy. This tends to be very system dependent. The+*only* way you should use an ``EntropySource`` is to pass it to a PRNG+that will extract entropy from it -- never use the output directly for+any kind of key or nonce generation!++``EntropySource`` has a pair of functions for getting entropy from+some external source, called ``fast_poll`` and ``slow_poll``. These+pass a buffer of bytes to be written; the functions then return how+many bytes of entropy were gathered.++Note for writers of ``EntropySource`` subclasses: it isn't necessary+to use any kind of cryptographic hash on your output. The data+produced by an EntropySource is only used by an application after it+has been hashed by the ``RandomNumberGenerator`` that asked for the+entropy, thus any hashing you do will be wasteful of both CPU cycles+and entropy.++The following entropy sources are currently used:++ * The system RNG (``arc4random``, ``/dev/urandom``, or ``RtlGenRandom``).+ * RDRAND and RDSEED are used if available, but not counted as contributing entropy+ * ``/dev/random`` and ``/dev/urandom``. This may be redundant with the system RNG+ * ``getentropy``, only used on OpenBSD currently+ * ``/proc`` walk: read files in ``/proc``. Last ditch protection against+ flawed system RNG.+ * Win32 stats: takes snapshot of current system processes. Last ditch+ protection against flawed system RNG.++Fork Safety+---------------------------------++On Unix platforms, the ``fork()`` and ``clone()`` system calls can+be used to spawn a new child process. Fork safety ensures that the+child process doesn't see the same output of random bytes as the+parent process. Botan tries to ensure fork safety by feeding the+process ID into the internal state of the random generator and by+automatically reseeding the random generator if the process ID+changed between two requests of random bytes. However, this does+not protect against PID wrap around. The process ID is usually+implemented as a 16 bit integer. In this scenario, a process will+spawn a new child process, which exits the parent process and+spawns a new child process himself. If the PID wrapped around, the+second child process may get assigned the process ID of it's +grandparent and the fork safety can not be ensured.++Therefore, it is strongly recommended to explicitly reseed any+userspace random generators after forking a new process. If this is+not possible in your application, prefer using the system PRNG+instead.
+ third_party/botan/doc/api_ref/roughtime.rst view
@@ -0,0 +1,6 @@+Roughtime+===========++.. versionadded:: 2.13.0++Botan includes a Roughtime client, available in ``botan/roughtime.h``
+ third_party/botan/doc/api_ref/secmem.rst view
@@ -0,0 +1,31 @@++Memory container+========================================++A major concern with mixing modern multi-user OSes and cryptographic+code is that at any time the code (including secret keys) could be+swapped to disk, where it can later be read by an attacker, or left+floating around in memory for later retrieval.++For this reason the library uses a ``std::vector`` with a custom+allocator that will zero memory before deallocation, named via typedef+as ``secure_vector``. Because it is simply a STL vector with a custom+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 occurring. Typically this operation is+restricted to privileged 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+of this small locked pool, and then if that fails will fall back to+normal heap allocations.++The ``secure_vector`` template is only meant for primitive data types+(bytes or ints): if you want a container of higher level Botan+objects, you can just use a ``std::vector``, since these objects know+how to clear themselves when they are destroyed. You cannot, however,+have a ``std::vector`` (or any other container) of ``Pipe`` objects or+filters, because these types have pointers to other filters, and+implementing copy constructors for these types would be both hard and+quite expensive (vectors of pointers to such objects is fine, though).
+ third_party/botan/doc/api_ref/srp.rst view
@@ -0,0 +1,77 @@+Secure Remote Password+========================================++The library contains an implementation of the+`SRP6-a <http://srp.stanford.edu/design.html>`_ password authenticated+key exchange protocol in ``srp6.h``.++A SRP client provides what is called a SRP *verifier* to the server.+This verifier is based on a password, but the password cannot be+easily derived from the verifier (however brute force attacks are+possible). Later, the client and server can perform an SRP exchange,+which results in a shared secret key. This key can be used for mutual+authentication and/or encryption.++SRP works in a discrete logarithm group. Special parameter sets for+SRP6 are defined, denoted in the library as "modp/srp/<size>", for+example "modp/srp/2048".++.. warning::++ While knowledge of the verifier does not easily allow an attacker+ to get the raw password, they could still use the verifier to+ impersonate the server to the client, so verifiers should be+ protected as carefully as a plaintext password would be.++.. cpp:function:: BigInt generate_srp6_verifier( \+ const std::string& username, \+ const std::string& password, \+ const std::vector<uint8_t>& salt, \+ const std::string& group_id, \+ const std::string& hash_id)++ Generates a new verifier using the specified password and salt.+ This is stored by the server. The salt must also be stored. Later,+ the given username and password are used to by the client during+ the key agreement step.++.. cpp:function:: std::string srp6_group_identifier( \+ const BigInt& N, const BigInt& g)++.. cpp:class:: SRP6_Server_Session++ .. cpp:function:: BigInt step1(const BigInt& v, \+ const std::string& group_id, \+ const std::string& hash_id, \+ RandomNumberGenerator& rng)++ Takes a verifier (generated by generate_srp6_verifier) along+ with the group_id, and output a value `B` which is provided to+ the client.++ .. cpp:function:: SymmetricKey step2(const BigInt& A)++ Takes the parameter A generated by srp6_client_agree,+ and return the shared secret key.++ In the event of an impersonation attack (or wrong username/password, etc)+ no error occurs, but the key returned will be different on the two sides.+ The two sides must verify each other, for example by using the shared+ secret to key an HMAC and then exchanging authenticated messages.++.. cpp:function:: std::pair<BigInt,SymmetricKey> srp6_client_agree( \+ const std::string& username, \+ const std::string& password, \+ const std::string& group_id, \+ const std::string& hash_id, \+ const std::vector<uint8_t>& salt, \+ const BigInt& B, \+ RandomNumberGenerator& rng)++ The client receives these parameters from the server, except for+ the username and password which are provided by the user. The+ parameter B is the output of `step1`.++ The client agreement step outputs a shared symmetric key along+ with the parameter A which is returned to the server (and allows+ it the compute the shared key).
+ third_party/botan/doc/api_ref/stream_ciphers.rst view
@@ -0,0 +1,211 @@+Stream Ciphers+========================++In contrast to block ciphers, stream ciphers operate on a plaintext stream+instead of blocks. Thus encrypting data results in changing the internal state+of the cipher and encryption of plaintext with arbitrary length is possible in+one go (in byte amounts). All implemented stream ciphers derive from the base+class :cpp:class:`StreamCipher` (`botan/stream_cipher.h`).++.. warning::++ Using a stream cipher without an authentication code is extremely insecure,+ because an attacker can trivially modify messages. Prefer using an+ authenticated cipher mode such as GCM or SIV.++.. warning::++ Encrypting more than one message with the same key requires careful management+ of initialization vectors. Otherwise the keystream will be reused, which causes+ the security of the cipher to completely fail.++.. cpp:class:: StreamCipher++ .. cpp:function:: std::string name() const++ Returns a human-readable string of the name of this algorithm.++ .. cpp:function:: void clear()++ Clear the key.++ .. cpp:function:: StreamCipher* clone() const++ Return a newly allocated object of the same type as this one.++ .. cpp:function:: void set_key(const uint8_t* key, size_t length)++ Set the stream cipher key. If the length is not accepted, an+ ``Invalid_Key_Length`` exception is thrown.++ .. cpp:function:: bool valid_keylength(size_t length) const++ This function returns true if and only if *length* is a valid+ keylength for the algorithm.++ .. cpp:function:: size_t minimum_keylength() const++ Return the smallest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: size_t maximum_keylength() const++ Return the largest key length (in bytes) that is acceptable for the+ algorithm.++ .. cpp:function:: bool valid_iv_length(size_t iv_len) const++ This function returns true if and only if *length* is a valid IV length for+ the stream cipher. Some ciphers do not support IVs at all, and will return+ false for any value except zero.++ .. cpp:function:: size_t default_iv_length() const++ Returns some default IV size, normally the largest IV supported by the cipher.+ If this function returns zero, then IVs are not supported and any call to+ ``set_iv`` with a non-empty value will fail.++ .. cpp:function:: void set_iv(const uint8_t*, size_t len)++ Load IV into the stream cipher state. This should happen after the key is+ set and before any operation (encrypt/decrypt/seek) is called.++ If the cipher does not support IVs, then a call with ``len`` equal to zero+ will be accepted and any other length will cause a ``Invalid_IV_Length``+ exception.++ .. cpp:function:: void seek(uint64_t offset)++ Sets the state of the stream cipher and keystream according to the passed+ *offset*, exactly as if *offset* bytes had first been encrypted. The key+ and (if required) the IV have to be set before this can be called. Not all+ ciphers support seeking; such objects will throw ``Not_Implemented`` in+ this case.++ .. cpp:function:: void cipher(const uint8_t* in, uint8_t* out, size_t n)++ Processes *n* bytes plain/ciphertext from *in* and writes the result to *out*.++ .. cpp:function:: void cipher1(uint8_t* inout, size_t n)++ Processes *n* bytes plain/ciphertext in place. Acts like :cpp:func:`cipher`\ (inout, inout, n).++ .. cpp:function:: void encipher(std::vector<uint8_t> inout)+ .. cpp:function:: void encrypt(std::vector<uint8_t> inout)+ .. cpp:function:: void decrypt(std::vector<uint8_t> inout)++ Processes plain/ciphertext *inout* in place. Acts like :cpp:func:`cipher`\ (inout.data(), inout.data(), inout.size()).++Code Example+-----------------++The following code encrypts a provided plaintext using ChaCha20.++.. code-block:: cpp++ #include <botan/stream_cipher.h>+ #include <botan/auto_rng.h>+ #include <botan/hex.h>+ #include <iostream>++ int main()+ {+ std::string plaintext("This is a tasty burger!");+ std::vector<uint8_t> pt(plaintext.data(),plaintext.data()+plaintext.length());+ const std::vector<uint8_t> key = Botan::hex_decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");+ std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create("ChaCha(20)"));++ //generate fresh nonce (IV)+ std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);+ std::vector<uint8_t> iv(8);+ rng->randomize(iv.data(),iv.size());++ //set key and IV+ cipher->set_key(key);+ cipher->set_iv(iv.data(),iv.size());+ cipher->encipher(pt);++ std::cout << cipher->name() << " with iv " << Botan::hex_encode(iv) << ": "+ << Botan::hex_encode(pt) << "\n";+ return 0;+ }++Available Stream Ciphers+----------------------------++Botan provides the following stream ciphers. If in doubt use ChaCha20 or CTR(AES-256).++CTR-BE+~~~~~~~++A cipher mode that converts a block cipher into a stream cipher. It offers+parallel execution and can seek within the output stream, both useful+properties.++CTR mode requires an IV which can be any length up to the block size of the+underlying cipher. If it is shorter than the block size, sufficient zero bytes+are appended.++It is possible to choose the width of the counter portion, which can improve+performance somewhat, but limits the maximum number of bytes that can safely be+encrypted. Different protocols have different conventions for the width of the+counter portion. This is done by specifying with width (which must be at least 4+bytes, allowing to encrypt 2\ :sup:`32` blocks of data) for example+"CTR(AES-256,8)" to select a 64-bit counter.++(The ``-BE`` suffix refers to big-endian convention for the counter.+This is the most common case.)++OFB+~~~~~++Another stream cipher based on a block cipher. Unlike CTR mode, it does not+allow parallel execution or seeking within the output stream. Prefer CTR.++Available if ``BOTAN_HAS_OFB`` is defined.++ChaCha+~~~~~~~~++A very fast cipher, now widely deployed in TLS as part of the ChaCha20Poly1305+AEAD. Can be used with 8 (fast but dangerous), 12 (balance), or 20 rounds+(conservative). Even with 20 rounds, ChaCha is very fast. Use 20 rounds.++ChaCha supports an optional IV (which defaults to all zeros). It can be of+length 64, 96 or (since 2.8) 192 bits. Using ChaCha with a 192 bit nonce is also+known as XChaCha.++Available if ``BOTAN_HAS_CHACHA`` is defined.++Salsa20+~~~~~~~~~++An earlier iteration of the ChaCha design, this cipher is popular due to its use+in the libsodium library. Prefer ChaCha.++Salsa supports an optional IV (which defaults to all zeros). It can be of length+64 or 192 bits. Using Salsa with a 192 bit nonce is also known as XSalsa.++Available if ``BOTAN_HAS_SALSA20`` is defined.++SHAKE-128+~~~~~~~~~~~~++This is the SHAKE-128 XOF exposed as a stream cipher. It is slower than ChaCha+and somewhat obscure. It does not support IVs or seeking within the cipher+stream.++Available if ``BOTAN_HAS_SHAKE_CIPHER`` is defined.++RC4+~~~~++An old and very widely deployed stream cipher notable for its simplicity. It+does not support IVs or seeking within the cipher stream.++.. warning::++ RC4 is now badly broken. **Avoid in new code** and use only if required for+ compatibility with existing systems.++Available if ``BOTAN_HAS_RC4`` is defined.
+ third_party/botan/doc/api_ref/tls.rst view
@@ -0,0 +1,1926 @@+Transport Layer Security (TLS)+========================================++.. versionadded:: 1.11.0++Botan has client and server implementations of various versions of the+TLS protocol, including TLS v1.0, TLS v1.1, and TLS v1.2. As of+version 1.11.13, support for the insecure SSLv3 protocol has been+removed.++There is also support for DTLS (v1.0 and v1.2), a variant of TLS+adapted for operation on datagram transports such as UDP and+SCTP. DTLS support should be considered as beta quality and further+testing is invited.++The TLS implementation does not know anything about sockets or the+network layer. Instead, it calls a user provided callback (hereafter+``output_fn``) whenever it has data that it would want to send to the+other party (for instance, by writing it to a network socket), and+whenever the application receives some data from the counterparty (for+instance, by reading from a network socket) it passes that information+to TLS using :cpp:func:`TLS::Channel::received_data`. If the data+passed in results in some change in the state, such as a handshake+completing, or some data or an alert being received from the other+side, then the appropriate user provided callback will be invoked.++If the reader is familiar with OpenSSL's BIO layer, it might be analogous+to saying the only way of interacting with Botan's TLS is via a `BIO_mem` I/O+abstraction. This makes the library completely agnostic to how you+write your network layer, be it blocking sockets, libevent, asio, a+message queue, lwIP on RTOS, some carrier pigeons, etc.++Starting in 1.11.31, the application callbacks are encapsulated as the class+``TLS::Callbacks`` with the following members. The first four (``tls_emit_data``,+``tls_record_received``, ``tls_alert``, and ``tls_session_established``) are+mandatory for using TLS, all others are optional and provide additional+information about the connection.++ .. cpp:function:: void tls_emit_data(const uint8_t data[], size_t data_len)++ Mandatory. The TLS stack requests that all bytes of *data* be queued up to send to the+ counterparty. After this function returns, the buffer containing *data* will+ be overwritten, so a copy of the input must be made if the callback+ cannot send the data immediately.++ As an example you could ``send`` to perform a blocking write on a socket,+ or append the data to a queue managed by your application, and initiate+ an asynchronous write.++ For TLS all writes must occur *in the order requested*.+ For DTLS this ordering is not strictly required, but is still recommended.++ .. cpp:function:: void tls_record_received(uint64_t rec_no, const uint8_t data[], size_t data_len)++ Mandatory. Called once for each application_data record which is received, with the+ matching (TLS level) record sequence number.++ Currently empty records are ignored and do not instigate a callback,+ but this may change in a future release.++ As with ``tls_emit_data``, the array will be overwritten sometime after+ the callback returns, so a copy should be made if needed.++ For TLS the record number will always increase.++ For DTLS, it is possible to receive records with the `rec_no` field out of+ order, or with gaps, corresponding to reordered or lost datagrams.++ .. cpp:function:: void tls_alert(Alert alert)++ Mandatory. Called when an alert is received from the peer. Note that alerts+ received before the handshake is complete are not authenticated and+ could have been inserted by a MITM attacker.++ .. cpp:function:: bool tls_session_established(const TLS::Session& session)++ Mandatory. Called whenever a negotiation completes. This can happen more+ than once on any connection, if renegotiation occurs. The *session* parameter+ provides information about the session which was just established.++ If this function returns false, the session will not be cached+ for later resumption.++ If this function wishes to cancel the handshake, it can throw an+ exception which will send a close message to the counterparty and+ reset the connection state.++ .. cpp:function:: void tls_verify_cert_chain(const std::vector<X509_Certificate>& cert_chain, \+ const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, \+ const std::vector<Certificate_Store*>& trusted_roots, \+ Usage_Type usage, \+ const std::string& hostname, \+ const Policy& policy)++ Optional - default implementation should work for many users.+ It can be overridden for implementing extra validation routines+ such as public key pinning.++ Verifies the certificate chain in *cert_chain*, assuming the leaf+ certificate is the first element. Throws an exception if any+ error makes this certificate chain unacceptable.++ If usage is `Usage_Type::TLS_SERVER_AUTH`, then *hostname* should+ match the information in the server certificate. If usage is+ `TLS_CLIENT_AUTH`, then *hostname* specifies the host the client+ is authenticating against (from SNI); the callback can use this for+ any special site specific auth logic.++ The `ocsp_responses` is a possibly empty list of OCSP responses provided by+ the server. In the current implementation of TLS OCSP stapling, only a+ single OCSP response can be returned. A existing TLS extension allows the+ server to send multiple OCSP responses, this extension may be supported in+ the future in which case more than one OCSP response may be given during+ this callback.++ The `trusted_roots` parameter was returned by a call from the associated+ `Credentials_Manager`.++ The `policy` provided is the policy for the TLS session which is+ being authenticated using this certificate chain. It can be consulted+ for values such as allowable signature methods and key sizes.++ .. cpp:function:: std::chrono::milliseconds tls_verify_cert_chain_ocsp_timeout() const++ Called by default `tls_verify_cert_chain` to set timeout for online OCSP requests+ on the certificate chain. Return 0 to disable OCSP. Current default is 0.++ .. cpp:function:: std::string tls_server_choose_app_protocol(const std::vector<std::string>& client_protos)++ Optional. Called by the server when a client includes a list of protocols in the ALPN extension.+ The server then choose which protocol to use, or "" to disable sending any ALPN response.+ The default implementation returns the empty string all of the time, effectively disabling+ ALPN responses.++ .. cpp:function:: void tls_session_activated()++ Optional. By default does nothing. This is called when the session is+ activated, that is once it is possible to send or receive data on the+ channel. In particular it is possible for an implementation of this+ function to perform an initial write on the channel.++ .. cpp:function:: std::vector<uint8_t> tls_provide_cert_status(const std::vector<X509_Certificate>& chain, \+ const Certificate_Status_Request& csr)++ Optional. This can return a cached OCSP response. This is only+ used on the server side, and only if the client requests OCSP+ stapling.++ .. cpp:function:: std::string tls_peer_network_identity()++ Optional. Return a string that identifies the peer in some unique way+ (for example, by formatting the remote IP and port into a string).+ This is currently used to bind DTLS cookies to the network identity.++ .. cpp:function:: void tls_inspect_handshake_msg(const Handshake_Message&)++ This callback is optional, and can be used to inspect all handshake messages+ while the session establishment occurs.++ .. cpp:function:: void tls_modify_extensions(Extensions& extn, Connection_Side which_side)++ This callback is optional, and can be used to modify extensions before they+ are sent to the peer. For example this enables adding a custom extension,+ or replacing or removing an extension set by the library.++ .. cpp:function:: void tls_examine_extensions(const Extensions& extn, Connection_Side which_side)++ This callback is optional, and can be used to examine extensions sent by+ the peer.++ .. cpp:function:: void tls_log_error(const char* msg)++ Optional logging for an error message. (Not currently used)++ .. cpp:function:: void tls_log_debug(const char* msg)++ Optional logging for an debug message. (Not currently used)++ .. cpp:function:: void tls_log_debug_bin(const char* descr, const uint8_t val[], size_t len)++ Optional logging for an debug value. (Not currently used)++ .. cpp:function:: std::string tls_decode_group_param(TLS::Group_Params group_param)++ Optional. Called by the server when a client hello includes a list of supported groups in the+ supported_groups extension and by the client when decoding the server key exchange including the selected curve identifier.+ The function should return the name of the DH group or elliptic curve the passed+ TLS group identifier should be mapped to. Therefore this callback enables the use of custom + elliptic curves or DH groups in TLS, if both client and server map the custom identifiers correctly.+ Please note that it is required to allow the group TLS identifier in+ in the used :cpp:class:`TLS::Policy`.++Versions from 1.11.0 to 1.11.30 did not have ``TLS::Callbacks`` and instead+used independent std::functions to pass the various callback functions.+This interface is currently still included but is deprecated and will be removed+in a future release. For the documentation for this interface, please check+the docs for 1.11.30. This version of the manual only documents the new interface+added in 1.11.31.++TLS Channels+----------------------------------------++TLS servers and clients share an interface called `TLS::Channel`. A+TLS channel (either client or server object) has these methods+available:++.. cpp:class:: TLS::Channel++ .. cpp:function:: size_t received_data(const uint8_t buf[], size_t buf_size)+ .. cpp:function:: size_t received_data(const std::vector<uint8_t>& buf)++ This function is used to provide data sent by the counterparty+ (eg data that you read off the socket layer). Depending on the+ current protocol state and the amount of data provided this may+ result in one or more callback functions that were provided to+ the constructor being called.++ The return value of ``received_data`` specifies how many more+ bytes of input are needed to make any progress, unless the end of+ the data fell exactly on a message boundary, in which case it+ will return 0 instead.++ .. cpp:function:: void send(const uint8_t buf[], size_t buf_size)+ .. cpp:function:: void send(const std::string& str)+ .. cpp:function:: void send(const std::vector<uint8_t>& vec)++ Create one or more new TLS application records containing the+ provided data and send them. This will eventually result in at+ least one call to the ``output_fn`` callback before ``send``+ returns.++ If the current TLS connection state is unable to transmit new+ application records (for example because a handshake has not+ yet completed or the connection has already ended due to an+ error) an exception will be thrown.++ .. cpp:function:: void close()++ A close notification is sent to the counterparty, and the+ internal state is cleared.++ .. cpp:function:: void send_alert(const Alert& alert)++ Some other alert is sent to the counterparty. If the alert is+ fatal, the internal state is cleared.++ .. cpp:function:: bool is_active()++ Returns true if and only if a handshake has been completed on+ this connection and the connection has not been subsequently+ closed.++ .. cpp:function:: bool is_closed()++ Returns true if and only if either a close notification or a+ fatal alert message have been either sent or received.++ .. cpp:function:: bool timeout_check()++ This function does nothing unless the channel represents a DTLS+ connection and a handshake is actively in progress. In this case+ it will check the current timeout state and potentially initiate+ retransmission of handshake packets. Returns true if a timeout+ condition occurred.++ .. cpp:function:: void renegotiate(bool force_full_renegotiation = false)++ Initiates a renegotiation. The counterparty is allowed by the+ protocol to ignore this request. If a successful renegotiation+ occurs, the *handshake_cb* callback will be called again.++ If *force_full_renegotiation* is false, then the client will+ attempt to simply renew the current session - this will refresh+ the symmetric keys but will not change the session master+ secret. Otherwise it will initiate a completely new session.++ For a server, if *force_full_renegotiation* is false, then a+ session resumption will be allowed if the client attempts+ it. Otherwise the server will prevent resumption and force the+ creation of a new session.++ .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain()++ Returns the certificate chain of the counterparty. When acting+ as a client, this value will be non-empty unless the client's+ policy allowed anonymous connections and the server then chose+ an anonymous ciphersuite. Acting as a server, this value will+ ordinarily be empty, unless the server requested a certificate+ and the client responded with one.++ .. cpp:function:: SymmetricKey key_material_export( \+ const std::string& label, \+ const std::string& context, \+ size_t length)++ Returns an exported key of *length* bytes derived from *label*,+ *context*, and the session's master secret and client and server+ random values. This key will be unique to this connection, and+ as long as the session master secret remains secure an attacker+ should not be able to guess the key.++ Per :rfc:`5705`, *label* should begin with "EXPERIMENTAL" unless+ the label has been standardized in an RFC.++.. _tls_client:++TLS Clients+----------------------------------------++.. cpp:class:: TLS::Client++ .. cpp:function:: Client( \+ Callbacks& callbacks, \+ Session_Manager& session_manager, \+ Credentials_Manager& creds, \+ const Policy& policy, \+ RandomNumberGenerator& rng, \+ const Server_Information& server_info = Server_Information(), \+ const Protocol_Version offer_version = Protocol_Version::latest_tls_version(), \+ const std::vector<std::string>& next_protocols = std::vector<std::string>(), \+ size_t reserved_io_buffer_size = 16*1024 \+ )++ Initialize a new TLS client. The constructor will immediately+ initiate a new session.++ The *callbacks* parameter specifies the various application callbacks+ which pertain to this particular client connection.++ The *session_manager* is an interface for storing TLS sessions,+ which allows for session resumption upon reconnecting to a server.+ In the absence of a need for persistent sessions, use+ :cpp:class:`TLS::Session_Manager_In_Memory` which caches+ connections for the lifetime of a single process. See+ :ref:`tls_session_managers` for more about session managers.++ The *credentials_manager* is an interface that will be called to+ retrieve any certificates, secret keys, pre-shared keys, or SRP+ information; see :doc:`credentials_manager` for more information.++ Use the optional *server_info* to specify the DNS name of the+ server you are attempting to connect to, if you know it. This helps+ the server select what certificate to use and helps the client+ validate the connection.++ Note that the server name indicator name must be a FQDN. IP+ addresses are not allowed by RFC 6066 and may lead to interoperability+ problems.++ Use the optional *offer_version* to control the version of TLS you+ wish the client to offer. Normally, you'll want to offer the most+ recent version of (D)TLS that is available, however some broken+ servers are intolerant of certain versions being offered, and for+ classes of applications that have to deal with such servers+ (typically web browsers) it may be necessary to implement a version+ backdown strategy if the initial attempt fails.++ .. warning::++ Implementing such a backdown strategy allows an attacker to+ downgrade your connection to the weakest protocol that both you+ and the server support.++ Setting *offer_version* is also used to offer DTLS instead of TLS;+ use :cpp:func:`TLS::Protocol_Version::latest_dtls_version`.++ Optionally, the client will advertise *app_protocols* to the+ server using the ALPN extension.++ The optional *reserved_io_buffer_size* specifies how many bytes to+ pre-allocate in the I/O buffers. Use this if you want to control+ how much memory the channel uses initially (the buffers will be+ resized as needed to process inputs). Otherwise some reasonable+ default is used.++Code Example+^^^^^^^^^^^^+A minimal example of a TLS client is provided below.+The full code for a TLS client using BSD sockets is in `src/cli/tls_client.cpp`++.. code-block:: cpp++ #include <botan/tls_client.h>+ #include <botan/tls_callbacks.h>+ #include <botan/tls_session_manager.h>+ #include <botan/tls_policy.h>+ #include <botan/auto_rng.h>+ #include <botan/certstor.h>++ /**+ * @brief Callbacks invoked by TLS::Channel.+ *+ * Botan::TLS::Callbacks is an abstract class.+ * For improved readability, only the functions that are mandatory+ * to implement are listed here. See src/lib/tls/tls_callbacks.h.+ */+ class Callbacks : public Botan::TLS::Callbacks+ {+ public:+ void tls_emit_data(const uint8_t data[], size_t size) override+ {+ // send data to tls server, e.g., using BSD sockets or boost asio+ }++ void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override+ {+ // process full TLS record received by tls server, e.g.,+ // by passing it to the application+ }++ void tls_alert(Botan::TLS::Alert alert) override+ {+ // handle a tls alert received from the tls server+ }++ bool tls_session_established(const Botan::TLS::Session& session) override+ {+ // the session with the tls server was established+ // return false to prevent the session from being cached, true to+ // cache the session in the configured session manager+ return false;+ }+ };++ /**+ * @brief Credentials storage for the tls client.+ *+ * It returns a list of trusted CA certificates from a local directory.+ * TLS client authentication is disabled. See src/lib/tls/credentials_manager.h.+ */+ class Client_Credentials : public Botan::Credentials_Manager+ {+ public:+ Client_Credentials()+ {+ // Here we base trust on the system managed trusted CA list+ m_stores.push_back(new Botan::System_Certificate_Store);+ }++ std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(+ const std::string& type,+ const std::string& context) override+ {+ // return a list of certificates of CAs we trust for tls server certificates+ // ownership of the pointers remains with Credentials_Manager+ return m_stores;+ }++ std::vector<Botan::X509_Certificate> cert_chain(+ const std::vector<std::string>& cert_key_types,+ const std::string& type,+ const std::string& context) override+ {+ // when using tls client authentication (optional), return+ // a certificate chain being sent to the tls server,+ // else an empty list+ return std::vector<Botan::X509_Certificate>();+ }++ Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert,+ const std::string& type,+ const std::string& context) override+ {+ // when returning a chain in cert_chain(), return the private key+ // associated with the leaf certificate here+ return nullptr;+ }++ private:+ std::vector<Botan::Certificate_Store*> m_stores;+ };++ int main()+ {+ // prepare all the parameters+ Callbacks callbacks;+ Botan::AutoSeeded_RNG rng;+ Botan::TLS::Session_Manager_In_Memory session_mgr(rng);+ Client_Credentials creds;+ Botan::TLS::Strict_Policy policy;++ // open the tls connection+ Botan::TLS::Client client(callbacks,+ session_mgr,+ creds,+ policy,+ rng,+ Botan::TLS::Server_Information("botan.randombit.net", 443),+ Botan::TLS::Protocol_Version::TLS_V12);++ while(!client.is_closed())+ {+ // read data received from the tls server, e.g., using BSD sockets or boost asio+ // ...++ // send data to the tls server using client.send_data()+ }+ }++.. _tls_server:++TLS Servers+----------------------------------------++.. cpp:class:: TLS::Server++ .. cpp:function:: Server( \+ Callbacks& callbacks, \+ Session_Manager& session_manager, \+ Credentials_Manager& creds, \+ const Policy& policy, \+ RandomNumberGenerator& rng, \+ bool is_datagram = false, \+ size_t reserved_io_buffer_size = 16*1024 \+ )++The first 5 arguments as well as the final argument+*reserved_io_buffer_size*, are treated similarly to the :ref:`client+<tls_client>`.++If a client sends the ALPN extension, the ``callbacks`` function+``tls_server_choose_app_protocol`` will be called and the result+sent back to the client. If the empty string is returned, the server+will not send an ALPN response. The function can also throw an exception+to abort the handshake entirely, the ALPN specification says that if this+occurs the alert should be of type `NO_APPLICATION_PROTOCOL`.++The optional argument *is_datagram* specifies if this is a TLS or DTLS+server; unlike clients, which know what type of protocol (TLS vs DTLS)+they are negotiating from the start via the *offer_version*, servers+would not until they actually received a client hello.++Code Example+^^^^^^^^^^^^+A minimal example of a TLS server is provided below.+The full code for a TLS server using asio is in `src/cli/tls_proxy.cpp`.++.. code-block:: cpp++ #include <botan/tls_client.h>+ #include <botan/tls_callbacks.h>+ #include <botan/tls_session_manager.h>+ #include <botan/tls_policy.h>+ #include <botan/auto_rng.h>+ #include <botan/certstor.h>+ #include <botan/pk_keys.h>++ #include <memory>++ /**+ * @brief Callbacks invoked by TLS::Channel.+ *+ * Botan::TLS::Callbacks is an abstract class.+ * For improved readability, only the functions that are mandatory+ * to implement are listed here. See src/lib/tls/tls_callbacks.h.+ */+ class Callbacks : public Botan::TLS::Callbacks+ {+ public:+ void tls_emit_data(const uint8_t data[], size_t size) override+ {+ // send data to tls client, e.g., using BSD sockets or boost asio+ }++ void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override+ {+ // process full TLS record received by tls client, e.g.,+ // by passing it to the application+ }++ void tls_alert(Botan::TLS::Alert alert) override+ {+ // handle a tls alert received from the tls server+ }++ bool tls_session_established(const Botan::TLS::Session& session) override+ {+ // the session with the tls client was established+ // return false to prevent the session from being cached, true to+ // cache the session in the configured session manager+ return false;+ }+ };++ /**+ * @brief Credentials storage for the tls server.+ *+ * It returns a certificate and the associated private key to+ * authenticate the tls server to the client.+ * TLS client authentication is not requested.+ * See src/lib/tls/credentials_manager.h.+ */+ class Server_Credentials : public Botan::Credentials_Manager+ {+ public:+ Server_Credentials() : m_key(Botan::PKCS8::load_key("botan.randombit.net.key"))+ {+ }++ std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(+ const std::string& type,+ const std::string& context) override+ {+ // if client authentication is required, this function+ // shall return a list of certificates of CAs we trust+ // for tls client certificates, otherwise return an empty list+ return std::vector<Certificate_Store*>();+ }++ std::vector<Botan::X509_Certificate> cert_chain(+ const std::vector<std::string>& cert_key_types,+ const std::string& type,+ const std::string& context) override+ {+ // return the certificate chain being sent to the tls client+ // e.g., the certificate file "botan.randombit.net.crt"+ return { Botan::X509_Certificate("botan.randombit.net.crt") };+ }++ Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert,+ const std::string& type,+ const std::string& context) override+ {+ // return the private key associated with the leaf certificate,+ // in this case the one associated with "botan.randombit.net.crt"+ return &m_key;+ }++ private:+ std::unique_ptr<Botan::Private_Key> m_key;+ };++ int main()+ {+ // prepare all the parameters+ Callbacks callbacks;+ Botan::AutoSeeded_RNG rng;+ Botan::TLS::Session_Manager_In_Memory session_mgr(rng);+ Server_Credentials creds;+ Botan::TLS::Strict_Policy policy;++ // accept tls connection from client+ Botan::TLS::Server server(callbacks,+ session_mgr,+ creds,+ policy,+ rng);++ // read data received from the tls client, e.g., using BSD sockets or boost asio+ // and pass it to server.received_data().+ // ...++ // send data to the tls client using server.send_data()+ // ...+ }++.. _tls_sessions:++TLS Sessions+----------------------------------------++TLS allows clients and servers to support *session resumption*, where+the end point retains some information about an established session+and then reuse that information to bootstrap a new session in way that+is much cheaper computationally than a full handshake.++Every time your handshake callback is called, a new session has been+established, and a ``TLS::Session`` is included that provides+information about that session:++.. note::++ The serialization format of Session is not considered stable and is allowed+ to change even across minor releases. In the event of such a change, old+ sessions will no longer be able to be resumed.++.. cpp:class:: TLS::Session++ .. cpp:function:: Protocol_Version version() const++ Returns the :cpp:class:`protocol version <TLS::Protocol_Version>`+ that was negotiated++ .. cpp:function:: Ciphersuite ciphersite() const++ Returns the :cpp:class:`ciphersuite <TLS::Ciphersuite>` that+ was negotiated.++ .. cpp:function:: Server_Information server_info() const++ Returns information that identifies the server side of the+ connection. This is useful for the client in that it+ identifies what was originally passed to the constructor. For+ the server, it includes the name the client specified in the+ server name indicator extension.++ .. cpp:function:: std::vector<X509_Certificate> peer_certs() const++ Returns the certificate chain of the peer++ .. cpp:function:: std::string srp_identifier() const++ If an SRP ciphersuite was used, then this is the identifier+ that was used for authentication.++ .. cpp:function:: bool secure_renegotiation() const++ Returns ``true`` if the connection was negotiated with the+ correct extensions to prevent the renegotiation attack.++ .. cpp:function:: std::vector<uint8_t> encrypt(const SymmetricKey& key, \+ RandomNumberGenerator& rng)++ Encrypts a session using a symmetric key *key* and returns a raw+ binary value that can later be passed to ``decrypt``. The key+ may be of any length. The format is described in+ :ref:`tls_session_encryption`.++ .. cpp:function:: static Session decrypt(const uint8_t ciphertext[], \+ size_t length, \+ const SymmetricKey& key)++ Decrypts a session that was encrypted previously with ``encrypt`` and+ ``key``, or throws an exception if decryption fails.++ .. cpp:function:: secure_vector<uint8_t> DER_encode() const++ Returns a serialized version of the session.++ .. warning:: The return value of ``DER_encode`` contains the+ master secret for the session, and an attacker who+ recovers it could recover plaintext of previous+ sessions or impersonate one side to the other.++.. _tls_session_managers:++TLS Session Managers+----------------------------------------++You may want sessions stored in a specific format or storage type. To+do so, implement the ``TLS::Session_Manager`` interface and pass your+implementation to the ``TLS::Client`` or ``TLS::Server`` constructor.++.. cpp:class:: TLS::Session_Mananger++ .. cpp:function:: void save(const Session& session)++ Save a new *session*. It is possible that this sessions session+ ID will replicate a session ID already stored, in which case the+ new session information should overwrite the previous information.++ .. cpp:function:: void remove_entry(const std::vector<uint8_t>& session_id)++ Remove the session identified by *session_id*. Future attempts+ at resumption should fail for this session.++ .. cpp:function:: bool load_from_session_id(const std::vector<uint8_t>& session_id, \+ Session& session)++ Attempt to resume a session identified by *session_id*. If+ located, *session* is set to the session data previously passed+ to *save*, and ``true`` is returned. Otherwise *session* is not+ modified and ``false`` is returned.++ .. cpp:function:: bool load_from_server_info(const Server_Information& server, \+ Session& session)++ Attempt to resume a session with a known server.++ .. cpp:function:: std::chrono::seconds session_lifetime() const++ Returns the expected maximum lifetime of a session when using+ this session manager. Will return 0 if the lifetime is unknown+ or has no explicit expiration policy.++.. _tls_session_manager_inmem:++In Memory Session Manager+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The ``TLS::Session_Manager_In_Memory`` implementation saves sessions+in memory, with an upper bound on the maximum number of sessions and+the lifetime of a session.++It is safe to share a single object across many threads as it uses a+lock internally.++.. cpp:class:: TLS::Session_Managers_In_Memory++ .. cpp:function:: Session_Manager_In_Memory(RandomNumberGenerator& rng, \+ size_t max_sessions = 1000, \+ std::chrono::seconds session_lifetime = 7200)++ Limits the maximum number of saved sessions to *max_sessions*, and+ expires all sessions older than *session_lifetime*.++Noop Session Mananger+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The ``TLS::Session_Manager_Noop`` implementation does not save+sessions at all, and thus session resumption always fails. Its+constructor has no arguments.++SQLite3 Session Manager+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++This session manager is only available if support for SQLite3 was+enabled at build time. If the macro+``BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER`` is defined, then+``botan/tls_session_manager_sqlite.h`` contains+``TLS::Session_Manager_SQLite`` which stores sessions persistently to+a sqlite3 database. The session data is encrypted using a passphrase,+and stored in two tables, named ``tls_sessions`` (which holds the+actual session information) and ``tls_sessions_metadata`` (which holds+the PBKDF information).++.. warning:: The hostnames associated with the saved sessions are+ stored in the database in plaintext. This may be a+ serious privacy risk in some applications.++.. cpp:class:: TLS::Session_Manager_SQLite++ .. cpp:function:: Session_Manager_SQLite( \+ const std::string& passphrase, \+ RandomNumberGenerator& rng, \+ const std::string& db_filename, \+ size_t max_sessions = 1000, \+ std::chrono::seconds session_lifetime = 7200)++ Uses the sqlite3 database named by *db_filename*.++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 compatibility) and ``Text_Policy`` which reads+policy settings from a file.++.. cpp:class:: TLS::Policy++ .. cpp:function:: std::vector<std::string> allowed_ciphers() const++ Returns the list of ciphers we are willing to negotiate, in order+ of preference.++ Clients send a list of ciphersuites in order of preference,+ servers are free to choose any of them. Some servers will use the+ clients preferences, others choose from the clients list+ prioritizing based on its preferences.++ No export key exchange mechanisms or ciphersuites are supported+ by botan. The null encryption ciphersuites (which provide only+ authentication, sending data in cleartext) are also not supported+ by the implementation and cannot be negotiated.++ Cipher names without an explicit mode refers to CBC+HMAC ciphersuites.++ Default value: "ChaCha20Poly1305", "AES-256/GCM", "AES-128/GCM"++ Also allowed: "AES-256", "AES-128",+ "AES-256/CCM", "AES-128/CCM", "AES-256/CCM(8)", "AES-128/CCM(8)",+ "Camellia-256/GCM", "Camellia-128/GCM", "ARIA-256/GCM", "ARIA-128/GCM",+ "Camellia-256", "Camellia-128"++ Also allowed (though currently experimental): "AES-128/OCB(12)",+ "AES-256/OCB(12)"++ In versions up to 2.8.0, the CBC and CCM ciphersuites "AES-256",+ "AES-128", "AES-256/CCM" and "AES-128/CCM" were enabled by default.++ Also allowed (although **not recommended**): "SEED", "3DES"++ .. note::++ Before 1.11.30 only the non-standard ChaCha20Poly1305 ciphersuite+ was implemented. The RFC 7905 ciphersuites are supported in 1.11.30+ onwards.++ .. note::++ Support for the broken RC4 cipher was removed in 1.11.17++ .. note::++ SEED and 3DES are deprecated and will be removed in a future release.++ .. cpp:function:: std::vector<std::string> allowed_macs() const++ Returns the list of algorithms we are willing to use for+ message authentication, in order of preference.++ Default: "AEAD", "SHA-256", "SHA-384", "SHA-1"++ A plain hash function indicates HMAC++ .. note::++ SHA-256 is preferred over SHA-384 in CBC mode because the+ protections against the Lucky13 attack are somewhat more+ effective for SHA-256 than SHA-384.++ .. cpp:function:: std::vector<std::string> allowed_key_exchange_methods() const++ Returns the list of key exchange methods we are willing to use,+ in order of preference.++ Default: "CECPQ1", "ECDH", "DH"++ .. note::++ CECPQ1 key exchange provides post-quantum security to the key exchange+ by combining NewHope with a standard x25519 ECDH exchange. This prevents+ an attacker, even one with a quantum computer, from later decrypting the+ contents of a recorded TLS transcript. The NewHope algorithm is very+ fast, but adds roughly 4 KiB of additional data transfer to every TLS+ handshake. And even if NewHope ends up completely broken, the 'extra'+ x25519 exchange secures the handshake.++ For applications where the additional data transfer size is unacceptable,+ simply allow only ECDH key exchange in the application policy. DH+ exchange also often involves transferring several additional Kb (without+ the benefit of post quantum security) so if CECPQ1 is being disabled for+ traffic overhead reasons, DH should also be avoided.++ Also allowed: "RSA", "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK"++ .. note::++ Static RSA ciphersuites are disabled by default since 1.11.34.+ In addition to not providing forward security, any server which is+ willing to negotiate these ciphersuites exposes themselves to a variety+ of chosen ciphertext oracle attacks which are all easily avoided by+ signing (as in PFS) instead of decrypting.++ .. note::++ In order to enable RSA, SRP, or PSK ciphersuites one must also enable+ authentication method "IMPLICIT", see :cpp:func:`allowed_signature_methods`.++ .. cpp:function:: std::vector<std::string> allowed_signature_hashes() const++ Returns the list of hash algorithms we are willing to use for+ public key signatures, in order of preference.++ Default: "SHA-512", "SHA-384", "SHA-256"++ Also allowed (although **not recommended**): "SHA-1"++ .. note::++ This is only used with TLS v1.2. In earlier versions of the+ protocol, signatures are fixed to using only SHA-1 (for+ DSA/ECDSA) or a MD5/SHA-1 pair (for RSA).++ .. cpp:function:: std::vector<std::string> allowed_signature_methods() const++ Default: "ECDSA", "RSA"++ Also allowed (disabled by default): "DSA", "IMPLICIT", "ANONYMOUS"++ "IMPLICIT" enables ciphersuites which are authenticated not by a signature+ but through a side-effect of the key exchange. In particular this setting+ is required to enable PSK, SRP, and static RSA ciphersuites.++ "ANONYMOUS" allows purely anonymous DH/ECDH key exchanges. **Enabling this+ is not recommended**++ .. note::++ Both DSA authentication and anonymous DH ciphersuites are deprecated,+ and will be removed in a future release.++ .. cpp:function:: std::vector<Group_Params> key_exchange_groups() const++ Return a list of ECC curve and DH group TLS identifiers we are willing to use, in order of preference.+ The default ordering puts the best performing ECC first.++ Default:+ Group_Params::X25519,+ Group_Params::SECP256R1, Group_Params::BRAINPOOL256R1,+ Group_Params::SECP384R1, Group_Params::BRAINPOOL384R1,+ Group_Params::SECP521R1, Group_Params::BRAINPOOL512R1,+ Group_Params::FFDHE_2048, Group_Params::FFDHE_3072, Group_Params::FFDHE_4096,+ Group_Params::FFDHE_6144, Group_Params::FFDHE_8192++ No other values are currently defined.++ .. cpp:function:: bool use_ecc_point_compression() const++ Prefer ECC point compression.++ Signals that we prefer ECC points to be compressed when transmitted to us.+ The other party may not support ECC point compression and therefore may still+ send points uncompressed.++ Note that the certificate used during authentication must also follow the other+ party's preference.++ Default: false++ .. note::++ Support for EC point compression is deprecated and will be removed in a+ future major release.++ .. cpp:function:: bool acceptable_protocol_version(Protocol_Version version)++ Return true if this version of the protocol is one that we are+ willing to negotiate.++ Default: Accepts TLS v1.2 and DTLS v1.2, and rejects all older versions.++ .. cpp:function:: bool server_uses_own_ciphersuite_preferences() const++ If this returns true, a server will pick the cipher it prefers the+ most out of the client's list. Otherwise, it will negotiate the+ first cipher in the client's ciphersuite list that it supports.++ Default: true++ .. cpp:function:: bool allow_client_initiated_renegotiation() const++ If this function returns true, a server will accept a+ client-initiated renegotiation attempt. Otherwise it will send+ the client a non-fatal ``no_renegotiation`` alert.++ Default: false++ .. cpp:function:: bool allow_server_initiated_renegotiation() const++ If this function returns true, a client will accept a+ server-initiated renegotiation attempt. Otherwise it will send+ the server a non-fatal ``no_renegotiation`` alert.++ Default: false++ .. cpp:function:: bool abort_connection_on_undesired_renegotiation() const++ If a renegotiation attempt is being rejected due to the configuration of+ :cpp:func:`TLS::Policy::allow_client_initiated_renegotiation` or+ :cpp:func:`TLS::Policy::allow_server_initiated_renegotiation`, and+ this function returns true then the connection is closed with a fatal+ alert instead of the default warning alert.++ Default: false++ .. cpp:function:: bool allow_insecure_renegotiation() const++ If this function returns true, we will allow renegotiation attempts+ even if the counterparty does not support the RFC 5746 extensions.++ .. warning:: Returning true here could expose you to attacks++ Default: false++ .. cpp:function:: size_t minimum_signature_strength() const++ Return the minimum strength (as ``n``, representing ``2**n`` work)+ we will accept for a signature algorithm on any certificate.++ Use 80 to enable RSA-1024 (*not recommended*), or 128 to require+ either ECC or large (~3000 bit) RSA keys.++ Default: 110 (allowing 2048 bit RSA)++ .. cpp:function:: bool require_cert_revocation_info() const++ If this function returns true, and a ciphersuite using certificates was+ negotiated, then we must have access to a valid CRL or OCSP response in+ order to trust the certificate.++ .. warning:: Returning false here could expose you to attacks++ Default: true++ .. cpp:function:: Group_Params default_dh_group() const++ For ephemeral Diffie-Hellman key exchange, the server sends a+ group parameter. Return the 2 Byte TLS group identifier specifying the group parameter a+ server should use.++ Default: 2048 bit IETF IPsec group ("modp/ietf/2048")++ .. cpp:function:: size_t minimum_dh_group_size() const++ Return the minimum size in bits for a Diffie-Hellman group that a+ client will accept. Due to the design of the protocol the client+ has only two options - accept the group, or reject it with a+ fatal alert then attempt to reconnect after disabling ephemeral+ Diffie-Hellman.++ Default: 2048 bits++ .. cpp:function:: bool allow_tls10() const++ Return true from here to allow TLS v1.0. Since 2.8.0, returns+ ``false`` by default.++ .. cpp:function:: bool allow_tls11() const++ Return true from here to allow TLS v1.1. Since 2.8.0, returns+ ``false`` by default.++ .. cpp:function:: bool allow_tls12() const++ Return true from here to allow TLS v1.2. Returns ``true`` by default.++ .. cpp:function:: size_t minimum_rsa_bits() const++ Minimum accepted RSA key size. Default 2048 bits.++ .. cpp:function:: size_t minimum_dsa_group_size() const++ Minimum accepted DSA key size. Default 2048 bits.++ .. cpp:function:: size_t minimum_ecdsa_group_size() const++ Minimum size for ECDSA keys (256 bits).++ .. cpp:function:: size_t minimum_ecdh_group_size() const++ Minimum size for ECDH keys (255 bits).++ .. cpp:function:: void check_peer_key_acceptable(const Public_Key& public_key) const++ Allows the policy to examine peer public keys. Throw an exception+ if the key should be rejected. Default implementation checks+ against policy values `minimum_dh_group_size`, `minimum_rsa_bits`,+ `minimum_ecdsa_group_size`, and `minimum_ecdh_group_size`.++ .. cpp:function:: bool hide_unknown_users() const++ The SRP and PSK suites work using an identifier along with a+ shared secret. If this function returns true, when an identifier+ that the server does not recognize is provided by a client, a+ random shared secret will be generated in such a way that a+ client should not be able to tell the difference between the+ identifier not being known and the secret being wrong. This can+ help protect against some username probing attacks. If it+ returns false, the server will instead send an+ ``unknown_psk_identity`` alert when an unknown identifier is+ used.++ Default: false++ .. cpp:function:: u32bit session_ticket_lifetime() const++ Return the lifetime of session tickets. Each session includes the+ start time. Sessions resumptions using tickets older than+ ``session_ticket_lifetime`` seconds will fail, forcing a full+ renegotiation.++ Default: 86400 seconds (1 day)++TLS Ciphersuites+----------------------------------------++.. cpp:class:: TLS::Ciphersuite++ .. cpp:function:: uint16_t ciphersuite_code() const++ Return the numerical code for this ciphersuite++ .. cpp:function:: std::string to_string() const++ Return the full name of ciphersuite (for example+ "RSA_WITH_RC4_128_SHA" or "ECDHE_RSA_WITH_AES_128_GCM_SHA256")++ .. cpp:function:: std::string kex_algo() const++ Return the key exchange algorithm of this ciphersuite++ .. cpp:function:: std::string sig_algo() const++ Return the signature algorithm of this ciphersuite++ .. cpp:function:: std::string cipher_algo() const++ Return the cipher algorithm of this ciphersuite++ .. cpp:function:: std::string mac_algo() const++ Return the authentication algorithm of this ciphersuite++ .. cpp:function:: bool acceptable_ciphersuite(const Ciphersuite& suite) const++ Return true if ciphersuite is accepted by the policy.++ Allows an application to reject any ciphersuites, which are+ undesirable for whatever reason without having to reimplement+ :cpp:func:`TLS::Ciphersuite::ciphersuite_list`++ .. cpp:function:: std::vector<uint16_t> ciphersuite_list(Protocol_Version version, bool have_srp) const++ Return allowed ciphersuites in order of preference++ Allows an application to have full control over ciphersuites+ by returning desired ciphersuites in preference order.++.. _tls_alerts:++TLS Alerts+----------------------------------------++A ``TLS::Alert`` is passed to every invocation of a channel's *alert_cb*.++.. cpp:class:: TLS::Alert++ .. cpp:function:: is_valid() const++ Return true if this alert is not a null alert++ .. cpp:function:: is_fatal() const++ Return true if this alert is fatal. A fatal alert causes the+ connection to be immediately disconnected. Otherwise, the alert+ is a warning and the connection remains valid.++ .. cpp:function:: Type type() const++ Returns the type of the alert as an enum++ .. cpp:function:: std::string type_string()++ Returns the type of the alert as a string++TLS Protocol Version+----------------------------------------++TLS has several different versions with slightly different behaviors.+The ``TLS::Protocol_Version`` class represents a specific version:++.. cpp:class:: TLS::Protocol_Version++ .. cpp:enum:: Version_Code++ ``TLS_V10``, ``TLS_V11``, ``TLS_V12``, ``DTLS_V10``, ``DTLS_V12``++ .. cpp:function:: Protocol_Version(Version_Code named_version)++ Create a specific version++ .. cpp:function:: uint8_t major_version() const++ Returns major number of the protocol version++ .. cpp:function:: uint8_t minor_version() const++ Returns minor number of the protocol version++ .. cpp:function:: std::string to_string() const++ Returns string description of the version, for instance "TLS+ v1.1" or "DTLS v1.0".++ .. cpp:function:: static Protocol_Version latest_tls_version()++ Returns the latest version of the TLS protocol known to the library+ (currently TLS v1.2)++ .. cpp:function:: static Protocol_Version latest_dtls_version()++ Returns the latest version of the DTLS protocol known to the+ library (currently DTLS v1.2)++TLS Custom Curves+----------------------------------------++The supported_groups TLS extension is used in the client hello to advertise a list of supported elliptic curves+and DH groups. The server subsequently selects one of the groups, which is supported by both endpoints.+The groups are represented by their TLS identifier. This 2 Byte identifier is standardized for commonly used groups and curves.+In addition, the standard reserves the identifiers 0xFE00 to 0xFEFF for custom groups or curves.++Using non standardized custom curves is however not recommended and can be a serious risk if an+insecure curve is used. Still, it might be desired in some scenarios to use custom curves or groups in the TLS handshake.++To use custom curves with the Botan :cpp:class:`TLS::Client` or :cpp:class:`TLS::Server` the following additional adjustments have to be implemented+as shown in the following code examples.++1. Registration of the custom curve+2. Implementation TLS callback ``tls_decode_group_param``+3. Adjustment of the TLS policy by allowing the custom curve++Client Code Example+^^^^^^^^^^^^^^^^^^^^++.. code-block:: cpp++ #include <botan/tls_client.h>+ #include <botan/tls_callbacks.h>+ #include <botan/tls_session_manager.h>+ #include <botan/tls_policy.h>+ #include <botan/auto_rng.h>+ #include <botan/certstor.h>++ #include <botan/ec_group.h>+ #include <botan/oids.h>+++ /**+ * @brief Callbacks invoked by TLS::Channel.+ *+ * Botan::TLS::Callbacks is an abstract class.+ * For improved readability, only the functions that are mandatory+ * to implement are listed here. See src/lib/tls/tls_callbacks.h.+ */+ class Callbacks : public Botan::TLS::Callbacks+ {+ public:+ void tls_emit_data(const uint8_t data[], size_t size) override+ {+ // send data to tls server, e.g., using BSD sockets or boost asio+ }++ void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override+ {+ // process full TLS record received by tls server, e.g.,+ // by passing it to the application+ }++ void tls_alert(Botan::TLS::Alert alert) override+ {+ // handle a tls alert received from the tls server+ }++ bool tls_session_established(const Botan::TLS::Session& session) override+ {+ // the session with the tls server was established+ // return false to prevent the session from being cached, true to+ // cache the session in the configured session manager+ return false;+ }+ std::string tls_decode_group_param(Botan::TLS::Group_Params group_param) override+ {+ // handle TLS group identifier decoding and return name as string+ // return empty string to indicate decoding failure++ switch(static_cast<uint16_t>(group_param))+ {+ case 0xFE00:+ return "testcurve1102";+ default:+ //decode non-custom groups+ return Botan::TLS::Callbacks::tls_decode_group_param(group_param);+ }+ }+ };++ /**+ * @brief Credentials storage for the tls client.+ *+ * It returns a list of trusted CA certificates from a local directory.+ * TLS client authentication is disabled. See src/lib/tls/credentials_manager.h.+ */+ class Client_Credentials : public Botan::Credentials_Manager+ {+ public:+ std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(+ const std::string& type,+ const std::string& context) override+ {+ // return a list of certificates of CAs we trust for tls server certificates,+ // e.g., all the certificates in the local directory "cas"+ return { new Botan::Certificate_Store_In_Memory("cas") };+ }++ std::vector<Botan::X509_Certificate> cert_chain(+ const std::vector<std::string>& cert_key_types,+ const std::string& type,+ const std::string& context) override+ {+ // when using tls client authentication (optional), return+ // a certificate chain being sent to the tls server,+ // else an empty list+ return std::vector<Botan::X509_Certificate>();+ }++ Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert,+ const std::string& type,+ const std::string& context) override+ {+ // when returning a chain in cert_chain(), return the private key+ // associated with the leaf certificate here+ return nullptr;+ }+ };++ class Client_Policy : public Botan::TLS::Strict_Policy+ {+ public:+ std::vector<Botan::TLS::Group_Params> key_exchange_groups() const override+ {+ // modified strict policy to allow our custom curves+ return+ {+ static_cast<Botan::TLS::Group_Params>(0xFE00)+ }; + }+ };++ int main()+ {+ // prepare rng+ Botan::AutoSeeded_RNG rng;++ // prepare custom curve++ // prepare curve parameters+ const Botan::BigInt p("0x92309a3e88b94312f36891a2055725bb35ab51af96b3a651d39321b7bbb8c51575a76768c9b6b323");+ const Botan::BigInt a("0x4f30b8e311f6b2dce62078d70b35dacb96aa84b758ab5a8dff0c9f7a2a1ff466c19988aa0acdde69");+ const Botan::BigInt b("0x9045A513CFFF9AE1F1CC84039D852D240344A1D5C9DB203C844089F855C387823EB6FCDDF49C909C");++ const Botan::BigInt x("0x9120f3779a31296cefcb5a5a08831f1a6d438ad5a3f2ce60585ac19c74eebdc65cadb96bb92622c7");+ const Botan::BigInt y("0x836db8251c152dfee071b72c6b06c5387d82f1b5c30c5a5b65ee9429aa2687e8426d5d61276a4ede");+ const Botan::BigInt order("0x248c268fa22e50c4bcda24688155c96ecd6ad46be5c82d7a6be6e7068cb5d1ca72b2e07e8b90d853");++ const Botan::BigInt cofactor(4);++ const Botan::OID oid("1.2.3.1");++ // create EC_Group object to register the curve+ Botan::EC_Group testcurve1102(p, a, b, x, y, order, cofactor, oid);++ if(!testcurve1102.verify_group(rng))+ {+ // Warning: if verify_group returns false the curve parameters are insecure+ }++ // register name to specified oid+ Botan::OIDS::add_oid(oid, "testcurve1102"); ++ // prepare all the parameters+ Callbacks callbacks;+ Botan::TLS::Session_Manager_In_Memory session_mgr(rng);+ Client_Credentials creds;+ Client_Policy policy;++ // open the tls connection+ Botan::TLS::Client client(callbacks,+ session_mgr,+ creds,+ policy,+ rng,+ Botan::TLS::Server_Information("botan.randombit.net", 443),+ Botan::TLS::Protocol_Version::TLS_V12);+++ while(!client.is_closed())+ {+ // read data received from the tls server, e.g., using BSD sockets or boost asio+ // ...++ // send data to the tls server using client.send_data()++ }+ }++Server Code Example+^^^^^^^^^^^^^^^^^^^^^++.. code-block:: cpp++ #include <botan/tls_server.h>+ #include <botan/tls_callbacks.h>+ #include <botan/tls_session_manager.h>+ #include <botan/tls_policy.h>+ #include <botan/auto_rng.h>+ #include <botan/certstor.h>+ #include <botan/pk_keys.h>+ #include <botan/pkcs8.h>++ #include <botan/ec_group.h>+ #include <botan/oids.h>++ #include <memory>++ /**+ * @brief Callbacks invoked by TLS::Channel.+ *+ * Botan::TLS::Callbacks is an abstract class.+ * For improved readability, only the functions that are mandatory+ * to implement are listed here. See src/lib/tls/tls_callbacks.h.+ */+ class Callbacks : public Botan::TLS::Callbacks+ {+ public:+ void tls_emit_data(const uint8_t data[], size_t size) override+ {+ // send data to tls client, e.g., using BSD sockets or boost asio+ }++ void tls_record_received(uint64_t seq_no, const uint8_t data[], size_t size) override+ {+ // process full TLS record received by tls client, e.g.,+ // by passing it to the application+ }++ void tls_alert(Botan::TLS::Alert alert) override+ {+ // handle a tls alert received from the tls server+ }++ bool tls_session_established(const Botan::TLS::Session& session) override+ {+ // the session with the tls client was established+ // return false to prevent the session from being cached, true to+ // cache the session in the configured session manager+ return false;+ }++ std::string tls_decode_group_param(Botan::TLS::Group_Params group_param) override+ {+ // handle TLS group identifier decoding and return name as string+ // return empty string to indicate decoding failure++ switch(static_cast<uint16_t>(group_param))+ {+ case 0xFE00:+ return "testcurve1102";+ default:+ //decode non-custom groups+ return Botan::TLS::Callbacks::tls_decode_group_param(group_param);+ }+ }+ };++ /**+ * @brief Credentials storage for the tls server.+ *+ * It returns a certificate and the associated private key to+ * authenticate the tls server to the client.+ * TLS client authentication is not requested.+ * See src/lib/tls/credentials_manager.h.+ */+ class Server_Credentials : public Botan::Credentials_Manager+ {+ public:+ Server_Credentials() : m_key(Botan::PKCS8::load_key("botan.randombit.net.key")+ {+ }++ std::vector<Botan::Certificate_Store*> trusted_certificate_authorities(+ const std::string& type,+ const std::string& context) override+ {+ // if client authentication is required, this function+ // shall return a list of certificates of CAs we trust+ // for tls client certificates, otherwise return an empty list+ return std::vector<Botan::Certificate_Store*>();+ }++ std::vector<Botan::X509_Certificate> cert_chain(+ const std::vector<std::string>& cert_key_types,+ const std::string& type,+ const std::string& context) override+ {+ // return the certificate chain being sent to the tls client+ // e.g., the certificate file "botan.randombit.net.crt"+ return { Botan::X509_Certificate("botan.randombit.net.crt") };+ }++ Botan::Private_Key* private_key_for(const Botan::X509_Certificate& cert,+ const std::string& type,+ const std::string& context) override+ {+ // return the private key associated with the leaf certificate,+ // in this case the one associated with "botan.randombit.net.crt"+ return m_key.get();+ }++ private:+ std::unique_ptr<Botan::Private_Key> m_key;+ };++ class Server_Policy : public Botan::TLS::Strict_Policy+ {+ public:+ std::vector<Botan::TLS::Group_Params> key_exchange_groups() const override+ {+ // modified strict policy to allow our custom curves+ return+ {+ static_cast<Botan::TLS::Group_Params>(0xFE00)+ }; + }+ };++ int main()+ {++ // prepare rng+ Botan::AutoSeeded_RNG rng;++ // prepare custom curve++ // prepare curve parameters+ const Botan::BigInt p("0x92309a3e88b94312f36891a2055725bb35ab51af96b3a651d39321b7bbb8c51575a76768c9b6b323");+ const Botan::BigInt a("0x4f30b8e311f6b2dce62078d70b35dacb96aa84b758ab5a8dff0c9f7a2a1ff466c19988aa0acdde69");+ const Botan::BigInt b("0x9045A513CFFF9AE1F1CC84039D852D240344A1D5C9DB203C844089F855C387823EB6FCDDF49C909C");++ const Botan::BigInt x("0x9120f3779a31296cefcb5a5a08831f1a6d438ad5a3f2ce60585ac19c74eebdc65cadb96bb92622c7");+ const Botan::BigInt y("0x836db8251c152dfee071b72c6b06c5387d82f1b5c30c5a5b65ee9429aa2687e8426d5d61276a4ede");+ const Botan::BigInt order("0x248c268fa22e50c4bcda24688155c96ecd6ad46be5c82d7a6be6e7068cb5d1ca72b2e07e8b90d853");++ const Botan::BigInt cofactor(4);++ const Botan::OID oid("1.2.3.1");++ // create EC_Group object to register the curve+ Botan::EC_Group testcurve1102(p, a, b, x, y, order, cofactor, oid);++ if(!testcurve1102.verify_group(rng))+ {+ // Warning: if verify_group returns false the curve parameters are insecure+ }++ // register name to specified oid+ Botan::OIDS::add_oid(oid, "testcurve1102");++ // prepare all the parameters+ Callbacks callbacks;+ Botan::TLS::Session_Manager_In_Memory session_mgr(rng);+ Server_Credentials creds;+ Server_Policy policy;++ // accept tls connection from client+ Botan::TLS::Server server(callbacks,+ session_mgr,+ creds,+ policy,+ rng);++ // read data received from the tls client, e.g., using BSD sockets or boost asio+ // and pass it to server.received_data().+ // ...++ // send data to the tls client using server.send_data()+ // ...+ }++TLS Stream+----------------------------------------++:cpp:class:`TLS::Stream` offers a Boost.Asio compatible wrapper around :cpp:class:`TLS::Client` and :cpp:class:`TLS::Server`.+It can be used as an alternative to Boost.Asio's `ssl::stream <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ssl__stream.html>`_ with minor adjustments to the using code.+It offers the following interface:++.. cpp:class:: template <class StreamLayer, class ChannelT> TLS::Stream++ *StreamLayer* specifies the type of the stream's *next layer*, for example a `Boost.Asio TCP socket <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ip__tcp/socket.html>`_.+ *ChannelT* is the type of the stream's *native handle*; it defaults to :cpp:class:`TLS::Channel` and should not be specified manually.++ .. cpp:function:: template <typename... Args> \+ explicit Stream(Context& context, Args&& ... args)++ Construct a new TLS stream.+ The *context* parameter will be used to initialize the underlying *native handle*, i.e. the :ref:`TLS::Client <tls_client>` or :ref:`TLS::Server <tls_server>`, when :cpp:func:`handshake` is called.+ Using code must ensure the context is kept alive for the lifetime of the stream.+ The further *args* will be forwarded to the *next layer*'s constructor.++ .. cpp:function:: template <typename... Args> \+ explicit Stream(Arg&& arg, Context& context)++ Convenience constructor for :cpp:class:`boost::asio::ssl::stream` compatibility.+ The parameters have the same meaning as for the first constructor, but their order is changed and only one argument can be passed to the *next layer* constructor.+++ .. cpp:function:: void handshake(Connection_Side side, boost::system::error_code& ec)++ Set up the *native handle* and perform the TLS handshake.++ .. cpp:function:: void handshake(Connection_Side side)++ Overload of :cpp:func:`handshake` that throws an exception if an error occurs.++ .. cpp:function:: template <typename HandshakeHandler> \+ DEDUCED async_handshake(Connection_Side side, HandshakeHandler&& handler)++ Asynchronous variant of :cpp:func:`handshake`.+ The function returns immediately and calls the *handler* callback function after performing asynchronous I/O to complete the TLS handshake.+ The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *HandshakeHandler* type.+++ .. cpp:function:: void shutdown(boost::system::error_code& ec)++ Calls :cpp:func:`TLS::Channel::close` on the native handle and writes the TLS alert to the *next layer*.++ .. cpp:function:: void shutdown()++ Overload of :cpp:func:`shutdown` that throws an exception if an error occurs.++ .. cpp:function:: template <typename ShutdownHandler> \+ void async_shutdown(ShutdownHandler&& handler)++ Asynchronous variant of :cpp:func:`shutdown`.+ The function returns immediately and calls the *handler* callback function after performing asynchronous I/O to complete the TLS shutdown.+++ .. cpp:function:: template <typename MutableBufferSequence> \+ std::size_t read_some(const MutableBufferSequence& buffers, boost::system::error_code& ec)++ Reads encrypted data from the *next layer*, decrypts it, and writes it into the provided *buffers*.+ If an error occurs, *error_code* is set.+ Returns the number of bytes read.++ .. cpp:function:: template <typename MutableBufferSequence> \+ std::size_t read_some(const MutableBufferSequence& buffers)++ Overload of :cpp:func:`read_some` that throws an exception if an error occurs.++ .. cpp:function:: template <typename MutableBufferSequence, typename ReadHandler> \+ DEDUCED async_read_some(const MutableBufferSequence& buffers, ReadHandler&& handler)++ Asynchronous variant of :cpp:func:`read_some`.+ The function returns immediately and calls the *handler* callback function after writing the decrypted data into the provided *buffers*.+ The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *ReadHandler* type.+ *ReadHandler* should suffice the `requirements to a Boost.Asio read handler <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ReadHandler.html>`_.+++ .. cpp:function:: template <typename ConstBufferSequence> \+ std::size_t write_some(const ConstBufferSequence& buffers, boost::system::error_code& ec)++ Encrypts data from the provided *buffers* and writes it to the *next layer*.+ If an error occurs, *error_code* is set.+ Returns the number of bytes written.++ .. cpp:function:: template <typename ConstBufferSequence> \+ std::size_t write_some(const ConstBufferSequence& buffers)++ Overload of :cpp:func:`write_some` that throws an exception rather than setting an error code.++ .. cpp:function:: template <typename ConstBufferSequence, typename WriteHandler> \+ DEDUCED async_write_some(const ConstBufferSequence& buffers, WriteHandler&& handler)++ Asynchronous variant of :cpp:func:`write_some`.+ The function returns immediately and calls the *handler* callback function after writing the encrypted data to the *next layer*.+ The return type is an automatically deduced specialization of :cpp:class:`boost::asio::async_result`, depending on the *WriteHandler* type.+ *WriteHandler* should suffice the `requirements to a Boost.Asio write handler <https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/WriteHandler.html>`_.++.. cpp:class:: TLS::Context++ A helper class to initialize and configure the Stream's underlying *native handle* (see :cpp:class:`TLS::Client` and :cpp:class:`TLS::Server`).++ .. cpp:function:: Context(Credentials_Manager& credentialsManager, \+ RandomNumberGenerator& randomNumberGenerator, \+ Session_Manager& sessionManager, \+ Policy& policy, \+ Server_Information serverInfo = Server_Information())++ Constructor for TLS::Context.++ .. cpp:function:: void set_verify_callback(Verify_Callback_T callback)++ Set a user-defined callback function for certificate chain verification. This+ will cause the stream to override the default implementation of the+ :cpp:func:`tls_verify_cert_chain` callback.++TLS Stream Client Code Example+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The code below illustrates how to build a simple HTTPS client based on the TLS Stream and Boost.Beast. When run, it fetches the content of `https://botan.randombit.net/news.html` and prints it to stdout.++.. code-block:: cpp++ #include <iostream>++ #include <botan/asio_stream.h>+ #include <botan/auto_rng.h>+ #include <botan/certstor_system.h>++ #include <boost/asio.hpp>+ #include <boost/beast.hpp>+ #include <boost/bind.hpp>++ namespace http = boost::beast::http;+ namespace _ = boost::asio::placeholders;++ // very basic credentials manager+ class Credentials_Manager : public Botan::Credentials_Manager+ {+ public:+ Credentials_Manager() {}++ std::vector<Botan::Certificate_Store*>+ trusted_certificate_authorities(const std::string&, const std::string&) override+ {+ return {&cert_store_};+ }++ private:+ Botan::System_Certificate_Store cert_store_;+ };++ // a simple https client based on TLS::Stream+ class client+ {+ public:+ client(boost::asio::io_context& io_context,+ boost::asio::ip::tcp::resolver::iterator endpoint_iterator,+ http::request<http::string_body> req)+ : request_(req)+ , ctx_(credentials_mgr_,+ rng_,+ session_mgr_,+ policy_,+ Botan::TLS::Server_Information())+ , stream_(io_context, ctx_)+ {+ boost::asio::async_connect(stream_.lowest_layer(), endpoint_iterator,+ boost::bind(&client::handle_connect, this, _::error));+ }++ void handle_connect(const boost::system::error_code& error)+ {+ if(error)+ {+ std::cout << "Connect failed: " << error.message() << "\n";+ return;+ }+ stream_.async_handshake(Botan::TLS::Connection_Side::CLIENT,+ boost::bind(&client::handle_handshake, this, _::error));+ }++ void handle_handshake(const boost::system::error_code& error)+ {+ if(error)+ {+ std::cout << "Handshake failed: " << error.message() << "\n";+ return;+ }+ http::async_write(stream_, request_,+ boost::bind(&client::handle_write, this, _::error, _::bytes_transferred));+ }++ void handle_write(const boost::system::error_code& error, size_t)+ {+ if(error)+ {+ std::cout << "Write failed: " << error.message() << "\n";+ return;+ }+ http::async_read(stream_, reply_, response_,+ boost::bind(&client::handle_read, this, _::error, _::bytes_transferred));+ }++ void handle_read(const boost::system::error_code& error, size_t)+ {+ if(!error)+ {+ std::cout << "Reply: ";+ std::cout << response_.body() << "\n";+ }+ else+ {+ std::cout << "Read failed: " << error.message() << "\n";+ }+ }++ private:+ http::request<http::dynamic_body> request_;+ http::response<http::string_body> response_;+ boost::beast::flat_buffer reply_;++ Botan::TLS::Session_Manager_Noop session_mgr_;+ Botan::AutoSeeded_RNG rng_;+ Credentials_Manager credentials_mgr_;+ Botan::TLS::Policy policy_;++ Botan::TLS::Context ctx_;+ Botan::TLS::Stream<boost::asio::ip::tcp::socket> stream_;+ };++ int main()+ {+ boost::asio::io_context io_context;++ boost::asio::ip::tcp::resolver resolver(io_context);+ boost::asio::ip::tcp::resolver::query query("botan.randombit.net", "443");+ boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);++ http::request<http::string_body> req;+ req.version(11);+ req.method(http::verb::get);+ req.target("/news.html");+ req.set(http::field::host, "botan.randombit.net");++ client c(io_context, iterator, req);++ io_context.run();+ }++.. _tls_session_encryption:++TLS Session Encryption+-------------------------++A unified format is used for encrypting TLS sessions either for durable storage+(on client or server) or when creating TLS session tickets. This format is *not+stable* even across the same major version.++The current session encryption scheme was introduced in 2.13.0, replacing the+format previously used since 1.11.13.++Session encryption accepts a key of any length, though for best security a key+of 256 bits should be used. This master key is used to key an instance of HMAC+using the SHA-512/256 hash.++First a "key name" or identifier is created, by HMAC'ing the fixed string "BOTAN+TLS SESSION KEY NAME" and truncating to 4 bytes. This is the initial prefix of+the encrypted session, and will remain fixed as long as the same ticket key is+used. This allows quickly rejecting sessions which are encrypted using an+unknown or incorrect key.++Then a key used for AES-256 in GCM mode is created by first choosing a 128 bit+random seed, and HMAC'ing it to produce a 256-bit value. This means for any one+master key as many as 2\ :sup:`128` GCM keys can be created. This is done+because NIST recommends that when using random nonces no one GCM key be used to+encrypt more than 2\ :sup:`32` messages (to avoid the possiblity of nonce+reuse).++A random 96-bit nonce is created and included in the header.++AES in GCM is used to encrypt and authenticate the serialized session. The+key name, key seed, and AEAD nonce are all included as additional data.
+ third_party/botan/doc/api_ref/tpm.rst view
@@ -0,0 +1,113 @@+Trusted Platform Module (TPM)+==========================================++.. versionadded:: 1.11.26++Some computers come with a TPM, which is a small side processor which can+perform certain operations which include RSA key generation and signing, a+random number generator, accessing a small amount of NVRAM, and a set of PCRs+which can be used to measure software state (this is TPMs most famous use, for+authenticating a boot sequence).++The TPM NVRAM and PCR APIs are not supported by Botan at this time, patches welcome.++Currently only v1.2 TPMs are supported, and the only TPM library supported is+TrouSerS (http://trousers.sourceforge.net/). Hopefully both of these limitations+will be removed in a future release, in order to support newer TPM v2.0 systems.+The current code has been tested with an ST TPM running in a Lenovo laptop.++Test for TPM support with the macro ``BOTAN_HAS_TPM``, include ``<botan/tpm.h>``.++First, create a connection to the TPM with a ``TPM_Context``. The context is+passed to all other TPM operations, and should remain alive as long as any other+TPM object which the context was passed to is still alive, otherwise errors or+even an application crash are possible. In the future, the API may change to+using ``shared_ptr`` to remove this problem.++.. cpp:class:: TPM_Context++ .. cpp:function:: TPM_Context(pin_cb cb, const char* srk_password)++ The (somewhat improperly named) pin_cb callback type takes a std::string as+ an argument, which is an informative message for the user. It should return+ a string containing the password entered by the user.++ Normally the SRK password is null. Use nullptr to signal this.++The TPM contains a RNG of unknown design or quality. If that doesn't scare you+off, you can use it with ``TPM_RNG`` which implements the standard+``RandomNumberGenerator`` interface.++.. cpp:class:: TPM_RNG++ .. cpp:function:: TPM_RNG(TPM_Context& ctx)++ Initialize a TPM RNG object. After initialization, reading from+ this RNG reads from the hardware? RNG on the TPM.++The v1.2 TPM uses only RSA, but because this key is implemented completely in+hardware it uses a different private key type, with a somewhat different API to+match the TPM's behavior.++.. cpp:class:: TPM_PrivateKey++ .. cpp:function:: TPM_PrivateKey(TPM_Context& ctx, size_t bits, const char* key_password)++ Create a new RSA key stored on the TPM. The bits should be either 1024+ or 2048; the TPM interface hypothetically allows larger keys but in+ practice no v1.2 TPM hardware supports them.++ The TPM processor is not fast, be prepared for this to take a while.++ The key_password is the password to the TPM key ?++ .. cpp:function:: std::string register_key(TPM_Storage_Type storage_type)++ Registers a key with the TPM. The storage_type can be either+ `TPM_Storage_Type::User` or `TPM_Storage_Type::System`. If System, the+ key is stored on the TPM itself. If User, it is stored on the local hard+ drive in a database maintained by an intermediate piece of system+ software (which actual interacts with the physical TPM on behalf of any+ number of applications calling the TPM API).++ The TPM has only some limited space to store private keys and may reject+ requests to store the key.++ In either case the key is encrypted with an RSA key which was generated+ on the TPM and which it will not allow to be exported. Thus (so goes the+ theory) without physically attacking the TPM++ Returns a UUID which can be passed back to constructor below.++ .. cpp:function:: TPM_PrivateKey(TPM_Context& ctx, const std::string& uuid, \+ TPM_Storage_Type storage_type)++ Load a registered key. The UUID was returned by the ``register_key`` function.++ .. cpp:function:: std::vector<uint8_t> export_blob() const++ Export the key as an encrypted blob. This blob can later be presented+ back to the same TPM to load the key.++ .. cpp:function:: TPM_PrivateKey(TPM_Context& ctx, const std::vector<uint8_t>& blob)++ Load a TPM key previously exported as a blob with ``export_blob``.++ .. cpp:function:: std::unique_ptr<Public_Key> public_key() const++ Return the public key associated with this TPM private key.++ TPM does not store public keys, nor does it support signature verification.++ .. cpp:function:: TSS_HKEY handle() const++ Returns the bare TSS key handle. Use if you need to call the raw TSS API.++A ``TPM_PrivateKey`` can be passed to a ``PK_Signer`` constructor and used to+sign messages just like any other key. Only PKCS #1 v1.5 signatures are supported+by the v1.2 TPM.++.. cpp:function:: std::vector<std::string> TPM_PrivateKey::registered_keys(TPM_Context& ctx)++ This static function returns the list of all keys (in URL format)+ registered with the system
+ third_party/botan/doc/api_ref/tss.rst view
@@ -0,0 +1,45 @@+Threshold Secret Sharing+========================================++.. versionadded:: 1.9.1++Threshold secret sharing allows splitting a secret into ``N`` shares such that+``M`` (for specified ``M`` <= ``N``) is sufficient to recover the secret, but an+attacker with ``M - 1`` shares cannot derive any information about the secret.++The implementation in Botan follows an expired Internet draft+"draft-mcgrew-tss-03". Several other implementations of this TSS format exist.++.. cpp:class:: RTSS_Share++ .. cpp:function:: static std::vector<RTSS_Share> split(uint8_t M, uint8_t N, \+ const uint8_t secret[], uint16_t secret_len, \+ const std::vector<uint8_t>& identifier, \+ const std::string& hash_fn, \+ RandomNumberGenerator& rng)++ Split a secret. The identifier is an optional key identifier which may be+ up to 16 bytes long. Shorter identifiers are padded with zeros.++ The hash function must be either "SHA-1", "SHA-256", or "None" to disable+ the checksum.++ This will return a vector of length ``N``, any ``M`` of these shares is+ sufficient to reconstruct the data.++ .. cpp:function:: static secure_vector<uint8_t> reconstruct(const std::vector<RTSS_Share>& shares)++ Given a sufficient number of shares, reconstruct a secret.++ .. cpp:function:: RTSS_Share(const uint8_t data[], size_t len)++ Read a TSS share as a sequence of bytes.++ .. cpp:function:: const secure_vector<uint8>& data() const++ Return the data of this share.++ .. cpp:function:: uint8_t share_id() const++ Return the share ID which will be in the range 1...255+
+ third_party/botan/doc/api_ref/versions.rst view
@@ -0,0 +1,100 @@++Versioning+========================================++All versions are of the tuple (major,minor,patch).++As of Botan 2.0.0, Botan uses semantic versioning. The minor number increases if+any feature addition is made. The patch version is used to indicate a release+where only bug fixes were applied. If an incompatible API change is required,+the major version will be increased.++The library has functions for checking compile-time and runtime versions.++The build-time version information is defined in `botan/build.h`++.. c:macro:: BOTAN_VERSION_MAJOR++ The major version of the release.++.. c:macro:: BOTAN_VERSION_MINOR++ The minor version of the release.++.. c:macro:: BOTAN_VERSION_PATCH++ The patch version of the release.++.. c:macro:: BOTAN_VERSION_DATESTAMP++ Expands to an integer of the form YYYYMMDD if this is an official+ release, or 0 otherwise. For instance, 1.10.1, which was released+ on July 11, 2011, has a `BOTAN_VERSION_DATESTAMP` of 20110711.++.. c:macro:: BOTAN_DISTRIBUTION_INFO++ .. versionadded:: 1.9.3++ A macro expanding to a string that is set at build time using the+ ``--distribution-info`` option. It allows a packager of the library+ to specify any distribution-specific patches. If no value is given+ at build time, the value is the string "unspecified".++.. c:macro:: BOTAN_VERSION_VC_REVISION++ .. versionadded:: 1.10.1++ A macro expanding to a string that is set to a revision identifier+ corresponding to the source, or "unknown" if this could not be+ determined. It is set for all official releases, and for builds that+ originated from within a git checkout.++The runtime version information, and some helpers for compile time+version checks, are included in `botan/version.h`++.. cpp:function:: std::string version_string()++ Returns a single-line string containing relevant information about+ this build and version of the library in an unspecified format.++.. cpp:function:: uint32_t version_major()++ Returns the major part of the version.++.. cpp:function:: uint32_t version_minor()++ Returns the minor part of the version.++.. cpp:function:: uint32_t version_patch()++ Returns the patch part of the version.++.. cpp:function:: uint32_t version_datestamp()++ Return the datestamp of the release (or 0 if the current version is+ not an official release).++.. cpp:function:: std::string runtime_version_check(uint32_t major, uint32_t minor, uint32_t patch)++ Call this function with the compile-time version being built against, eg::++ Botan::runtime_version_check(BOTAN_VERSION_MAJOR, BOTAN_VERSION_MINOR, BOTAN_VERSION_PATCH)++ It will return an empty string if the versions match, or otherwise+ an error message indicating the discrepancy. This only is useful in+ dynamic libraries, where it is possible to compile and run against+ different versions.++.. c:macro:: BOTAN_VERSION_CODE_FOR(maj,min,patch)++ Return a value that can be used to compare versions. The current+ (compile-time) version is available as the macro+ `BOTAN_VERSION_CODE`. For instance, to choose one code path for+ version 2.1.0 and later, and another code path for older releases::++ #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,1,0)+ // 2.1+ code path+ #else+ // code path for older versions+ #endif+
+ third_party/botan/doc/api_ref/x509.rst view
@@ -0,0 +1,914 @@+.. _x509_certificates:++X.509 Certificates and CRLs+=================================++A certificate is a binding between some identifying information+(called a *subject*) and a public key. This binding is asserted by a+signature on the certificate, which is placed there by some authority+(the *issuer*) that at least claims that it knows the subject named in+the certificate really "owns" the private key corresponding to the+public key in the certificate.++The major certificate format in use today is X.509v3, used for instance in the+:doc:`tls` protocol. A X.509 certificate is represented by the class+``X509_Certificate``. The data of an X.509 certificate is stored as a+``shared_ptr`` to a structure containing the decoded information. So copying+``X509_Certificate`` objects is quite cheap.+++.. cpp:class:: X509_Certificate++ .. cpp:function:: X509_Certificate(const std::string& filename)++ Load a certificate from a file. PEM or DER is accepted.++ .. cpp:function:: X509_Certificate(const std::vector<uint8_t>& in)++ Load a certificate from a byte string.++ .. cpp:function:: X509_Certificate(DataSource& source)++ Load a certificate from an abstract ``DataSource``.++ .. cpp:function:: X509_DN subject_dn() const++ Returns the distinguished name (DN) of the certificate's subject. This is+ the primary place where information about the subject of the certificate is+ stored. However "modern" information that doesn't fit in the X.500+ framework, such as DNS name, email, IP address, or XMPP address, appears+ instead in the subject alternative name.++ .. cpp:function:: X509_DN issuer_dn() const++ Returns the distinguished name (DN) of the certificate's issuer, ie the CA+ that issued this certificate.++ .. cpp:function:: const AlternativeName& subject_alt_name() const++ Return the subjects alternative name. This is used to store+ values like associated URIs, DNS addresses, and email addresses.++ .. cpp:function:: const AlternativeName& issuer_alt_name() const++ Return alternative names for the issuer.++ .. cpp:function:: std::unique_ptr<Public_Key> load_subject_public_key() const++ Deserialize the stored public key and return a new object. This+ might throw, if it happens that the public key object stored in+ the certificate is malformed in some way, or in the case that the+ public key algorithm used is not supported by the library.++ See :ref:`serializing_public_keys` for more information about what to do+ with the returned object. It may be any type of key, in principle, though+ RSA and ECDSA are most common.++ .. cpp:function:: std::vector<uint8_t> subject_public_key_bits() const++ Return the binary encoding of the subject public key. This value (or a hash of+ it) is used in various protocols, eg for public key pinning.++ .. cpp:function:: AlgorithmIdentifier subject_public_key_algo() const++ Return an algorithm identifier that identifies the algorithm used in the+ subject's public key.++ .. cpp:function:: std::vector<uint8_t> serial_number() const++ Return the certificates serial number. The tuple of issuer DN and+ serial number should be unique.++ .. cpp:function:: std::vector<uint8> raw_subject_dn() const++ Return the binary encoding of the subject DN.++ .. cpp:function:: std::vector<uint8> raw_issuer_dn() const++ Return the binary encoding of the issuer DN.++ .. cpp:function:: X509_Time not_before() const++ Returns the point in time the certificate becomes valid++ .. cpp:function:: X509_Time not_after() const++ Returns the point in time the certificate expires++ .. cpp:function:: const Extensions& v3_extensions() const++ Returns all extensions of this certificate. You can use this+ to examine any extension data associated with the certificate,+ including custom extensions the library doesn't know about.++ .. cpp:function:: std::vector<uint8_t> authority_key_id() const++ Return the authority key id, if set. This is an arbitrary string; in the+ issuing certificate this will be the subject key id.++ .. cpp:function:: std::vector<uint8_t> subject_key_id() const++ Return the subject key id, if set.++ .. cpp:function:: bool allowed_extended_usage(const OID& usage) const++ Return true if and only if the usage OID appears in the extended key usage+ extension. Also will return true if the extended key usage extension is+ not used in the current certificate.++ .. cpp:function:: std::vector<OID> extended_key_usage() const++ Return the list of extended key usages. May be empty.++ .. cpp:function:: std::string fingerprint(const std::string& hash_fn = "SHA-1") const++ Return a fingerprint for the certificate, which is basically just a hash+ of the binary contents. Normally SHA-1 or SHA-256 is used, but any hash+ function is allowed.++ .. cpp:function:: Key_Constraints constraints() const++ Returns either an enumeration listing key constraints (what the+ associated key can be used for) or ``NO_CONSTRAINTS`` if the+ relevant extension was not included. Example values are+ ``DIGITAL_SIGNATURE`` and ``KEY_CERT_SIGN``. More than one value+ might be specified.++ .. cpp:function:: bool matches_dns_name(const std::string& name) const++ Check if the certificate's subject alternative name DNS fields+ match ``name``. This function also handles wildcard certificates.++ .. cpp:function:: std::string to_string() const++ Returns a free-form human readable string describing the certificate.++ .. cpp:function:: std::string PEM_encode() const++ Returns the PEM encoding of the certificate++ .. cpp:function:: std::vector<uint8_t> BER_encode() const++ Returns the DER/BER encoding of the certificate++X.509 Distinguished Names+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++.. cpp:class:: X509_DN++ .. cpp:function:: bool has_field(const std::string& attr) const++ Returns true if ``get_attribute`` or ``get_first_attribute`` will return a value.++ .. cpp:function:: std::vector<std::string> get_attribute(const std::string& attr) const++ Return all attributes associated with a certain attribute type.++ .. cpp:function:: std::string get_first_attribute(const std::string& attr) const++ Like ``get_attribute`` but returns just the first attribute, or+ empty if the DN has no attribute of the specified type.++ .. cpp:function:: std::multimap<OID, std::string> get_attributes() const++ Get all attributes of the DN. The OID maps to a DN component such as+ 2.5.4.10 ("Organization"), and the strings are UTF-8 encoded.++ .. cpp:function:: std::multimap<std::string, std::string> contents() const++ Similar to ``get_attributes``, but the OIDs are decoded to strings.++ .. cpp:function:: void add_attribute(const std::string& key, const std::string& val)++ Add an attribute to a DN.++ .. cpp:function:: void add_attribute(const OID& oid, const std::string& val)++ Add an attribute to a DN using an OID instead of string-valued attribute type.++The ``X509_DN`` type also supports iostream extraction and insertion operators,+for formatted input and output.++X.509v3 Extensions+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++X.509v3 specifies a large number of possible extensions. Botan supports some,+but by no means all of them. The following listing lists which X.509v3+extensions are supported and notes areas where there may be problems with the+handling.++ - Key Usage and Extended Key Usage: No problems known.++ - Basic Constraints: No problems known. A self-signed v1 certificate+ is assumed to be a CA, while a v3 certificate is marked as a CA if+ and only if the basic constraints extension is present and set for+ a CA cert.++ - Subject Alternative Names: Only the "rfc822Name", "dNSName", and+ "uniformResourceIdentifier" and raw IPv4 fields will be stored; all+ others are ignored.++ - Issuer Alternative Names: Same restrictions as the Subject+ Alternative Names extension. New certificates generated by Botan+ never include the issuer alternative name.++ - Authority Key Identifier: Only the version using KeyIdentifier is+ supported. If the GeneralNames version is used and the extension is+ critical, an exception is thrown. If both the KeyIdentifier and GeneralNames+ versions are present, then the KeyIdentifier will be used, and the+ GeneralNames ignored.++ - Subject Key Identifier: No problems known.++ - Name Constraints: No problems known (though encoding is not supported).++Any unknown critical extension in a certificate will lead to an+exception during path validation.++Extensions are handled by a special class taking care of encoding+and decoding. It also supports encoding and decoding of custom extensions.+To do this, it internally keeps two lists of extensions. Different lookup+functions are provided to search them.++.. note::++ Validation of custom extensions during path validation is currently not supported.++.. cpp:class:: Extensions++ .. cpp:function:: void add(Certificate_Extension* extn, bool critical = false)++ Adds a new extension to the extensions object. If an extension of the same+ type already exists, ``extn`` will replace it. If ``critical`` is true the+ extension will be marked as critical in the encoding.++ .. cpp:function:: bool add_new(Certificate_Extension* extn, bool critical = false)++ Like ``add`` but an existing extension will not be replaced. Returns true if the+ extension was used, false if an extension of the same type was already in place.++ .. cpp:function:: void replace(Certificate_Extension* extn, bool critical = false)++ Adds an extension to the list or replaces it, if the same+ extension was already added++ .. cpp:function:: std::unique_ptr<Certificate_Extension> get(const OID& oid) const++ Searches for an extension by OID and returns the result++ .. cpp:function:: template<typename T> \+ std::unique_ptr<T> get_raw(const OID& oid)++ Searches for an extension by OID and returns the result.+ Only the unknown extensions, that is, extensions types that are not+ listed above, are searched for by this function.++ .. cpp:function:: std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> extensions() const++ Returns the list of extensions together with the corresponding+ criticality flag. Only contains the supported extension types+ listed above.++ .. cpp:function:: std::map<OID, std::pair<std::vector<uint8_t>, bool>> extensions_raw() const++ Returns the list of extensions as raw, encoded bytes+ together with the corresponding criticality flag.+ Contains all extensions, known as well as unknown extensions.++Certificate Revocation Lists+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++It will occasionally happen that a certificate must be revoked before+its expiration date. Examples of this happening include the private+key being compromised, or the user to which it has been assigned+leaving an organization. Certificate revocation lists are an answer to+this problem (though online certificate validation techniques are+starting to become somewhat more popular). Every once in a while the+CA will release a new CRL, listing all certificates that have been+revoked. Also included is various pieces of information like what time+a particular certificate was revoked, and for what reason. In most+systems, it is wise to support some form of certificate revocation,+and CRLs handle this easily.++For most users, processing a CRL is quite easy. All you have to do is+call the constructor, which will take a filename (or a+``DataSource&``). The CRLs can either be in raw BER/DER, or in PEM+format; the constructor will figure out which format without any extra+information. For example::++ X509_CRL crl1("crl1.der");++ DataSource_Stream in("crl2.pem");+ X509_CRL crl2(in);++After that, pass the ``X509_CRL`` object to a ``Certificate_Store`` object+with++.. cpp:function:: void Certificate_Store::add_crl(const X509_CRL& crl)++and all future verifications will take into account the provided CRL.++Certificate Stores+----------------------------------------++An object of type ``Certificate_Store`` is a generalized interface to+an external source for certificates (and CRLs). Examples of such a+store would be one that looked up the certificates in a SQL database,+or by contacting a CGI script running on a HTTP server. There are+currently three mechanisms for looking up a certificate, and one for+retrieving CRLs. By default, most of these mechanisms will return an+empty ``std::shared_ptr`` of ``X509_Certificate``. This storage mechanism+is *only* queried when doing certificate validation: it allows you to+distribute only the root key with an application, and let some online+method handle getting all the other certificates that are needed to+validate an end entity certificate. In particular, the search routines+will not attempt to access the external database.++The certificate lookup methods are ``find_cert`` (by Subject+Distinguished Name and optional Subject Key Identifier) and+``find_cert_by_pubkey_sha1`` (by SHA-1 hash of the certificate's+public key). The Subject Distinguished Name is given as a ``X509_DN``,+while the SKID parameter takes a ``std::vector<uint8_t>`` containing+the subject key identifier in raw binary. Both lookup methods are+mandatory to implement.++Finally, there is a method for finding a CRL, called ``find_crl_for``,+that takes an ``X509_Certificate`` object, and returns a+``std::shared_ptr`` of ``X509_CRL``. The ``std::shared_ptr`` return+type makes it easy to return no CRLs by returning ``nullptr``+(eg, if the certificate store doesn't support retrieving CRLs).+Implementing the function is optional, and by default will return+``nullptr``.++Certificate stores are used in the :doc:`tls` module to store a+list of trusted certificate authorities.++In Memory Certificate Store+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The in memory certificate store keeps all objects in memory only.+Certificates can be loaded from disk initially, but also added+later.++.. cpp:class:: Certificate_Store_In_Memory++ .. cpp:function:: Certificate_Store_In_Memory(const std::string& dir)++ Attempt to parse all files in ``dir`` (including subdirectories)+ as certificates. Ignores errors.++ .. cpp:function:: Certificate_Store_In_Memory(const X509_Certificate& cert)++ Adds given certificate to the store++ .. cpp:function:: Certificate_Store_In_Memory()++ Create an empty store++ .. cpp:function:: void add_certificate(const X509_Certificate& cert)++ Add a certificate to the store++ .. cpp:function:: void add_certificate(std::shared_ptr<const X509_Certificate> cert)++ Add a certificate already in a shared_ptr to the store++ .. cpp:function:: void add_crl(const X509_CRL& crl)++ Add a certificate revocation list (CRL) to the store.++ .. cpp:function:: void add_crl(std::shared_ptr<const X509_CRL> crl)++ Add a certificate revocation list (CRL) to the store as a shared_ptr++SQL-backed Certificate Stores+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The SQL-backed certificate stores store all objects in an SQL database. They+also additionally provide private key storage and revocation of individual+certificates.++.. cpp:class:: Certificate_Store_In_SQL++ .. cpp:function:: Certificate_Store_In_SQL(const std::shared_ptr<SQL_Database> db, \+ const std::string& passwd, RandomNumberGenerator& rng, const std::string& table_prefix = "")++ Create or open an existing certificate store from an SQL database.+ The password in ``passwd`` will be used to encrypt private keys.++ .. cpp:function:: bool insert_cert(const X509_Certificate& cert)++ Inserts ``cert`` into the store. Returns `false` if the certificate is+ already known and `true` if insertion was successful.++ .. cpp:function:: remove_cert(const X509_Certificate& cert)++ Removes ``cert`` from the store. Returns `false` if the certificate could not+ be found and `true` if removal was successful.++ .. cpp:function:: std::shared_ptr<const Private_Key> find_key(const X509_Certificate&) const++ Returns the private key for "cert" or an empty shared_ptr if none was found++ .. cpp:function:: std::vector<std::shared_ptr<const X509_Certificate>> \+ find_certs_for_key(const Private_Key& key) const++ Returns all certificates for private key ``key``++ .. cpp:function:: bool insert_key(const X509_Certificate& cert, const Private_Key& key)++ Inserts ``key`` for ``cert`` into the store, returns `false` if the key is+ already known and `true` if insertion was successful.++ .. cpp:function:: void remove_key(const Private_Key& key)++ Removes ``key`` from the store++ .. cpp:function:: void revoke_cert(const X509_Certificate&, CRL_Code, \+ const X509_Time& time = X509_Time())++ Marks ``cert`` as revoked starting from ``time``++ .. cpp:function:: void affirm_cert(const X509_Certificate&)++ Reverses the revocation for ``cert``++ .. cpp:function:: std::vector<X509_CRL> generate_crls() const++ Generates CRLs for all certificates marked as revoked.+ A CRL is returned for each unique issuer DN.++The ``Certificate_Store_In_SQL`` class operates on an abstract ``SQL_Database``+object. If support for sqlite3 was enabled at build time, Botan includes an+implementation of this interface for sqlite3, and a subclass of+``Certificate_Store_In_SQL`` which creates or opens a sqlite3 database.++.. cpp:class:: Certificate_Store_In_SQLite++ .. cpp:function:: Certificate_Store_In_SQLite(const std::string& db_path, \+ const std::string& passwd, RandomNumberGenerator& rng, const std::string& table_prefix = "")++ Create or open an existing certificate store from an sqlite database file.+ The password in ``passwd`` will be used to encrypt private keys. ++Path Validation+----------------------------------------++The process of validating a certificate chain up to a trusted root is+called `path validation`, and in botan that operation is handled by a+set of functions in ``x509path.h`` named ``x509_path_validate``:++.. cpp:function:: Path_Validation_Result \+ x509_path_validate(const X509_Certificate& end_cert, \+ const Path_Validation_Restrictions& restrictions, \+ const Certificate_Store& store, const std::string& hostname = "", \+ Usage_Type usage = Usage_Type::UNSPECIFIED, \+ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), \+ std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), \+ const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = std::vector<std::shared_ptr<const OCSP::Response>>())++ The last five parameters are optional. ``hostname`` specifies a hostname which is+ matched against the subject DN in ``end_cert`` according to RFC 6125.+ An empty hostname disables hostname validation.+ ``usage`` specifies key usage restrictions that are compared+ to the key usage fields in `end_cert` according to RFC 5280, if not set to+ ``UNSPECIFIED``. ``validation_time`` allows setting the time point at which all certificates+ are validated. This is really only useful for testing. The default is the+ current system clock's current time. ``ocsp_timeout`` sets the timeout for+ OCSP requests. The default of 0 disables OCSP checks completely.+ ``ocsp_resp`` allows adding additional OCSP responses retrieved from outside+ of the path validation. Note that OCSP online checks are done only+ as long as the http_util module was compiled in. Availability of online+ OCSP checks can be checked using the macro BOTAN_HAS_ONLINE_REVOCATION_CHECKS.++ For the different flavors of ``x509_path_validate``, check ``x509path.h``.++The result of the validation is returned as a class:++.. cpp:class:: Path_Validation_Result++ Specifies the result of the validation++ .. cpp:function:: bool successful_validation() const++ Returns true if a certificate path from *end_cert* to a trusted+ root was found and all path validation checks passed.++ .. cpp:function:: std::string result_string() const++ Returns a descriptive string of the validation status (for+ instance "Verified", "Certificate is not yet valid", or+ "Signature error"). This is the string value of+ the `result` function below.++ .. cpp:function:: const X509_Certificate& trust_root() const++ If the validation was successful, returns the certificate which+ is acting as the trust root for *end_cert*.++ .. cpp:function:: const std::vector<X509_Certificate>& cert_path() const++ Returns the full certificate path starting with the end entity+ certificate and ending in the trust root.++ .. cpp:function:: Certificate_Status_Code result() const++ 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+ relatively innocuous and common error) when the signature isn't+ even valid.++ .. cpp:function:: const std::vector<std::set<Certificate_Status_Code>>& all_statuses() const++ For each certificate in the chain, returns a set of status which+ indicate all errors which occurred during validation. This is+ primarily useful for diagnostic purposes.++ .. cpp:function:: std::set<std::string> trusted_hashes() const++ Returns the set of all cryptographic hash functions which are+ implicitly trusted for this validation to be correct.+++A ``Path_Validation_Restrictions`` is passed to the path+validator and specifies restrictions and options for the validation+step. The two constructors are:++ .. cpp:function:: Path_Validation_Restrictions(bool require_rev, \+ size_t minimum_key_strength, \+ bool ocsp_all_intermediates, \+ const std::set<std::string>& trusted_hashes)++ If `require_rev` is true, then any path without revocation+ information (CRL or OCSP check) is rejected with the code+ `NO_REVOCATION_DATA`. The `minimum_key_strength` parameter+ specifies the minimum strength of public key signature we will+ accept is. The set of hash names `trusted_hashes` indicates which+ hash functions we'll accept for cryptographic signatures. Any+ untrusted hash will cause the error case `UNTRUSTED_HASH`.++ .. cpp:function:: Path_Validation_Restrictions(bool require_rev = false, \+ size_t minimum_key_strength = 80, \+ bool ocsp_all_intermediates = false)++ A variant of the above with some convenient defaults. The current+ default `minimum_key_strength` of 80 roughly corresponds to 1024+ bit RSA. The set of trusted hashes is set to all SHA-2 variants,+ and, if `minimum_key_strength` is less than or equal to 80, then+ SHA-1 signatures will also be accepted.++Creating New Certificates+---------------------------------++A CA is represented by the type ``X509_CA``, which can be found in+``x509_ca.h``. A CA always needs its own certificate, which can either+be a self-signed certificate (see below on how to create one) or one+issued by another CA (see the section on PKCS #10 requests). Creating+a CA object is done by the following constructor:++.. cpp:function:: X509_CA::X509_CA(const X509_Certificate& cert, \+ const Private_Key& key, \+ const std::string& hash_fn, \+ RandomNumberGenerator& rng)++The private ``key`` is the private key corresponding to the public key in the+CA's certificate. ``hash_fn`` is the name of the hash function to use+for signing, e.g., `SHA-256`. ``rng`` is queried for random during signing.++There is an alternative constructor that lets you set additional options, namely+the padding scheme that will be used by the X509_CA object to sign certificates+and certificate revocation lists. If the padding is not set explicitly, the CA+will use the padding scheme that was used when signing the CA certificate.++.. cpp:function:: X509_CA::X509_CA(const X509_Certificate& cert, \+ const Private_Key& key, \+ const std::map<std::string,std::string>& opts, \+ const std::string& hash_fn, \+ RandomNumberGenerator& rng)++The only option valid at this moment is "padding". The supported padding schemes+can be found in src/lib/pubkey/padding.cpp. Some alternative names for the+padding schemes are understood, as well.++Requests for new certificates are supplied to a CA in the form of PKCS+#10 certificate requests (called a ``PKCS10_Request`` object in+Botan). These are decoded in a similar manner to+certificates/CRLs/etc. A request is vetted by humans (who somehow+verify that the name in the request corresponds to the name of the+entity who requested it), and then signed by a CA key, generating a+new certificate:++.. cpp:function:: X509_Certificate \+ X509_CA::sign_request(const PKCS10_Request& req, \+ RandomNumberGenerator& rng, \+ const X509_Time& not_before, \+ const X509_Time& not_after)++Generating CRLs+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++As mentioned previously, the ability to process CRLs is highly+important in many PKI systems. In fact, according to strict X.509+rules, you must not validate any certificate if the appropriate CRLs+are not available (though hardly any systems are that strict). In any+case, a CA should have a valid CRL available at all times.++Of course, you might be wondering what to do if no certificates have+been revoked. Never fear; empty CRLs, which revoke nothing at all, can+be issued. To generate a new, empty CRL, just call++.. cpp:function:: X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, \+ uint32_t next_update = 0)++ This function will return a new, empty CRL. The ``next_update`` parameter is+ the number of seconds before the CRL expires. If it is set to the (default)+ value of zero, then a reasonable default (currently 7 days) will be used.++On the other hand, you may have issued a CRL before. In that case, you will+want to issue a new CRL that contains all previously revoked+certificates, along with any new ones. This is done by calling++.. cpp:function:: X509_CRL X509_CA::update_crl(const X509_CRL& last_crl, \+ std::vector<CRL_Entry> new_entries, RandomNumberGenerator& rng, \+ size_t next_update = 0)++ Where ``last_crl`` is the last CRL this CA issued, and+ ``new_entries`` is a list of any newly revoked certificates. The+ function returns a new ``X509_CRL`` to make available for+ clients.++The ``CRL_Entry`` type is a structure that contains, at a minimum, the serial+number of the revoked certificate. As serial numbers are never repeated, the+pairing of an issuer and a serial number (should) distinctly identify any+certificate. In this case, we represent the serial number as a+``secure_vector<uint8_t>`` called ``serial``. There are two additional (optional)+values, an enumeration called ``CRL_Code`` that specifies the reason for+revocation (``reason``), and an object that represents the time that the+certificate became invalid (if this information is known).++If you wish to remove an old entry from the CRL, insert a new entry for the+same cert, with a ``reason`` code of ``REMOVE_FROM_CRL``. For example, if a+revoked certificate has expired 'normally', there is no reason to continue to+explicitly revoke it, since clients will reject the cert as expired in any+case.++Self-Signed Certificates+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Generating a new self-signed certificate can often be useful, for+example when setting up a new root CA, or for use in specialized+protocols. The library provides a utility function for this:++.. cpp:function:: X509_Certificate create_self_signed_cert( \+ const X509_Cert_Options& opts, const Private_Key& key, \+ const std::string& hash_fn, RandomNumberGenerator& rng)++ Where ``key`` is the private key you wish to use (the public key,+ used in the certificate itself is extracted from the private key),+ and ``opts`` is an structure that has various bits of information+ that will be used in creating the certificate (this structure, and+ its use, is discussed below).++Creating PKCS #10 Requests+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Also in ``x509self.h``, there is a function for generating new PKCS #10+certificate requests:++.. cpp:function:: PKCS10_Request create_cert_req( \+ const X509_Cert_Options& opts, const Private_Key& key, \+ const std::string& hash_fn, RandomNumberGenerator& rng)++This function acts quite similarly to+:cpp:func:`create_self_signed_cert`, except it instead returns a PKCS+#10 certificate request. After creating it, one would typically+transmit it to a CA, who signs it and returns a freshly minted X.509+certificate.++.. cpp:function:: PKCS10_Request PKCS10_Request::create(const Private_Key& key, \+ const X509_DN& subject_dn, \+ const Extensions& extensions, \+ const std::string& hash_fn, \+ RandomNumberGenerator& rng, \+ const std::string& padding_scheme = "", \+ const std::string& challenge = "")++ This function (added in 2.5) is similar to ``create_cert_req`` but allows+ specifying all the parameters directly. In fact ``create_cert_req`` just+ creates the DN and extensions from the options, then uses this call to+ actually create the ``PKCS10_Request`` object.+++Certificate Options+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++What is this ``X509_Cert_Options`` thing we've been passing around?+It's a class representing a bunch of information that will end up+being stored into the certificate. This information comes in 3 major+flavors: information about the subject (CA or end-user), the validity+period of the certificate, and restrictions on the usage of the+certificate. For special cases, you can also add custom X.509v3+extensions.++First and foremost is a number of ``std::string`` members, which+contains various bits of information about the user: ``common_name``,+``serial_number``, ``country``, ``organization``, ``org_unit``,+``locality``, ``state``, ``email``, ``dns_name``, and ``uri``. As many+of these as possible should be filled it (especially an email+address), though the only required ones are ``common_name`` and+``country``.++Additionally there are a small selection of ``std::vector<std::string>``+members, which allow space for repeating elements:+``more_org_units`` and ``more_dns``.++There is another value that is only useful when creating a PKCS #10+request, which is called ``challenge``. This is a challenge password,+which you can later use to request certificate revocation (*if* the CA+supports doing revocations in this manner).++Then there is the validity period; these are set with ``not_before``+and ``not_after``. Both of these functions also take a+``std::string``, which specifies when the certificate should start+being valid, and when it should stop being valid. If you don't set the+starting validity period, it will automatically choose the current+time. If you don't set the ending time, it will choose the starting+time plus a default time period. The arguments to these functions+specify the time in the following format: "2002/11/27 1:50:14". The+time is in 24-hour format, and the date is encoded as+year/month/day. The date must be specified, but you can omit the time+or trailing parts of it, for example "2002/11/27 1:50" or+"2002/11/27".++Third, you can set constraints on a key. The one you're mostly likely+to want to use is to create (or request) a CA certificate, which can+be done by calling the member function ``CA_key``. This should only be+used when needed.++Moreover, you can specify the padding scheme to be used when digital signatures+are computed by calling function ``set_padding_scheme`` with a string+representing the padding scheme. This way, you can control the padding scheme+for self-signed certificates and PKCS #10 requests. The padding scheme used by+a CA when building a certificate or a certificate revocation list can be set in+the ``X509_CA`` constructor. The supported padding schemes can be found in+src/lib/pubkey/padding.cpp. Some alternative names for the padding schemes are+understood, as well.++Other constraints can be set by calling the member functions+``add_constraints`` and ``add_ex_constraints``. The first takes a+``Key_Constraints`` value, and replaces any previously set value. If+no value is set, then the certificate key is marked as being valid for+any usage. You can set it to any of the following (for more than one+usage, OR them together): ``DIGITAL_SIGNATURE``, ``NON_REPUDIATION``,+``KEY_ENCIPHERMENT``, ``DATA_ENCIPHERMENT``, ``KEY_AGREEMENT``,+``KEY_CERT_SIGN``, ``CRL_SIGN``, ``ENCIPHER_ONLY``,+``DECIPHER_ONLY``. Many of these have quite special semantics, so you+should either consult the appropriate standards document (such as RFC+5280), or just not call ``add_constraints``, in which case the+appropriate values will be chosen for you.++The second function, ``add_ex_constraints``, allows you to specify an+OID that has some meaning with regards to restricting the key to+particular usages. You can, if you wish, specify any OID you like, but+there is a set of standard ones that other applications will be able+to understand. These are the ones specified by the PKIX standard, and+are named "PKIX.ServerAuth" (for TLS server authentication),+"PKIX.ClientAuth" (for TLS client authentication), "PKIX.CodeSigning",+"PKIX.EmailProtection" (most likely for use with S/MIME),+"PKIX.IPsecUser", "PKIX.IPsecTunnel", "PKIX.IPsecEndSystem", and+"PKIX.TimeStamping". You can call "add_ex_constraints" any number of+times - each new OID will be added to the list to include in the+certificate.++Lastly, you can add any X.509v3 extensions in the `extensions` member, which is+useful if you want to encode a custom extension, or encode an extension in a way+differently from how Botan defaults.++OCSP Requests+----------------------------------------++A client makes an OCSP request to what is termed an 'OCSP responder'. This+responder returns a signed response attesting that the certificate in question+has not been revoked. The most recent OCSP specification is as of this+writing :rfc:`6960`.++Normally OCSP validation happens automatically as part of X.509 certificate+validation, as long as OCSP is enabled (by setting a non-zero ``ocsp_timeout``+in the call to ``x509_path_validate``, or for TLS by implementing the related+``tls_verify_cert_chain_ocsp_timeout`` callback and returning a non-zero value+from that). So most applications should not need to directly manipulate OCSP+request and response objects.++For those that do, the primary ocsp interface is in ``ocsp.h``. First a request+must be formed, using information contained in the subject certificate and in+the subject's issuing certificate.++.. cpp:class:: OCSP::Request++ .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \+ const BigInt& subject_serial)++ Create a new OCSP request++ .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \+ const X509_Certificate& subject_cert)++ Variant of the above, using serial number from ``subject_cert``.++ .. cpp:function:: std::vector<uint8_t> BER_encode() const++ Encode the current OCSP request as a binary string.++ .. cpp:function:: std::string base64_encode() const++ Encode the current OCSP request as a base64 string.++Then the response is parsed and validated, and if valid, can be consulted+for certificate status information.++.. cpp:class:: OCSP::Response++ .. cpp:function:: OCSP::Response(const uint8_t response_bits[], size_t response_bits_len)++ Attempts to parse ``response_bits`` as an OCSP response. Throws an+ exception if parsing fails. Note that this does not verify that the OCSP+ response is valid (ie that the signature is correct), merely that the+ ASN.1 structure matches an OCSP response.++ .. cpp:function:: Certificate_Status_Code check_signature( \+ const std::vector<Certificate_Store*>& trust_roots, \+ const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path = const std::vector<std::shared<const X509_Certificate>>()) const++ Find the issuing certificate of the OCSP response, and check the signature.++ If possible, pass the full certificate path being validated in+ the optional ``cert_path`` argument: this additional information+ helps locate the OCSP signer's certificate in some cases. If this+ does not return ``Certificate_Status_Code::OCSP_SIGNATURE_OK``,+ then the request must not be be used further.++ .. cpp:function:: Certificate_Status_Code verify_signature(const X509_Certificate& issuing_cert) const++ If the certificate that issued the OCSP response is already known (eg,+ because in some specific application all the OCSP responses will always+ be signed by a single trusted issuer whose cert is baked into the code)+ this provides an alternate version of `check_signature`.++ .. cpp:function:: Certificate_Status_Code status_for(const X509_Certificate& issuer, \+ const X509_Certificate& subject, \+ std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const++ Assuming the signature is valid, returns the status for the subject certificate.+ Make sure to get the ordering of the issuer and subject certificates correct.++ The ``ref_time`` is normally just the system clock, but can be used if+ validation against some other reference time is desired (such as for+ testing, to verify an old previously valid OCSP response, or to use an+ alternate time source such as the Roughtime protocol instead of the local+ client system clock).++ .. cpp:function:: const X509_Time& produced_at() const++ Return the time this OCSP response was (claimed to be) produced at.++ .. cpp:function:: const X509_DN& signer_name() const++ Return the distinguished name of the signer. This is used to help+ find the issuing certificate.++ This field is optional in OCSP responses, and may not be set.++ .. cpp:function:: const std::vector<uint8_t>& signer_key_hash() const++ Return the SHA-1 hash of the public key of the signer. This is used to+ help find the issuing certificate. The ``Certificate_Store`` API+ ``find_cert_by_pubkey_sha1`` can search on this value.++ This field is optional in OCSP responses, and may not be set.++ .. cpp:function:: const std::vector<uint8_t>& raw_bits() const++ Return the entire raw ASN.1 blob (for debugging or specialized decoding needs)++One common way of making OCSP requests is via HTTP, see :rfc:`2560`+Appendix A for details. A basic implementation of this is the function+``online_check``, which is available as long as the ``http_util`` module+was compiled in; check by testing for the macro ``BOTAN_HAS_HTTP_UTIL``.++.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \+ const BigInt& subject_serial, \+ const std::string& ocsp_responder, \+ const Certificate_Store* trusted_roots)++ Assemble a OCSP request for serial number ``subject_serial`` and attempt to request+ it to responder at URI ``ocsp_responder`` over a new HTTP socket, parses and returns+ the response. If trusted_roots is not null, then the response is additionally+ validated using OCSP response API ``check_signature``. Otherwise, this call must be+ performed later by the application.++.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \+ const X509_Certificate& subject, \+ const Certificate_Store* trusted_roots)++ Variant of the above but uses serial number and OCSP responder URI from ``subject``.
+ third_party/botan/doc/authors.txt view
@@ -0,0 +1,102 @@+Alastair Houghton+Alexander Bluhm (genua GmbH)+Alex Gaynor+Alf-André Walla+Allan L. Bazinet+Alon Bar-Lev+Andrew Moon+Antonio Coratelli+Atanas Filyanov+Baruch Burstein+Bhaskar Biswas+Bi11+Bogdan Gusiev+Chris Desjardins+Christian Mainka (Hackmanit GmbH)+Christopher Bläsius+Christoph Ludwig+cryptosource GmbH+cynecx+Dan Brown+Daniel Neus (Rohde & Schwarz Cybersecurity)+Daniel Seither (Kullo GmbH)+Daniel Wyatt+Eric Cornelius+Erwan Chaussy+etcimon+Evgeny Pokhilko+Fabian Weissberg+Falko Strenzke (cryptosource GmbH)+Felix Yan+FlexSecure GmbH+Florent Le Coz+Francis Dupont+Frank Schoenmann+Google Inc+Gustavo Serra Scalet+guywithcrookedface+Hannes Rantzsch+Harry Reimann+Hegedüs Márton Csaba+Hubert Bugaj+ilovezfs+J08nY+Jack Lloyd+Jeffrey Walton+Joel Low+joerg+Jose Luis Pereira (Fyde Inc.)+Juraj Somorovsky (Hackmanit GmbH)+Justin Karneges+Kai Michaelis (Rohde & Schwarz Cybersecurity)+Kirill A. Korinsky+Konstantinos Kolelis+Krzysztof Kwiatkowski+Lauri Nurmi+Luca Piccarreta+Manuel Hartl+Marcus Brinkmann+Markus Wanner+Martin Doering+Matej Kenda (TopIT d.o.o.)+Mathieu Souchaud+Matthew Gregan+Matthias Gierlings (Hackmanit GmbH)+Matt Johnston+Nathan Hourt+Nicolas Sendrier+Nuno Goncalves+Ori Peleg+Patrick Sona+Patrick Wildt+Patrik Fiedler+Peter J Jones+Philippe Lieser (Rohde & Schwarz Cybersecurity)+Philipp Weber (Rohde & Schwarz Cybersecurity)+Projet SECRET, INRIA, Rocquencourt+René Korthaus (Rohde & Schwarz Cybersecurity)+René Meusel+Ribose Inc+Robert Dailey+Ryuhei Mori+schregger+Sergii Cherkavskyi+seu+Shlomi Fish+Simon Cogliani+Simon Warta (Kullo GmbH)+slaviber+souch+t0b3+tcely+Technische Universitat Darmstadt+Tim Oesterreich+Tobias @neverhub+Tomasz Frydrych+Uri Blumenthal+Vaclav Ovsik+Volker Aßmann+Yuri+Yves Jerschow+Zoltan Gyarmati+0xdefaced
+ third_party/botan/doc/building.rst view
@@ -0,0 +1,1019 @@+.. _building:++Building The Library+=================================++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+maintainer if you would like to build Botan on such a system.++Botan's build is controlled by configure.py, which is a `Python+<https://www.python.org>`_ script. Python 2.6 or later is required.++.. highlight:: none++For the impatient, this works for most systems::++ $ ./configure.py [--prefix=/some/directory]+ $ make+ $ make install++Or using ``nmake``, if you're compiling on Windows with Visual C++. On+platforms that do not understand the '#!' convention for beginning+script files, or that have Python installed in an unusual spot, you+might need to prefix the ``configure.py`` command with ``python`` or+``/path/to/python``::++ $ python ./configure.py [arguments]++Configuring the Build+---------------------------------++The first step is to run ``configure.py``, which is a Python script+that creates various directories, config files, and a Makefile for+building everything. This script should run under a vanilla install of+Python 2.6, 2.7, or 3.x.++The script will attempt to guess what kind of system you are trying to+compile for (and will print messages telling you what it guessed).+You can override this process by passing the options ``--cc``,+``--os``, and ``--cpu``.++You can pass basically anything reasonable with ``--cpu``: the script+knows about a large number of different architectures, their+sub-models, and common aliases for them. You should only select the+64-bit version of a CPU (such as "sparc64" or "mips64") if your+operating system knows how to handle 64-bit object code - a 32-bit+kernel on a 64-bit CPU will generally not like 64-bit code.++By default the script tries to figure out what will work on your+system, and use that. It will print a display at the end showing which+algorithms have and have not been enabled. For instance on one system+we might see lines like::++ INFO: Skipping (dependency failure): certstor_sqlite3 sessions_sqlite3+ INFO: Skipping (incompatible CPU): aes_power8+ INFO: Skipping (incompatible OS): darwin_secrandom getentropy win32_stats+ INFO: Skipping (incompatible compiler): aes_armv8 pmull sha1_armv8 sha2_32_armv8+ INFO: Skipping (no enabled compression schemes): compression+ INFO: Skipping (requires external dependency): boost bzip2 lzma openssl sqlite3 tpm zlib++The ones that are skipped because they are require an external+dependency have to be explicitly asked for, because they rely on third+party libraries which your system might not have or that you might not+want the resulting binary to depend on. For instance to enable zlib+support, add ``--with-zlib`` to your invocation of ``configure.py``.+All available modules can be listed with ``--list-modules``.++You can control which algorithms and modules are built using the+options ``--enable-modules=MODS`` and ``--disable-modules=MODS``, for+instance ``--enable-modules=zlib`` and ``--disable-modules=xtea,idea``.+Modules not listed on the command line will simply be loaded if needed+or if configured to load by default. If you use ``--minimized-build``,+only the most core modules will be included; you can then explicitly+enable things that you want to use with ``--enable-modules``. This is+useful for creating a minimal build targeting to a specific+application, especially in conjunction with the amalgamation option;+see :ref:`amalgamation` and :ref:`minimized_builds`.++For instance::++ $ ./configure.py --minimized-build --enable-modules=rsa,eme_oaep,emsa_pssr++will set up a build that only includes RSA, OAEP, PSS along with any+required dependencies. Note that a minimized build does not by default+include any random number generator, which is needed for example to+generate keys, nonces and IVs. See :doc:`api_ref/rng` on which random number+generators are available.++Cross Compiling+---------------------++Cross compiling refers to building software on one type of host (say Linux+x86-64) but creating a binary for some other type (say MinGW x86-32). This is+completely supported by the build system. To extend the example, we must tell+`configure.py` to use the MinGW tools::++ $ ./configure.py --os=mingw --cpu=x86_32 --cc-bin=i686-w64-mingw32-g++ --ar-command=i686-w64-mingw32-ar+ ...+ $ make+ ...+ $ file botan.exe+ botan.exe: PE32 executable (console) Intel 80386, for MS Windows++.. note::+ For whatever reason, some distributions of MinGW lack support for+ threading or mutexes in the C++ standard library. You can work around+ this by disabling thread support using ``--without-os-feature=threads``++You can also specify the alternate tools by setting the `CXX` and `AR`+environment variables (instead of the `--cc-bin` and `--ar-command` options), as+is commonly done with autoconf builds.++On Unix+----------------++The basic build procedure on Unix and Unix-like systems is::++ $ ./configure.py [--enable-modules=<list>] [--cc=CC]+ $ make+ $ make check++If the tests look OK, install::++ $ make install++On Unix systems the script will default to using GCC; use ``--cc`` if+you want something else. For instance use ``--cc=icc`` for Intel C+++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::++ $ ./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+``/etc/ld.so.conf`` and run ``ldconfig`` (as root) in order for new+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 macOS+--------------++A build on macOS works much like that on any other Unix-like system.++To build a universal binary for macOS, you need to set some additional+build flags. Do this with the `configure.py` flag `--cc-abi-flags`::++ --cc-abi-flags="-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc"++On Windows+--------------++.. note::++ The earliest versions of Windows supported are Windows 7 and Windows 2008 R2++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 --os=windows+ $ nmake+ $ nmake check+ $ nmake install++Botan supports the nmake replacement `Jom <https://wiki.qt.io/Jom>`_+which enables you to run multiple build jobs in parallel.++For MinGW, use::++ $ python configure.py --cc=gcc --os=mingw+ $ make++By default the install target will be ``C:\botan``; you can modify+this with the ``--prefix`` option.++When building your applications, all you have to do is tell the+compiler to look for both include files and library files in+``C:\botan``, and it will find both. Or you can move them to a+place where they will be in the default compiler search paths (consult+your documentation and/or local expert for details).+++For iOS using XCode+-------------------------++For iOS, you typically build for 3 architectures: armv7 (32 bit, older+iOS devices), armv8-a (64 bit, recent iOS devices) and x86_64 for+the iPhone simulator. You can build for these 3 architectures and then+create a universal binary containing code for all of these+architectures, so you can link to Botan for the simulator as well as+for an iOS device.++To cross compile for armv7, configure and make with::++ $ ./configure.py --os=ios --prefix="iphone-32" --cpu=armv7 --cc=clang \+ --cc-abi-flags="-arch armv7"+ $ xcrun --sdk iphoneos make install++To cross compile for armv8-a, configure and make with::++ $ ./configure.py --os=ios --prefix="iphone-64" --cpu=armv8-a --cc=clang \+ --cc-abi-flags="-arch arm64"+ $ xcrun --sdk iphoneos make install++To compile for the iPhone Simulator, configure and make with::++ $ ./configure.py --os=ios --prefix="iphone-simulator" --cpu=x86_64 --cc=clang \+ --cc-abi-flags="-arch x86_64"+ $ xcrun --sdk iphonesimulator make install++Now create the universal binary and confirm the library is compiled+for all three architectures::++ $ xcrun --sdk iphoneos lipo -create -output libbotan-2.a \+ iphone-32/lib/libbotan-2.a \+ iphone-64/lib/libbotan-2.a \+ iphone-simulator/lib/libbotan-2.a+ $ xcrun --sdk iphoneos lipo -info libbotan-2.a+ Architectures in the fat file: libbotan-2.a are: armv7 x86_64 armv64++The resulting static library can be linked to your app in Xcode.++For Android+---------------------++Modern versions of Android NDK use Clang and support C++11. Simply+configure using the appropriate NDK compiler::++ $ export CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang+++ $ ./configure.py --os=android --cc=clang --cpu=arm64++Docker+^^^^^^^^^^^++To build android version, there is the possibility to use+the docker way::++ sudo ANDROID_SDK_VER=21 ANDROID_ARCH=arm64 src/scripts/docker-android.sh++This will produce the docker-builds/android folder containing+each architecture compiled.++Emscripten (WebAssembly)+---------------------------++To build for WebAssembly using Emscripten, try::++ CXX=em++ ./configure.py --cc=clang --cpu=llvm --os=emscripten+ make++This will produce bitcode files ``botan-test.bc`` and ``botan.bc``+along with a static archive ``libbotan-2.a`` which can linked with+other modules. To convert the tests into a WASM file which can be+executed on a browser, use::++ em++ -s ALLOW_MEMORY_GROWTH=1 -s DISABLE_EXCEPTION_CATCHING=0 -s WASM=1 \+ --preload-file src/tests/data botan-test.bc -o botan-test.html++Supporting Older Distros+--------------------------++Some "stable" distributions, notably RHEL/CentOS, ship very obsolete+versions of binutils, which do not support more recent CPU instructions.+As a result when building you may receive errors like::++ Error: no such instruction: `sha256rnds2 %xmm0,%xmm4,%xmm3'++Depending on how old your binutils is, you may need to disable BMI2,+AVX2, SHA-NI, and/or RDSEED. These can be disabled by passing the+flags ``--disable-bmi2``, ``--disable-avx2``, ``--disable-sha-ni``,+and ``--disable-rdseed`` to ``configure.py``.++Other Build-Related Tasks+----------------------------------------++.. _building_docs:++Building The Documentation+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++There are two documentation options available, Sphinx and Doxygen.+Sphinx will be used if ``sphinx-build`` is detected in the PATH, or if+``--with-sphinx`` is used at configure time. Doxygen is only enabled+if ``--with-doxygen`` is used. Both are generated by the makefile+target ``docs``.+++.. _amalgamation:++The Amalgamation Build+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++You can also configure Botan to be built using only a single source file; this+is quite convenient if you plan to embed the library into another application.++To generate the amalgamation, run ``configure.py`` with whatever options you+would ordinarily use, along with the option ``--amalgamation``. This will create+two (rather large) files, ``botan_all.h`` and ``botan_all.cpp``.++.. note::++ The library will as usual be configured to target some specific operating+ system and CPU architecture. You can use the CPU target "generic" if you need+ to target multiple CPU architectures, but this has the effect of disabling+ *all* CPU specific features such as SIMD, AES instruction sets, or inline+ assembly. If you need to ship amalgamations for multiple targets, it would be+ better to create different amalgamation files for each individual target.++Whenever you would have included a botan header, you can then include+``botan_all.h``, and include ``botan_all.cpp`` along with the rest of the source+files in your build. If you want to be able to easily switch between amalgamated+and non-amalgamated versions (for instance to take advantage of prepackaged+versions of botan on operating systems that support it), you can instead ignore+``botan_all.h`` and use the headers from ``build/include`` as normal.++You can also build the library using Botan's build system (as normal) but+utilizing the amalgamation instead of the individual source files by running+something like ``./configure.py --amalgamation && make``. This is essentially a+very simple form of link time optimization; because the entire library source is+visible to the compiler, it has more opportunities for interprocedural+optimizations. Additionally (assuming you are not making use of a compiler+cache such as ``ccache`` or ``sccache``) amalgamation builds usually have+significantly shorter compile times for full rebuilds.++Modules Relying on Third Party Libraries+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Currently ``configure.py`` cannot detect if external libraries are+available, so using them is controlled explicitly at build time+by the user using++ - ``--with-bzip2`` enables the filters providing bzip2 compression and+ decompression. Requires the bzip2 development libraries to be installed.++ - ``--with-zlib`` enables the filters providing zlib compression and+ decompression. Requires the zlib development libraries to be installed.++ - ``--with-lzma`` enables the filters providing lzma compression and+ decompression. Requires the lzma development libraries to be installed.++ - ``--with-sqlite3`` enables using sqlite3 databases in various contexts+ (TLS session cache, PSK database, etc).++ - ``--with-openssl`` adds an engine that uses OpenSSL for some ciphers, hashes,+ and public key operations. OpenSSL 1.0.2 or later is supported. LibreSSL can+ also be used.++ - ``--with-tpm`` adds support for using TPM hardware via the TrouSerS library.++ - ``--with-boost`` enables using some Boost libraries. In particular+ Boost.Filesystem is used for a few operations (but on most platforms, a+ native API equivalent is available), and Boost.Asio is used to provide a few+ extra TLS related command line utilities.++Multiple Builds+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++It may be useful to run multiple builds with different configurations.+Specify ``--with-build-dir=<dir>`` to set up a build environment in a+different directory.++Setting Distribution Info+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The build allows you to set some information about what distribution+this build of the library comes from. It is particularly relevant to+people packaging the library for wider distribution, to signify what+distribution this build is from. Applications can test this value by+checking the string value of the macro ``BOTAN_DISTRIBUTION_INFO``. It+can be set using the ``--distribution-info`` flag to ``configure.py``,+and otherwise defaults to "unspecified". For instance, a `Gentoo+<https://www.gentoo.org>`_ ebuild might set it with+``--distribution-info="Gentoo ${PVR}"`` where ``${PVR}`` is an ebuild+variable automatically set to a combination of the library and ebuild+versions.++Local Configuration Settings+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++You may want to do something peculiar with the configuration; to+support this there is a flag to ``configure.py`` called+``--with-local-config=<file>``. The contents of the file are+inserted into ``build/build.h`` which is (indirectly) included+into every Botan header and source file.++Enabling or Disabling Use of Certain OS Features+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Botan uses compile-time flags to enable or disable use of certain operating+specific functions. You can also override these at build time if desired.++The default feature flags are given in the files in ``src/build-data/os`` in the+``target_features`` block. For example Linux defines flags like ``proc_fs``,+``getauxval``, and ``sockets``. The ``configure.py`` option+``--list-os-features`` will display all the feature flags for all operating+system targets.++To disable a default-enabled flag, use ``--without-os-feature=feat1,feat2,...``++To enable a flag that isn't otherwise enabled, use ``--with-os-feature=feat``.+For example, modern Linux systems support the ``getentropy`` call, but it is not+enabled by default because many older systems lack it. However if you know you+will only deploy to recently updated systems you can use+``--with-os-feature=getentropy`` to enable it.++A special case if dynamic loading, which applications for certain environments+will want to disable. There is no specific feature flag for this, but+``--disable-modules=dyn_load`` will prevent it from being used.++.. note:: Disabling ``dyn_load`` module will also disable the PKCS #11+ wrapper, which relies on dynamic loading.++Configuration Parameters+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++There are some configuration parameters which you may want to tweak+before building the library. These can be found in ``build.h``. This+file is overwritten every time the configure script is run (and does+not exist until after you run the script for the first time).++Also included in ``build/build.h`` are macros which let applications+check which features are included in the current version of the+library. All of them begin with ``BOTAN_HAS_``. For example, if+``BOTAN_HAS_RSA`` is defined, then an application knows that this+version of the library has RSA available.++``BOTAN_MP_WORD_BITS``: This macro controls the size of the words used for+calculations with the MPI implementation in Botan. It must be set to either 32+or 64 bits. The default is chosen based on the target processor. There is+normally no reason to change this.++``BOTAN_DEFAULT_BUFFER_SIZE``: This constant is used as the size of+buffers throughout Botan. The default should be fine for most+purposes, reduce if you are very concerned about runtime memory usage.++Building Applications+----------------------------------------++Unix+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Botan usually links in several different system libraries (such as+``librt`` or ``libz``), depending on which modules are configured at+compile time. In many environments, particularly ones using static+libraries, an application has to link against the same libraries as+Botan for the linking step to succeed. But how does it figure out what+libraries it *is* linked against?++The answer is to ask the ``botan`` command line tool using+the ``config`` and ``version`` commands.++``botan version``: Print the Botan version number.++``botan config prefix``: If no argument, print the prefix where Botan is+installed (such as ``/opt`` or ``/usr/local``).++``botan config cflags``: Print options that should be passed to the+compiler whenever a C++ file is compiled. Typically this is used for+setting include paths.++``botan config libs``: Print options for which libraries to link to+(this will include a reference to the botan library itself).++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.++Windows+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++No special help exists for building applications on Windows. However,+given that typically Windows software is distributed as binaries, this+is less of a problem - only the developer needs to worry about it. As+long as they can remember where they installed Botan, they just have+to set the appropriate flags in their Makefile/project file.++Language Wrappers+----------------------------------------++Building the Python wrappers+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The Python wrappers for Botan use ctypes and the C89 API so no special+build step is required, just import botan2.py++See :doc:`Python Bindings <api_ref/python>` for more information about+the Python bindings.++.. _minimized_builds:++Minimized Builds+--------------------++Many developers wish to configure a minimized build which contains only the+specific features their application will use. In general this is straighforward:+use ``--minimized-build`` plus ``--enable-modules=`` to enable the specific modules+you wish to use. Any such configurations should build and pass the tests; if you+encounter a case where it doesn't please file an issue.++The only trick is knowing which features you want to enable. The most common+difficulty comes with entropy sources. By default, none are enabled, which means+if you attempt to use ``AutoSeeded_RNG``, it will fail. The easiest resolution+is to also enable ``system_rng`` which can act as either an entropy source or+used directly as the RNG.++If you are building for x86, ARM, or POWER, it can be beneficial to enable+hardware support for the relevant instruction sets with modules such as+``aes_ni`` and ``clmul`` for x86, or ``aes_armv8``, ``pmull``, and+``sha2_32_armv8`` on ARMv8. SIMD optimizations such as ``chacha_avx2`` also can+provide substantial performance improvements.++.. note::+ In a future release, hardware specific modules will be enabled by default if+ the underlying "base" module is enabled.++If you are building a TLS application, you may (or may not) want to include+``tls_cbc`` which enables support for CBC ciphersuites. If ``tls_cbc`` is+disabled, then it will not be possible to negotiate TLS v1.0/v1.1. In general+this should be considered a feature; only enable this if you need backward+compatability with obsolete clients or servers.++For TLS another useful feature which is not enabled by default is the+ChaCha20Poly1305 ciphersuites. To enable these, add ``chacha20poly1305``.+++Configure Script Options+---------------------------++``--cpu=CPU``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the target CPU architecture. If not used, the arch of the current+system is detected (using Python's platform module) and used.++``--os=OS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the target operating system.++``--cc=COMPILER``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the desired build compiler++``--cc-min-version=MAJOR.MINOR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the minimal version of the target+compiler. Use --cc-min-version=0.0 to support all compiler+versions. Default is auto detection.++``--cc-bin=BINARY``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set path to compiler binary++If not provided, the value of the ``CXX`` environment variable is used if set.++``--cc-abi-flags=FLAGS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set ABI flags, which for the purposes of this option mean options+which should be passed to both the compiler and linker.++``--cxxflags=FLAGS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Override all compiler flags. This is equivalent to setting ``CXXFLAGS``+in the environment.++``--extra-cxxflags=FLAGS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set extra compiler flags, which are appended to the default set. This+is useful if you want to set just one or two additional options but+leave the normal logic for selecting flags alone.++``--ldflags=FLAGS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set flags to pass to the linker. This is equivalent to setting ``LDFLAGS``++``--ar-command=AR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the path to the tool to use to create static archives (``ar``).+This is normally only used for cross-compilation.++If not provided, the value of the ``AR`` environment variable is used if set.++``--ar-options=AR_OPTIONS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Specify the options to pass to ``ar``.++If not provided, the value of the ``AR_OPTIONS`` environment variable is used if set.++``--msvc-runtime=RT``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Specify the MSVC runtime to use (MT, MD, MTd, or MDd). If not specified,+picks either MD or MDd depending on if debug mode is set.++``--with-endian=ORDER``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The parameter should be either "little" or "big". If not used then if+the target architecture has a default, that is used. Otherwise left+unspecified, which causes less optimal codepaths to be used but will+work on either little or big endian.++``--with-os-features=FEAT``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Specify an OS feature to enable. See ``src/build-data/os`` and+``doc/os.rst`` for more information.++``--without-os-features=FEAT``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Specify an OS feature to disable.++``--disable-sse2``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of SSE2 intrinsics++``--disable-ssse3``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of SSSE3 intrinsics++``--disable-sse4.1``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of SSE4.1 intrinsics++``--disable-sse4.2``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of SSE4.2 intrinsics++``--disable-avx2``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of AVX2 intrinsics++``--disable-bmi2``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of BMI2 intrinsics++``--disable-rdrand``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of RDRAND intrinsics++``--disable-rdseed``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of RDSEED intrinsics++``--disable-aes-ni``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of AES-NI intrinsics++``--disable-sha-ni``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of SHA-NI intrinsics++``--disable-altivec``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of AltiVec intrinsics++``--disable-neon``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of NEON intrinsics++``--disable-armv8crypto``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of ARMv8 Crypto intrinsics++``--disable-powercrypto``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable use of POWER Crypto intrinsics++``--with-debug-info``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Include debug symbols.++``--with-sanitizers``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable some default set of sanitizer checks. What exactly is enabled+depends on the compiler.++``--enable-sanitizers=SAN``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable specific sanitizers. See ``src/build-data/cc`` for more information.++``--without-stack-protector``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable stack smashing protections. **not recommended**++``--with-coverage``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Add coverage info and disable optimizations++``--with-coverage-info``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Add coverage info, but leave optimizations alone++``--disable-shared-library``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable building a shared library++``--disable-static-library``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable building static library++``--optimize-for-size``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Optimize for code size.++``--no-optimizations``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable all optimizations for debugging.++``--debug-mode``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable debug info and disable optimizations++``--amalgamation``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use amalgamation to build++``--system-cert-bundle=PATH``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set a path to a file containing one or more trusted CA certificates in+PEM format. If not given, some default locations are checked.++``--with-build-dir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Setup the build in a specified directory instead of ``./build``++``--with-external-includedir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Search for includes in this directory. Provide this parameter multiple times to+define multiple additional include directories.++``--with-external-libdir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Add DIR to the link path. Provide this parameter multiple times to define+multiple additional library link directories.++``--define-build-macro``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set a compile-time pre-processor definition (i.e. add a -D... to the compiler+invocations). Provide this parameter multiple times to add multiple compile-time+definitions. Both KEY=VALUE and KEY (without specific value) are supported.++``--with-sysroot-dir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use specified dir for system root while cross-compiling++``--with-openmp``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable use of OpenMP++``--link-method=METHOD``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++During build setup a directory linking to each header file is created.+Choose how the links are performed (options are "symlink", "hardlink",+or "copy").++``--with-local-config=FILE``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Include the contents of FILE into the generated build.h++``--distribution-info=STRING``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set distribution specific version information++``--maintainer-mode``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A build configuration used by library developers, which enables extra+warnings and turns most warnings into errors.++.. warning::++ When this option is used, all relevant warnings available in the+ most recent release of GCC/Clang are enabled, so it may fail to+ build if your compiler is not sufficiently recent. In addition+ there may be non-default configurations or unusual platforms which+ cause warnings which are converted to errors. Patches addressing+ such warnings are welcome, but otherwise no support is available+ when using this option.++``--werror-mode``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Turns most warnings into errors.++``--no-install-python-module``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Skip installing Python module.++``--with-python-versions=N.M``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Where to install botan2.py. By default this is chosen to be the+version of Python that is running ``configure.py``.++``--with-valgrind``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use valgrind API to perform additional checks. Not needed by end users.++``--unsafe-fuzzer-mode``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable essential checks for testing. **UNSAFE FOR PRODUCTION**++``--build-fuzzers=TYPE``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Select which interface the fuzzer uses. Options are "afl",+"libfuzzer", "klee", or "test". The "test" mode builds fuzzers that+read one input from stdin and then exit.++``--with-fuzzer-lib=LIB``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Specify an additional library that fuzzer binaries must link with.++``--build-targets=BUILD_TARGETS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Build only the specific targets and tools+(``static``, ``shared``, ``cli``, ``tests``, ``bogo_shim``).++``--boost-library-name``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Provide an alternative name for a boost library. Depending on the platform and+boost's build configuration these library names differ significantly (see `Boost docs+<https://www.boost.org/doc/libs/1_70_0/more/getting_started/unix-variants.html#library-naming>`_).+The provided library name must be suitable as identifier in a linker parameter,+e.g on unix: ``boost_system`` or windows: ``libboost_regex-vc71-x86-1_70``.++``--without-documentation``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Skip building/installing documentation++``--with-sphinx``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use Sphinx to generate the handbook++``--with-pdf``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use Sphinx to generate PDF doc++``--with-rst2man``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use rst2man to generate a man page for the CLI++``--with-doxygen``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use Doxygen to generate API reference++``--module-policy=POL``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The option ``--module-policy=POL`` enables modules required by and+disables modules prohibited by a text policy in ``src/build-data/policy``.+Additional modules can be enabled if not prohibited by the policy.+Currently available policies include ``bsi``, ``nist`` and ``modern``::++ $ ./configure.py --module-policy=bsi --enable-modules=tls,xts++``--enable-modules=MODS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable some specific modules++``--disable-modules=MODS``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Disable some specific modules++``--minimized-build``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Start with the bare minimum. This is mostly useful in conjuction with+``--enable-modules`` to get a build that has just the features a+particular application requires.++``--with-boost``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Use Boost.Asio for networking support. This primarily affects the+command line utils.++``--with-bzip2``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable bzip2 compression++``--with-lzma``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable lzma compression++``--with-zlib``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable using zlib compression++``--with-openssl``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable using OpenSSL for certain operations++``--with-commoncrypto``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable using CommonCrypto for certain operations++``--with-sqlite3``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable using sqlite3 for data storage++``--with-tpm``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Enable support for TPM++``--program-suffix=SUFFIX``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A string to append to all program binaries.++``--library-suffix=SUFFIX``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++A string to append to all library names.++``--prefix=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the install prefix.++``--docdir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the documentation installation dir.++``--bindir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the binary installation dir.++``--libdir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the library installation dir.++``--mandir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the man page installation dir.++``--includedir=DIR``+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Set the include file installation dir.
+ third_party/botan/doc/cli.rst view
@@ -0,0 +1,406 @@+Command Line Interface+========================================+.. highlight:: sh++Outline+------------++The ``botan`` program is a command line tool for using a broad variety+of functions of the Botan library in the shell.++All commands follow the syntax ``botan <command> <command-options>``.++If ``botan`` is run with an unknown command, or without any command, or with the+``--help`` option, all available commands will be printed. If a particular+command is run with the ``--help`` option (like ``botan <command> --help``)+some information about the usage of the command is printed.++Starting in version 2.9, commands that take a passphrase (such as+``gen_bcrypt`` or ``pkcs8``) will also accept the literal ``-`` to mean+ask for the passphrase on the terminal. If supported by the operating+system, echo will be disabled while reading the passphrase.++Most arguments that take a path to a file will also accept the literal ``-``+to mean the file content should be read from STDIN instead.++Hash Function+----------------+``hash --algo=SHA-256 --buf-size=4096 --no-fsname --format=hex *files``+ Compute the *algo* digest over the data in any number of *files*. If+ no files are listed on the command line, the input source defaults+ to standard input. Unless the ``--no-fsname`` option is given, the+ filename is printed alongside the hash, in the style of tools such+ as ``sha256sum``.++Password Hash+----------------+``gen_argon2 --mem=65536 --p=1 --t=1 password``+ Calculate the Argon2 password digest of *password*. *mem* is the amount of+ memory to use in Kb, *p* the parallelization parameter and *t* the number of+ iterations to use.++``check_argon2 password hash``+ Checks if the Argon2 hash of the passed *password* equals the passed *hash* value.++``gen_bcrypt --work-factor=12 password``+ Calculate the bcrypt password digest of *password*. *work-factor* is an+ integer between 4 and 18. A higher *work-factor* value results in a+ more expensive hash calculation.++``check_bcrypt password hash``+ Checks if the bcrypt hash of the passed *password* equals the passed *hash* value.++``pbkdf_tune --algo=Scrypt --max-mem=256 --output-len=32 --check *times``+ Tunes the PBKDF algorithm specified with ``--algo=`` for the given *times*.++HMAC+----------------+``hmac --hash=SHA-256 --buf-size=4096 --no-fsname key files``+ Compute the HMAC tag with the cryptographic hash function *hash*+ using the key in file *key* over the data in *files*. *files*+ defaults to STDIN. Unless the ``--no-fsname`` option is given, the+ filename is printed alongside the HMAC value.++Encryption+----------------+``encryption --buf-size=4096 --decrypt --mode= --key= --iv= --ad=``+ Encrypt a given file with the specified *mode*. If ``--decrypt`` is provided+ the file is decrypted instead.++Public Key Cryptography+-------------------------------------+``keygen --algo=RSA --params= --passphrase= --pbe= --pbe-millis=300 --provider= --der-out``+ Generate a PKCS #8 *algo* private key. If *der-out* is passed, the pair is BER+ encoded. Otherwise, PEM encoding is used. To protect the PKCS #8 formatted+ key, it is recommended to encrypt it with a provided *passphrase*. *pbe* is+ the name of the desired encryption algorithm, which uses *pbe-millis*+ milliseconds to derive the encryption key from the passed+ *passphrase*. Algorithm specific parameters, as the desired bit length of an+ RSA key, can be passed with *params*.++ - For RSA *params* specifies the bit length of the RSA modulus. It defaults to 3072.+ - For DH *params* specifies the DH parameters. It defaults to modp/ietf/2048.+ - For DSA *params* specifies the DSA parameters. It defaults to dsa/botan/2048.+ - For EC algorithms *params* specifies the elliptic curve. It defaults to secp256r1.++ The default *pbe* algorithm is "PBES2(AES-256/CBC,SHA-256)".++ With PBES2 scheme, you can select any CBC or GCM mode cipher which has an OID+ defined (such as 3DES, Camellia, SM4, Twofish or Serpent). However most other+ implementations support only AES or 3DES in CBC mode. You can also choose+ Scrypt instead of PBKDF2, by using "Scrypt" instead of the name of a hash+ function, for example "PBES2(AES-256/CBC,Scrypt)". Scrypt is also supported by+ some other implementations including OpenSSL.++``pkcs8 --pass-in= --pub-out --der-out --pass-out= --pbe= --pbe-millis=300 key``+ Open a PKCS #8 formatted key at *key*. If *key* is encrypted, the passphrase+ must be passed as *pass-in*. It is possible to (re)encrypt the read key with+ the passphrase passed as *pass-out*. The parameters *pbe-millis* and *pbe*+ work similarly to ``keygen``.++``sign --der-format --passphrase= --hash=SHA-256 --emsa= --provider= key file``+ Sign the data in *file* using the PKCS #8 private key *key*. If *key* is+ encrypted, the used passphrase must be passed as *pass-in*. *emsa* specifies+ the signature scheme and *hash* the cryptographic hash function used in the+ scheme.++ - For RSA signatures EMSA4 (RSA-PSS) is the default scheme.+ - For ECDSA and DSA *emsa* defaults to EMSA1 (signing the hash directly)++ For ECDSA and DSA, the option ``--der-format`` outputs the signature as an+ ASN.1 encoded blob. Some other tools (including ``openssl``) default to this+ format.++ The signature is formatted for your screen using base64.++``verify --der-format --hash=SHA-256 --emsa= pubkey file signature``+ Verify the authenticity of the data in *file* with the provided signature+ *signature* and the public key *pubkey*. Similarly to the signing process,+ *emsa* specifies the signature scheme and *hash* the cryptographic hash+ function used in the scheme.++``gen_dl_group --pbits=1024 --qbits=0 --seed= --type=subgroup``+ Generate ANSI X9.42 encoded Diffie-Hellman group parameters.++ - If *type=subgroup* is passed, the size of the prime subgroup q is sampled+ as a prime of *qbits* length and p is *pbits* long. If *qbits* is not+ passed, its length is estimated from *pbits* as described in RFC 3766.+ - If *type=strong* is passed, p is sampled as a safe prime with length+ *pbits* and the prime subgroup has size q with *pbits*-1 length.+ - If *type=dsa* is used, p and q are generated by the algorithm specified in+ FIPS 186-4. If the ``--seed`` parameter is used, it allows to select the+ seed value, instead of one being randomly generated. If the seed does not+ in fact generate a valid DSA group, the command will fail.++``dl_group_info --pem name``+ Print raw Diffie-Hellman parameters (p,g) of the standardized DH group+ *name*. If *pem* is set, the X9.42 encoded group is printed.++``ec_group_info --pem name``+ Print raw elliptic curve domain parameters of the standardized curve *name*. If+ *pem* is set, the encoded domain is printed.++``pk_encrypt --aead=AES-256/GCM rsa_pubkey datafile``+ Encrypts ``datafile`` using the specified AEAD algorithm, under a key protected+ by the specified RSA public key.++``pk_decrypt rsa_privkey datafile``+ Decrypts a file encrypted with ``pk_encrypt``. If the key is encrypted using a+ password, it will be prompted for on the terminal.++``fingerprint --no-fsname --algo=SHA-256 *keys``+ Calculate the public key fingerprint of the *keys*.++``pk_workfactor --type=rsa bits``+ Provide an estimate of the strength of a public key based on it's size.+ ``--type=`` can be "rsa", "dl" or "dl_exp".++X.509+----------------------------------------------++``gen_pkcs10 key CN --country= --organization= --ca --path-limit=1 --email= --dns= --ext-ku= --key-pass= --hash=SHA-256 --emsa=``+ Generate a PKCS #10 certificate signing request (CSR) using the passed PKCS #8+ private key *key*. If the private key is encrypted, the decryption passphrase+ *key-pass* has to be passed.*emsa* specifies the padding scheme to be used+ when calculating the signature.++ - For RSA keys EMSA4 (RSA-PSS) is the default scheme.+ - For ECDSA, DSA, ECGDSA, ECKCDSA and GOST-34.10 keys *emsa* defaults to EMSA1.++``gen_self_signed key CN --country= --dns= --organization= --email= --path-limit=1 --days=365 --key-pass= --ca --hash=SHA-256 --emsa= --der``+ Generate a self signed X.509 certificate using the PKCS #8 private key+ *key*. If the private key is encrypted, the decryption passphrase *key-pass*+ has to be passed. If *ca* is passed, the certificate is marked for certificate+ authority (CA) usage. *emsa* specifies the padding scheme to be used when+ calculating the signature.++ - For RSA keys EMSA4 (RSA-PSS) is the default scheme.+ - For ECDSA, DSA, ECGDSA, ECKCDSA and GOST-34.10 keys *emsa* defaults to EMSA1.++``sign_cert --ca-key-pass= --hash=SHA-256 --duration=365 --emsa= ca_cert ca_key pkcs10_req``+ Create a CA signed X.509 certificate from the information contained in the+ PKCS #10 CSR *pkcs10_req*. The CA certificate is passed as *ca_cert* and the+ respective PKCS #8 private key as *ca_key*. If the private key is encrypted,+ the decryption passphrase *ca-key-pass* has to be passed. The created+ certificate has a validity period of *duration* days. *emsa* specifies the+ padding scheme to be used when calculating the signature. *emsa* defaults to+ the padding scheme used in the CA certificate.++``ocsp_check --timeout=3000 subject issuer``+ Verify an X.509 certificate against the issuers OCSP responder. Pass the+ certificate to validate as *subject* and the CA certificate as *issuer*.++``cert_info --fingerprint file``+ Parse X.509 PEM certificate and display data fields. If ``--fingerprint`` is+ used, the certificate's fingerprint is also printed.++``cert_verify subject *ca_certs``+ Verify if the provided X.509 certificate *subject* can be successfully+ validated. The list of trusted CA certificates is passed with *ca_certs*,+ which is a list of one or more certificates.++``trust_roots --dn --dn-only --display``+ List the certificates in the system trust store.++TLS Server/Client+-----------------------++The ``--policy=`` argument of the TLS commands specifies the TLS policy to use.+The policy can be any of the the strings "default", "suiteb_128", "suiteb_192",+"bsi", "strict", or "all" to denote built-in policies, or it can name a file+from which a policy description will be read.++``tls_ciphers --policy=default --version=tls1.2``+ Prints the list of ciphersuites that will be offered under a particular+ policy/version.++``tls_client host --port=443 --print-certs --policy=default --tls1.0 --tls1.1 --tls1.2 --skip-system-cert-store --trusted-cas= --session-db= --session-db-pass= --next-protocols= --type=tcp``+ Implements a testing TLS client, which connects to *host* via TCP or UDP on+ port *port*. The TLS version can be set with the flags *tls1.0*, *tls1.1* and+ *tls1.2* of which the lowest specified version is automatically chosen. If+ none of the TLS version flags is set, the latest supported version is+ chosen. The client honors the TLS policy specified with *policy* and+ prints all certificates in the chain, if *print-certs* is passed.+ *next-protocols* is a comma separated list and specifies the protocols to+ advertise with Application-Layer Protocol Negotiation (ALPN).++``tls_server cert key --port=443 --type=tcp --policy=default --dump-traces= --max-clients=0 --socket-id=0``+ Implements a testing TLS server, which allows TLS clients to connect and which+ echos any data that is sent to it. Binds to either TCP or UDP on port+ *port*. The server uses the certificate *cert* and the respective PKCS #8+ private key *key*. The server honors the TLS policy specified with *policy*.+ *socket-id* is only available on FreeBSD and sets the *so_user_cookie* value+ of the used socket.++``tls_http_server cert key --port=443 --policy=default --threads=0 --max-clients=0 --session-db --session-db-pass=``+ Only available if Boost.Asio support was enabled. Provides a simple HTTP server+ which replies to all requests with an informational text output. The server+ honors the TLS policy specified with *policy*.++``tls_proxy listen_port target_host target_port server_cert server_key--policy=default --threads=0 --max-clients=0 --session-db= --session-db-pass=``+ Only available if Boost.Asio support was enabled. Listens on a port and+ forwards all connects to a target server specified at+ ``target_host`` and ``target_port``.++``tls_client_hello --hex input``+ Parse and print a TLS client hello message.++Number Theory+-----------------------+``is_prime --prob=56 n``+ Test if the integer *n* is composite or prime with a Miller-Rabin primality test with *(prob+2)/2* iterations.++``factor n``+ Factor the integer *n* using a combination of trial division by small primes, and Pollard's Rho algorithm.+ It can in reasonable time factor integers up to 110 bits or so.++``gen_prime --count=1 bits``+ Samples *count* primes with a length of *bits* bits.++``mod_inverse n mod``+ Calculates a modular inverse.++PSK Database+--------------------++The PSK database commands are only available if sqlite3 support was compiled in.++``psk_set db db_key name psk``+ Using the PSK database named db and encrypting under the (hex) key ``db_key``,+ save the provided psk (also hex) under ``name``::++ $ botan psk_set psk.db deadba55 bunny f00fee++``psk_get db db_key name``+ Get back a value saved with ``psk_set``::++ $ botan psk_get psk.db deadba55 bunny+ f00fee++``psk_list db db_key``+ List all values saved to the database under the given key::++ $ botan psk_list psk.db deadba55+ bunny++Secret Sharing+------------------++Split a file into several shares.++``tss_split M N data_file --id= --share-prefix=share --share-suffix=tss --hash=SHA-256``+ Split a file into ``N`` pieces any ``M`` of which suffices to+ recover the original input. The ID allows specifying a unique key ID+ which may be up to 16 bytes long, this ensures that shares can be+ uniquely matched. If not specified a random 16 byte value is+ used. A checksum can be appended to the data to help verify correct+ recovery, this can be disabled using ``--hash=None``.++``tss_recover *shares``+ Recover some data split by ``tss_split``. If insufficient number of+ shares are provided an error is printed.++Data Encoding/Decoding+------------------------++``base32_dec file``+ Encode *file* to Base32.++``base32_enc file``+ Decode Base32 encoded *file*.++``base58_enc --check file``+ Encode *file* to Base58. If ``--check`` is provided Base58Check is used.++``base58_dec --check file``+ Decode Base58 encoded *file*. If ``--check`` is provided Base58Check is used.++``base64_dec file``+ Encode *file* to Base64.++``base64_enc file``+ Decode Base64 encoded *file*.++``hex_dec file``+ Encode *file* to Hex.++``hex_enc file``+ Decode Hex encoded *file*.++Miscellaneous Commands+-------------------------------------+``version --full``+ Print the version number. If option ``--full`` is provided,+ additional details are printed.++``has_command cmd``+ Test if the command *cmd* is available.++``config info_type``+ Prints build information, useful for applications which want to+ build against the library. The ``info_type`` argument can be any of+ ``prefix``, ``cflags``, ``ldflags``, or ``libs``. This is+ similar to information provided by the ``pkg-config`` tool.++``cpuid``+ List available processor flags (AES-NI, SIMD extensions, ...).++``cpu_clock --test-duration=500``+ Estimate the speed of the CPU cycle counter.++``asn1print --skip-context-specific --print-limit=4096 --bin-limit=2048 --max-depth=64 --pem file```+ Decode and print *file* with ASN.1 Basic Encoding Rules (BER). If flag ``--pem`` is+ used, or the filename ends in ``.pem``, then PEM encoding is assumed. Otherwise+ the input is assumed to be binary DER/BER.++``http_get --redirects=1 --timeout=3000 url``+ Retrieve resource from the passed http *url*.++``speed --msec=500 --format=default --ecc-groups= --provider= --buf-size=1024 --clear-cpuid= --cpu-clock-speed=0 --cpu-clock-ratio=1.0 *algos``+ Measures the speed of the passed *algos*. If no *algos* are passed all+ available speed tests are executed. *msec* (in milliseconds) sets the period+ of measurement for each algorithm. The *buf-size* option allows testing the+ same algorithm on one or more input sizes, for example+ ``speed --buf-size=136,1500 AES-128/GCM`` tests the performance of GCM for+ small and large packet sizes.+ *format* can be "default", "table" or "json".++``timing_test test_type --test-data-file= --test-data-dir=src/tests/data/timing --warmup-runs=1000 --measurement-runs=10000``+ Run various timing side channel tests.++``rng --format=hex --system --rdrand --auto --entropy --drbg --drbg-seed= *bytes``+ Sample *bytes* random bytes from the specified random number generator. If+ *system* is set, the system RNG is used. If *rdrand* is set, the hardware+ RDRAND instruction is used. If *auto* is set, AutoSeeded_RNG is used, seeded+ with the system RNG if available or the global entropy source otherwise. If+ *entropy* is set, AutoSeeded_RNG is used, seeded with the global entropy+ source. If *drbg* is set, HMAC_DRBG is used seeded with *drbg-seed*.++``entropy --truncate-at=128 source``+ Sample a raw entropy source.++``cc_encrypt CC passphrase --tweak=``+ Encrypt the passed valid credit card number *CC* using FPE encryption and the+ passphrase *passphrase*. The key is derived from the passphrase using PBKDF2+ with SHA256. Due to the nature of FPE, the ciphertext is also a credit card+ number with a valid checksum. *tweak* is public and parameterizes the+ encryption function.++``cc_decrypt CC passphrase --tweak=``+ Decrypt the passed valid ciphertext *CC* using FPE decryption with+ the passphrase *passphrase* and the tweak *tweak*.++``roughtime_check --raw-time chain-file``+ Parse and validate a Roughtime chain file.++``roughtime --raw-time --chain-file=roughtime-chain --max-chain-size=128 --check-local-clock=60 --host= --pubkey= --servers-file=``+ Retrieve time from a Roughtime server and store it in a chain file.++``uuid``+ Generate and print a random UUID.++``compress --type=gzip --level=6 --buf-size=8192 file``+ Compress a given file.++``decompress --buf-size=8192 file``+ Decompress a given compressed archive.
+ third_party/botan/doc/contents.rst view
@@ -0,0 +1,25 @@++Contents+========================================++.. toctree::++ index+ goals+ support+ building+ api_ref/contents+ cli+ deprecated+ roadmap+ credits+ abi+ packaging+ security+ side_channels+ dev_ref/contents++.. toctree::+ :hidden:++ old_news
+ third_party/botan/doc/credits.rst view
@@ -0,0 +1,156 @@++Credits+========================================++This is at least a partial credits-file of people that have contributed+to botan. It is sorted by name and formatted to allow easy grepping+and beautification by scripts. The fields are name (N), email (E),+web-address (W), PGP key ID and fingerprint (P), description (D),+snail-mail address (S), and Bitcoin address (B).++.. highlight:: none++::++ N: Alexander Bluhm+ W: https://www.genua.de/+ P: 1E3B BEA4 6C20 EA00 2FFC DE4D C5F4 83AD DEE8 6380+ D: improve support for OpenBSD+ S: Kirchheim, Germany++ N: Charles Brockman+ W: http://www.securitygenetics.com/+ D: documentation editing+ S: Oregon, USA++ N: Simon Cogliani+ E: simon.cogliani@tanker.io+ W: https://www.tanker.io/+ P: EA73 D0AF 5A81 A61A 8931 C2CA C9AB F2E4 3820 4F25+ D: Getting keystream of ChaCha+ S: Paris, France++ N: Martin Doering+ E: doering@cdc.informatik.tu-darmstadt.de+ D: GF(p) arithmetic++ N: Olivier de Gaalon+ D: SQLite encryption codec (src/contrib/sqlite)++ N: Matthias Gierlings+ E: matthias.gierlings@hackmanit.de+ W: https://www.hackmanit.de/+ P: 39E0 D270 19A4 B356 05D0 29AE 1BD3 49CF 744A 02FF+ D: GMAC, Extended Hash-Based Signatures (XMSS)+ S: Bochum, Germany++ N: Matthew Gregan+ D: Binary file I/O support, allocator fixes++ N: Hany Greiss+ D: Windows porting++ N: Manuel Hartl+ E: hartl@flexsecure.de+ W: http://www.flexsecure.de/+ D: ECDSA, ECDH++ N: Yves Jerschow+ E: yves.jerschow@uni-duesseldorf.de+ D: Optimizations for memory load/store and HMAC+ D: Support for IPv4 addresses in X.509 alternative names+ S: Germany++ N: Matt Johnston+ D: Allocator fixes and optimizations, decompressor fixes++ N: Peter J. Jones+ E: pjones@pmade.org+ D: Bzip2 compression module+ S: Colorado, USA++ N: Justin Karneges+ D: Qt support modules (mutexes and types), X.509 API design++ N: Vojtech Kral+ E: vojtech@kral.hk+ D: LZMA compression module+ S: Czech Republic++ N: Matej Kenda+ E: matej.kenda@topit.si+ D: Locking in Algo_Registry for Windows OS+ S: Slovenia++ N: René Korthaus+ E: r.korthaus@sirrix.com+ W: https://www.sirrix.com+ P: C196 FF9D 3DDC A5E7 F98C E745 9AD0 F9FA 587E 74D6+ D: CI, ECGDSA, ECKCDSA+ S: Bochum, Germany++ N: Adam Langley+ E: agl@imperialviolet.org+ D: Curve25519++ N: Jack Lloyd+ E: jack@randombit.net+ W: https://www.randombit.net/+ P: 3F69 2E64 6D92 3BBE E7AE 9258 5C0F 96E8 4EC1 6D6B+ B: 1DwxWb2J4vuX4vjsbzaCXW696rZfeamahz+ D: Original designer/author, maintainer 2001-current+ S: Vermont, USA++ N: Joel Low+ D: DLL symbol visibility and Windows DLL support in general+ D: Threaded_Fork++ N: Christoph Ludwig+ E: ludwig@fh-worms.de+ D: GP(p) arithmetic++ N: Vaclav Ovsik+ E: vaclav.ovsik@i.cz+ D: Perl XS module (src/contrib/perl-xs)++ N: Luca Piccarreta+ E: luca.piccarreta@gmail.com+ D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module+ S: Italy++ N: Daniel Seither+ E: post@tiwoc.de+ D: iOS support, improved Android support, improved MSVC support++ N: Falko Strenzke+ E: fstrenzke@cryptosource.de+ W: http://www.cryptosource.de+ D: McEliece, GF(p) arithmetic, CVC, Shanks-Tonelli algorithm+ S: Darmstadt, Germany++ N: Simon Warta+ E: simon@kullo.net+ W: https://www.kullo.net+ D: Build system+ S: Germany++ N: Philipp Weber+ E: p.weber@sirrix.com+ W: https://sirrix.com/+ D: KDF1-18033, ECIES+ S: Saarland, Germany++ N: Daniel Neus+ E: d.neus@sirrix.com+ W: https://sirrix.com/+ D: CI, PKCS#11, RdSeed, BSI module policy+ S: Bochum, Germany++ N: Erwan Chaussy+ D: Base32, Base64 matching Base32 implementation+ S: France++ N: Daniel Wyatt (on behalf of Ribose Inc)+ E: daniel.wyatt@ribose.com+ W: https://www.ribose.com/+ D: SM3, Streebog, various minor contributions
+ third_party/botan/doc/deprecated.rst view
@@ -0,0 +1,297 @@+Deprecated Features+========================++Certain functionality is deprecated and is likely to be removed in+a future major release.++To help warn users, macros are used to annotate deprecated functions+and headers. These warnings are enabled by default, but can be+disabled by defining the macro ``BOTAN_NO_DEPRECATED_WARNINGS`` prior+to including any Botan headers.++.. warning::+ Not all of the functionality which is currently deprecated has an+ associated warning.++If you are using something which is currently deprecated and there+doesn't seem to be an obvious alternative, contact the developers to+explain your use case if you want to make sure your code continues to+work.++TLS Protocol Deprecations+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The following TLS protocol features are deprecated and will be removed+in a future major release:++- Support for TLSv1.0/v1.1 and DTLS v1.0++- All support for DSA ciphersuites/certificates++- Support for point compression in TLS. This is supported in v1.2 but+ removed in v1.3. For simplicity it will be removed in v1.2 also.++- Support for using SHA-1 to sign TLS v1.2 ServerKeyExchange.++- All CBC mode ciphersuites. This includes all available 3DES and SEED+ ciphersuites. This implies also removing Encrypt-then-MAC extension.++- All ciphersuites using DH key exchange (DHE-DSS, DHE-RSA, DHE-PSK, anon DH)++- Support for renegotiation in TLS v1.2++- All ciphersuites using static RSA key exchange++- All anonymous (DH/ECDH) ciphersuites. This does not include PSK and+ ECDHE-PSK, which will be retained.++- SRP ciphersuites. This is implied by the removal of CBC mode, since+ all available SRP ciphersuites use CBC. To avoid use of obsolete+ ciphers, it would be better to instead perform a standard TLS+ negotiation, then a PAKE authentication within (and bound to) the+ TLS channel.++- OCB ciphersuites using 128-bit keys++Deprecated Functionality+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++This section lists cryptographic functionality which will be removed+in a future major release.++- Block ciphers CAST-256, GOST 28147, Kasumi, MISTY1, DESX, and XTEA.++- Hash functions GOST 34.11-94 and Tiger++- DLIES++- MCEIES++- CBC-MAC++- PBKDF1 key derivation++- GCM support for 64-bit tags++- Weak or rarely used ECC builtin groups including "secp160k1", "secp160r1",+ "secp160r2", "secp192k1", "secp224k1",+ "brainpool160r1", "brainpool192r1", "brainpool224r1", "brainpool320r1",+ "x962_p192v2", "x962_p192v3", "x962_p239v1", "x962_p239v2", "x962_p239v3".++- All built in MODP groups < 2048 bits++- Support for explicit ECC curve parameters and ImplicitCA encoded parameters in+ EC_Group and all users (including X.509 certificates and PKCS#8 private keys).++- All pre-created DSA groups++- All support for loading, generating or using RSA keys with a public+ exponent larger than 2**64-1++- All or nothing package transform (``package.h``)+++Deprecated Headers+^^^^^^^^^^^^^^^^^^^^^^++* The following headers and all functionality contained within them+ are outright deprecated, and will be removed entirely in a future+ major release. Most are either simply forwarding includes to another+ (still public) header, or contain functionality which is entirely+ deprecated. Consult the relevent file for more information.+ ``basefilt.h``, ``botan.h``, ``buf_filt.h``, ``cipher_filter.h``, ``comp_filter.h``,+ ``compiler.h``, ``init.h``, ``key_filt.h``, ``lookup.h``, ``sm2_enc.h``, ``threefish.h``,+ ``xmss_key_pair.h``++* The following headers have useful functionality but which we wish to+ hide from applications to allow easier library evolution. They will+ be made internal in a future major release, and will only be+ available to the library itself. In most cases, there is an+ alternative available. For example instead of using algorithm+ specific interfaces, use X::create to create the object dynamically.++ Block cipher headers (interact using BlockCipher interface):+ ``aes.h``,+ ``aria.h``,+ ``blowfish.h``,+ ``camellia.h``,+ ``cascade.h``,+ ``cast128.h``,+ ``cast256.h``,+ ``des.h``,+ ``desx.h``,+ ``gost_28147.h``,+ ``idea.h``,+ ``kasumi.h``,+ ``lion.h``,+ ``misty1.h``,+ ``noekeon.h``,+ ``seed.h``,+ ``serpent.h``,+ ``shacal2.h``,+ ``sm4.h``,+ ``threefish_512.h``,+ ``twofish.h``,+ ``xtea.h``,++ Hash function headers (interact using HashFunction interface):+ ``adler32.h``,+ ``blake2b.h``,+ ``comb4p.h``,+ ``crc24.h``,+ ``crc32.h``,+ ``gost_3411.h``,+ ``keccak.h``,+ ``md4.h``,+ ``md5.h``,+ ``par_hash.h``,+ ``rmd160.h``,+ ``sha160.h``,+ ``sha2_32.h``,+ ``sha2_64.h``,+ ``sha3.h``,+ ``shake.h``,+ ``skein_512.h``,+ ``sm3.h``,+ ``streebog.h``,+ ``tiger.h``,+ ``whrlpool.h``,++ MAC headers:+ ``cbc_mac.h``,+ ``cmac.h``,+ ``gmac.h``,+ ``hmac.h``,+ ``poly1305.h``,+ ``siphash.h``,+ ``x919_mac.h``,++ Stream cipher headers:+ ``chacha.h``,+ ``ctr.h``,+ ``ofb.h``,+ ``rc4.h``,+ ``salsa20.h``,++ Cipher mode headers:+ ``cbc.h``,+ ``ccm.h``,+ ``cfb.h``,+ ``chacha20poly1305.h``,+ ``eax.h``,+ ``gcm.h``,+ ``ocb.h``,+ ``shake_cipher.h``,+ ``siv.h``,+ ``xts.h``,++ KDF headers:+ ``hkdf.h``,+ ``kdf1.h``,+ ``kdf1_iso18033.h``,+ ``kdf2.h``,+ ``prf_tls.h``,+ ``prf_x942.h``,+ ``sp800_108.h``,+ ``sp800_56a.h``,+ ``sp800_56c.h``,++ PBKDF headers:+ ``bcrypt_pbkdf.h``,+ ``pbkdf1.h``,+ ``pbkdf2.h``,+ ``pgp_s2k.h``,+ ``scrypt.h``,++ Internal implementation headers - seemingly no reason for applications to use:+ ``blinding.h``,+ ``curve_gfp.h``,+ ``curve_nistp.h``,+ ``datastor.h``,+ ``divide.h``,+ ``eme.h``,+ ``eme_pkcs.h``,+ ``eme_raw.h``,+ ``emsa.h``,+ ``emsa1.h``,+ ``emsa_pkcs1.h``,+ ``emsa_raw.h``,+ ``emsa_x931.h``,+ ``gf2m_small_m.h``,+ ``ghash.h``,+ ``iso9796.h``,+ ``keypair.h``,+ ``mdx_hash.h``,+ ``mode_pad.h``,+ ``mul128.h``,+ ``oaep.h``,+ ``pbes2.h``,+ ``polyn_gf2m.h``,+ ``pow_mod.h``,+ ``pssr.h``,+ ``reducer.h``,+ ``rfc6979.h``,+ ``scan_name.h``,+ ``stream_mode.h``,+ ``tls_algos.h``,+ ``tls_magic.h``,+ ``xmss_common_ops.h``,+ ``xmss_hash.h``,+ ``xmss_index_registry.h``,+ ``xmss_tools.h``,++ Utility headers, nominally useful in applications but not a core part of+ the library API and most are just sufficient for what the library needs+ to implement other functionality.+ ``atomic.h``,+ ``bswap.h``,+ ``charset.h``,+ ``compiler.h``,+ ``cpuid.h``,+ ``http_util.h``,+ ``loadstor.h``,+ ``locking_allocator.h``,+ ``parsing.h``,+ ``rotate.h``,+ ``secqueue.h``,+ ``stl_compatibility.h``,+ ``uuid.h``,++Other API deprecations+^^^^^^^^^^^^^^^^^^^^^^^^^^^^++- Directly accessing the member variables of types ``calendar_point``,+ ``ASN1_Attribute``, ``AlgorithmIdentifier``, and ``BER_Object``++- Using a default output length for "SHAKE-128" and "SHAKE-256". Instead,+ always specify the desired output length.++- Currently, for certain KDFs, if KDF interface is invoked with a+ requested output length larger than supported by the KDF, it returns+ instead a truncated key. In a future major release, instead if KDF+ is called with a length larger than it supports an exception will be+ thrown.++- The TLS constructors taking ``std::function`` for callbacks. Instead+ use the ``TLS::Callbacks`` interface.++- Using ``X509_Certificate::subject_info`` and ``issuer_info`` to access any+ information that is not included in the DN or subject alternative name. Prefer+ using the specific assessor functions for other data, eg instead of+ ``cert.subject_info("X509.Certificate.serial")`` use ``cert.serial_number()``.++- The ``Buffered_Computation`` base class. In a future release the+ class will be removed, and all of member functions instead declared+ directly on ``MessageAuthenticationCode`` and ``HashFunction``. So+ this only affects you if you are directly referencing+ ``Botan::Buffered_Computation`` in some way.++Deprecated Build Targets+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++- Configuring a build (with ``configure.py``) using Python2. In a future+ major release, Python3 will be required.++- Platform support for Google Native Client++- Support for PathScale and HP compilers
+ third_party/botan/doc/dev_ref/configure.rst view
@@ -0,0 +1,407 @@+Understanding configure.py+============================++.. highlight:: none++Botan's build is handled with a custom Python script, ``configure.py``.+This document tries to explain how configure works.++.. note::+ You only need to read this if you are modifying the library,+ or debugging some problem with your build. For how to use it,+ see :ref:`building`.++Build Structure+--------------------++Modules are a group of related source and header files, which can be+individually enabled or disabled at build time. Modules can depend on+other modules; if a dependency is not available then the module itself+is also removed from the list. Examples of modules in the existing+codebase are ``asn1`` and ``x509``, Since ``x509`` depends on (among+other things) ``asn1``, disabling ``asn1`` will also disable ``x509``.++Most modules define one or more macros, which application code can use+to detect the modules presence or absence. The value of each macro is+a datestamp, in the form YYYYMMDD which indicates the last time this+module changed in a way that would be visible to an application. For+example if a class gains a new function, the datestamp should be+incremented. That allows applications to detect if the new feature is+available.++What ``configure.py`` does+-----------------------------++First, all command line options are parsed.++Then all of the files giving information about target CPUs, compilers,+etc are parsed and sanity checked.++In ``calculate_cc_min_version`` the compiler version is detected using+the preprocessor.++Then in ``check_compiler_arch`` the target architecture are detected, again+using the preprocessor.++Now that the target is identified and options have been parsed, the modules to+include into the artifact are picked, in ``ModulesChooser``.++In ``create_template_vars``, a dictionary of variables is created which describe+different aspects of the build. These are serialized to+``build/build_config.json``.++Up until this point no changes have been made on disk. This occurs in+``do_io_for_build``. Build output directories are created, and header files are+linked into ``build/include/botan``. Templates are processed to create the+Makefile, ``build.h`` and other artifacts.++When Modifying ``configure.py``+--------------------------------++For now, any changes to ``configure.py`` must work under both CPython 2.7 and+CPython 3.x. In a future major release, support for CPython2 will be dropped,+but until then if making modifications verify the code works as expected on+both versions.++Run ``./src/scripts/ci_build.py lint`` to run Pylint checks after any change.++Template Language+--------------------++Various output files are generated by processing input files using a simple+template language. All input files are stored in ``src/build-data`` and use the+suffix ``.in``. Anything not recognized as a template command is passed through+to the output unmodified. The template elements are:++ * Variable substitution, ``%{variable_name}``. The configure script creates+ many variables for various purposes, this allows getting their value within+ the output. If a variable is not defined, an error occurs.++ If a variable reference ends with ``|upper``, the value is uppercased before+ being inserted into the template output.++ * Iteration, ``%{for variable} block %{endfor}``. This iterates over a list and+ repeats the block as many times as it is included. Variables within the block+ are expanded. The two template elements ``%{for ...}`` and ``%{endfor}`` must+ appear on lines with no text before or after.++ * Conditional inclusion, ``%{if variable} block %{endif}``. If the variable+ named is defined and true (in the Python sense of the word; if the variable+ is empty or zero it is considered false), then the block will be included and+ any variables expanded. As with the for loop syntax, both the start and end+ of the conditional must be on their own lines with no additional text.++Adding a new module+--------------------++Create a directory in the appropriate place and create a info.txt file.++Syntax of ``info.txt``+------------------------++.. warning::++ The syntax described here is documented to make it easier to use+ and understand, but it is not considered part of the public API+ contract. That is, the developers are allowed to change the syntax+ at any time on the assumption that all users are contained within+ the library itself. If that happens this document will be updated.++Modules and files describing information about the system use the same+parser and have common syntactical elements.++Comments begin with '#' and continue to end of line.++There are three main types: maps, lists, and variables.++A map has a syntax like::++ <MAP_NAME>+ NAME1 -> VALUE1+ NAME2 -> VALUE2+ ...+ </MAP_NAME>++The interpretation of the names and values will depend on the map's name+and what type of file is being parsed.++A list has similar syntax, it just doesn't have values::++ <LIST_NAME>+ ELEM1+ ELEM2+ ...+ </LIST_NAME>++Lastly there are single value variables like::++ VAR1 SomeValue+ VAR2 "Quotes Can Be Used (And will be stripped out)"+ VAR3 42++Variables can have string, integer or boolean values. Boolean values+are specified with 'yes' or 'no'.++Module Syntax+---------------------++The ``info.txt`` files have the following elements. Not all are required; a minimal+file for a module with no dependencies might just contain a macro define.++Lists:+ * ``comment`` and ``warning`` provides block-comments which+ are displayed to the user at build time.+ * ``requires`` is a list of module dependencies. An ``os_features`` can be+ specified as a condition for needing the dependency by writing it before+ the module name and separated by a ``?``, e.g. ``rtlgenrandom?dyn_load``.+ * ``header:internal`` is the list of headers (from the current module)+ which are internal-only.+ * ``header:public`` is a the list of headers (from the+ current module) which should be exported for public use. If neither+ ``header:internal`` nor ``header:public`` are used then all headers+ in the current directory are assumed public.++ .. note:: If you omit a header from both internal and public lists, it will+ be ignored.++ * ``header:external`` is used when naming headers which are included+ in the source tree but might be replaced by an external version. This is used+ for the PKCS11 headers.+ * ``arch`` is a list of architectures this module may be used on.+ * ``isa`` lists ISA features which must be enabled to use this module.+ Can be proceeded by an ``arch`` name followed by a ``:`` if it is only needed+ on a specific architecture, e.g. ``x86_64:ssse3``.+ * ``cc`` is a list of compilers which can be used with this module. If the+ compiler name is suffixed with a version (like "gcc:5.0") then only compilers+ with that minimum version can use the module.+ * ``os_features`` is a list of OS features which are required in order to use this+ module. Each line can specify one or more features combined with ','. Alternatives+ can be specified on additional lines.++Maps:+ * ``defines`` is a map from macros to datestamps. These macros will be defined in+ the generated ``build.h``.+ * ``libs`` specifies additional libraries which should be linked if this module is+ included. It maps from the OS name to a list of libraries (comma seperated).+ * ``frameworks`` is a macOS/iOS specific feature which maps from an OS name to+ a framework.++Variables:+ * ``load_on`` Can take on values ``never``, ``always``, ``auto``, ``dep`` or ``vendor``.+ TODO describe the behavior of these+ * ``endian`` Required endian for the module (``any`` (default), ``little``, ``big``)++An example::++ # Disable this by default+ load_on never++ <isa>+ sse2+ </isa>++ <defines>+ DEFINE1 -> 20180104+ DEFINE2 -> 20190301+ </defines>++ <comment>+ I have eaten+ the plums+ that were in+ the icebox+ </comment>++ <warning>+ There are no more plums+ </warning>++ <header:public>+ header1.h+ </header:public>++ <header:internal>+ header_helper.h+ whatever.h+ </header:internal>++ <arch>+ x86_64+ </arch>++ <cc>+ gcc:4.9 # gcc 4.8 doesn't work for <reasons>+ clang+ </cc>++ # Can work with POSIX+getentropy or Win32+ <os_features>+ posix1,getentropy+ win32+ </os_features>++ <frameworks>+ macos -> FramyMcFramerson+ </frameworks>++ <libs>+ qnx -> foo,bar,baz+ solaris -> socket+ </libs>++Supporting a new CPU type+---------------------------++CPU information is stored in ``src/build-data/arch``.++There is also a file ``src/build-data/detect_arch.cpp`` which is used+for build-time architecture detection using the compiler preprocessor.+Supporting this is optional but recommended.++Lists:+ * ``aliases`` is a list of alternative names for the CPU architecture.+ * ``isa_extensions`` is a list of possible ISA extensions that can be used on+ this architecture. For example x86-64 has extensions "sse2", "ssse3",+ "avx2", "aesni", ...++Variables:+ * ``endian`` if defined should be "little" or "big". This can also be+ controlled or overridden at build time.+ * ``family`` can specify a family group for several related architecture.+ For example both x86_32 and x86_64 use ``family`` of "x86".+ * ``wordsize`` is the default wordsize, which controls the size of limbs+ in the multi precision integers. If not set, defaults to 32.++Supporting a new compiler+---------------------------++Compiler information is stored in ``src/build-data/cc``. Looking over+those files will probably help understanding, especially the ones for+GCC and Clang which are most complete.++In addition to the info file, for compilers there is a file+``src/build-data/detect_version.cpp``. The ``configure.py`` script runs the+preprocessor over this file to attempt to detect the compiler+version. Supporting this is not strictly necessary.++Maps:+ * ``binary_link_commands`` gives the command to use to run the linker,+ it maps from operating system name to the command to use. It uses+ the entry "default" for any OS not otherwise listed.+ * ``cpu_flags_no_debug`` unused, will be removed+ * ``cpu_flags`` used to emit CPU specific flags, for example LLVM+ bitcode target uses ``-emit-llvm`` flag. Rarely needed.+ * ``isa_flags`` maps from CPU extensions (like NEON or AES-NI) to+ compiler flags which enable that extension. These have the same name+ as the ISA flags listed in the architecture files.+ * ``lib_flags`` has a single possible entry "debug" which if set maps+ to additional flags to pass when building a debug library.+ Rarely needed.+ * ``mach_abi_linking`` specifies flags to enable when building and+ linking on a particular CPU. This is usually flags that modify+ ABI. There is a special syntax supported here+ "all!os1,arch1,os2,arch2" which allows setting ABI flags which are+ used for all but the named operating systems and/or architectures.+ * ``sanitizers`` is a map of sanitizers the compiler supports. It must+ include "default" which is a list of sanitizers to include by default+ when sanitizers are requested. The other keys should map to compiler+ flags.+ * ``so_link_commands`` maps from operating system to the command to+ use to build a shared object.++Variables:+ * ``binary_name`` the default name of the compiler binary.+ * ``linker_name`` the name of the linker to use with this compiler.+ * ``macro_name`` a macro of the for ``BOTAN_BUILD_COMPILER_IS_XXX``+ will be defined.+ * ``output_to_object`` (default "-o") gives the compiler option used to+ name the output object.+ * ``output_to_exe`` (default "-o") gives the compiler option used to+ name the output object.+ * ``add_include_dir_option`` (default "-I") gives the compiler option used+ to specify an additional include dir.+ * ``add_lib_dir_option`` (default "-L") gives the compiler option used+ to specify an additional library dir.+ * ``add_sysroot_option`` gives the compiler option used to specify the sysroot.+ * ``add_lib_option`` (default "-l%s") gives the compiler option to+ link in a library. ``%s`` will be replaced with the library name.+ * ``add_framework_option`` (default "-framework") gives the compiler option+ to add a macOS framework.+ * ``preproc_flags`` (default "-E") gives the compiler option used to run+ the preprocessor.+ * ``compile_flags`` (default "-c") gives the compiler option used to compile a file.+ * ``debug_info_flags`` (default "-g") gives the compiler option used to enable debug info.+ * ``optimization_flags`` gives the compiler optimization flags to use.+ * ``size_optimization_flags`` gives compiler optimization flags to use when+ compiling for size. If not set then ``--optimize-for-size`` will use+ the default optimization flags.+ * ``sanitizer_optimization_flags`` gives compiler optimization flags to use+ when building with sanitizers.+ * ``coverage_flags`` gives the compiler flags to use when generating coverage+ information.+ * ``stack_protector_flags`` gives compiler flags to enable stack overflow checking.+ * ``shared_flags`` gives compiler flags to use when generation shared libraries.+ * ``lang_flags`` gives compiler flags used to enable the required version of C++.+ * ``warning_flags`` gives warning flags to enable.+ * ``maintainer_warning_flags`` gives extra warning flags to enable during maintainer+ mode builds.+ * ``visibility_build_flags`` gives compiler flags to control symbol visibility+ when generation shared libraries.+ * ``visibility_attribute`` gives the attribute to use in the ``BOTAN_DLL`` macro+ to specify visibility when generation shared libraries.+ * ``ar_command`` gives the command to build static libraries+ * ``ar_options`` gives the options to pass to ``ar_command``, if not set here+ takes this from the OS specific information.+ * ``ar_output_to`` gives the flag to pass to ``ar_command`` to specify where to+ output the static library.+ * ``werror_flags`` gives the complier flags to treat warnings as errors.++Supporting a new OS+---------------------------++Operating system information is stored in ``src/build-data/os``.++Lists:+ * ``aliases`` is a list of alternative names which will be accepted+ * ``target_features`` is a list of target specific OS features. Some of these+ are supported by many OSes (for example "posix1") others are specific to+ just one or two OSes (such as "getauxval"). Adding a value here causes a new+ macro ``BOTAN_TARGET_OS_HAS_XXX`` to be defined at build time. Use+ ``configure.py --list-os-features`` to list the currently defined OS+ features.+ * ``feature_macros`` is a list of macros to define.++Variables:+ * ``ar_command`` gives the command to build static libraries+ * ``ar_options`` gives the options to pass to ``ar_command``+ * ``ar_output_to`` gives the flag to pass to ``ar_command`` to specify where to+ output the static library.+ * ``bin_dir`` (default "bin") specifies where binaries should be installed,+ relative to install_root.+ * ``cli_exe_name`` (default "botan") specifies the name of the command line utility.+ * ``default_compiler`` specifies the default compiler to use for this OS.+ * ``doc_dir`` (default "doc") specifies where documentation should be installed,+ relative to install_root+ * ``header_dir`` (default "include") specifies where include files+ should be installed, relative to install_root+ * ``install_root`` (default "/usr/local") specifies where to install+ by default.+ * ``lib_dir`` (default "lib") specifies where library should be installed,+ relative to install_root.+ * ``lib_prefix`` (default "lib") prefix to add to the library name+ * ``library_name``+ * ``man_dir`` specifies where man files should be installed, relative to install_root+ * ``obj_suffix`` (default "o") specifies the suffix used for object files+ * ``program_suffix`` (default "") specifies the suffix used for executables+ * ``shared_lib_symlinks`` (default "yes) specifies if symbolic names should be+ created from the base and patch soname to the library name.+ * ``soname_pattern_abi``+ * ``soname_pattern_base``+ * ``soname_pattern_patch``+ * ``soname_suffix`` file extension to use for shared library if ``soname_pattern_base``+ is not specified.+ * ``static_suffix`` (default "a") file extension to use for static library.+ * ``use_stack_protector`` (default "true") specify if by default stack smashing+ protections should be enabled.+ * ``uses_pkg_config`` (default "yes") specify if by default a pkg-config file+ should be created.
+ third_party/botan/doc/dev_ref/contents.rst view
@@ -0,0 +1,20 @@+Developer Reference+=====================++This section contains information useful to people making+contributions to the library++.. toctree::+ :maxdepth: 1++ contributing+ configure+ test_framework+ continuous_integration+ fuzzing+ release_process+ todo+ os+ oids+ reading_list+ mistakes
+ third_party/botan/doc/dev_ref/continuous_integration.rst view
@@ -0,0 +1,75 @@+Continuous Integration and Automated Testing+===============================================++CI Build Script+----------------++The Travis and AppVeyor builds are orchestrated using a script+``src/scripts/ci_build.py``. This allows one to easily reproduce the CI process+on a local machine.++Travis CI+-----------++https://travis-ci.org/randombit/botan++This is the primary CI, and tests the Linux, macOS, and iOS builds. Among other+things it runs tests using valgrind, cross compilation to different+architectures (currently ARM, PowerPC and MIPS), MinGW build, and a build that+produces the coverage report.++The Travis configurations is in ``src/scripts/ci/travis.yml``, which executes a+setup script ``src/scripts/ci/setup_travis.sh`` to install needed packages.+Then ``src/scripts/ci_build.py`` is invoked.++AppVeyor+----------++https://ci.appveyor.com/project/randombit/botan++Runs a build/test cycle using MSVC on Windows. Like Travis it uses+``src/scripts/ci_build.py``. The AppVeyor setup script is in+``src/scripts/ci/setup_appveyor.bat``++The AppVeyor build uses `sccache <https://github.com/mozilla/sccache>`_ as a+compiler cache. Since that is not available in the AppVeyor images, the setup+script downloads a release binary from the upstream repository.++LGTM+---------++https://lgtm.com/projects/g/randombit/botan/++An automated linter that is integrated with Github. It automatically checks each+incoming PR. It also supports custom queries/alerts, which likely would be worth+investigating but is not something currently in use.++Coverity+---------++https://scan.coverity.com/projects/624++An automated source code scanner. Use of Coverity scanner is rate-limited,+sometimes it is very slow to produce a new report, and occasionally the service+goes offline for days or weeks at a time. New reports are kicked off manually by+rebasing branch ``coverity_scan`` against the most recent master and force+pushing it.++Sonar+-------++https://sonarcloud.io/dashboard?id=botan++Sonar scanner is another software quality scanner. Unfortunately a recent update+of their scanner caused it to take over an hour to produce a report which caused+Travis CI timeouts, so it has been disabled. It should be re-enabled to run on+demand in the same way Coverity is.++OSS-Fuzz+----------++https://github.com/google/oss-fuzz/++OSS-Fuzz is a distributed fuzzer run by Google. Every night, each library fuzzer+in ``src/fuzzer`` is built and run on many machines with any findings reported+to the developers by email.
+ third_party/botan/doc/dev_ref/contributing.rst view
@@ -0,0 +1,268 @@++Notes for New Contributors+===================================++Source Code Layout+-------------------------------------------------++Under ``src`` there are directories++* ``lib`` is the library itself, more on that below+* ``cli`` is the command line application ``botan``+* ``tests`` contain what you would expect. Input files go under ``tests/data``.+* ``build-data`` contains files read by the configure script. For+ example ``build-data/cc/gcc.txt`` describes various gcc options.+* ``scripts`` contains misc scripts: install, distribution, various+ codegen things. Scripts controlling CI go under ``scripts/ci``.+* ``configs`` contains configuration files for emacs, astyle, pylint, etc+* ``python/botan2.py`` is the Python ctypes wrapper++Library Layout+----------------------------------------++* ``base`` defines some high level types+* ``utils`` contains various utility functions and types+* ``codec`` has hex, base64+* ``block`` contains the block cipher implementations+* ``modes`` contains block cipher modes (CBC, GCM, etc)+* ``stream`` contains the stream ciphers+* ``hash`` contains the hash function implementations+* ``passhash`` contains password hashing algorithms for authentication+* ``kdf`` contains the key derivation functions+* ``mac`` contains the message authentication codes+* ``pbkdf`` contains password hashing algorithms for key derivation+* ``math`` is the big integer math library. It is divided into three parts:+ ``mp`` which are the low level algorithms; ``bigint`` which is a C++ wrapper+ around ``mp``, and ``numbertheory`` which contains higher level algorithms like+ primality testing and exponentiation+* ``pubkey`` contains the public key algorithms+* ``pk_pad`` contains padding schemes for public key algorithms+* ``rng`` contains the random number generators+* ``entropy`` has various entropy sources used by some of the RNGs+* ``asn1`` is the DER encoder/decoder+* ``x509`` is X.509 certificates, PKCS #10 requests, OCSP+* ``tls`` contains the TLS implementation+* ``filters`` is a filter/pipe API for data transforms+* ``compression`` has the compression wrappers (zlib, bzip2, lzma)+* ``ffi`` is the C99 API+* ``prov`` contains bindings to external libraries like OpenSSL and PKCS #11+* ``misc`` contains odds and ends: format preserving encryption, SRP, threshold+ secret sharing, all or nothing transform, and others++Sending patches+----------------------------------------++All contributions should be submitted as pull requests via GitHub+(https://github.com/randombit/botan). If you are planning a large+change email the mailing list or open a discussion ticket on github+before starting out to make sure you are on the right path. And once+you have something written, free to open a [WIP] PR for early review+and comment.++If possible please sign your git commits using a PGP key.+See https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work for+instructions on how to set this up.++Depending on what your change is, your PR should probably also include an update+to ``news.rst`` with a note explaining the change. If your change is a+simple bug fix, a one sentence description is perhaps sufficient. If there is an+existing ticket on GitHub with discussion or other information, reference it in+your change note as 'GH #000'.++Update ``doc/credits.txt`` with your information so people know what you did!++If you are interested in contributing but don't know where to start check out+``doc/dev_ref/todo.rst`` for some ideas - these are changes we would almost+certainly accept once they've passed code review.++Also, try building and testing it on whatever hardware you have handy,+especially unusual platforms, or using C++ compilers other than the regularly+tested GCC, Clang, and Visual Studio.++FFI Additions+----------------++If adding a new function declaration to ``ffi.h``, the same PR must+also add the same declaration in the Python binding ``botan2.py``, in+addition the new API functionality must be exposed to Python and a+test written in Python.++Git Usage+----------------------------------------++Do *NOT* merge ``master`` into your topic branch, this creates+needless commits and noise in history. Instead, as needed, rebase your+branch against master (``git rebase -i master``) and force push the+branch to update the PR. If the GitHub PR page does not report any+merge conflicts and nobody asks you to rebase, you don't need to+rebase.++Try to keep your history clean and use rebase to squash your commits+as needed. If your diff is less than roughly 100 lines, it should+probably be a single commit. Only split commits as needed to help with+review/understanding of the change.++Python+----------------------------------------++Scripts should be in Python whenever possible.++For configure.py (and helper scripts install.py, cleanup.py and build_docs.py)+the target is stock (no modules outside the standard library) CPython 2.7 plus+latest CPython 3.x. Support for CPython 2.6, PyPy, etc is great when viable (in+the sense of not causing problems for 2.7 or 3.x, and not requiring huge blocks+of version dependent code). As running this program successfully is required for+a working build, making it as portable as possible is considered key.++The python wrapper botan2.py targets CPython 2.7, 3.x, and latest PyPy. Note that+a single file is used to avoid dealing with any of Python's various crazy module+distribution issues.++For random scripts not typically run by an end-user (codegen, visualization, and+so on) there isn't any need to worry about 2.6 and even just running under+Python2 xor Python3 is acceptable if needed. Here it's fine to depend on any+useful modules such as graphviz or matplotlib, regardless if it is available+from a stock CPython install. Since Python2 is now end of life, prefer Python3+for new scripts of this sort.++Build Tools and Hints+----------------------------------------++If you don't already use it for all your C/C++ development, install ``ccache``+(or on Windows, ``sccache``) right now, and configure a large cache on a fast+disk. It allows for very quick rebuilds by caching the compiler output.++Use ``--enable-sanitizers=`` flag to enable various sanitizer checks. Supported+values including "address" and "undefined" for GCC and Clang. GCC also supports+"iterator" (checked iterators), and Clang supports "memory" (MSan) and+"coverage" (for fuzzing).++On Linux if you have the ``lcov`` and ``gcov`` tools installed, then running+``./src/scripts/ci_build.py coverage`` will produce a coverage enabled build,+run the tests, test the fuzzers against a corpus, and produce an HTML report+of total coverage. This coverage build requires the development headers for+zlib, bzip2, liblzma, OpenSSL, TrouSerS (libtspi), and Sqlite3.++Copyright Notice+----------------------------------------++At the top of any new file add a comment with a copyright and a reference to the+license, for example::++ /*+ * (C) 20xx Copyright Holder+ * Botan is released under the Simplified BSD License (see license.txt)+ */++If you are making a substantial or non-trivial change to an existing file, add+or update your own copyright statement at the top of each file.++Style Conventions+----------------------------------------++When writing your code remember the need for it to be easily understood by+reviewers and auditors, both at the time of the patch submission and in the+future.++Avoid complicated template metaprogramming where possible. It has its places but+should be used judiciously.++When designing a new API (for use either by library users or just internally)+try writing out the calling code first. That is, write out some code calling+your idealized API, then just implement that API. This can often help avoid+cut-and-paste by creating the correct abstractions needed to solve the problem+at hand.++The C++11 ``auto`` keyword is very convenient but only use it when the type+truly is obvious (considering also the potential for unexpected integer+conversions and the like, such as an apparent uint8_t being promoted to an int).++If a variable is defined and not modified, declare it ``const``. Some exception+for very short-lived variables, but generally speaking being able to read the+declaration and know it will not be modified is useful.++Use ``override`` annotations whenever overriding a virtual function. If+introducing a new type that is not intended for derivation, mark it ``final``.++Avoid explicit ``delete`` - use RAII.++Use ``m_`` prefix on all member variables.++For formatting, there are configs for emacs and astyle in ``src/configs``.+No tabs, and remove trailing whitespace.++Prefer using braces on both sides of if/else blocks, even if only using a single+statement. The current code doesn't always do this.++Avoid ``using namespace`` declarations, even inside of single functions. One+allowed exception is ``using namespace std::placeholders`` in functions which+use ``std::bind``. (But, don't use ``std::bind`` - use a lambda instead).++Use ``::`` to explicitly refer to the global namespace (eg, when calling an OS+or external library function like ``::select`` or ``::sqlite3_open``).++Use of External Dependencies+----------------------------------------++Compiler Dependencies+~~~~~~~~~~~~~~~~~~~~~~~++The library should always be as functional as possible when compiled with just+C++11. However, feel free to use the full C++11 language. No accomodations are+made for compilers that are incomplete or buggy.++Use of compiler extensions is fine whenever appropriate; this is typically+restricted to a single file or an internal header. Compiler extensions used+currently include native uint128_t, SIMD intrinsics, inline asm syntax and so+on, so there are some existing examples of appropriate use.++Generally intrinsics or inline asm is preferred over bare assembly to avoid+calling convention issues among different platforms; the improvement in+maintainability is seen as worth any potential performance tradeoff. One risk+with intrinsics is that the compiler might rewrite your clever const-time SIMD+into something with a conditional jump, but code intended to be const-time+should in any case be annotated so it can be checked at runtime with tools.++Operating System Dependencies+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++If you're adding a small OS dependency in some larger piece of code, try to+contain the actual non-portable operations to utils/os_utils.* and then call+them from there.++As a policy, operating systems which are not supported by their original vendor+are not supported by Botan either. Patches that complicate the code in order to+support obsolete operating systems will likely be rejected. In writing OS+specific code, feel free to assume roughly POSIX 2008, or for Windows, Windows 8+/Server 2012 (which are as of this writing the oldest versions still supported+by Microsoft).++Some operating systems, such as OpenBSD, only support the latest release. For+such cases, it's acceptable to add code that requires APIs added in the most+recent release of that OS as soon as the release is available.++Library Dependencies+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++Any external library dependency - even optional ones - is met with as one PR+submitter put it "great skepticism".++At every API boundary there is potential for confusion that does not exist when+the call stack is all contained within the boundary. So the additional API+really needs to pull its weight. For example a simple text parser or such which+can be trivially implemented is not really for consideration. As a rough idea of+the bar, equate the viewed cost of an external dependency as at least 1000+additional lines of code in the library. That is, if the library really does+need this functionality, and it can be done in the library for less than that,+then it makes sense to just write the code. Yup.++Currently the (optional) external dependencies of the library are OpenSSL (for+access to fast and side channel hardened RSA, ECDSA, AES), some compression+libraries (zlib, bzip2, lzma), sqlite3 database, Trousers (TPM integration),+plus various operating system utilities like basic filesystem operations. These+provide major pieces of functionality which seem worth the trouble of+maintaining an integration with.++At this point the most plausible examples of an appropriate new external+dependency are all deeper integrations with system level cryptographic systems+(CommonCrypto, CryptoAPI, /dev/crypto, iOS keychain, TPM 2.0, etc)
+ third_party/botan/doc/dev_ref/fuzzing.rst view
@@ -0,0 +1,91 @@+Fuzzing The Library+============================++Botan comes with a set of fuzzing endpoints which can be used to test+the library.++.. highlight:: shell++Fuzzing with libFuzzer+------------------------++To fuzz with libFuzzer (https://llvm.org/docs/LibFuzzer.html), you'll first+need to compile libFuzzer::++ $ svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer libFuzzer+ $ cd libFuzzer && clang -c -g -O2 -std=c++11 *.cpp+ $ ar cr libFuzzer.a libFuzzer/*.o++Then build the fuzzers::++ $ ./configure.py --cc=clang --build-fuzzer=libfuzzer --unsafe-fuzzer-mode \+ --enable-sanitizers=coverage,address,undefined+ $ make fuzzers++Enabling 'coverage' sanitizer flags is required for libFuzzer to work.+Address sanitizer and undefined sanitizer are optional.++The fuzzer binaries will be in `build/fuzzer`. Simply pick one and run it, optionally+also passing a directory containing corpus inputs.++Using `libfuzzer` build mode implicitly assumes the fuzzers need to+link with `libFuzzer`; if another library is needed (for example in+OSS-Fuzz, which uses `libFuzzingEngine`), use the flag+`--with-fuzzer-lib` to specify the desired name.++Fuzzing with AFL+--------------------++To fuzz with AFL (http://lcamtuf.coredump.cx/afl/)::++ $ ./configure.py --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g+++ $ make fuzzers++For AFL sanitizers are optional. You can also use `afl-clang-fast++`+or `afl-clang++`, be sure to set `--cc=clang` also.++The fuzzer binaries will be in `build/fuzzer`. To run them you need to+run under `afl-fuzz`::++ $ afl-fuzz -i corpus_path -o output_path ./build/fuzzer/binary++Fuzzing with TLS-Attacker+--------------------------++TLS-Attacker (https://github.com/RUB-NDS/TLS-Attacker) includes a mode for fuzzing+TLS servers. A prebuilt copy of TLS-Attacker is available in a git repository::++ $ git clone --depth 1 https://github.com/randombit/botan-ci-tools.git++To run it against Botan's server::++ $ ./configure.py --with-sanitizers+ $ make botan+ $ ./src/scripts/run_tls_attacker.py ./botan ./botan-ci-tools++Output and logs from the fuzzer are placed into `/tmp`. See the+TLS-Attacker documentation for more information about how to use this+tool.++Input Corpus+-----------------------++AFL requires an input corpus, and libFuzzer can certainly make good+use of it.++Some crypto corpus repositories include++* https://github.com/randombit/crypto-corpus+* https://github.com/mozilla/nss-fuzzing-corpus+* https://github.com/google/boringssl/tree/master/fuzz+* https://github.com/openssl/openssl/tree/master/fuzz/corpora++Adding new fuzzers+---------------------++New fuzzers are created by adding a source file to `src/fuzzers` which+have the signature:++``void fuzz(const uint8_t in[], size_t len)``++After adding your fuzzer, rerun ``./configure.py`` and build.
+ third_party/botan/doc/dev_ref/mistakes.rst view
@@ -0,0 +1,77 @@++Mistakes Were Made+===================++These are mistakes made early on in the project's history which are difficult to+fix now, but mentioned in the hope they may serve as an example for others.++C++ API+---------++As an implementation language, I still think C++ is the best choice (or at least+the best choice available in early '00s) at offering good performance,+reasonable abstractions, and low overhead. But the user API should have been+pure C with opaque structs (rather like the FFI layer, which was added much+later). Then an expressive C++ API could be built on top of the C API. This+would have given us a stable ABI, allowed C applications to use the library, and+(these days) make it easier to progressively rewrite the library in Rust.++Public Algorithm Specific Classes+------------------------------------++Classes like AES_128 and SHA_256 should never have been exposed to applications.+Intead such operations should have been accessible only via the higher level+interfaces (here BlockCipher and HashFunction). This would substantially reduce+the overall API and ABI surface.++These interfaces are now deprecated, and perhaps will be able to be+removed eventually.++Header Directories+-------------------++It would have been better to install all headers as ``X/header.h``+where ``X`` is the base dir in the source, eg ``block/aes128.h``,+``hash/md5.h``, ...++Exceptions+-----------++Constant ABI headaches from this, and it impacts performance and makes APIs+harder to understand. Should have been handled with a result<> type instead.++Virtual inheritance+---------------------++This was used in the public key interfaces and the hierarchy is a tangle.+Public and private keys should be distinct classes, with a function on private+keys that creates a new object corresponding to the public key.++Cipher Interface+------------------++The cipher interface taking a secure_vector that it reads from and writes to was+an artifact of an earlier design which supported both compression and encryption+in a single API. But it leads to inefficient copies.++(I am hoping this issue can be somewhat fixed by introducing a new cipher API+and implementing the old API in terms of the new one.)++Pipe Interface+----------------++On the surface this API seems very convenient and easy to use. And it is. But+the downside is it makes the application code totally opaque; some bytes go into+a Pipe object and then come out the end transformed in some way. What happens in+between? Unless the Pipe was built in the same function and you can see the+parameters to the constructor, there is no way to find out.++The problems with the Pipe API are documented, and it is no longer used within+the library itself. But since many people seem to like it and many applications+use it, we are stuck at least with maintaining it as it currently exists.++License+---------++MIT is more widely used and doesn't have the ambiguity surrounding the+various flavors of BSD.
+ third_party/botan/doc/dev_ref/oids.rst view
@@ -0,0 +1,43 @@+Private OID Assignments+==========================++The library uses some OIDs under a private arc assigned by IANA,+1.3.6.1.4.1.25258++Values currently assigned are::++ randombit OBJECT IDENTIFIER ::= { 1 3 6 1 4 1 25258 }++ publicKey OBJECT IDENTIFIER ::= { randombit 1 }++ mceliece OBJECT IDENTIFIER ::= { publicKey 3 }+ -- { publicKey 4 } previously used as private X25519+ -- { publicKey 5 } previously used for XMSS draft 6+ gost-3410-with-sha256 OBJECT IDENTIFIER ::= { publicKey 6 1 }+ kyber OBJECT IDENTIFIER ::= { publicKey 7 }+ xmss OBJECT IDENTIFIER ::= { publicKey 8 }++ symmetricKey OBJECT IDENTIFIER ::= { randombit 3 }++ ocbModes OBJECT IDENTIFIER ::= { symmetricKey 2 }++ aes-128-ocb OBJECT IDENTIFIER ::= { ocbModes 1 }+ aes-192-ocb OBJECT IDENTIFIER ::= { ocbModes 2 }+ aes-256-ocb OBJECT IDENTIFIER ::= { ocbModes 3 }+ serpent-256-ocb OBJECT IDENTIFIER ::= { ocbModes 4 }+ twofish-256-ocb OBJECT IDENTIFIER ::= { ocbModes 5 }+ camellia-128-ocb OBJECT IDENTIFIER ::= { ocbModes 6 }+ camellia-192-ocb OBJECT IDENTIFIER ::= { ocbModes 7 }+ camellia-256-ocb OBJECT IDENTIFIER ::= { ocbModes 8 }++ sivModes OBJECT IDENTIFIER ::= { symmetricKey 4 }++ aes-128-siv OBJECT IDENTIFIER ::= { sivModes 1 }+ aes-192-siv OBJECT IDENTIFIER ::= { sivModes 2 }+ aes-256-siv OBJECT IDENTIFIER ::= { sivModes 3 }+ serpent-256-siv OBJECT IDENTIFIER ::= { sivModes 4 }+ twofish-256-siv OBJECT IDENTIFIER ::= { sivModes 5 }+ camellia-128-siv OBJECT IDENTIFIER ::= { sivModes 6 }+ camellia-192-siv OBJECT IDENTIFIER ::= { sivModes 7 }+ camellia-256-siv OBJECT IDENTIFIER ::= { sivModes 8 }+ sm4-128-siv OBJECT IDENTIFIER ::= { sivModes 9 }
+ third_party/botan/doc/dev_ref/os.rst view
@@ -0,0 +1,61 @@+OS Features+========================================++A summary of OS features as defined in ``src/build-data/os``.++::++ a: aix+ a: android+ c: cygwin+ d: dragonfly+ e: emscripten+ f: freebsd+ h: haiku+ h: hpux+ h: hurd+ i: includeos+ i: ios+ l: linux+ l: llvm+ m: macos+ m: mingw+ n: nacl+ n: netbsd+ o: openbsd+ q: qnx+ s: solaris+ u: uwp+ w: windows++.. csv-table::+ :header: "Feature", "a", "a", "c", "d", "e", "f", "h", "h", "h", "i", "i", "l", "l", "m", "m", "n", "n", "o", "q", "s", "u", "w"++ "apple_keychain", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "+ "arc4random", " ", "X", " ", "X", " ", "X", " ", " ", " ", " ", "X", " ", " ", "X", " ", " ", "X", "X", " ", " ", " ", " "+ "cap_enter", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "+ "certificate_store", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X"+ "clock_gettime", "X", "X", " ", "X", " ", "X", "X", "X", "X", " ", " ", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", " "+ "commoncrypto", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "+ "crypto_ng", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " "+ "dev_random", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", " "+ "elf_aux_info", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "+ "explicit_bzero", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " "+ "explicit_memset", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " "+ "filesystem", "X", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X", "X"+ "getauxval", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "+ "getentropy", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", "X", " ", " ", " ", " "+ "pledge", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " "+ "posix1", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", " "+ "posix_mlock", "X", "X", " ", "X", " ", "X", " ", "X", "X", " ", "X", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", " "+ "proc_fs", "X", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " "+ "rtlgenrandom", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", "X"+ "rtlsecurezeromemory", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", "X"+ "sockets", "X", "X", "X", "X", " ", "X", "X", "X", "X", " ", "X", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", " "+ "threads", "X", "X", "X", "X", " ", "X", "X", "X", "X", " ", "X", "X", " ", "X", "X", "X", "X", "X", "X", "X", "X", "X"+ "virtual_lock", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", "X"+ "win32", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X", "X"+ "winsock2", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", "X"++.. note::+ This file is auto generated by ``src/scripts/gen_os_features.py``. Dont modify it manually.
+ third_party/botan/doc/dev_ref/reading_list.rst view
@@ -0,0 +1,93 @@+Reading List+================++These are papers, articles and books that are interesting or useful from the+perspective of crypto implementation.++Papers+--------++Implementation Techniques+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++* "Randomizing the Montgomery Powering Ladder"+ Le, Tan, Tunstall https://eprint.iacr.org/2015/657+ A variant of Algorithm 7 is used for GF(p) point multplications when+ BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER is set++* "Accelerating AES with vector permute instructions"+ Mike Hamburg https://shiftleft.org/papers/vector_aes/+ His public doman assembly code was rewritten into SSS3 intrinsics+ for aes_ssse3.++* "Elliptic curves and their implementation" Langley+ http://www.imperialviolet.org/2010/12/04/ecc.html+ Describes sparse representations for ECC math++Random Number Generation+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++* "On Extract-then-Expand Key Derivation Functions and an HMAC-based KDF"+ Hugo Krawczyk http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.131.8254+ RNG design underlying HMAC_RNG++AES Side Channels+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++* "Software mitigations to hedge AES against cache-based software side+ channel vulnerabilities" https://eprint.iacr.org/2006/052.pdf++* "Cache Games - Bringing Access-Based Cache Attacks on AES to Practice"+ http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper031.pdf++* "Cache-Collision Timing Attacks Against AES" Bonneau, Mironov+ http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753++Public Key Side Channels+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++* "Fast Elliptic Curve Multiplications Resistant against Side Channel Attacks"+ http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.98.1028&rep=rep1&type=pdf++* "Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems"+ Coron http://www.jscoron.fr/publications/dpaecc.pdf++* "Further Results and Considerations on Side Channel Attacks on RSA"+ Klima, Rosa https://eprint.iacr.org/2002/071+ Side channel attacks on RSA-KEM and MGF1-SHA1++* "Side-Channel Attacks on the McEliece and Niederreiter Public-Key Cryptosystems"+ Avanzi, Hoerder, Page, and Tunstall https://eprint.iacr.org/2010/479++* "Minimum Requirements for Evaluating Side-Channel Attack Resistance+ of Elliptic Curve Implementations" BSI+ https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Zertifizierung/Interpretationen/AIS_46_ECCGuide_e_pdf.pdf++Books+------++* "Handbook of Elliptic and Hyperelliptic Curve Cryptography"+ Cohen and Frey https://www.hyperelliptic.org/HEHCC/+ An excellent reference for ECC math, algorithms, and side channels++* "Post-Quantum Cryptography" Bernstein, Buchmann, Dahmen+ Covers code, lattice, and hash based cryptography++Standards+-----------++* IEEE 1363 http://grouper.ieee.org/groups/1363/+ Very influential early in the library lifetime, so a lot of terminology used+ in the public key (such as "EME" for message encoding) code comes from here.++* ISO/IEC 18033-2 http://www.shoup.net/iso/std4.pdf+ RSA-KEM, PSEC-KEM++* NIST SP 800-108+ http://csrc.nist.gov/publications/nistpubs/800-108/sp800-108.pdf+ KDF schemes++* NIST SP 800-90A+ http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf+ HMAC_DRBG, Hash_DRBG, CTR_DRBG, maybe one other thing?+
+ third_party/botan/doc/dev_ref/release_process.rst view
@@ -0,0 +1,129 @@+Release Process and Checklist+========================================++Releases are done quarterly, normally on the first non-holiday Monday+of January, April, July and October. A feature freeze goes into effect+starting 9 days before the release.++.. highlight:: shell++.. note::++ This information is only useful if you are a developer of botan who+ is creating a new release of the library.++Pre Release Testing+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Kick off a Coverity scan a day or so before the planned release.++Do maintainer-mode builds with Clang and GCC to catch any warnings+that should be corrected. Also check Visual C++ build logs for any+warnings that should be addressed.++And remember that CI doesn't test everything. In particular, not all+tests run under valgrind or on the qemu cross builds due to time+constraints. So before release:++ - Run under valgrind, building with ``--with-valgrind`` flag+ - Using Clang sanitizers (ASan + UbSan)+ - Native compile on FreeBSD x86-64+ - Native compile on at least one unusual platform (AIX, NetBSD, ...)+ - Build the website content to detect any Doxygen problems+ - Test many build configurations (using `src/scripts/test_all_configs.py`)+ - Build/test SoftHSM++Confirm that the release notes in ``news.rst`` are accurate and+complete and that the version number in ``version.txt`` is correct.++Tag the Release+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Update the release date in the release notes and change the entry for+the appropriate branch in ``readme.rst`` to point to the new release.++Now check in, and backport changes to the release branch::++ $ git commit readme.rst news.rst -m "Update for 2.6.13 release"+ $ git checkout release-2+ $ git merge master+ $ git tag 2.6.13++Build The Release Tarballs+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The release script is ``src/scripts/dist.py`` and must be run from a+git workspace.++ $ src/scripts/dist.py 2.6.13++One useful option is ``--output-dir``, which specifies where the+output will be placed.++Now do a final build/test of the released tarball.++The ``--pgp-key-id`` option is used to specify 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``,+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.++The releases served on the official site are taken from the contents+in a git repository::++ $ git checkout git@botan.randombit.net:/srv/git/botan-releases.git+ $ src/scripts/dist.py 2.6.13 --output-dir=botan-releases+ $ cd botan-releases+ $ sha256sum Botan-2.6.13.tgz >> sha256sums.txt+ $ git add .+ $ git commit -m "Release version 2.6.13"+ $ git push origin master++A cron job updates the live site every 10 minutes.++Push to GitHub+^^^^^^^^^^^^^^^^^^++Don't forget to also push tags::++ $ git push origin --tags release-2 master++Build The Windows Installer+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++.. note::+ We haven't distributed Windows binaries for some time.++On Windows, run ``configure.py`` to setup a build::++ $ python ./configure.py --cc=msvc --cpu=$ARCH --distribution-info=unmodified++After completing the build (and running the tests), use `InnoSetup+<http://www.jrsoftware.org/isinfo.php>`_ to create the installer. A+InnoSetup script is created from ``src/build-data/innosetup.in`` and+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-2.6.13-x86_64.exe``. Sign the installers with GPG.++Update The Website+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++The website content is created by ``src/scripts/website.py``.++The website is mirrored automatically from a git repository which must be updated::++ $ git checkout git@botan.randombit.net:/srv/git/botan-website.git+ $ ./src/scripts/website.py --output botan-website+ $ cd botan-website+ $ git add .+ $ git commit -m "Update for 2.6.13"+ $ git push origin master++Announce The Release+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Send an email to the botan-announce and botan-devel mailing lists+noting that a new release is available.
+ third_party/botan/doc/dev_ref/test_framework.rst view
@@ -0,0 +1,314 @@+Test Framework+================++Botan uses a custom-built test framework. Some portions of it are+quite similar to assertion-based test frameworks such as Catch or+Gtest, but it also includes many features which are well suited for+testing cryptographic algorithms.++The intent is that the test framework and the test suite evolve+symbiotically; as a general rule of thumb if a new function would make+the implementation of just two distinct tests simpler, it is worth+adding to the framework on the assumption it will prove useful again.+Feel free to propose changes to the test system.++When writing a new test, there are three key classes that are used,+namely ``Test``, ``Test::Result``, and ``Text_Based_Test``. A ``Test``+(or ``Test_Based_Test``) runs and returns one or more ``Test::Result``.++Namespaces in Test+-------------------++The test code lives in a distinct namespace (``Botan_Tests``) and all+code in the tests which calls into the library should use the+namespace prefix ``Botan::`` rather than a ``using namespace``+declaration. This makes it easier to see where the test is actually+invoking the library, and makes it easier to reuse test code for+applications.++Test Data+-----------++The test framework is heavily data driven. As of this writing, there+is about 1 Mib of test code and 17 MiB of test data. For most (though+certainly not all) tests, it is better to add a data file representing+the input and outputs, and run the tests over it. Data driven tests+make adding or editing tests easier, for example by writing scripts+which produce new test data and output it in the expected format.++Test+--------++.. cpp:class:: Test++ .. cpp:function:: virtual std::vector<Test::Result> run() = 0++ This is the key function of a ``Test``: it executes and returns a+ list of results. Almost all other functions on ``Test`` are+ static functions which just serve as helper functions for ``run``.++ .. cpp:function:: static std::string read_data_file(const std::string& path)++ Return the contents of a data file and return it as a string.++ .. cpp:function:: static std::vector<uint8_t> read_binary_data_file(const std::string& path)++ Return the contents of a data file and return it as a vector of+ bytes.++ .. cpp:function:: static std::string data_file(const std::string& what)++ An alternative to ``read_data_file`` and ``read_binary_file``,+ use only as a last result, typically for library APIs which+ themselves accept a filename rather than a data blob.++ .. cpp:function:: static bool run_long_tests() const++ Returns true if the user gave option ``--run-long-tests``. Use+ this to gate particularly time-intensive tests.++ .. cpp:function:: static Botan::RandomNumberGenerator& rng()++ Returns a reference to a fast, not cryptographically secure+ random number generator. It is deterministicly seeded with the+ seed logged by the test runner, so it is possible to reproduce+ results in "random" tests.++Tests are registered using the macro ``BOTAN_REGISTER_TEST`` which+takes 2 arguments: the name of the test and the name of the test class.+For example given a ``Test`` instance named ``MyTest``, use::++ BOTAN_REGISTER_TEST("mytest", MyTest);++All test names should contain only lowercase letters, numbers, and+underscore.++Test::Result+-------------++.. cpp:class:: Test::Result++ A ``Test::Result`` records one or more tests on a particular topic+ (say "AES-128/CBC" or "ASN.1 date parsing"). Most of the test functions+ return true or false if the test was successful or not; this allows+ performing conditional blocks as a result of earlier tests::++ if(result.test_eq("first value", produced, expected))+ {+ // further tests that rely on the initial test being correct+ }++ Only the most commonly used functions on ``Test::Result`` are documented here,+ see the header ``tests.h`` for more.++ .. cpp:function:: Test::Result(const std::string& who)++ Create a test report on a particular topic. This will be displayed in the+ test results.++ .. cpp:function:: bool test_success()++ Report a test that was successful.++ .. cpp:function:: bool test_success(const std::string& note)++ Report a test that was successful, including some comment.++ .. cpp:function:: bool test_failure(const std::string& err)++ Report a test failure of some kind. The error string will be logged.++ .. cpp:function:: bool test_failure(const std::string& what, const std::string& error)++ Report a test failure of some kind, with a description of what failed and+ what the error was.++ .. cpp:function:: void test_failure(const std::string& what, const uint8_t buf[], size_t buf_len)++ Report a test failure due to some particular input, which is provided as+ arguments. Normally this is only used if the test was using some+ randomized input which unexpectedly failed, since if the input is+ hardcoded or from a file it is easier to just reference the test number.++ .. cpp:function:: bool test_eq(const std::string& what, const std::string& produced, const std::string& expected)++ Compare to strings for equality.++ .. cpp:function:: bool test_ne(const std::string& what, const std::string& produced, const std::string& expected)++ Compare to strings for non-equality.++ .. cpp:function:: bool test_eq(const char* producer, const std::string& what, \+ const uint8_t produced[], size_t produced_len, \+ const uint8_t expected[], size_t expected_len)++ Compare two arrays for equality.++ .. cpp:function:: bool test_ne(const char* producer, const std::string& what, \+ const uint8_t produced[], size_t produced_len, \+ const uint8_t expected[], size_t expected_len)++ Compare two arrays for non-equality.++ .. cpp:function:: bool test_eq(const std::string& producer, const std::string& what, \+ const std::vector<uint8_t>& produced, \+ const std::vector<uint8_t>& expected)++ Compare two vectors for equality.++ .. cpp:function:: bool test_ne(const std::string& producer, const std::string& what, \+ const std::vector<uint8_t>& produced, \+ const std::vector<uint8_t>& expected)++ Compare two vectors for non-equality.++ .. cpp:function:: bool confirm(const std::string& what, bool expr)++ Test that some expression evaluates to ``true``.++ .. cpp:function:: template<typename T> bool test_not_null(const std::string& what, T* ptr)++ Verify that the pointer is not null.++ .. cpp:function:: bool test_lt(const std::string& what, size_t produced, size_t expected)++ Test that ``produced`` < ``expected``.++ .. cpp:function:: bool test_lte(const std::string& what, size_t produced, size_t expected)++ Test that ``produced`` <= ``expected``.++ .. cpp:function:: bool test_gt(const std::string& what, size_t produced, size_t expected)++ Test that ``produced`` > ``expected``.++ .. cpp:function:: bool test_gte(const std::string& what, size_t produced, size_t expected)++ Test that ``produced`` >= ``expected``.++ .. cpp:function:: bool test_throws(const std::string& what, std::function<void ()> fn)++ Call a function and verify it throws an exception of some kind.++ .. cpp:function:: bool test_throws(const std::string& what, const std::string& expected, std::function<void ()> fn)++ Call a function and verify it throws an exception of some kind+ and that the exception message exactly equals ``expected``.++Text_Based_Test+-----------------++A ``Text_Based_Text`` runs tests that are produced from a text file+with a particular format which looks somewhat like an INI-file::++ # Comments begin with # and continue to end of line+ [Header]+ # Test 1+ Key1 = Value1+ Key2 = Value2++ # Test 2+ Key1 = Value1+ Key2 = Value2++.. cpp:class:: VarMap++ An object of this type is passed to each invocation of the text-based test.+ It is used to access the test variables. All access takes a key, which is+ one of the strings which was passed to the constructor of ``Text_Based_Text``.+ Accesses are either required (``get_req_foo``), in which case an exception is+ throwing if the key is not set, or optional (``get_opt_foo``) in which case+ the test provides a default value which is returned if the key was not set+ for this particular instance of the test.++ .. cpp:function:: std::vector<uint8_t> get_req_bin(const std::string& key) const++ Return a required binary string. The input is assumed to be hex encoded.++ .. cpp:function:: std::vector<uint8_t> get_opt_bin(const std::string& key) const++ Return an optional binary string. The input is assumed to be hex encoded.++ .. cpp:function:: std::vector<std::vector<uint8_t>> get_req_bin_list(const std::string& key) const++ .. cpp:function:: Botan::BigInt get_req_bn(const std::string& key) const++ Return a required BigInt. The input can be decimal or (with "0x" prefix) hex encoded.++ .. cpp:function:: Botan::BigInt get_opt_bn(const std::string& key, const Botan::BigInt& def_value) const++ Return an optional BigInt. The input can be decimal or (with "0x" prefix) hex encoded.++ .. cpp:function:: std::string get_req_str(const std::string& key) const++ Return a required text string.++ .. cpp:function:: std::string get_opt_str(const std::string& key, const std::string& def_value) const++ Return an optional text string.++ .. cpp:function:: size_t get_req_sz(const std::string& key) const++ Return a required integer. The input should be decimal.++ .. cpp:function:: size_t get_opt_sz(const std::string& key, const size_t def_value) const++ Return an optional integer. The input should be decimal.++.. cpp:class:: Text_Based_Test : public Test++ .. cpp:function:: Text_Based_Test(const std::string& input_file, \+ const std::string& required_keys, \+ const std::string& optional_keys = "")++ This constructor is++ .. note::+ The final element of required_keys is the "output key", that is+ the key which signifies the boundary between one test and the next.+ When this key is seen, ``run_one_test`` will be invoked. In the+ test input file, this key must always appear least for any particular+ test. All the other keys may appear in any order.++ .. cpp:function:: Test::Result run_one_test(const std::string& header, \+ const VarMap& vars)++ Runs a single test and returns the result of it. The ``header``+ parameter gives the value (if any) set in a ``[Header]`` block.+ This can be useful to distinguish several types of tests within a+ single file, for example "[Valid]" and "[Invalid]".++ .. cpp:function:: bool clear_between_callbacks() const++ By default this function returns ``false``. If it returns+ ``true``, then when processing the data in the file, variables+ are not cleared between tests. This can be useful when several+ tests all use some common parameters.++Test Runner+-------------++If you are simply writing a new test there should be no need to modify+the runner, however it can be useful to be aware of its abilities.++The runner can run tests concurrently across many cores. By default single+threaded execution is used, but you can use ``--test-threads`` option to+specify the number of threads to use. If you use ``--test-threads=0`` then+the runner will probe the number of active CPUs and use that (but limited+to at most 16). If you want to run across many cores on a large machine,+explicitly specify a thread count. The speedup is close to linear.++The RNG used in the tests is deterministic, and the seed is logged for each+execution. You can cause the random sequence to repeat using ``--drbg-seed``+option.++.. note::+ Currently the RNG is seeded just once at the start of execution. So you+ must run the exact same sequence of tests as the original test run in+ order to get reproducible results.++If you are trying to track down a bug that happens only occasionally, two very+useful options are ``--test-runs`` and ``--abort-on-first-fail``. The first+takes an integer and runs the specified test cases that many times. The second+causes abort to be called on the very first failed test. This is sometimes+useful when tracing a memory corruption bug.
+ third_party/botan/doc/dev_ref/todo.rst view
@@ -0,0 +1,199 @@+Todo List+========================================++Feel free to take one of these on if it interests you. Before starting+out on something, send an email to the dev list or open a discussion+ticket on GitHub to make sure you're on the right track.++Request a new feature by opening a pull request to update this file.++Ciphers, Hashes, PBKDF+----------------------------------------++* Stiched AES/GCM mode for CPUs supporting both AES and CLMUL+* Combine AES-NI, ARMv8 and POWER AES implementations (as already done for CLMUL)+* Vector permute AES only supports little-endian systems; fix for big-endian+* SM4 using AES-NI (https://github.com/mjosaarinen/sm4ni) or vector permute+* Poly1305 using AVX2+* ChaCha using SSSE3+* Skein-MAC+* PMAC+* SIV-PMAC+* GCM-SIV (RFC 8452)+* EME* tweakable block cipher (https://eprint.iacr.org/2004/125)+* FFX format preserving encryption (NIST 800-38G)+* SHA-512 using BMI2+AVX2+* Constant time DES using bitslicing and/or BMI2+* Threefish-1024+* SIMD evaluation of SHA-2 and SHA-3 compression functions+* Adiantum (https://eprint.iacr.org/2018/720)+* CRC using clmul/pmull++Public Key Crypto, Math+----------------------------------------++* Short vector optimization for BigInt+* Abstract representation of ECC point elements to allow specific+ implementations of the field arithmetic depending upon the curve.+* Use NAF (joint sparse form) for ECC multi-exponentiation+* Curves for pairings (BN-256, BLS12-381)+* Identity based encryption+* Paillier homomorphic cryptosystem+* Socialist Millionaires Protocol (needed for OTRv3)+* Hashing onto an elliptic curve (draft-irtf-cfrg-hash-to-curve)+* New PAKEs (pending CFRG bakeoff results)+* New post quantum schemes (pending NIST contest results)+* SPHINX password store (https://eprint.iacr.org/2018/695)+* X448 and Ed448+* Use GLV decomposition to speed up secp256k1 operations++Utility Functions+------------------++* Add a memory span type+* Make Memory_Pool more concurrent (currently uses a global lock)+* Guarded integer type to prevent overflow bugs+* Add logging callbacks+* Add latency tracing framework++Multiparty Protocols+----------------------++* Distributed key generation for DL, RSA+* Threshold signing, decryption++External Providers, Hardware Support+----------------------------------------++* Add support ARMv8.4-A SHA-512, SHA-3, SM3 and RNG+* Aarch64 inline asm for BigInt+* Extend OpenSSL provider (DH, HMAC, CMAC, GCM)+* Support using BoringSSL instead of OpenSSL or LibreSSL+* /dev/crypto provider (ciphers, hashes)+* Windows CryptoNG provider (ciphers, hashes)+* Extend Apple CommonCrypto provider (HMAC, CMAC, RSA, ECDSA, ECDH)+* Add support for iOS keychain access+* POWER8 SHA-2 extensions (GH #1486 + #1487)+* Add support VPSUM on big-endian PPC64 (GH #2252)+* Better TPM support: NVRAM, PCR measurements, sealing+* Add support for TPM 2.0 hardware+* Support Intel QuickAssist accelerator cards++TLS+----------------------------------------++* Make DTLS support optional at build time+* Improve/optimize DTLS defragmentation and retransmission+* Implement logging callbacks for TLS+* Make RSA optional at build time+* Make finite field DH optional at build time+* Authentication using TOFU (sqlite3 storage)+* Certificate pinning (using TACK?)+* Certificate Transparency extensions+* TLS supplemental authorization data (RFC 4680, RFC 5878)+* DTLS-SCTP (RFC 6083)++PKIX+----------------------------------------++* Further tests of validation API (see GH #785)+* Test suite for validation of 'real world' cert chains (GH #611)+* Improve output of X509_Certificate::to_string+ This is a free-form string for human consumption so the only constraints+ are being informative and concise. (GH #656)+* X.509 policy constraints+* OCSP responder logic++New Protocols / Formats+----------------------------------------++* ACME protocol+* PKCS7 / Cryptographic Message Syntax+* PKCS12 / PFX+* Off-The-Record v3 https://otr.cypherpunks.ca/+* Certificate Management Protocol (RFC 5273); requires CMS+* Fernet symmetric encryption (https://cryptography.io/en/latest/fernet/)+* RNCryptor format (https://github.com/RNCryptor/RNCryptor)+* Useful OpenPGP subset 1: symmetrically encrypted files.+ Not aiming to process arbitrary OpenPGP, but rather produce+ something that happens to be readable by `gpg` and is relatively+ simple to process for decryption. Require AEAD mode (EAX/OCB).+* Useful OpenPGP subset 2: Process OpenPGP public keys+* Useful OpenPGP subset 3: Verification of OpenPGP signatures++Cleanups+-----------++* Split test_ffi.cpp into multiple files+* Unicode path support on Windows (GH #1615)+* The X.509 path validation tests have much duplicated logic++Compat Headers+----------------++* OpenSSL compatible API headers: EVP, TLS, certificates, etc++New C APIs+----------------------------------------++* PKCS10 requests+* Certificate signing+* Expose TLS+* Expose NIST key wrap with padding+* Expose secret sharing+* Expose deterministic PRNG+* base32+* base58+* DL_Group+* EC_Group++Python+----------------++* Anywhere Pylint warnings too-many-locals, too-many-branches, or+ too-many-statements are skipped, fix the code so Pylint no longer warns.++* Write a CLI or HTTPS client in Python++Build/Test+----------------------------------------++* Start using GitHub Actions for CI, especially Windows builds+* Create Docker image for Travis that runs 18.04 and has all+ the tools we need pre-installed.+* Code signing for Windows installers+* Test runner python script that captures backtraces and other+ debug info during CI+* Support hardcoding all test vectors into the botan-test binary+ so it can run as a standalone item (copied to a device, etc)+* Run iOS binary under simulator in CI+* Run Android binary under simulator in CI+* Run the TPM tests against an emulator+ (https://github.com/PeterHuewe/tpm-emulator)+* Add clang-tidy, clang-analyzer, cppcheck to CI+* Add support for vxWorks+* Add support for Fuschia OS+* Add support for CloudABI+* Add support for SGX++CLI+----------------------------------------++* Add a ``--completion`` option to dump autocomplete info, write+ support for autocompletion in bash/zsh.+* Refactor ``speed``+* Change `tls_server` to be a tty<->socket app, like `tls_client` is,+ instead of a bogus echo server.+* `encrypt` / `decrypt` tools providing password based file encryption+* Add ECM factoring+* Clone of `minisign` signature utility+* Implementation of `tlsdate`+* Password store utility+* TOTP calculator++Documentation+----------------------------------------++* X.509 certs, path validation+* Specific docs covering one major topic (RSA, ECDSA, AES/GCM, ...)+* Some howto style docs (setting up CA, ...)
+ third_party/botan/doc/goals.rst view
@@ -0,0 +1,131 @@++Project Goals+================================++Botan seeks to be a broadly applicable library that can be used to implement a+range of secure distributed systems.++The library has the following project goals guiding changes. It does not succeed+in all of these areas in every way just yet, but it describes the system that is+the desired end result. Over time further progress is made in each.++* Secure and reliable. The implementations must of course be correct and well+ tested, and attacks such as side channels and fault attacks should be+ accounted for where necessary. The library should never crash, or invoke+ undefined behavior, regardless of circumstances.++* Implement schemes important in practice. It should be practical to implement+ any real-world crypto protocol using just what the library provides. It is+ worth some (limited) additional complexity in the library, in order to expand+ the set of applications which can easily adopt Botan.++* Ease of use. It should be straightforward for an application programmer to do+ whatever it is they need to do. There should be one obvious way to perform any+ operation. The API should be predicable, and follow the "principle of least+ astonishment" in its design. This is not just a nicety; confusing APIs often+ result in errors that end up compromising security.++* Simplicity of design, clarity of code, ease of review. The code should be easy+ to read and understand by other library developers, users seeking to better+ understand the behavior of the code, and by professional reviewers looking for+ bugs. This is important because bugs in convoluted code can easily escape+ multiple expert reviews, and end up living on for years.++* Well tested. The code should be correct against the spec, with as close to+ 100% test coverage as possible. All available static and dynamic analysis+ tools at our disposal should be used, including fuzzers, symbolic execution,+ and protocol specific tools. Within reason, all warnings from compilers and+ static analyzers should be addressed, even if they seem like false positives,+ because that maximizes the signal value of new warnings from the tool.++* Safe defaults. Policies should aim to be highly restrictive by default, and if+ they must be made less restrictive by certain applications, it should be+ obvious to the developer that they are doing something unsafe.++* Post quantum security. Possibly a practical quantum computer that can break+ RSA and ECC will never be built, but the future is notoriously hard to predict.+ It seems prudent to begin designing and deploying systems now which have at+ least the option of using a post-quantum scheme. Botan provides a conservative+ selection of algorithms thought to be post-quantum secure.++* Performance. Botan does not in every case strive to be faster than every other+ software implementation, but performance should be competitive and over time+ new optimizations are identified and applied.++* Support whatever I/O mechanism the application wants. Allow the application to+ control all aspects of how the network is contacted, and ensure the API makes+ asynchronous operations easy to handle. This both insulates Botan from+ system-specific details and allows the application to use whatever networking+ style they please.++* Portability to modern systems. Botan does not run everywhere, and we actually+ do not want it to (see non-goals below). But we do want it to run on anything+ that someone is deploying new applications on. That includes both major+ platforms like Windows, Linux, Android and iOS, and also promising new systems+ such as IncludeOS and Fuchsia.++* Well documented. Ideally every public API would have some place in the manual+ describing its usage.++* Useful command line utility. The botan command line tool should be flexible+ and featured enough to replace similar tools such as ``openssl`` for everyday+ users.++Non-Goals+-------------------------++There are goals some crypto libraries have, but which Botan actively does not+seek to address.++* Deep embedded support. Botan requires a heap, C++ exceptions, and RTTI, and at+ least in terms of performance optimizations effectively assumes a 32 or 64 bit+ processor. It is not suitable for deploying on, say FreeRTOS running on a+ MSP430, or smartcard with an 8 bit CPU and 256 bytes RAM. A larger SoC, such+ as a Cortex-A7 running Linux, is entirely within scope.++* Implementing every crypto scheme in existence. The focus is on algorithms+ which are in practical use in systems deployed now, as well as promising+ algorithms for future deployment. Many algorithms which were of interest+ in the past but never saw widespread deployment and have no compelling+ benefit over other designs have been removed to simplify the codebase.++* Portable to obsolete systems. There is no reason for crypto software to+ support ancient OS platforms like SunOS or Windows 2000, since these unpatched+ systems are completely unsafe anyway. The additional complexity supporting+ such platforms just creates more room for bugs.++* Portable to every C++ compiler ever made. Over time Botan moves forward to+ both take advantage of new language/compiler features, and to shed workarounds+ for dealing with bugs in ancient compilers, allowing further simplifications+ in the codebase. The set of supported compilers is fixed for each new release+ branch, for example Botan 2.x will always support GCC 4.8. But a future 3.x+ release version will likely increase the required versions for all compilers.++* FIPS 140 validation. The primary developer was (long ago) a consultant with a+ NIST approved testing lab. He does not have a positive view of the process or+ results, particularly when it comes to Level 1 software validations. The only+ benefit of a Level 1 validation is to allow for government sales, and the cost+ of validation includes enormous amounts of time and money, adding 'checks'+ that are useless or actively harmful, then freezing the software so security+ updates cannot be applied in the future. It does force a certain minimum+ standard (ie, FIPS Level 1 does assure AES and RSA are probably implemented+ correctly) but this is an issue of interop not security since Level 1 does not+ seriously consider attacks of any kind. Any security budget would be far+ better spent on a review from a specialized crypto consultancy, who would look+ for actual flaws.++ That said it would be easy to add a "FIPS 140" build mode to Botan, which just+ disabled all the builtin crypto and wrapped whatever the most recent OpenSSL+ FIPS module exports.++* Educational purposes. The library code is intended to be easy to read and+ review, and so might be useful in an educational context. However it does not+ contain any toy ciphers (unless you count DES and RC4) nor any tools for+ simple cryptanalysis. Generally the manual and source comments assume previous+ knowledge on the basic concepts involved.++* User proof. Some libraries provide a very high level API in an attempt to save+ the user from themselves. Occasionally they succeed. It would be appropriate+ and useful to build such an API on top of Botan, but Botan itself wants to+ cover a broad set of uses cases and some of these involve having pointy things+ within reach.
+ third_party/botan/doc/index.rst view
@@ -0,0 +1,58 @@++Getting Started+========================================++If you need to build the library first, start with :doc:`building`.+Some Linux distributions include packages for Botan, so building from+source may not be required on your system.++.. only:: html++ The :ref:`genindex` and :ref:`search` may be useful to get started.++.. only:: html and website++ You can also download this manual as a `PDF <https://botan.randombit.net/handbook/botan.pdf>`_.++Examples+----------++Some examples of usage are included in this documentation. However a better+source for example code is in the implementation of the+`command line interface <https://github.com/randombit/botan/tree/master/src/cli>`_,+which was intentionally written to act as practical examples of usage.++Books and other references+----------------------------++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+ <https://www.cl.cam.ac.uk/~rja14/book.html>`_ by Ross Anderson++- `Handbook of Applied Cryptography <http://www.cacr.math.uwaterloo.ca/hac/>`_+ by Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone++If you're doing something non-trivial or unique, you might want to at+the very least ask for review/input at a place such as the+`metzdowd <http://www.metzdowd.com/mailman/listinfo/cryptography>`_ or+`randombit <https://lists.randombit.net/mailman/listinfo/cryptography>`_+mailing lists or the+`cryptography stack exchange <https://crypto.stackexchange.com/>`_.+And (if possible) pay a professional cryptographer or security company+to review your design and code.+++.. toctree::+ :maxdepth: 1+ :numbered:
+ third_party/botan/doc/old_news.rst view
@@ -0,0 +1,4336 @@+Release Notes: 0.7.0 to 1.11.34+========================================++Version 1.10.17, 2017-10-02+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Address a side channel affecting modular exponentiation. An attacker+ capable of a local or cross-VM cache analysis attack may be able+ to recover bits of secret exponents as used in RSA, DH, etc.+ CVE-2017-14737++* Workaround a miscompilation bug in GCC 7 on x86-32 affecting GOST-34.11+ hash function. (GH #1192 #1148 #882)++* Add SecureVector::data() function which returns the start of the+ buffer. This makes it slightly simpler to support both 1.10 and 2.x+ APIs in the same codebase.++* When compiled by a C++11 (or later) compiler, a template typedef of+ SecureVector, secure_vector, is added. In 2.x this class is a+ std::vector with a custom allocator, so has a somewhat different+ interface than SecureVector in 1.10. But this makes it slightly+ simpler to support both 1.10 and 2.x APIs in the same codebase.++* Fix a bug that prevented `configure.py` from running under Python3++* Botan 1.10.x does not support the OpenSSL 1.1 API. Now the build+ will `#error` if OpenSSL 1.1 is detected. Avoid `--with-openssl`+ if compiling against 1.1 or later. (GH #753)++* Import patches from Debian adding basic support for building on+ aarch64, ppc64le, or1k, and mipsn32 platforms.++Version 1.10.16, 2017-04-04+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Fix a bug in X509 DN string comparisons that could result in out of bound+ reads. This could result in information leakage, denial of service, or+ potentially incorrect certificate validation results. (CVE-2017-2801)++* Avoid throwing during a destructor since this is undefined in C++11+ and rarely a good idea. (GH #930)++Version 1.10.15, 2017-01-12+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Fix a bug causing modular exponentiations done modulo even numbers+ to almost always be incorrect, unless the values were small. This+ bug is not known to affect any cryptographic operation in Botan. (GH #754)++* Avoid use of C++11 std::to_string in some code added in 1.10.14 (GH #747 #834)++Version 1.11.34, 2016-11-28+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Fix integer overflow during BER decoding, found by Falko Strenzke.+ This bug is not thought to be directly exploitable but upgrading ASAP+ is advised. (CVE-2016-9132)++* Add post-quantum signature scheme XMSS. Provides either 128 or 256 bit+ (post-quantum) security, with small public and private keys, fast+ verification, and reasonably small signatures (2500 bytes for 128-bit+ security). Signature generation is very slow, on the order of seconds. And+ very importantly the signature scheme is stateful: each leaf index must only+ be used once, or all security is lost. In the appropriate system where+ signatures are rarely generated (such as code signing) XMSS makes an excellent+ choice. (GH #717 #736)++* Add support for CECPQ1 TLS ciphersuites. These use a combination of x25519+ ECDH and NewHope to provide post-quantum security. The ciphersuites are not+ IETF standard, but is compatible with BoringSSL. (GH #729)++* Add support for client-side OCSP stapling to TLS. (GH #738)++* Previously both public and private keys performed automatic self testing after+ generation or loading. However this often caused unexpected application+ performance problems, and so has been removed. Instead applications must call+ check_key explicitly. (GH #704)++* Fix TLS session resumption bugs which caused resumption failures if an+ application used a single session cache for both TLS and DTLS. (GH #688)++* Add SHAKE-128 and SHAKE-256 XOFs as hash functions supporting paramaterized+ output lengths.++* Add MessageAuthenticationCode::start_msg interface, for MACs which require or+ can use a nonce (GH #691)++* Add GMAC, a MAC based on GCM (GH #488 / #691)++* Add ESP block cipher padding from RFC 4304. GH #724++* Incompatible change to HKDF: previously the HKDF type in Botan was only the+ Expand half of HKDF. Now HKDF is the full Extract-then-Expand KDF, and+ HKDF_Extract and HKDF_Expand are available. If you previously used HKDF, you+ must switch to using HKDF_Expand. (GH #723)++* Add Cipher_Mode::reset which resets message-specific state, allowing+ discarding state but allowing continued processing under the same key. (GH #552)++* The ability to add OIDs at runtime has been removed. This additionally removes+ a global lock which was acquired on each OID lookup. (GH #706)++* The default TLS policy now disables static RSA ciphersuites, all DSA+ ciphersuites, and the AES CCM-8 ciphersuites. Disabling static RSA by default+ protects servers from oracle attacks, as well as enforcing a forward secure+ ciphersuite. Some applications may be forced to re-enable RSA for interop+ reasons. DSA and CCM-8 are rarely used, and likely should not be negotiated+ outside of special circumstances.++* The default TLS policy now prefers ChaCha20Poly1305 cipher over any AES mode.++* The default TLS policy now orders ECC curve preferences in order by performance,+ with x25519 first, then P-256, then P-521, then the rest.++* Add a BSD sockets version of the HTTP client code used for OCSP. GH #699++* Export the public key workfactor functions (GH #734) and add tests for them.++* HMAC_DRBG allows configuring maximum number of bytes before reseed check (GH #690)++* Salsa20 now accepts a null IV as equivalent to an all-zero one (GH #697)++* Optimize ECKCDSA verification (GH #700 #701 #702)++* The deprecated RNGs HMAC_RNG and X9.31 RNG have been removed. Now the only+ userspace PRNG included in the library is HMAC_DRBG. (GH #692)++* The entropy sources for EGD and BeOS, as well as the Unix entropy source which+ executed processes to get statistical data have been removed. (GH #692)++* The openpgp module (which just implemented OpenPGP compatible base64 encoding+ and decoding, nothing else) has been removed.++* Added new configure.py argument `--optimize-for-size`. Currently just sets+ the flag for code size optimizations with the compiler, but may have other+ effects in the future.++* Fixed bug in Threaded_Fork causing incorrect computations (GH #695 #716)++* Add DSA deterministic parameter generation test from FIPS 186-3.++* Fix PKCS11_ECDSA_PrivateKey::check_key (GH #712)++* Fixed problems running configure.py outside of the base directory++* The BOTAN_ENTROPY_PROC_FS_PATH value in build.h was being ignored (GH #708)++* Add speed tests for ECGDSA and ECKCDSA (GH #696)++* Fix a crash in speed command for Salsa20 (GH #697)++* Allow a custom ECC curve to be specified at build time, for application or+ system specific curves. (GH #636 #710)++* Use NOMINMAX on Windows to avoid problems in amalgamation build. (GH #740)++* Add support to output bakefiles with new `configure.py` option `--with-bakefile`.+ (GH #360 #720)++* The function `zero_mem` has been renamed `secure_scrub_memory`++* More tests for pipe/filter (GH #689 #693), AEADs (GH #552), KDF::name (GH #727),++* Add a test suite for timing analysis for TLS CBC decryption, OAEP decryption,+ and PKCS #1 v1.5 decryption. These operations all have the feature that if an+ attacker can distinguish internal operations, such as through a variance in+ timing, they can use this oracle to decrypt arbitrary ciphertexts. GH #733++* Add a test suite for testing and fuzzing with TLS-Attacker, a tool for+ analyzing TLS libraries. (https://github.com/RUB-NDS/TLS-Attacker)++* Add a fuzzing framework. Supports fuzzing some APIs using AFL and libFuzzer.++* Added documentation for PKCS #11 (GH #725)++* The LibraryInitializer type is no longer needed and is now deprecated.++* The license and news files were moved from doc to the top level directory.+ There should not be any other visible change (eg, to the installed version)+ as a result of this move.++* Fixed some problems when running configure.py outside of the base directory,+ especially when using relative paths.++* Add (back) the Perl XS wrapper and sqlite encryption code.++Version 1.10.14, 2016-11-28+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* NOTE WELL: Botan 1.10.x is supported for security patches only until+ 2017-12-31++* Fix integer overflow during BER decoding, found by Falko Strenzke.+ This bug is not thought to be directly exploitable but upgrading ASAP+ is advised. (CVE-2016-9132)++* Fix two cases where (in error situations) an exception would be+ thrown from a destructor, causing a call to std::terminate.++* When RC4 is disabled in the build, also prevent it from being+ included in the OpenSSL provider. (GH #638)++Version 1.11.33, 2016-10-26+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Avoid side channel during OAEP decryption. (CVE-2016-8871)++* A countermeasure for the Lucky13 timing attack against CBC-based TLS+ ciphersuites has been added. (GH #675)++* Added X25519-based key exchange for TLS (GH #673)++* Add Certificate_Store_In_SQL which supports storing certs, keys, and+ revocation information in a SQL database. Subclass Certificate_Store_In_SQLite+ specializes with support for SQLite3 databases. (GH #631)++* The Certificate_Store interface has been changed to deal with+ ``std::shared_ptrs`` instead of raw pointers (GH #471 #631)++* Add support for official SHA-3. Keccak-1600 was already supported+ but used different padding from FIPS 202. (GH #669)++* Add SHAKE-128 based stream cipher. (GH #669)++* NewHope key exchange now supports the SHA-256/AES-128-CTR scheme+ used by BoringSSL in addition to the SHA-3/SHAKE-128 parameters used+ by the reference implementation. (GH #669)++* Add support for the TLS Supported Point Formats Extension from RFC 4492. Adds+ ``TLS::Policy::use_ecc_point_compression`` policy option. If supported on both+ sides, ECC points can be sent in compressed format which saves a few bytes+ during the handshake. (GH #645)++* Fix entropy source selection bug on Windows, which caused the CryptoAPI+ entropy source to be not available under its normal name "win32_cryptoapi" but+ instead "dev_random". GH #644++* Accept read-only access to ``/dev/urandom``. System_RNG previously required+ read-write access, to allow applications to provide inputs to the system+ PRNG. But local security policies might only allow read-only access, as is the+ case with Ubuntu's AppArmor profile for applications in the Snappy binary+ format. If opening read/write fails, System_RNG silently backs down to+ read-only, in which case calls to ``add_entropy`` on that object will fail.+ (GH #647 #648)++* Fix use of Win32 CryptoAPI RNG as an entropy source, which was accidentally+ disabled due to empty list of acceptable providers being specified. Typically+ the library would fall back to gathering entropy from OS functions returning+ statistical information, but if this functionality was disabled in the build a+ ``PRNG_Unseeded`` exception would result. (GH #655)++* Add support for building the library as part of the IncludeOS unikernel.+ This included making filesystem and threading support optional. (GH #665)++* Added ISA annotations so that with GCC (all supported versions) and+ Clang (since 3.7) it is no longer required to compile amalgamation+ files with ABI specific flags such as ``-maes``. (GH #665)++* Internal cleanups to TLS CBC record handling. TLS CBC ciphersuites+ can now be disabled by disabling ``tls_cbc`` module. (GH #642 #659)++* Internal cleanups to the object lookup code eliminates most global locks and+ all use of static initializers (GH #668 #465)++* Avoid ``static_assert`` triggering under MSVC debug builds (GH #646)++* The antique PBKDF1 password hashing scheme is deprecated and will be+ removed in a future release. It was only used to support the equally+ ancient PBES1 private key encryption scheme, which was removed in 1.11.8.++* Added MSVC debug/checked iterator builds (GH #666 #667)++* Added Linux ppc64le cross compile target to Travis CI (GH #654)++* If RC4 is disabled, also disable it coming from the OpenSSL provider (GH #641)++* Add TLS message parsing tests (GH #640)++* Updated BSI policy to prohibit DES, HKDF, HMAC_RNG (GH #649)++* Documentation improvements (GH #660 #662 #663 #670)++Version 1.11.32, 2016-09-28+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Add support for the NewHope Ring-LWE key encapsulation algorithm. This scheme+ provides an estimated ~200 bit security level against a quantum attacker while+ also being very fast and requiring only modest message sizes of 1824 and 2048+ bytes for initiator and responder, resp. This version is tested as having+ bit-for-bit identical output as the reference implementation by the authors.++ Be warned that NewHope is still a very new scheme and may yet fall to analysis.+ For best assurance, NewHope should be used only in combination with another+ key exchange mechanism, such as ECDH.++* New TLS callbacks API. Instead of numerous std::function callbacks, the+ application passes an object implementing the TLS::Callbacks interface, which+ has virtual functions matching the previous callbacks (plus some extras).+ Full source compatability with previous versions is maintained for now, but+ the old interface is deprecated and will be removed in a future release. The+ manual has been updated to reflect the changes. (GH #457 and #567)++* Add support for TLS Encrypt-then-MAC extension (GH #492 and #578), which fixes+ the known issues in the TLS CBC-HMAC construction.++* The format of the TLS session struct has changed (to support EtM), so old+ TLS session caches will be invalidated.++* How the library presents optimized algorithm implementations has changed. For+ example with the algorithm AES-128, previously there were three BlockCipher+ classes AES_128, AES_128_SSSE3, and AES_128_NI which used (resp) a table-based+ implementation vulnerable to side channels, a constant time version using+ SSSE3 SIMD extensions on modern x86, and x86 AES-NI instructions. Using the+ correct version at runtime required using ``BlockCipher::create``. Now, only+ the class AES_128 is presented, and the best available version is always used+ based on CPUID checks. The tests have been extended to selectively disable+ CPUID bits to ensure all available versions are tested. (GH #477 #623)++ Removes API classes AES_128_NI, AES_192_NI, AES_256_NI, AES_128_SSSE3,+ AES_192_SSSE3 AES_256_SSSE3, IDEA_SSE2, Noekeon_SIMD, Serpent_SIMD,+ Threefish_512_AVX2, SHA_160_SSE2++* The deprecated algorithms Rabin-Williams, Nyberg-Rueppel, MARS, RC2, RC5, RC6,+ SAFER-SK, TEA, MD2, HAS-160, and RIPEMD-128 have been removed. (GH #580)++* A new Cipher_Mode interface ``process`` allows encryption/decryption of+ buffers without requiring copying into ``secure_vector`` first. (GH #516)++* Fix verification of self-issued certificates (GH #634)++* SSE2 optimizations for ChaCha, 60% faster on both Westmere and Skylake (GH #616)++* The HMAC_RNG constructor added in 1.11.31 that took both an RNG and an+ entropy source list ignored the entropy sources.++* The configure option ``--via-amalgamation`` was renamed to ``--amalgamation``.+ The configure option ``--gen-amalgamation`` was removed. It did generate+ amalgamations but build Botan without amalgamation. Users should migrate to+ ``--amalgamation``. (GH #621)++* DH keys did not automatically self-test after being generated, contrary to+ the current behavior for other key types.++* Add tests for TLS 1.2 PRF (GH #628)++Version 1.11.31, 2016-08-30+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Fix undefined behavior in Curve25519 on platforms without a native 128-bit+ integer type. This was known to produce incorrect results on 32-bit ARM+ under Clang. GH #532 (CVE-2016-6878)++* If X509_Certificate::allowed_usage was called with more than one Key_Usage+ set in the enum value, the function would return true if *any* of the allowed+ usages were set, instead of if *all* of the allowed usages are set.+ GH #591 (CVE-2016-6879)++* Incompatible changes in DLIES: Previously the input to the KDF was+ the concatenation of the (ephemeral) public key and the secret value+ derived by the key agreement operation. Now the input is only the+ secret value obtained by the key agreement operation. That's how it+ is specified in the original paper "DHIES: An encryption scheme+ based on Diffie-Hellman Problem" or in BSI technical guideline+ TR-02102-1 for example. In addition to the already present+ XOR-encrypion/decryption mode it's now possible to use DLIES with a+ block cipher. Furthermore the order of the output was changed from+ {public key, tag, ciphertext} to {public key, ciphertext, tag}. Both+ modes are compatible with BouncyCastle.++* Add initial PKCS #11 support (GH #507). Currently includes a low level+ wrapper to all of PKCS #11 (p11.h) and high level code for RSA and ECDSA+ signatures and hardware RNG access.++* Add ECIES encryption scheme, compatible with BouncyCastle (GH #483)++* Add ECKCDSA signature algorithm (GH #504)++* Add KDF1 from ISO 18033 (GH #483)++* Add FRP256v1 curve (GH #551)++* Changes for userspace PRNGs HMAC_DRBG and HMAC_RNG (GH #520 and #593)++ These RNGs now derive from Stateful_RNG which handles issues like periodic+ reseeding and (on Unix) detecting use of fork. Previously these measures were+ included only in HMAC_RNG.++ Stateful_RNG allows reseeding from another RNG and/or a specified set of+ entropy sources. For example it is possible to configure a HMAC_DRBG to reseed+ using a PKCS #11 token RNG, the CPU's RDSEED instruction, and the system RNG+ but disabling all other entropy polls.++* AutoSeeded_RNG now uses NIST SP800-90a HMAC_DRBG(SHA-384). (GH #520)++* On Windows and Unix systems, the system PRNG is used as the sole reseeding+ source for a default AutoSeeded_RNG, completely skipping the standard entropy+ polling code. New constructors allow specifying the reseed RNG and/or entropy+ sources. (GH #520)++* The `hres_timer` entropy source module has been removed. Timestamp inputs to+ the RNG are now handled as additional_data inputs to HMAC_DRBG.++* Add RDRAND_RNG which directly exposes the CPU RNG (GH #543)++* Add PKCS #1 v1.5 id for SHA-512/256 (GH #554)++* Add X509_Time::to_std_timepoint (GH #560)++* Fix a bug in ANSI X9.23 padding mode, which returned one byte more+ than the given block size (GH #529).++* Fix bug in SipHash::clear, which did not reset all state (GH #547)++* Fixes for FreeBSD (GH #517) and OpenBSD (GH #523). The compiler defaults+ to Clang on FreeBSD now.++* SonarQube static analysis integration (GH #592)++* Switched Travis CI to Ubuntu 14.04 LTS (GH #592)++* Added ARM32, ARM64, PPC32, PPC64, and MinGW x86 cross compile targets to Travis CI (GH #608)++* Clean up in TLS ciphersuite handling (GH #583)++* Threefish-512 AVX2 optimization work (GH #581)++* Remove build configuration host and timestamp from build.h+ This makes this header reproducible and allows using ccache's direct mode+ (GH #586 see also #587)++* Prevent building for x86-64 with x86-32 compiler and the reverse (GH #585)++* Avoid build problem on 32-bit userspace ARMv8 (GH #563)++* Refactor of internal MP headers (GH #549)++* Avoid MSVC C4100 warning (GH #525)++* Change botan.exe to botan-cli.exe on Windows to workaround VC issue (GH #584)++* More tests for RSA-KEM (GH #538), DH (GH #556), EME (GH #553),+ cipher mode padding (GH #529), CTS mode (GH #531),+ KDF1/ISO18033 (GH #537), OctetString (GH #545), OIDs (GH #546),+ parallel hash (GH #548), charset handling (GH #555),+ BigInt (GH #558), HMAC_DRBG (GH #598 #600)++* New deprecations. See the full list in doc/deprecated.txt++ The X9.31 and HMAC_RNG RNGs are deprecated.+ If you need a userspace PRNG, use HMAC_DRBG (or AutoSeeded_RNG+ which is HMAC_DRBG with defaults).++ Support for getting entropy from EGD is deprecated, and will be+ removed in a future release. The developers believe that it is+ unlikely that any modern system requires EGD and so the code is now+ dead weight. If you rely on EGD support, you should contact the+ developers by email or GitHub ASAP.++ The TLS ciphersuites using 3DES and SEED are deprecated and will be+ removed in a future release.++ ECB mode Cipher_Mode is deprecated and will be removed in a future+ release.++ Support for BeOS/Haiku has not been tested in 5+ years and is in an+ unknown state. Unless reports are received of successful builds and+ use on this platform, support for BeOS/Haiku will be removed in a+ future release.++Version 1.11.30, 2016-06-19+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* In 1.11.23 a bug was introduced such that CBC-encrypted TLS packets+ containing no plaintext bytes at all were incorrectly rejected with+ a MAC failure. Records like this are used by OpenSSL in TLS 1.0+ connections in order to randomize the IV.++* A bug in GCM caused incorrect results if the 32-bit counter field+ overflowed. This bug has no implications on the security but affects+ interoperability.++ With a 96-bit nonce, this could only occur if at least 2**32 128-bit+ blocks (64 GiB) were encrypted. This actually exceeds the maximum+ allowable length of a GCM plaintext; when messages longer than+ 2**32 - 2 blocks are encrypted, GCM loses its security properties.++ In addition to 96-bit nonces, GCM also supports nonces of arbitrary+ length using a different method which hashes the provided nonce+ under the authentication key. When using such a nonce, the last 4+ bytes of the resulting CTR input might be near the overflow+ boundary, with the probability of incorrect overflow increasing with+ longer messages. when encrypting 256 MiB of data under a random 128+ bit nonce, an incorrect result would be produced about 1/256 of the+ time. With 1 MiB texts, the probability of error is reduced to 1/65536.++ Since TLS uses GCM with 96 bit nonces and limits the length of any+ record to far less than 64 GiB, TLS GCM ciphersuites are not+ affected by this bug.++ Reported by Juraj Somorovsky, described also in "Nonce-Disrespecting+ Adversaries: Practical Forgery Attacks on GCM in TLS"+ (https://eprint.iacr.org/2016/475.pdf)++* Previously when generating a new self-signed certificate or PKCS #10+ request, the subject DN was required to contain both common name+ (CN) and country (C) fields. These restrictions have been removed.+ GH #496++* The Transform and Keyed_Transform interfaces has been removed. The+ two concrete implementations of these interfaces were Cipher_Mode+ and Compressor_Transform. The Cipher_Mode interface remains unchanged+ as the Transform and Keyed_Transform signatures have moved to it;+ no changes to Cipher_Mode usage should be necessary. Any uses of+ Transform& or Keyed_Transform& to refer to a cipher should be replaced+ by Cipher_Mode&. The compression algorithm interface has changed; the start+ function now takes the per-message compression ratio to use. Previously the+ compression level to use had to be set once, at creation time, and+ the required ``secure_vector`` argument to ``start`` was required to be empty.+ The new API is documented in `compression.rst` in the manual.++* Add IETF versions of the ChaCha20Poly1305 TLS ciphersuites from+ draft-ietf-tls-chacha20-poly1305-04. The previously implemented+ (non-standard) ChaCha20Poly1305 ciphersuites from+ draft-agl-tls-chacha20poly1305 remain but are deprecated.++* The OCB TLS ciphersuites have been updated to use the new nonce+ scheme from draft-zauner-tls-aes-ocb-04. This is incompatible with+ previous versions of the draft, and the ciphersuite numbers used for+ the (still experimental) OCB ciphersuites have changed.++* Previously an unknown critical extension caused X.509 certificate+ parsing to fail; such a cert could not be created at all. Now+ parsing succeeds and the certificate validation fails with+ an error indicating an unknown critical extension. GH #469++* X509_CRL previously had an option to cause it to ignore unknown+ critical extensions. This has been removed.++* Added StreamCipher::seek allowing seeking to arbitrary position+ in the key stream. Currently only implemented for ChaCha. (GH #497)++* Added support for ChaCha stream cipher with 8 or 12 rounds.++* Add ECGDSA signature algorithm (GH #479)++* Add support for label argument to KDFs (GH #495)++* Add NIST SP800-108 and 56C KDFs (GH #481)++* Support for Card Verifiable Certificates and the obsolete EMSA1_BSI+ signature padding scheme have been removed. (GH #487)++* A bug in the IETF version of ChaCha20Poly1305 (with 96 bit nonces)+ caused incorrect computation when the plaintext or AAD was exactly+ a multiple of 16 bytes.++* Fix return type of TLS_Reader::get_u32bit, which was truncated to+ 16 bits. This only affected decoding of session ticket lifetimes.+ GH #478++* Fix OS X dylib naming problem (GH #468 #467)++* Fix bcrypt function under Python 3 (GH #461)++* The ``unix_procs`` entropy source is deprecated and will be removed+ in a future release. This entropy source attempts to get entropy by+ running Unix programs like ``arp``, ``netstat``, and ``dmesg`` which+ produce information which may be difficult for a remote attacker to+ guess. This exists primarily as a last-ditch for Unix systems+ without ``/dev/random``. But at this point such systems effectively+ no longer exist, and the use of ``fork`` and ``exec`` by the library+ complicates effective application sandboxing.++* Changes to avoid implicit cast warnings in Visual C++ (GH #484)++Version 1.10.13, 2016-04-23+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Use constant time modular inverse algorithm to avoid possible+ side channel attack against ECDSA (CVE-2016-2849)++* Use constant time PKCS #1 unpadding to avoid possible side channel+ attack against RSA decryption (CVE-2015-7827)++* Avoid a compilation problem in OpenSSL engine when ECDSA was+ disabled. Gentoo bug 542010++Version 1.11.29, 2016-03-20+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* CVE-2016-2849 DSA and ECDSA used a modular inverse function which+ had input dependent loops. It is possible a side channel attack on+ this function could be used to recover sufficient information about+ the nonce k to mount a lattice attack and recover the private key.+ Found by Sean Devlin.++* CVE-2016-2850 The TLS client did not check that the signature+ algorithm or ECC curve a v1.2 server used was actually acceptable by+ the policy. This would allow a server who ignored the preferences+ indicated in the client to use a weak algorithm, and may allow MITM+ attacks by an attacker who can break MD5 signatures or 160 bit ECC+ in real time. The server similarly failed to check on the hash a+ client used during client certificate authentication.++* Reject empty TLS records at the record processing layer since such a+ record is not valid regardless of the record type. Later checks+ already correctly rejected empty records, but during processing such+ a record, a pointer to the end of the vector was created, causing a+ assertion failure under checked iterators. Found by Juraj Somorovsky.++* Add PK_Decryptor::decrypt_or_random which allows an application to+ atomically (in constant time) check that a decrypted ciphertext has+ the expected length and/or apply content checks on the result. This+ is used by the TLS server for decrypting PKCS #1 v1.5 RSA ciphertexts.+ Previously the server used a implementation which was potentially+ vulnerable to side channels.++* Add support for processing X.509 name constraint extension during+ path validation. GH #454++* Add X509_Certificate::v3_extensions which allows retreiving the+ raw binary of all certificate extensions, including those which+ are not known to the library. This allows processing of custom+ extensions. GH #437++* Add support for module policies which are a preconfigured set of+ acceptable or prohibited modules. A policy based on BSI TR-02102-1+ is included. GH #439 #446++* Support for the deprecated TLS heartbeat extension has been removed.++* Support for the deprecated TLS minimum fragment length extension has+ been removed.++* SRP6 support is now optional in TLS++* Support for negotiating MD5 and SHA-224 signatures in TLS v1.2 has+ been removed. MD5 signatures are demonstratably insecure in TLS,+ SHA-224 is rarely used.++* Support for negotiating ECC curves secp160r1, secp160r2, secp160k1,+ secp192k1, secp192r1 (P-192), secp224k1, secp224r1 (P-224), and+ secp256k1 have been removed from the TLS implementation. All were+ already disabled in the default policy.++* HMAC_RNG now has an explicit check for fork using pid comparisons.+ It also includes the pid and system and CPU clocks into the PRF+ computation to help reduce the risk of pid wraparound. Even so,+ applications using fork and userspace RNGs should explicitly reseed+ all such RNGs whenever possible.++* Deprecation warning: support for DSA certificates in TLS is+ deprecated and will be removed in a future release.++* Deprecation warning: in addition to the algorithms deprecated in+ 1.11.26, the following algorithms are now deprecated and will be+ removed in a future release: Rabin-Williams signatures, TEA, XTEA.++* Deprecation warning: the library has a number of compiled in MODP+ and ECC DL parameters. All MODP parameter sets under 2048 bits and+ all ECC parameters under 256 bits are deprecated and will be removed+ in a future release. This includes the MODP groups "modp/ietf/1024",+ "modp/srp/1024", "modp/ietf/1536", "modp/srp/1536" and the ECC+ groups "secp160k1", "secp160r1", "secp160r2", "secp192k1",+ "secp192r1", "secp224k1", "secp224r1", "brainpool160r1",+ "brainpool192r1", "brainpool224r1", "x962_p192v2", "x962_p192v3",+ "x962_p239v1", "x962_p239v2" and "x962_p239v3". Additionally all+ compiled in DSA parameter sets ("dsa/jce/1024", "dsa/botan/2048",+ and "dsa/botan/3072") are also deprecated.++* RDSEED/RDRAND polling now retries if the operation fails. GH #373++* Fix various minor bugs found by static analysis with PVS-Studio (GH#421),+ Clang analyzer (GH #441), cppcheck (GH #444, #445), and Coverity.++* Add --with-valgrind configure option to enable building against the+ valgrind client API. This currently enables checking of const time+ operations using memcheck.++* Fix remaining Wshadow warnings. Enable Wshadow in build. GH #427++* Use noexcept in VS 2015 GH #429++* On Windows allow the user to explicitly request symlinks be used+ as part of the build. Likely only useful for someone working on+ the library itself. GH #430++* Remove use of TickCount64 introduced in 1.11.27 which caused problem+ with downstream distributors/users building XP compatiable binaries+ which is still an option even in VS 2015++* MCEIES requires KDF1 at runtime but did not require it be enabled+ in the build. GH #369++* Small optimizations to Keccak hash++* Support for locking allocator on Windows using VirtualLock. GH #450++Version 1.8.15, 2016-02-13+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+* NOTE WELL: Botan 1.8 is not supported for security issues anymore.+ Moving to 1.10 or 1.11 is certainly recommended.+* Fix CVE-2014-9742: Insufficient randomness in Miller-Rabin primality check+* Fix CVE-2016-2194: Infinite loop in modulur square root algorithm+* Fix CVE-2015-5726: Crash in BER decoder+* Fix CVE-2015-5727: Excess memory allocation in BER decoder+ Note: Unlike the fix in 1.10 which checks that the source actually+ contains enough data to satisfy the read before allocating the+ memory, 1.8.15 simply rejects all ASN.1 blocks larger than 1 MiB.+ This simpler check avoids the problem without breaking ABI.++Version 1.10.12, 2016-02-03+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* In 1.10.11, the check in PointGFp intended to check the affine y+ argument actually checked the affine x again. Reported by Remi Gacogne++ The CVE-2016-2195 overflow is not exploitable in 1.10.11 due to an+ additional check in the multiplication function itself which was+ also added in that release, so there are no security implications+ from the missed check. However to avoid confusion the change was+ pushed in a new release immediately.++ The 1.10.11 release notes incorrectly identified CVE-2016-2195 as CVE-2016-2915++Version 1.10.11, 2016-02-01+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Resolve heap overflow in ECC point decoding. CVE-2016-2195++* Resolve infinite loop in modular square root algorithm.+ CVE-2016-2194++* Correct BigInt::to_u32bit to not fail on integers of exactly 32 bits.+ GH #239++Version 1.11.28, 2016-02-01+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* One of the checks added while addressing CVE-2016-2195 was incorrect+ and could cause needless assertion failures.++Version 1.11.27, 2016-02-01+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* SECURITY: Avoid heap overflow in ECC point decoding. This could+ likely result in remote code execution. CVE-2016-2195++* SECURITY: Avoid one word heap overflow in P-521 reduction function.+ This could potentially lead to remote code execution or other+ attack. CVE-2016-2196.++* SECURITY: Avoid infinite or near-infinite loop during modular square+ root algorithm with invalid inputs. CVE-2016-2194++* Add Blake2b hash function. GH #413++* Use ``m_`` prefix on all member variables. GH #398 and #407++* Use final qualifier on many classes. GH #408++* Use noreturn attribute on assertion failure function to assist+ static analysis. GH #403++* Use TickCount64 and MemoryStatusEx in the Windows entropy source.+ Note these calls are only available in Vista/Server 2008. No+ accomodations are made for XP or Server 2003, both of which are+ no longer patched by the vendor. GH #365++Version 1.11.26, 2016-01-04+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Deprecation warnings: Nyberg-Rueppel signatures, MARS, RC2, RC5,+ RC6, SAFER, HAS-160, RIPEMD-128, MD2 and support for the TLS minimum+ fragment length extensions are all being considered for removal in a+ future release. If there is a compelling use case for keeping any of+ them in the library, please open a discussion ticket on GitHub.++* Support for the TLS extended master secret extension (RFC 7627) has+ been added.++* The format of serialized TLS sessions has changed to add a flag+ indicating support for the extended master secret flag, which is+ needed for proper handling of the extension.++* Root all exceptions thrown by the library in the ``Botan::Exception`` class.+ Previously the library would in many cases throw ``std::runtime_error``+ or ``std::invalid_argument`` exceptions which would make it hard to+ determine the source of the error in some cases.++* The command line interface has been mostly rewritten. The syntax of+ many of the sub-programs has changed, and a number have been+ extended with new features and options.++* Correct an error in PointGFp multiplication when multiplying a point+ by the scalar value 3. PointGFp::operator* would instead erronously+ compute it as if the scalar was 1 instead.++* Enable RdRand entropy source on Windows/MSVC. GH #364++* Add Intel's RdSeed as entropy source. GH #370++* Add preliminary support for accessing TPM v1.2 devices. Currently+ random number generation, RSA key generation, and signing are+ supported. Tested using Trousers and an ST TPM++* Add generalized interface for KEM (key encapsulation) techniques. Convert+ McEliece KEM to use it. The previous interfaces McEliece_KEM_Encryptor and+ McEliece_KEM_Decryptor have been removed. The new KEM interface now uses a KDF+ to hash the resulting keys; to get the same output as previously provided by+ McEliece_KEM_Encryptor, use "KDF1(SHA-512)" and request exactly 64 bytes.++* Add support for RSA-KEM from ISO 18033-2++* Add support for ECDH in the OpenSSL provider++* Fix a bug in DataSource::discard_next() which could cause either an+ infinite loop or the discarding of an incorrect number of bytes.+ Reported on mailing list by Falko Strenzke.++* Previously if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK was defined,+ the code doing low level loads/stores would use pointer casts to+ access larger words out of a (potentially misaligned) byte array,+ rather than using byte-at-a-time accesses. However even on platforms+ such as x86 where this works, it triggers UBSan errors under Clang.+ Instead use memcpy, which the C standard says is usable for such+ purposes even with misaligned values. With recent GCC and Clang, the+ same code seems to be emitted for either approach.++* Avoid calling memcpy, memset, or memmove with a length of zero to+ avoid undefined behavior, as calling these functions with an invalid+ or null pointer, even with a length of zero, is invalid. Often there+ are corner cases where this can occur, such as pointing to the very+ end of a buffer.++* The function ``RandomNumberGenerator::gen_mask`` (added in 1.11.20)+ had undefined behavior when called with a bits value of 32 or+ higher, and was tested to behave in unpleasant ways (such as+ returning zero) when compiled by common compilers. This function was+ not being used anywhere in the library and rather than support+ something without a use case to justify it it seemed simpler to+ remove it. Undefined behavior found by Daniel Neus.++* Support for using ``ctgrind`` for checking const time blocks has+ been replaced by calling the valgrind memcheck APIs directly. This+ allows const-time behavior to be tested without requiring a modified+ valgrind binary. Adding the appropriate calls requires defining+ BOTAN_HAS_VALGRIND in build.h. A binary compiled with this flag set+ can still run normally (though with some slight runtime overhead).++* Export MGF1 function mgf1_mask GH #380++* Work around a problem with some antivirus programs which causes the+ ``shutil.rmtree`` and ``os.makedirs`` Python calls to occasionally+ fail. The could prevent ``configure.py`` from running sucessfully+ on such systems. GH #353++* Let ``configure.py`` run under CPython 2.6. GH #362++Version 1.11.25, 2015-12-07+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* In this release the test suite has been largely rewritten. Previously the+ tests had internally used several different test helper frameworks created or+ adopted over time, each of which was insufficient on its own for testing the+ entire library. These have been fully converged on a new framework which+ suffices for all of the tests. There should be no user-visible change as a+ result of this, except that the output format of `botan-test` has changed.++* Improved side channel countermeasures for the table based AES implementation.+ The 4K T tables are computed (once) at runtime to avoid various cache based+ attacks which are possible due to shared VMM mappings of read only tables.+ Additionally every cache line of the table is read from prior to processing+ the block(s).++* Support for the insecure ECC groups secp112r1, secp112r2, secp128r1, and+ secp128r2 has been removed.++* The portable version of GCM has been changed to run using only+ constant time operations.++* Work around a bug in MSVC 2013 std::mutex which on some Windows+ versions can result in a deadlock during static initialization. On+ Windows a CriticalSection is used instead. Analysis and patch from+ Matej Kenda (TopIT d.o.o.). GH #321++* The OpenSSL implementation of RC4 would return the wrong value from `name` if+ leading bytes of the keystream had been skipped in the output.++* Fixed the signature of the FFI function botan_pubkey_destroy, which took the+ wrong type and was not usable.++* The TLS client would erronously reject any server key exchange packet smaller+ than 6 bytes. This prevented negotiating a plain PSK TLS ciphersuite with an+ empty identity hint. ECDHE_PSK and DHE_PSK suites were not affected.++* Fixed a bug that would cause the TLS client to occasionally reject a valid+ server key exchange message as having an invalid signature. This only affected+ DHE and SRP ciphersuites.++* Support for negotiating use of SHA-224 in TLS has been disabled in the+ default policy.++* Added `remove_all` function to the `TLS::Session_Manager` interface++* Avoid GCC warning in pedantic mode when including bigint.h GH #330++Version 1.11.24, 2015-11-04+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* When the bugs affecting X.509 path validation were fixed in 1.11.23, a check+ in Credentials_Manager::verify_certificate_chain was accidentally removed+ which caused path validation failures not to be signaled to the TLS layer.+ Thus in 1.11.23 certificate authentication in TLS is bypassed.+ Reported by Florent Le Coz in GH #324++* Fixed an endian dependency in McEliece key generation which caused+ keys to be generated differently on big and little endian systems,+ even when using a deterministic PRNG with the same seed.++* In `configure,py`, the flags for controlling use of debug, sanitizer, and+ converage information have been split out into individual options+ `--with-debug-info`, `--with-sanitizers`, and `--with-coverage`. These allow+ enabling more than one in a build in a controlled way. The `--build-mode` flag+ added in 1.11.17 has been removed.++Version 1.11.23, 2015-10-26+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* CVE-2015-7824: An information leak allowed padding oracle attacks against+ TLS CBC decryption. Found in a review by Sirrix AG and 3curity GmbH.++* CVE-2015-7825: Validating a malformed certificate chain could cause an+ infinite loop. Found in a review by Sirrix AG and 3curity GmbH.++* CVE-2015-7826: X.509 path validation violated RFC 6125 and would accept+ certificates which should not validate under those rules. In particular botan+ would accept wildcard certificates as matching in situations where it should+ not (for example it would erroneously accept ``*.example.com`` as a valid+ wildcard for ``foo.bar.example.com``)++* CVE-2015-7827: The routines for decoding PKCS #1 encryption and OAEP blocks+ have been rewritten to run without secret indexes or branches. These+ cryptographic operations are vulnerable to oracle attacks, including via side+ channels such as timing or cache-based analysis. In theory it would be+ possible to attack the previous implementations using such a side channel,+ which could allow an attacker to mount a plaintext recovery attack.++ By writing the code such that it does not depend on secret inputs for branch+ or memory indexes, such a side channel would be much less likely to exist.++ The OAEP code has previously made an attempt at constant time operation, but+ it used a construct which many compilers converted into a conditional jump.++* Add support for using ctgrind (https://github.com/agl/ctgrind) to test that+ sections of code do not use secret inputs to decide branches or memory indexes.+ The testing relies on dynamic checking using valgrind.++ So far PKCS #1 decoding, OAEP decoding, Montgomery reduction, IDEA, and+ Curve25519 have been notated and confirmed to be constant time on Linux/x86-64+ when compiled by gcc.++* Public key operations can now be used with specified providers by passing an+ additional parameter to the constructor of the PK operation.++* OpenSSL RSA provider now supports signature creation and verification.++* The blinding code used for RSA, Diffie-Hellman, ElGamal and Rabin-Williams now+ periodically reinitializes the sequence of blinding values instead of always+ deriving the next value by squaring the previous ones. The reinitializion+ interval can be controlled by the build.h parameter BOTAN_BLINDING_REINIT_INTERVAL.++* A bug decoding DTLS client hellos prevented session resumption for succeeding.++* DL_Group now prohibits creating a group smaller than 1024 bits.++* Add System_RNG type. Previously the global system RNG was only accessible via+ `system_rng` which returned a reference to the object. However is at times+ useful to have a unique_ptr<RandomNumberGenerator> which will be either the+ system RNG or an AutoSeeded_RNG, depending on availability, which this+ additional type allows.++* New command line tools `dl_group` and `prime`++* The `configure.py` option `--no-autoload` is now also available+ under the more understandable name `--minimized-build`.++* Note: 1.11.22 was briefly released on 2015-10-26. The only difference between+ the two was a fix for a compilation problem in the OpenSSL RSA code. As the+ 1.11.22 release had already been tagged it was simpler to immediately release+ 1.11.23 rather than redo the release.++Version 1.11.21, 2015-10-11+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Add new methods for creating types such as BlockCiphers or HashFunctions,+ T::providers() returning list of provider for a type, and T::create() creating+ a new object of a specified provider. The functions in lookup.h forward to+ these new APIs. A change to the lookup system in 1.11.14 had caused problems+ with static libraries (GH #52). These problems have been fixed as part of these+ changes. GH #279++* Fix loading McEliece public or private keys with PKCS::load_key / X509::load_key++* Add `mce` command line tool for McEliece key generation and file encryption++* Add Darwin_SecRandom entropy source which uses `SecRandomCopyBytes`+ API call for OS X and iOS, as this call is accessible even from a+ sandboxed application. GH #288++* Add new HMAC_DRBG constructor taking a name for the MAC to use, rather+ than a pointer to an object.++* The OCaml module is now a separate project at+ https://github.com/randombit/botan-ocaml++* The encrypted sqlite database support in contrib has moved to+ https://github.com/randombit/botan-sqlite++* The Perl XS module has been removed as it was no longer maintained.++Version 1.11.20, 2015-09-07+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* Additional countermeasures were added to ECC point multiplications+ including exponent blinding and randomization of the point+ representation to help protect against side channel attacks.++* An ECDSA provider using OpenSSL has been added.++* The ordering of algorithm priorities has been reversed. Previously+ 255 was the lowest priority and 0 was the highest priority. Now it+ is the reverse, with 0 being lowest priority and 255 being highest.+ The default priority for the base algorithms is 100. This only+ affects external providers or applications which directly set+ provider preferences.++* On OS X, rename libs to avoid trailing version numbers, e.g.+ libbotan-1.11.dylib.19 -> libbotan-1.11.19.dylib. This was requested+ by the Homebrew project package audit. GH #241, #260++* Enable use of CPUID interface with clang. GH #232++* Add support for MSVC 2015 debug builds by satisfying C++ allocator+ requirements. SO 31802806, GH #236++* Make `X509_Time` string parsing and `to_u32bit()` more strict to avoid+ integer overflows and other potentially dangerous misinterpretations.+ GH #240, #243++* Remove all 'extern "C"' declarations from src/lib/math/mp/ because some+ of those did throw exceptions and thus cannot be C methods. GH #249++* Fix build configuration for clang debug on Linux. GH #250++* Fix zlib error when compressing an empty buffer. GH #265++* Fix iOS builds by allowing multiple compiler flags with the same name.+ GH #266++* Fix Solaris build issue caused by `RLIMIT_MEMLOCK`. GH #262++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++* Botan is now fully compaitible with _GLIBCXX_DEBUG. GH #73++* BigInt::random_integer distribution was not uniform. GH #108++* Added unit testing framework Catch. GH #169++* Fix `make install`. GH #181, #186++* Public header `fs.h` moved to `internal/filesystem.h`. Added filesystem+ support for MSVC 2013 when boost is not available, allowing tests to run on+ those systems. GH #198, #199++* Added os "android" and fix Android compilation issues. GH #203++* Drop support for Python 2.6 for all Botan Python scripts. GH #217++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
+ third_party/botan/doc/packaging.rst view
@@ -0,0 +1,59 @@+Notes for Distributors+========================++This document has information for anyone who is packaging copies of Botan for+use by downstream developers, such as through a Linux distribution or other+package management system.++Recommended Options+------------------------++In most environments, zlib, bzip2, and sqlite are already installed, so there is+no reason to not include support for them in Botan as well. Build with options+``--with-zlib --with-bzip2 --with-sqlite3`` to enable these features.++Even though OpenSSL is also typically already installed, using+``--with-openssl`` by default is *not recommended*. OpenSSL is sometimes faster+and sometimes slower than Botan, and the relative speeds vary depending on the+algorithm and CPU.++Set Path to the System CA bundle+---------------------------------++Most Unix/Linux systems maintain a list of trusted CA certificates at some well+known path like ``/etc/ssl/certs/ca-certificates.crt`` or+``/etc/ssl/cert.pem``. Unfortunately the exact path varies between systems. Use+``--system-cert-bundle=PATH`` to set this path. If the option is not used,+``configure.py`` tries a list of known locations.++Set Distribution Info+------------------------++If your distribution of Botan involves creating library binaries, use the+configure.py flag ``--distribution-info=`` to set the version of your+packaging. For example Foonix OS might distribute its 4th revision of the+package for Botan 2.1.3 using ``--distribution-info='Foonix 2.1.3-4'``. The+string is completely free-form, since it depends on how the distribution numbers+releases and packages.++Any value set with ``--distribution-info`` flag will be included in the version+string, and can read through the ``BOTAN_DISTRIBUTION_INFO`` macro.++Minimize Distribution Patches+------------------------------++We (Botan upstream) *strongly* prefer that downstream distributions maintain no+long-term patches against Botan. Even if it is a build problem which probably+only affects your environment, please open an issue on github and include the+patch you are using. Perhaps the issue does affect other users, and even if not+it would be better for everyone if the library were improved so it were not+necessary for the patch to be created in the first place. For example, having to+modify or remove a build data file, or edit the makefile after generation,+suggests an area where the build system is insufficiently flexible.++Obviously nothing in the BSD-2 license prevents you from distributing patches or+modified versions of Botan however you please. But long term patches by+downstream distributors have a tendency to bitrot and sometimes even result in+security problems (such as in the Debian OpenSSL RNG fiasco) because the patches+are never reviewed by the library developers. So we try to discourage them, and+work to ensure they are never necessary.
+ third_party/botan/doc/pgpkey.txt view
@@ -0,0 +1,198 @@+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-----++This key can be used to contact the primary maintainer:++pub rsa3072/57123B60 2015-03-23+ Key fingerprint = 4E60 C735 51AF 2188 DF0A 5A62 78E9 8043 5712 3B60+ uid Jack Lloyd <jack@randombit.net>++-----BEGIN PGP PUBLIC KEY BLOCK-----++mQGNBFUQXRMBDACZJvcSkr+GNDtIdP9fQWRXByriiIKvuKbqU8KGdhTcPeKwl3y3+l1W9XsWA2DJ8QDKo4ZcV0lycszIvwBLZllJJWSVNFKxJK2IW33xcIo9dhNqj+hcz+LxKtBlBU3QKXdQ9+VKSY4EpO6gt/ar21PV+EQcFA9UtT1mRKVqY0pGGxqfQjrOss+rJKoJyA+1trH4ir7+0/524HNzsBj3B1GmrYfstspqetXyVQ1DoFiThUnj/zJGes5+uW9laI9VBgrtMTBbYrylBytXiF0Flzx+bd21krgL37NH2uU0EHPjSx571q/XGG2U+4iOEPvPu7vtV8Rpqd0xQyaHcpoHNklcfND1c/6uZG1Sx9atDScRYHinUZvtTRtN++OY5vW+H7LJqT6CeMjh6Ev53V+0JCDZFQLaBdP/NanSQBUhPkyfyQSiqWOSuaMD6n+Eu+BigmzwDlsauuReTJ65gdIGI9Egt7Ax/ooKpBvPkWeT+GORKTs+qGy6sbKXrTe+crFFN/HZPWAJ+c8AEQEAAbQhSmFjayBMbG95ZCA8amFjay5sbG95ZEBnbWFpbC5j+b20+iQG9BBMBCAAnAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheABQJXT0JHBQkE+IBi0AAoJEHjpgENXEjtgqIQL/28NiIuK+yZNvfEDifjatDUnmgaCVoF2cy02Wa1z+pKg7l2ccQBKzAoqN3j4GkgL1gxi96dp+rwgL5bwpRpVIrNLs1gFyIYDGxf/XZlbG+m8ezOA62uz8ErIdAURK+LvCpIabth7++mnUwQioGRZCjNBp6Nx7QLM2cK8n+PqMh+oLl6UZ4p3PZM76ygxOdukTXD9ExDVoiQIFCy+eh0g3JnIP6s0oAsnAl407UCqbXf+ahXI0jnaioAfpBKcWV8TGG/KQ1Ln2v5Xt56SDdYKogt0xaY8u8RAELI9Gwkhhuf/+t5kJmA/8J0qEUKUv7r8X/52PcZdjOGMnawT0mtWb13zqbAHGMhq+vW1HNwfprfes+lqfbiJ5iUC6bammgOaUao14T3wzzuk0jP2VK7owpfLTgycAkbAis5M4gmfZwbiU2++tZVU/h7E0THG7OQxbvMPeD5lcp2o4DlYqmpn07tGymiqUyqWdpHsCWS/EQYT+oN+uZQ8GeVGJq+A/WIUzDzGjQp+JokB1AQTAQoAPgIbAwULCQgHAgYVCAkKCwIEFgID+AQIeAQIXgBYhBE5gxzVRryGI3wpaYnjpgENXEjtgBQJeII8fBQkK8WWMAAoJEHjp+gENXEjtgk8EL/3HCYNwfdn2XWcbOcvGC2avq0yzxKkhtk+7fu7LbyEp7EL+ipA+f+gB7o/72ZeebVQHG8CYuYVvQzKI891hccyfQ/DfVuBrNvHq06+On6/YJuaKriP4i8+YewgJj2LKjoE1+aL6/3HmoTrlXD0h8CBuKtVptGOVxsMfVK2fkIH5pGZajMP9egV+ETIgDxLdO7FeJ4jro2fg8w+e/PqqruBxwQrdzzvjW+EqxcFNnql4CzP8JpQVuNMp+Sh1QxilrnMDIGo8l8cZ4kMIeS3V+WJuNmTo/0hbH30qMKn/vKC9CwmTxazG12X7N+9n0u0wuN8TFoAZsiYwGKiPygGxjtOzLbK9nDVd7ShFreEoFlOuTCMbc8FSk7FEGX+prgybH0if7vXM0D5dA5MYhQi8yDmgCyg8vFF3kvMqVvIidOBre0xmZI35tgufduw+ZppI4+PzrTMyLe0V6f13Sa6vE8S/hqq0FByGWUsRyfqbvmXYINxOqNxEuJ+mLhSE+pyP0Qh0c9EmQLbQgSmFjayBMbG95ZCA8bGxveWRAcmFuZG9tYml0Lm5ldD6JAbkE+EwECACMFAlUQXRMCGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRB46YBD+VxI7YI8aC/9GY4DNepqtopq1YlY1XrtyLg3tGzKvJVHXw07kGZiuvFOYXJcDzuKh+FaGuIKxJ+7PvreOXycD/9/WFXyCwvhczMgbRf3lFqkjQdmvnwmIGUfZL3pqorJDd+SjKiaXk8/NJBEBHlTN199bFECTzBr48keGHrzUPUYh2U3wo8CNW5ZsHHHmibjeoO+pfdLgK+dnUNwOk3/nEZtWUd9cTwCnd5vyxt7I1p1ntb3JLAEd4z5wd2afJHbjQZ3+uiTQBXDUd1PFH6I6fI7L+UeU+tGNPe3fe6G+zNhxmJPKBPEwzTA/r6iuLrQwNBHY+PYm6J/fKBDU117Hnwuz4W9RSVVrtizCWIba6EptFencigruCHaO4CWbFl71Cu8n6+ibEINHdKpE9qQzSD5kHfwsJ6FVnl9Qk8yJqh9U7NF/C8hHLbpF9J5n4WfN3qZyFp+UMbsEVp6Rhv/ObnxwaqNYWCqCyiCawsNk//ks4Xr+HmePJ3XA9lzvgVCoMEra+n1+RbHCEGImpUmJARwEEAEIAAYFAlYaUEwACgkQYhHr8e+637zLeQf+OdP/xE2YyFUJ+L1+xEKHpvAeN+98Vn1C2sTmotNIaPwVBY9FLeA484IWdFwnJfXx1gQyybxlytz4B+ZuC7Jzu60OEmk5IFRIqQoVywEXWCOUg/UEBWZm+ZcRzIFciqj9PcOfpt6s/aSZd5++Rcm5HUGALYCqek2s9nGO8a1Wnk4m9d1u/RAGlxFM2the1v5p597ItGhcOP3tjWV+PPOuTe0E+/FI3ZxpotKGdfS6F/GB2bP7kma2iVO621Cs9wsYmrZEamKpax7X7p9m+yaAG0YRdCTslFd/EOTLOllPhy58DTr7qyswBPEI0x8WEDTE0G0IdQYNmLq4kuzeO+aIlcUMULzYkBvwQTAQIAKQIbAwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheABQJX+T0JHBQkEIBi0AAoJEHjpgENXEjtg6wEL/0Eh78RRRk5DjWpbPuIQZFbScNlPHuVT+oNL3YNgtPvyF576aExl7ObpwsRAXPr6XxCYWhNW18ffgP42kZccGp6ACq8bhzh7g+lbjnaAR0+78Of8DHWkCYwV00kEF3QKkNRUNDSgqLC5m+QWl1os5qRhmBcfNU4/zz+51RzHqXcEPEZuHeInmrz496BNwzl/2eXnRGYENpc3FCBNsdvWwzaSotNJzdh4jFF+1eSSUFpJ6FMKRHxvtx1G8+1FjJ/NHMBjf/ulnuukl/Hf5KB/n8VWSiCD5c8X5hED+0lj9YHSJH1Q6rft5iWO+R1MyWlxZ2xJzZD5wfZ7gBEp8b32NH5mMmZqBhh5u/M7b+kpgr5ETrKlTCuARFdjzkXVfG0VszBRCFMpCmO4WAucLYEcJvqJhxOayVoFP10taC+Ouo+hPWM6v4WGMaWydcmcygscoF7u/K69om4h6kw/b2eB4DqMUe4GsaYbZHFfN/n+0FHUgQ7flpX2O5rnTrQ++Yle+fc8g36KSIkB1gQTAQoAQAIbAwcLCQgHAwIBBhUI+AgkKCwQWAgMBAh4BAheAFiEETmDHNVGvIYjfClpieOmAQ1cSO2AFAl4gjywFCQrx+ZYwACgkQeOmAQ1cSO2DZbwv/Z1+f7l71wUh44A4ovbpmK+IqhNMqDwdpltWOzT2V+UJQOrcWNIwtnycZ61S31/8XuDwOeh0xYIPYN7uayjwLpqLaPQPnU51ETH4/beCAh+ExgK9KCPrxuKmdzkTkmgsw1IFlE+iPSN58Bz0oX0KXs31JXb27RfPMK1StZqaJj3+zyq+TVnokpw8IQlWNyDuER50m0q1khim4qguXpKBKNJecmnaJVWZUwYjfoP8aOQB+3LybmGpsMshkwirueeoRBcGiqdPofTxBQYbeRVa3JWdBBuWKh6m4eYl6mvHIEdzG+7KmPG/bWCJSf8fVBcm/MH65aa7CcoKkCPuN+vDq9w3/Yp8+pxQlQFaRqvHGhQkxb+xvn2kmgZt7CDRJYjYaD++I598S6YecA2hstNh8lj1YyPgU4/wFJ8N27+pI13koda+n7tXx8LO6WjH45SPDgTEaO3i65rUQ3NHhQ8gGa8GUrTc1G+kzCG6+WvhYRrwn5gC+Z+39H2CXLtWzgx0qvyXNqToGtB9KYWNrIExsb3lkIDxqYWNrQHJhbmRvbWJpdC5u+ZXQ+iQG9BBMBCAAnBQJYCsPpAhsDBQkEIBi0BQsJCAcCBhUICQoLAgQWAgMBAh4B+AheAAAoJEHjpgENXEjtgqiML/3u7F/QhLb9FabkuicFrxmsHrNs2M6EKlSB3ZCjM+1krH/Ca59PpK4tjG8pC1FzJyb95vwE93qwl0yR+/K1PU94fudN9FFEHpcDIgh/rH+QEZg9fZWZe6EmizJA7kbYrJvqZr7x/cmMV17EQHSJMPKiboAkaKejm7m7CiPpoU4+fPATesU2wbN5uifSVsKWJYv28O0SawkoUC1aTG1HTxAblEriivQ5c2R45VcylcGd+BG17xztSttiREG5nuzk26ZeB/19kLhgSAYEack+EQegFkzKxGQ2R4ScaZulqjjaB+mQ688P56R2E+ly+Vjga3tck9ydxu/3KBvMqdEs1NSjx+74ULS4XwpPr+lVffKBOK+r/5RC+jr5Z692rN3+IukkBG3a2iKJdRPcTSCeq4qZ75ZdYb5KCZK83Mh8jAaqd7g+utimOTbywFBJeBWlDfAIolrQTMe8+wuOhWq48sdevxUMospb1RQ/oqq+DPGyNFN9+hMdAxEvJaffEdSge/QyrTiMll4kB1AQTAQoAPgIbAwULCQgHAgYVCAkKCwIEFgID+AQIeAQIXgBYhBE5gxzVRryGI3wpaYnjpgENXEjtgBQJeII8sBQkK8WWMAAoJEHjp+gENXEjtgHqsL/0+CKqak4LUcrXuHUj0pcbNsr8RNRqHon+ICVQhOyYcZkUkGmUic+4CVl3Gsus8kEfQmM9yP4T/+7CqDUFMDBihKnZ7evYJ2/SLmrjbmfdnQFIC03gjUa+i2QlInpBU2CFWJOmlm8tJt3fnQ6whAIj9380kJFkLDP7XBP5LN6YkCiCvopT3Jr8+sunOxxG/uT2oy+mXDsySPAr0NRvkymc7tGqO62Qst0ZYsrR4wnVGZNdmsdYN6jt8+/2JQasOaIEFgYXLB4XqxjYrfcZryeESCeDorXSRvpreokJoOZpeThdDpGC32JHkI+CBz1BaH5j8DJSedZN/LJdWi63E+eR6V8sFPvpt6oPgCELATskVZzOepFUlpr+5Vi++/aCv2TvFfUkMh/Oa3dOn2k83a5kSuT66ODkfs8IOEII51tApSsUngs/JlNvD8iX+8INgBnb8DJUen1FucmAwOhl9Uzh3VuBbWW3mB2uCwwQVHHL49NURP/S3TvoFrWbF+IXM7NLfQA+nubLkBjQRVEF0TAQwA3o0T99H866uziNzpJpWhwpJn7+kZdWvFD9kW+htruQmrT0MtBnbW8diSrvAysC1r0PqAflstn3TEjpJzJH19hNZgNd0MfHxKDsyPd+kqHGOvW1CJxE9PoE/hYuoEgJ2VRZX/84JEWTXcbx94M75lPxg/91VSuPef3+bB84+ebs2lvs8df8sW4PKj/URdlnKrDf8uUj7P7W4EoVgPZarMvDxKb9T5qPM/rLTjBSR+/jlWMuQUjZs+ToJVg23ZO84TMg7fMEA3oNItIU5Nif1TBHa+um+gmwOONJGNyNtn+/y4UJZ8uGBPAx5BwfSPEevjtCzZygCkcEAgHnt5Lpn/LhWNrdjQA2lvnUW7swM9d+BdbiDz0YxMgQq7b8pQ3+icYhiHomz1Fg1/xIn7BpDQ1QtcAyTUAB+SeXYCmX2ApE+MfoS969Bc9UjoSU5NnDiCobP3EaoL6BuaHZSZLmfwH+crZ3QAw37V6VkBqlMUV04+yEx0N4GT7UZFD+3/OwtNQ9JJFUsXABEBAAGJAZ8EGAECAAkFAlUQXRMCGwwACgkQ+eOmAQ1cSO2DeuAwAgMmCe4Rjud64kwjMfI7n1rxf72Kn1d94M3CNqomTSsiipJ2Q+iqMbwjoLiVt4vSmcbOWK528SZCKPiGdI185STnygbJF3JR4r14LYp5n4ezeyoy4C+GVgiH5FHqJ+jmSrFH+B6jqJcpLxWoNBGKqhJKsuqEhTuRCIVxBZzfBhpI5Rc2lnO++VOUxgzio/1ivO7x0bW0pJPd+ZaLyX39OYcg+2ySAHR3NN2Qp7aRmkkUWq5i2ita+0JDAX7Ca0DTY0wfCtDPCH9Go3P3BQTCFBUFr8DynTB0SyQsVBle3c+djwYdBXPn2+0CuiXDeR6zT9Wu2AJQVLu2+af3EjqUnG95CI3oRzbPmBvAoFKGRK+imLSDzdgt5I+0+sIgGYtII6bUCOxcXexBrMRioAaEHqqJsKy55vGemurxBr+PTCyrufxk7trpx1y+eG7h8Xdh1ZxpaUJQrPNZvxZdeh4Jo4rGYPkiCwaIDGc8q+wGB7WsyGUKgkmEkSZS+XDGg/rs23aYdtiH9+=M25I+-----END PGP PUBLIC KEY BLOCK-----+++This key is used for signing git commits:++pub rsa2048/AB50F90D 2016-03-03 [SC] [expires: 2020-03-02]+ Key fingerprint = 1175 1014 9DF4 18AB D19C B06D 9FFD 596F AB50 F90D+ uid Jack Lloyd (Git Signing Key) <jack@randombit.net>++-----BEGIN PGP PUBLIC KEY BLOCK-----++mQENBFbYWi4BCACjgz3gYgWMybPLiovNLnLonG0ex2y9kJgsR+Pm08L2fwCVCaHx+wjlK5Oq04x3bvujZk7P0TThqS1WonYtEiVxz3Hcvt7rlU5fSCj/1uYmZV+mbPBdY+f/yXMx3UD1UkZrdzbM21L78dfOoLZ2ybyuk4QOEad/AkouDCUA2pY3DJdNyX8Aee+dBdQ+sQqF6DyDz4SDY+KAq3nFmmT04bdkiL9sZb2HUokxIdeA6HIR+CxxFaZzrYW+Ky4iNPS1Zxv5D1KmpZzUOfN9RTgkbdRltgWxjpB+DFNUkpu3hYm/Y9lTPqGBt2C8+JfIS5OaHxUVz0A+DtIGy+lk8/O5ek4suQBZ3ABEBAAG0MUphY2sgTGxveWQgKEdp+dCBTaWduaW5nIEtleSkgPGphY2tAcmFuZG9tYml0Lm5ldD6JAVcEEwEIAEECGwMF+CwkIBwIGFQgJCgsCBBYCAwECHgECF4ACGQEWIQQRdRAUnfQYq9GcsG2f/Vlvq1D5+DQUCXl5bBQUJDSmbVwAKCRCf/Vlvq1D5DcTHB/9t0LZYlso93Jdq+ozRNTuo/SJl+MdViPlZ+upLi/5DqXBzUsNp9S4NkaaCendOIPbugSiGwWMk8LQpb7pTlbVFUJoem+Y0BUwuS5uk6YK4gxrTFl1P+VCbLA3UjXch1GWfh8JSp7SMcC0vcPd3WmuI06VdiU+sMeWThP56UA9SJbwWM735bosgYtdE3BMnEjDmvnmLcM3cn+saW+TkTFr/kkGjFHA+1Fg62vRfvsPokq5S1PdUjE7eY5u2W2r94mMcS/kY/Xg470XsBSbyjIviqX2irXgf+Ln0bmqsxNWiedocdVrdsk4n98eLXosKq4HKSWO9fwlwbF6P78K5Ygu1z2eGXiQE9+BBMBCAAnBQJYD2ybAhsDBQkHhM4ABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ+EJ/9WW+rUPkNXfIIAIOgepYeZN2HL2T3A8pk+5JR2cfBoRufYgnG6mVHPejgZDW++9PH1tPDgidnePw3/jfD1oskt1VwOCkqaSBAcG2QeOBEklcsrQuvOfW7B7XFydYGw+T9Fm8/sxekiGjDQQWQEEH4j3Vt1GlI2sJrpqMe/WMXISsEnLfw0kDspUSlFOn8oy+rBU9Pd8KaSi38lp05a9Mcun5enJ3JpQHQ5RlNXDNh/Sn9NZ+MKWggytZqIy82jnv+6zo0raZDup4hLKopjen/SINR5XcwRK2lUtYVwwQH8FHG9IkeVJNWJkVCdZLB08sq+4WHRbtVjy6mpvEHTmolAtHjLSiV5W50LDKLwX260MkphY2sgTGxveWQgKEdpdCBT+aWduaW5nIEtleSkgPGxsb3lkQHJhbmRvbWJpdC5uZXQ+iQE9BBMBCAAnBQJW2FwD+AhsDBQkHhM4ABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEJ/9WW+rUPkNK3cI+AI+6M5JixbjdyoVSDor0RW4u5h6UESe2mRZ5YFzh8F5uGms8PE5HrIZAfNVy9lJr+DoLSPpeb5KLAdGpaJ1NuJJ2glYzZFYr05gVHgCKJgfo6jkW22XnwO+vyXK+6TB6A+ExgO0RdN5aZcHL8KCfCWncVsWvF8d2cvbdb3sTfqtZoZ0l1DyYA62pz5BZd+iySj+nWGsL9YM53pC6hhq62onSqfv0X0fqzZ3+zIqTgVMOJxIFCXBiUBkHEuizUULfPrP+xfAiaEQcaOcpEos+/OsG3e3nFmXEAlDa9ZsS2VEaZ/nFJPIaKeDXt80ptScnxp2t+lecw8hR/OfJJ6MFMw4W/J8WJAZwEEAEIAAYFAlbYXDcACgkQeOmAQ1cSO2C8Kwv/+ebJNrhMoknG5dSPVJpJxL0ta/m4KYBjX94VsB6Ofz96UmnNlCe9Exbi02ecLygQf+B9UUv7nsrORGOSoIEIV/RSYgN2eYUM21DHddlgVG3DTRrG//iV6rzAdgkZdRkxBh+nzeFJRv4TMmnRQXM2x+gjognDWLpjgdvkRFcv5l6fTH24IldcdymnvmqBmsLvqoK+Fj13CtsDjngp5gGgp/ieIW6sPmgQX1pJCWHFDe/0qcjvuy0fKMq0Oyd0/8dXCnNa+wPb/9xlQY+lCpHILfvFsVty5djqHqDNKEBuYxyPjHICPGRukSK+zCS0EE8nz/oxo+r4OIr5svawfIO5Zw69USo01jC+K1OSRJQthFft5GqTwkfHniYJSVh7K1rPI/H35t+f+XZLBwlafWs7vQb8XZfAPzhqw9blc5RS478rqzNQ0F1PHITjbaSCkMCgaNa2aea+oIw9uQjp6uB2T4xGAeqsd6JPrr5g1VZFPqthXdiDu6JmN4aVksG/SCx2Cwv2qiuS+=kPHM+-----END PGP PUBLIC KEY BLOCK-----
+ third_party/botan/doc/roadmap.rst view
@@ -0,0 +1,54 @@++Development Roadmap+========================================++Near Term Plans+----------------------------------------++Here is an outline for the development plans over the next 12-18 months, as of+June 2019.++TLS Hardening/Testing+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Leverage TLS-Attacker better, for example using custom workflows. Add+interop testing with OpenSSL as part of CI. Improve fuzzer coverage.++Expose TLS at FFI layer+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++Exposing TLS to C would allow for many new applications to make use of Botan.++TLS v1.3+^^^^^^^^^^^^^^^++A complete implementation of TLS v1.3 is planned. DTLS v1.3 may or may not be+supported as well.++Botan 3.x+----------------------------------------++Botan 3 is currently planned for release in 2021. Botan 2 will remain+supported for several years past that, to allow plenty of time for+applications to switch over.++This version will adopt C++17 and use new std types such as string_view,+optional, and any, along with adopting memory span and guarded integer+types. All deprecated features/APIs of 2.x (which notably includes TLS v1.0/v1.1+support) will be removed. Beyond explicitly deprecated functionality, there+should be no breaking API changes in the transition to 3.x++Features currently targeted for Botan 3 include++* New post-quantum algorithms: especially a CCA2 secure encryption scheme and a+ lattice-based signature scheme are of interest.++* Password Authenticated Key Exchanges: one or more modern PAKEs+ (such as SPAKE2+ or OPAQUE) to replace SRP.++* Elliptic Curve Pairings: useful in many interesting protocols.+ BN-256 and BLS12-381 seem the most likely.++* New ASN.1 library++Some of these features may end being backported to Botan 2 as well.
+ third_party/botan/doc/security.rst view
@@ -0,0 +1,352 @@++.. highlight:: none++Security Advisories+========================================++If you think you have found a security bug in Botan please contact+Jack Lloyd (jack@randombit.net). If you would like to encrypt your+mail please use::++ pub rsa3072/57123B60 2015-03-23+ Key fingerprint = 4E60 C735 51AF 2188 DF0A 5A62 78E9 8043 5712 3B60+ uid Jack Lloyd <jack@randombit.net>++This key can be found in the file ``doc/pgpkey.txt`` or online at+https://keybase.io/jacklloyd and on most PGP keyservers.++2020+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2020-07-05: Failure to enforce name constraints on alternative names++ The path validation algorithm enforced name constraints on the primary DN+ included in the certificate but failed to do so against alternative DNs which+ may be included in the subject alternative name. This would allow a corrupted+ sub-CA which was constrained by a name constraints extension in its own+ certificate to issue a certificate containing a prohibited DN. Until 2.15.0,+ there was no API to access these alternative name DNs so it is unlikely that+ any application would make incorrect access control decisions on the basis of+ the incorrect DN. Reported by Mario Korth of Ruhr-Universität Bochum.++ Introduced in 1.11.29, fixed in 2.15.0++* 2020-03-24: Side channel during CBC padding++ The CBC padding operations were not constant time and as a result would leak+ the length of the plaintext values which were being padded to an attacker+ running a side channel attack via shared resources such as cache or branch+ predictor. No information about the contents was leaked, but the length alone+ might be used to make inferences about the contents. This issue affects TLS+ CBC ciphersuites as well as CBC encryption using PKCS7 or other similar padding+ mechanisms. In all cases, the unpadding operations were already constant time+ and are not affected. Reported by Maximilian Blochberger of Universität+ Hamburg.++ Fixed in 2.14.0, all prior versions affected.++2018+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2018-12-17 (CVE-2018-20187): Side channel during ECC key generation++ A timing side channel during ECC key generation could leak information about+ the high bits of the secret scalar. Such information allows an attacker to+ perform a brute force attack on the key somewhat more efficiently than they+ would otherwise. Found by Ján Jančár using ECTester.++ Introduced in 1.11.20, fixed in 2.8.0.++* 2018-06-13 (CVE-2018-12435): ECDSA side channel++ A side channel in the ECDSA signature operation could allow a local attacker+ to recover the secret key. Found by Keegan Ryan of NCC Group.++ Bug introduced in 2.5.0, fixed in 2.7.0. The 1.10 branch is not affected.++* 2018-04-10 (CVE-2018-9860): Memory overread in TLS CBC decryption++ An off by one error in TLS CBC decryption meant that for a particular+ malformed ciphertext, the receiver would miscompute a length field and HMAC+ exactly 64K bytes of data following the record buffer as if it was part of the+ message. This cannot be used to leak information since the MAC comparison will+ subsequently fail and the connection will be closed. However it might be used+ for denial of service. Found by OSS-Fuzz.++ Bug introduced in 1.11.32, fixed in 2.6.0++* 2018-03-29 (CVE-2018-9127): Invalid wildcard match++ RFC 6125 wildcard matching was incorrectly implemented, so that a wildcard+ certificate such as ``b*.domain.com`` would match any hosts ``*b*.domain.com``+ instead of just server names beginning with ``b``. The host and certificate+ would still have to be in the same domain name. Reported by Fabian Weißberg of+ Rohde and Schwarz Cybersecurity.++ Bug introduced in 2.2.0, fixed in 2.5.0++2017+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2017-10-02 (CVE-2017-14737): Potential side channel using cache information++ In the Montgomery exponentiation code, a table of precomputed values+ is used. An attacker able to analyze which cache lines were accessed+ (perhaps via an active attack such as Prime+Probe) could recover+ information about the exponent. Identified in "CacheD: Identifying+ Cache-Based Timing Channels in Production Software" by Wang, Wang,+ Liu, Zhang, and Wu (Usenix Security 2017).++ Fixed in 1.10.17 and 2.3.0, all prior versions affected.++* 2017-07-16: Failure to fully zeroize memory before free++ The secure_allocator type attempts to zeroize memory before freeing it. Due to+ a error sometimes only a portion of the memory would be zeroed, because of a+ confusion between the number of elements vs the number of bytes that those+ elements use. So byte vectors would always be fully zeroed (since the two+ notions result in the same value), but for example with an array of 32-bit+ integers, only the first 1/4 of the elements would be zeroed before being+ deallocated. This may result in information leakage, if an attacker can access+ memory on the heap. Reported by Roman Pozlevich.++ Bug introduced in 1.11.10, fixed in 2.2.0++* 2017-04-04 (CVE-2017-2801): Incorrect comparison in X.509 DN strings++ Botan's implementation of X.509 name comparisons had a flaw which+ could result in an out of bound memory read while processing a+ specially formed DN. This could potentially be exploited for+ information disclosure or denial of service, or result in incorrect+ validation results. Found independently by Aleksandar Nikolic of+ Cisco Talos, and OSS-Fuzz automated fuzzing infrastructure.++ Bug introduced in 1.6.0 or earlier, fixed in 2.1.0 and 1.10.16++* 2017-03-23 (CVE-2017-7252): Incorrect bcrypt computation++ Botan's implementation of bcrypt password hashing scheme truncated long+ passwords at 56 characters, instead of at bcrypt's standard 72 characters+ limit. Passwords with lengths between these two bounds could be cracked more+ easily than should be the case due to the final password bytes being ignored.+ Found and reported by Solar Designer.++ Bug introduced in 1.11.0, fixed in 2.1.0.++2016+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2016-11-27 (CVE-2016-9132) Integer overflow in BER decoder++ While decoding BER length fields, an integer overflow could occur. This could+ occur while parsing untrusted inputs such as X.509 certificates. The overflow+ does not seem to lead to any obviously exploitable condition, but exploitation+ cannot be positively ruled out. Only 32-bit platforms are likely affected; to+ cause an overflow on 64-bit the parsed data would have to be many gigabytes.+ Bug found by Falko Strenzke, cryptosource GmbH.++ Fixed in 1.10.14 and 1.11.34, all prior versions affected.++* 2016-10-26 (CVE-2016-8871) OAEP side channel++ A side channel in OAEP decoding could be used to distinguish RSA ciphertexts+ that did or did not have a leading 0 byte. For an attacker capable of+ precisely measuring the time taken for OAEP decoding, this could be used as an+ oracle allowing decryption of arbitrary RSA ciphertexts. Remote exploitation+ seems difficult as OAEP decoding is always paired with RSA decryption, which+ takes substantially more (and variable) time, and so will tend to mask the+ timing channel. This attack does seems well within reach of a local attacker+ capable of a cache or branch predictor based side channel attack. Finding,+ analysis, and patch by Juraj Somorovsky.++ Introduced in 1.11.29, fixed in 1.11.33++* 2016-08-30 (CVE-2016-6878) Undefined behavior in Curve25519++ On systems without a native 128-bit integer type, the Curve25519 code invoked+ undefined behavior. This was known to produce incorrect results on 32-bit ARM+ when compiled by Clang.++ Introduced in 1.11.12, fixed in 1.11.31++* 2016-08-30 (CVE-2016-6879) Bad result from X509_Certificate::allowed_usage++ If allowed_usage was called with more than one Key_Usage set in the enum+ value, the function would return true if *any* of the allowed usages were set,+ instead of if *all* of the allowed usages are set. This could be used to+ bypass an application key usage check. Credit to Daniel Neus of Rohde &+ Schwarz Cybersecurity for finding this issue.++ Introduced in 1.11.0, fixed in 1.11.31++* 2016-03-17 (CVE-2016-2849): ECDSA side channel++ ECDSA (and DSA) signature algorithms perform a modular inverse on the+ signature nonce `k`. The modular inverse algorithm used had input dependent+ loops, and it is possible a side channel attack could recover sufficient+ information about the nonce to eventually recover the ECDSA secret key. Found+ by Sean Devlin.++ Introduced in 1.7.15, fixed in 1.10.13 and 1.11.29++* 2016-03-17 (CVE-2016-2850): Failure to enforce TLS policy++ TLS v1.2 allows negotiating which signature algorithms and hash functions each+ side is willing to accept. However received signatures were not actually+ checked against the specified policy. This had the effect of allowing a+ server to use an MD5 or SHA-1 signature, even though the default policy+ prohibits it. The same issue affected client cert authentication.++ The TLS client also failed to verify that the ECC curve the server chose to+ use was one which was acceptable by the client policy.++ Introduced in 1.11.0, fixed in 1.11.29++* 2016-02-01 (CVE-2016-2196): Overwrite in P-521 reduction++ The P-521 reduction function would overwrite zero to one word+ following the allocated block. This could potentially result+ in remote code execution or a crash. Found with AFL++ Introduced in 1.11.10, fixed in 1.11.27++* 2016-02-01 (CVE-2016-2195): Heap overflow on invalid ECC point++ The PointGFp constructor did not check that the affine coordinate+ arguments were less than the prime, but then in curve multiplication+ assumed that both arguments if multiplied would fit into an integer+ twice the size of the prime.++ The bigint_mul and bigint_sqr functions received the size of the+ output buffer, but only used it to dispatch to a faster algorithm in+ cases where there was sufficient output space to call an unrolled+ multiplication function.++ The result is a heap overflow accessible via ECC point decoding,+ which accepted untrusted inputs. This is likely exploitable for+ remote code execution.++ On systems which use the mlock pool allocator, it would allow an+ attacker to overwrite memory held in secure_vector objects. After+ this point the write will hit the guard page at the end of the+ mmap'ed region so it probably could not be used for code execution+ directly, but would allow overwriting adjacent key material.++ Found by Alex Gaynor fuzzing with AFL++ Introduced in 1.9.18, fixed in 1.11.27 and 1.10.11++* 2016-02-01 (CVE-2016-2194): Infinite loop in modular square root algorithm++ The ressol function implements the Tonelli-Shanks algorithm for+ finding square roots could be sent into a nearly infinite loop due+ to a misplaced conditional check. This could occur if a composite+ modulus is provided, as this algorithm is only defined for primes.+ This function is exposed to attacker controlled input via the OS2ECP+ function during ECC point decompression. Found by AFL++ Introduced in 1.7.15, fixed in 1.11.27 and 1.10.11++2015+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2015-11-04: TLS certificate authentication bypass++ When the bugs affecting X.509 path validation were fixed in 1.11.22, a check+ in Credentials_Manager::verify_certificate_chain was accidentally removed+ which caused path validation failures not to be signaled to the TLS layer. So+ for affected versions, certificate authentication in TLS is bypassed. As a+ workaround, applications can override the call and implement the correct+ check. Reported by Florent Le Coz in GH #324++ Introduced in 1.11.22, fixed in 1.11.24++* 2015-10-26 (CVE-2015-7824): Padding oracle attack on TLS++ A padding oracle attack was possible against TLS CBC ciphersuites because if a+ certain length check on the packet fields failed, a different alert type than+ one used for message authentication failure would be returned to the sender.+ This check triggering would leak information about the value of the padding+ bytes and could be used to perform iterative decryption.++ As with most such oracle attacks, the danger depends on the underlying+ protocol - HTTP servers are particularly vulnerable. The current analysis+ suggests that to exploit it an attacker would first have to guess several+ bytes of plaintext, but again this is quite possible in many situations+ including HTTP.++ Found in a review by Sirrix AG and 3curity GmbH.++ Introduced in 1.11.0, fixed in 1.11.22++* 2015-10-26 (CVE-2015-7825): Infinite loop during certificate path validation++ When evaluating a certificate path, if a loop in the certificate chain+ was encountered (for instance where C1 certifies C2, which certifies C1)+ an infinite loop would occur eventually resulting in memory exhaustion.+ Found in a review by Sirrix AG and 3curity GmbH.++ Introduced in 1.11.6, fixed in 1.11.22++* 2015-10-26 (CVE-2015-7826): Acceptance of invalid certificate names++ RFC 6125 specifies how to match a X.509v3 certificate against a DNS name+ for application usage.++ Otherwise valid certificates using wildcards would be accepted as matching+ certain hostnames that should they should not according to RFC 6125. For+ example a certificate issued for ``*.example.com`` should match+ ``foo.example.com`` but not ``example.com`` or ``bar.foo.example.com``. Previously+ Botan would accept such a certificate as also valid for ``bar.foo.example.com``.++ RFC 6125 also requires that when matching a X.509 certificate against a DNS+ name, the CN entry is only compared if no subjectAlternativeName entry is+ available. Previously X509_Certificate::matches_dns_name would always check+ both names.++ Found in a review by Sirrix AG and 3curity GmbH.++ Introduced in 1.11.0, fixed in 1.11.22++* 2015-10-26 (CVE-2015-7827): PKCS #1 v1.5 decoding was not constant time++ During RSA decryption, how long decoding of PKCS #1 v1.5 padding took was+ input dependent. If these differences could be measured by an attacker, it+ could be used to mount a Bleichenbacher million-message attack. PKCS #1 v1.5+ decoding has been rewritten to use a sequence of operations which do not+ contain any input-dependent indexes or jumps. Notations for checking constant+ time blocks with ctgrind (https://github.com/agl/ctgrind) were added to PKCS+ #1 decoding among other areas. Found in a review by Sirrix AG and 3curity GmbH.++ Fixed in 1.11.22 and 1.10.13. Affected all previous versions.++* 2015-08-03 (CVE-2015-5726): Crash in BER decoder++ 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. This can be+ used to easily crash applications reading untrusted ASN.1 data, but does not+ seem exploitable for code execution. Found with afl.++ Fixed in 1.11.19 and 1.10.10, affected all previous versions of 1.10 and 1.11++* 2015-08-03 (CVE-2015-5727): Excess memory allocation in BER decoder++ 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.++ Fixed in 1.11.19 and 1.10.10, affected all previous versions of 1.10 and 1.11++2014+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^++* 2014-04-10 (CVE-2014-9742): Insufficient randomness in Miller-Rabin primality check++ A bug in the Miller-Rabin primality test resulted in only a single random base+ being used instead of a sequence of such bases. This increased the probability+ that a non-prime would be accepted by is_prime or that a randomly generated+ prime might actually be composite. The probability of a random 1024 bit+ number being incorrectly classed as prime with a single base is around 2^-40.+ Reported by Jeff Marrison.++ Introduced in 1.8.3, fixed in 1.10.8 and 1.11.9
+ third_party/botan/doc/side_channels.rst view
@@ -0,0 +1,449 @@+Side Channels+=========================++Many cryptographic systems can be easily broken by side channels. This document+notes side channel protections which are currently implemented, as well as areas+of the code which are known to be vulnerable to side channels. The latter are+obviously all open for future improvement.++The following text assumes the reader is already familiar with cryptographic+implementations, side channel attacks, and common countermeasures.++Modular Exponentiation+------------------------++Modular exponentiation uses a fixed window algorithm with Montgomery+representation. A side channel silent table lookup is used to access the+precomputed powers. The caller provides the maximum possible bit length of the+exponent, and the exponent is zero-padded as required. For example, in a DSA+signature with 256-bit q, the caller will specify a maximum length of exponent+of 256 bits, even if the k that was generated was 250 bits. This avoids leaking+the length of the exponent through the number of loop iterations.+See monty_exp.cpp and monty.cpp++Karatsuba multiplication algorithm avoids any conditional branches; in+cases where different operations must be performed it instead uses masked+operations. See mp_karat.cpp for details.++The Montgomery reduction is written to run in constant time.+The final reduction is handled with a masked subtraction. See mp_monty.cpp.++Barrett Reduction+--------------------++The Barrett reduction code is written to avoid input dependent branches. The+Barrett algorithm only works for inputs up to a certain size, and larger values+fall back on a different (slower) division algorithm. This secondary algorithm+is also const time, but the branch allows detecting when a value larger than+2^{2k} was reduced, where k is the word length of the modulus. This leaks only+the size of the two values, and not anything else about their value.++RSA+----------------------++Blinding is always used to protect private key operations (there is no way to+turn it off). Both base blinding and exponent blinding are used.++For base blinding, as an optimization, instead of choosing a new random mask and+inverse with each decryption, both the mask and its inverse are simply squared+to choose the next blinding factor. This is much faster than computing a fresh+value each time, and the additional relation is thought to provide only minimal+useful information for an attacker. Every BOTAN_BLINDING_REINIT_INTERVAL+(default 64) operations, a new starting point is chosen.++Exponent blinding uses new values for each signature, with 64 bit masks.++RSA signing uses the CRT optimization, which is much faster but vulnerable to+trivial fault attacks [RsaFault] which can result in the key being entirely+compromised. To protect against this (or any other computational error which+would have the same effect as a fault attack in this case), after every private+key operation the result is checked for consistency with the public key. This+introduces only slight additional overhead and blocks most fault attacks; it is+possible to use a second fault attack to bypass this verification, but such a+double fault attack requires significantly more control on the part of an+attacker than a BellCore style attack, which is possible if any error at all+occurs during either modular exponentiation involved in the RSA signature+operation.++See blinding.cpp and rsa.cpp.++If the OpenSSL provider is enabled, then no explicit blinding is done; we assume+OpenSSL handles this. See openssl_rsa.cpp.++Decryption of PKCS #1 v1.5 Ciphertexts+----------------------------------------++This padding scheme is used with RSA, and is very vulnerable to errors. In a+scenario where an attacker can repeatedly present RSA ciphertexts, and a+legitimate key holder will attempt to decrypt each ciphertext and simply+indicates to the attacker if the PKCS padding was valid or not (without+revealing any additional information), the attacker can use this behavior as an+oracle to perform iterative decryption of arbitrary RSA ciphertexts encrypted+under that key. This is the famous million message attack [MillionMsg]. A side+channel such as a difference in time taken to handle valid and invalid RSA+ciphertexts is enough to mount the attack [MillionMsgTiming].++As a first step, the PKCS v1.5 decoding operation runs without any+conditional jumps or indexes, with the only variance in runtime being+based on the length of the public modulus, which is public information.++Preventing the attack in full requires some application level changes. In+protocols which know the expected length of the encrypted key, PK_Decryptor+provides the function `decrypt_or_random` which first generates a random fake+key, then decrypts the presented ciphertext, then in constant time either copies+out the random key or the decrypted plaintext depending on if the ciphertext was+valid or not (valid padding and expected plaintext length). Then in the case of+an attack, the protocol will carry on with a randomly chosen key, which will+presumably cause total failure in a way that does not allow an attacker to+distinguish (via any timing or other side channel, nor any error messages+specific to the one situation vs the other) if the RSA padding was valid or+invalid.++One very important user of PKCS #1 v1.5 encryption is the TLS protocol. In TLS,+some extra versioning information is embedded in the plaintext message, along+with the key. It turns out that this version information must be treated in an+identical (constant-time) way with the PKCS padding, or again the system is+broken. [VersionOracle]. This is supported by a special version of+PK_Decryptor::decrypt_or_random that additionally allows verifying one or more+content bytes, in addition to the PKCS padding.++See eme_pkcs.cpp and pubkey.cpp.++Verification of PKCS #1 v1.5 Signatures+----------------------------------------++One way of verifying PKCS #1 v1.5 signature padding is to decode it with an+ASN.1 BER parser. However such a design commonly leads to accepting signatures+besides the (single) valid RSA PKCS #1 v1.5 signature for any given message,+because often the BER parser accepts variations of the encoding which are+actually invalid. It also needlessly exposes the BER parser to untrusted inputs.++It is safer and simpler to instead re-encode the hash value we are expecting+using the PKCS #1 v1.5 encoding rules, and const time compare our expected+encoding with the output of the RSA operation. So that is what Botan does.++See emsa_pkcs.cpp.++OAEP+----------------------++RSA OAEP is (PKCS#1 v2) is the recommended version of RSA encoding standard,+because it is not directly vulnerable to Bleichenbacher attack. However, if+implemented incorrectly, a side channel can be presented to an attacker and+create an oracle for decrypting RSA ciphertexts [OaepTiming].++This attack is avoided in Botan by making the OAEP decoding operation run+without any conditional jumps or indexes, with the only variance in runtime+coming from the length of the RSA key (which is public information).++See eme_oaep.cpp.++ECC point decoding+----------------------++The API function OS2ECP, which is used to convert byte strings to ECC points,+verifies that all points satisfy the ECC curve equation. Points that do not+satisfy the equation are invalid, and can sometimes be used to break+protocols ([InvalidCurve] [InvalidCurveTLS]). See point_gfp.cpp.++ECC scalar multiply+----------------------++There are several different implementations of ECC scalar multiplications which+depend on the API invoked. This include ``PointGFp::operator*``,+``EC_Group::blinded_base_point_multiply`` and+``EC_Group::blinded_var_point_multiply``.++The ``PointGFp::operator*`` implementation uses the Montgomery ladder, which is+fairly resistant to side channels. However it leaks the size of the scalar,+because the loop iterations are bounded by the scalar size. It should not be+used in cases when the scalar is a secret.++Both ``blinded_base_point_multiply`` and ``blinded_var_point_multiply`` apply+side channel countermeasures. The scalar is masked by a multiple of the group+order (this is commonly called Coron's first countermeasure [CoronDpa]),+currently the mask is an 80 bit random value.++Botan stores all ECC points in Jacobian representation. This form allows faster+computation by representing points (x,y) as (X,Y,Z) where x=X/Z^2 and+y=Y/Z^3. As the representation is redundant, for any randomly chosen non-zero r,+(X*r^2,Y*r^3,Z*r) is an equivalent point. Changing the point values prevents an+attacker from mounting attacks based on the input point remaining unchanged over+multiple executions. This is commonly called Coron's third countermeasure, see+again [CoronDpa].++The base point multiplication algorithm is a comb-like technique which+precomputes ``P^i,(2*P)^i,(3*P)^i`` for all ``i`` in the range of valid scalars.+This means the scalar multiplication involves only point additions and no+doublings, which may help against attacks which rely on distinguishing between+point doublings and point additions. The elements of the table are accessed by+masked lookups, so as not to leak information about bits of the scalar via a+cache side channel. However, whenever 3 sequential bits of the (masked) scalar+are all 0, no operation is performed in that iteration of the loop. This exposes+the scalar multiply to a cache-based side channel attack; scalar blinding is+necessary to prevent this attack from leaking information about the scalar.++The variable point multiplication algorithm uses a fixed-window algorithm. Since+this is normally invoked using untrusted points (eg during ECDH key exchange) it+randomizes all inputs to prevent attacks which are based on chosen input+points. The table of precomputed multiples is accessed using a masked lookup+which should not leak information about the secret scalar to an attacker who can+mount a cache-based side channel attack.++See point_gfp.cpp and point_mul.cpp++ECDH+----------------------++ECDH verifies (through its use of OS2ECP) that all input points received from+the other party satisfy the curve equation. This prevents twist attacks. The+same check is performed on the output point, which helps prevent fault attacks.++ECDSA+----------------------++Inversion of the ECDSA nonce k must be done in constant time, as any leak of+even a single bit of the nonce can be sufficient to allow recovering the private+key. In Botan all inverses modulo an odd number are performed using a constant+time algorithm due to Niels Möller.++x25519+----------------------++The x25519 code is independent of the main Weierstrass form ECC code, instead+based on curve25519-donna-c64.c by Adam Langley. The code seems immune to cache+based side channels. It does make use of integer multiplications; on some old+CPUs these multiplications take variable time and might allow a side channel+attack. This is not considered a problem on modern processors.++TLS CBC ciphersuites+----------------------++The original TLS v1.0 CBC Mac-then-Encrypt mode is vulnerable to an oracle+attack. If an attacker can distinguish padding errors through different error+messages [TlsCbcOracle] or via a side channel attack like [Lucky13], they can+abuse the server as a decryption oracle.++The side channel protection for Lucky13 follows the approach proposed in the+Lucky13 paper. It is not perfectly constant time, but does hide the padding+oracle in practice. Tools to test TLS CBC decoding are included in the timing+tests. See https://github.com/randombit/botan/pull/675 for more information.++The Encrypt-then-MAC extension, which completely avoids the side channel, is+implemented and used by default for CBC ciphersuites.++CBC mode padding+----------------------++In theory, any good protocol protects CBC ciphertexts with a MAC. But in+practice, some protocols are not good and cannot be fixed immediately. To avoid+making a bad problem worse, the code to handle decoding CBC ciphertext padding+bytes runs in constant time, depending only on the block size of the cipher.++AES+----------------------++Some x86, ARMv8 and POWER processors support AES instructions which+are fast and are thought to be side channel silent. These instructions+are used when available.++On CPUs which do not have hardware AES instructions but do support SIMD vectors+with a byte shuffle (including x86's SSSE3, ARM's NEON and PowerPC AltiVec), a+version of AES is implemented which is side channel silent. This implementation+is based on code by Mike Hamburg [VectorAes], see aes_vperm.cpp.++On all other processors, a constant time bitsliced implementation is used. This+is typically slower than the vector permute implementation, and additionally for+best performance multiple blocks must be processed in parellel. So modes such+as CTR, GCM or XTS are relatively fast, but others such as CBC encryption+suffer.++GCM+---------------------++On platforms that support a carryless multiply instruction (ARMv8 and recent x86),+GCM is fast and constant time.++On all other platforms, GCM uses an algorithm based on precomputing all powers+of H from 1 to 128. Then for every bit of the input a mask is formed which+allows conditionally adding that power without leaking information via a cache+side channel. There is also an SSSE3 variant of this algorithm which is somewhat+faster on processors which have SSSE3 but no AES-NI instructions.++OCB+-----------------------++It is straightforward to implement OCB mode in a efficient way that does not+depend on any secret branches or lookups. See ocb.cpp for the implementation.++Poly1305+----------------------++The Poly1305 implementation does not have any secret lookups or conditionals.+The code is based on the public domain version by Andrew Moon.++DES/3DES+----------------------++The DES implementation uses table lookups, and is likely vulnerable to side+channel attacks. DES or 3DES should be avoided in new systems. The proper fix+would be a scalar bitsliced implementation, this is not seen as worth the+engineering investment given these algorithms end of life status.++Twofish+------------------------++This algorithm uses table lookups with secret sboxes. No cache-based side+channel attack on Twofish has ever been published, but it is possible nobody+sufficiently skilled has ever tried.++ChaCha20, Serpent, Threefish, ...+-----------------------------------++Some algorithms including ChaCha, Salsa, Serpent and Threefish are 'naturally'+silent to cache and timing side channels on all recent processors.++IDEA+---------------++IDEA encryption, decryption, and key schedule are implemented to take constant+time regardless of their inputs.++Hash Functions+-------------------------++Most hash functions included in Botan such as MD5, SHA-1, SHA-2, SHA-3, Skein,+and BLAKE2 do not require any input-dependent memory lookups, and so seem to not be+affected by common CPU side channels. However the implementations of Whirlpool+and Streebog use table lookups and probably can be attacked by side channels.++Memory comparisons+----------------------++The function same_mem in header mem_ops.h provides a constant-time comparison+function. It is used when comparing MACs or other secret values. It is also+exposed for application use.++Memory zeroizing+----------------------++There is no way in portable C/C++ to zero out an array before freeing it, in+such a way that it is guaranteed that the compiler will not elide the+'additional' (seemingly unnecessary) writes to zero out the memory.++The function secure_scrub_memory (in mem_ops.cpp) uses some system specific+trick to zero out an array. If possible an OS provided routine (such as+``RtlSecureZeroMemory`` or ``explicit_bzero``) is used.++On other platforms, by default the trick of referencing memset through a+volatile function pointer is used. This approach is not guaranteed to work on+all platforms, and currently there is no systematic check of the resulting+binary function that it is compiled as expected. But, it is the best approach+currently known and has been verified to work as expected on common platforms.++If BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO is set to 0 in build.h (not the default) a+byte at a time loop through a volatile pointer is used to overwrite the array.++Memory allocation+----------------------++Botan's secure_vector type is a std::vector with a custom allocator. The+allocator calls secure_scrub_memory before freeing memory.++Some operating systems support an API call to lock a range of pages+into memory, such that they will never be swapped out (``mlock`` on POSIX,+``VirtualLock`` on Windows). On many POSIX systems ``mlock`` is only usable by+root, but on Linux, FreeBSD and possibly other systems a small amount+of memory can be locked by processes without extra credentials.++If available, Botan uses such a region for storing key material. A page-aligned+block of memory is allocated and locked, then the memory is scrubbed before+freeing. This memory pool is used by secure_vector when available. It can be+disabled at runtime setting the environment variable BOTAN_MLOCK_POOL_SIZE to 0.++Automated Analysis+---------------------++Currently the main tool used by the Botan developers for testing for side+channels at runtime is valgrind; valgrind's runtime API is used to taint memory+values, and any jumps or indexes using data derived from these values will cause+a valgrind warning. This technique was first used by Adam Langley in ctgrind.+See header ct_utils.h.++To check, install valgrind, configure the build with --with-valgrind, and run+the tests.++.. highlight:: shell++There is also a test utility built into the command line util, `timing_test`,+which runs an operation on several different inputs many times in order to+detect simple timing differences. The output can be processed using the+Mona timing report library (https://github.com/seecurity/mona-timing-report).+To run a timing report (here for example pow_mod)::++ $ ./botan timing_test pow_mod > pow_mod.raw++This must be run from a checkout of the source, or otherwise ``--test-data-dir=``+must be used to point to the expected input files.++Build and run the Mona report as::++ $ git clone https://github.com/seecurity/mona-timing-report.git+ $ cd mona-timing-report+ $ ant+ $ java -jar ReportingTool.jar --lowerBound=0.4 --upperBound=0.5 --inputFile=pow_mod.raw --name=PowMod++This will produce plots and an HTML file in subdirectory starting with+``reports_`` followed by a representation of the current date and time.++References+---------------++[Aes256Sc] Neve, Tiri "On the complexity of side-channel attacks on AES-256"+(https://eprint.iacr.org/2007/318.pdf)++[AesCacheColl] Bonneau, Mironov "Cache-Collision Timing Attacks Against AES"+(http://www.jbonneau.com/doc/BM06-CHES-aes_cache_timing.pdf)++[CoronDpa] Coron,+"Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems"+(https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.5695)++[InvalidCurve] Biehl, Meyer, Müller: Differential fault attacks on+elliptic curve cryptosystems+(https://www.iacr.org/archive/crypto2000/18800131/18800131.pdf)++[InvalidCurveTLS] Jager, Schwenk, Somorovsky: Practical Invalid Curve+Attacks on TLS-ECDH+(https://www.nds.rub.de/research/publications/ESORICS15/)++[SafeCurves] Bernstein, Lange: SafeCurves: choosing safe curves for+elliptic-curve cryptography. (https://safecurves.cr.yp.to)++[Lucky13] AlFardan, Paterson "Lucky Thirteen: Breaking the TLS and DTLS Record Protocols"+(http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)++[MillionMsg] Bleichenbacher "Chosen Ciphertext Attacks Against Protocols Based+on the RSA Encryption Standard PKCS1"+(https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.8543)++[MillionMsgTiming] Meyer, Somorovsky, Weiss, Schwenk, Schinzel, Tews: Revisiting+SSL/TLS Implementations: New Bleichenbacher Side Channels and Attacks+(https://www.nds.rub.de/research/publications/mswsst2014-bleichenbacher-usenix14/)++[OaepTiming] Manger, "A Chosen Ciphertext Attack on RSA Optimal Asymmetric+Encryption Padding (OAEP) as Standardized in PKCS #1 v2.0"+(http://archiv.infsec.ethz.ch/education/fs08/secsem/Manger01.pdf)++[RsaFault] Boneh, Demillo, Lipton+"On the importance of checking cryptographic protocols for faults"+(https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.9764)++[RandomMonty] Le, Tan, Tunstall "Randomizing the Montgomery Powering Ladder"+(https://eprint.iacr.org/2015/657)++[VectorAes] Hamburg, "Accelerating AES with Vector Permute Instructions"+https://shiftleft.org/papers/vector_aes/vector_aes.pdf++[VersionOracle] Klíma, Pokorný, Rosa "Attacking RSA-based Sessions in SSL/TLS"+(https://eprint.iacr.org/2003/052)
+ third_party/botan/doc/support.rst view
@@ -0,0 +1,70 @@+Support Information+=======================++Supported Platforms+------------------------++For Botan 2, the tier-1 supported platforms are++* Linux x86-64, GCC 4.8 or higher+* Linux x86-64, Clang 3.5 or higher+* Linux aarch64, GCC 4.8++* Linux ppc64le, GCC 4.8++* Windows x86-64, Visual C++ 2015 and 2017++These platforms are all tested by continuous integration, and the developers+have access to hardware in order to test patches. Problems affecting these+platforms are considered release blockers.++For Botan 2, the tier-2 supported platforms are++* Linux x86-32, GCC 4.8++* Linux arm32, GCC 4.8++* Windows x86-64, MinGW GCC+* macOS x86-64, XCode Clang+* iOS aarch64, XCode Clang+* Android aarch64, NDK Clang+* FreeBSD x86-64, Clang 3.8+++Some (but not all) of the tier-2 platforms are tested by CI. Everything should+work, and if problems are encountered, the developers will probably be able to+help. But they are not as carefully tested as tier-1.++Of course most other modern OSes such as QNX, AIX, OpenBSD, NetBSD, and Solaris+also work just fine. Some are tested occasionally, usually just before a new+release. But very little code specific to these platforms is written by the+primary developers. For example, any functionality in the library which+utilizes OpenBSD specific APIs was likely contributed by someone interested in+that platform.++In theory any working C++11 compiler is fine but in practice, we only regularly+test with GCC, Clang, and Visual C++. Recent versions of IBM XLC can compile+the library but occasionally codegen bugs occur. Several other compilers (such+as Intel and PGI) are supported by the build system but are not tested by the+developers and may have build or codegen problems. Patches to improve support+for these compilers is welcome.++Branch Support Status+-------------------------++Following table provides the support status for Botan branches as of+September 2020. Any branch not listed here (including 1.11) is no+longer supported. Dates in the future are approximate.++============== ============== ========================== ============+Branch First Release End of Active Development End of Life+============== ============== ========================== ============+1.8 2008-12-08 2010-08-31 2016-02-13+1.10 2011-06-20 2012-07-10 2018-12-31+2.x 2017-01-06 2020-10-05 2024-01-01 or later+3.x 2021? ? ?+============== ============== ========================== ============++"Active development" refers to adding new features and optimizations. At the+conclusion of the active development phase, only bugfixes are applied.++Getting Help+------------------++To get help with Botan, open an issue on+`GitHub <https://github.com/randombit/botan/issues>`_
+ third_party/botan/src/bogo_shim/config.json view
@@ -0,0 +1,128 @@+{+ "LooseErrorTests": {+ "AppDataBeforeHandshake": "BoGo expects different error before vs after CCS",+ "AppDataBeforeHandshake-Empty": "Invalid record message",+ "ServerHelloBogusCipher": "Unexpected error",+ "Garbage": "Decoding error",+ "Resume-Client-CipherMismatch": "Unexpected error",+ "InvalidECDHPoint-Server": "Unexpected error",+ "NoSharedCipher": "Unexpected error"+ },++ "DisabledTests": {+ "*KeyUpdate*": "No TLS 1.3",+ "*TLS13*": "No TLS 1.3",+ "Server-JDK11*": "No TLS 1.3",+ "*Binder*": "No TLS 1.3",+ "PartialEncryptedExtensionsWithServerHello": "No TLS 1.3",+ "Client-RejectJDK11DowngradeRandom": "No TLS 1.3",+ "FragmentedClientVersion": "No TLS 1.3",+ "NoExportEarlyKeyingMaterial*": "No TLS 1.3",+ "EarlyDataEnabled*": "No TLS 1.3",+ "DelegatedCredentials*": "No TLS 1.3",+ "ExportTrafficSecrets-*": "No TLS 1.3",+ "IgnoreClientVersionOrder": "No TLS 1.3",+ "Resume-Server-OmitPSKsOnSecondClientHello": "No TLS 1.3",++ "DuplicateCertCompressionExt*": "No support for 1.3 cert compression extension",++ "SupportedVersionSelection-TLS12": "We just ignore the version extension in this case",++ "Downgrade-*-Client-Ignore": "Not possible to ignore downgrade indicator",+ "Downgrade-TLS12-*": "Not a downgrade when we don't support v1.3",++ "*SSL3*": "No SSLv3",+ "*SSLv3*": "No SSLv3",++ "*NPN*": "No support for NPN",+ "ALPNServer-Preferred-*": "No support for NPN",+ "*-NextProtocol": "No support for NPN",++ "*SignedCertificateTimestamp*": "No support for SCT",+ "*SCT*": "No support for SCT",+ "Renegotiation-ChangeAuthProperties": "No support for SCT",+ "UnsolicitedCertificateExtensions-TLS*": "No support for SCT",++ "*NULL-SHA*": "No support for NULL ciphers",+ "*WITH_NULL*": "No support for NULL ciphers",+ "*GREASE*": "No support for GREASE",+ "QUICTransportParams*": "No support for QUIC",+ "*ChannelID*": "No support for ChannelID",+ "*TokenBinding*": "No support for Token Binding",+ "ClientHelloPadding": "No support for client hello padding extension",+ "TLSUnique*": "Not supported",+ "*CECPQ2*": "Not implemented",+ "PQExperimentSignal*": "Not implemented",+ "*P-224*": "P-224 not supported in TLS",+ "*V2ClientHello*": "No support for SSLv2 client hellos",+ "*Ed25519*": "Ed25519 not implemented in TLS",+ "Http*": "Stack does not have detection logic for HTTP",+ "*FalseStart*": "Botan doesn't do false start",+ "MaxSendFragment*": "Maximum fragment extension not supported",+ "ExportKeyingMaterial-EmptyContext*": "No support for empty context",++ "Peek-*": "No peek API",+ "*OldCallback*": "BoringSSL specific API test",+ "*Renegotiate-Client-Explicit*": "BoringSSL specific API test",+ "CBCRecordSplittingPartialWrite*": "BoringSSL specific API test",+ "TicketCallback*": "BoringSSL specific API test",+ "Server-DDoS*": "BoringSSL specific API test",+ "RetainOnlySHA256-*": "BoringSSL specific API test",+ "Renegotiate-Client-UnfinishedWrite": "BoringSSL specific API test",+ "FailEarlyCallback": "BoringSSL specific API test",++ "ShimTicketRewritable": "Botan has a different ticket format",+ "Resume-Server-DeclineCrossVersion*": "Botan has a different ticket format",+ "Resume-Server-DeclineBadCipher*": "Botan has a different ticket format",+ "Resume-Server-CipherNotPreferred*": "Botan has a different ticket format",++ "TLS*-NoTicket-NoAccept": "BoGo expects that if ticket is issued stateful resumption is impossible",++ "CheckLeafCurve": "Botan doesn't care what curve an ECDSA cert uses",++ "CertificateVerificationDoesNotFailOnResume*": "Botan doesn't support reverify on resume",+ "CertificateVerificationFailsOnResume*": "Botan doesn't support reverify on resume",+ "CertificateVerificationPassesOnResume*": "Botan doesn't support reverify on resume",++ "CipherNegotiation-2": "No support for cipher equivalence classes",+ "CipherNegotiation-3": "No support for cipher equivalence classes",+ "CipherNegotiation-4": "No support for cipher equivalence classes",+ "CipherNegotiation-5": "No support for cipher equivalence classes",+ "CipherNegotiation-8": "No support for cipher equivalence classes",++ "ALPNServer-SelectEmpty-*": "Botan treats empty ALPN from callback as a decline",++ "AppDataAfterChangeCipherSpec-DTLS*": "BoringSSL DTLS drops out of order AppData, we reject",++ "Resume-Client-NoResume-TLS1-TLS11": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-NoResume-TLS1-TLS12": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-NoResume-TLS11-TLS12": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-NoResume-TLS1-TLS12-DTLS": "BoGo expects resumption attempt sends latest version",++ "Resume-Client-Mismatch-TLS1-TLS11": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-Mismatch-TLS1-TLS12": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-Mismatch-TLS11-TLS12": "BoGo expects resumption attempt sends latest version",+ "Resume-Client-Mismatch-TLS1-TLS12-DTLS": "BoGo expects resumption attempt sends latest version",++ "CurveTest-*-Compressed*": "Point compression is supported, which BoGo doesn't expect",+ "PointFormat-*-MissingUncompressed": "Point compression is supported, which BoGo doesn't expect",++ "RSAPSSSupport-ConfigPSS-NoCerts-TLS12-*": "Needs investigation",+ "RSAPSSSupport-Default-NoCerts-TLS12-*": "Needs investigation",++ "DTLS-Retransmit*": "Shim needs timeout support",++ "DTLS-StrayRetransmitFinished-ClientFull": "Needs investigation",+ "DTLS-StrayRetransmitFinished-ServerResume": "Needs investigation",++ "SRTP-Server-IgnoreMKI-*": "Non-empty MKI is rejected (bug)",++ "Renegotiate-Client-Packed": "Packing HelloRequest with Finished loses the HelloRequest (bug)",+ "SendHalfHelloRequest*PackHandshake": "Packing HelloRequest with Finished loses the HelloRequest (bug)",++ "PartialClientFinishedWithClientHello": "Need to check for buffered messages when CCS (bug)",+ "SendUnencryptedFinished-DTLS": "Need to check for buffered messages when CCS (bug)",++ "RSAKeyUsage-*-UnenforcedTLS*": "We always enforce key usage"+ }+}
third_party/botan/src/lib/ffi/ffi.h view
@@ -1633,6 +1633,8 @@ BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_load_file(botan_x509_certstore_t* certstore_obj, const char* certstore_path); +BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj);+ BOTAN_PUBLIC_API(2,19) int botan_x509_certstore_destroy(botan_x509_certstore_t crl); BOTAN_PUBLIC_API(2,19)
third_party/botan/src/lib/ffi/ffi_cert.cpp view
@@ -17,9 +17,15 @@ #endif #if defined(BOTAN_HAS_CERTSTOR_FLATFILE)- #include <botan/certstor_flatfile/certstor_flatfile.h>+ #include <botan/certstor_flatfile.h> #endif +#if defined(BOTAN_HAS_CERTSTOR_MACOS)+ #include <botan/certstor_macos.h>+#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)+ #include <botan/certstor_windows.h>+#endif+ extern "C" { using namespace Botan_FFI;@@ -522,6 +528,33 @@ return ffi_guard_thunk(__func__, [=]() -> int { std::unique_ptr<Botan::Certificate_Store> c(new Botan::Flatfile_Certificate_Store(certstore_path));+ *certstore_obj = new botan_x509_certstore_struct(c.release());+ return BOTAN_FFI_SUCCESS;+ });++#else+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;+#endif+ }++int botan_x509_certstore_load_system(botan_x509_certstore_t* certstore_obj)+ {+ if(!certstore_obj)+ return BOTAN_FFI_ERROR_NULL_POINTER;++#if defined(BOTAN_HAS_X509_CERTIFICATES) ++ return ffi_guard_thunk(__func__, [=]() -> int {+#if defined(BOTAN_HAS_CERTSTOR_MACOS)+ std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_MacOS);+#elif defined(BOTAN_HAS_CERTSTOR_WINDOWS)+ std::unique_ptr<Botan::Certificate_Store> c(new Botan::Certificate_Store_Windows);+#elif defined(BOTAN_HAS_CERTSTOR_FLATFILE) && defined(BOTAN_SYSTEM_CERT_BUNDLE)+ std::unique_ptr<Botan::Certificate_Store> c(+ new Botan::Flatfile_Certificate_Store(BOTAN_SYSTEM_CERT_BUNDLE, true));+#else+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;+#endif *certstore_obj = new botan_x509_certstore_struct(c.release()); return BOTAN_FFI_SUCCESS; });
third_party/cacert.md view
@@ -1,4 +1,4 @@ CA certificates extracted from Mozilla ====================================== -This bundle was generated at Wed Oct 14 03:12:15 2020 GMT, see https://curl.haxx.se/docs/caextract.html.+This bundle was generated at Tue Apr 13 03:12:04 2021 GMT, see https://curl.haxx.se/docs/caextract.html.
third_party/cacert.pem view
@@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ##-## Certificate data from Mozilla as of: Wed Oct 14 03:12:15 2020 GMT+## Certificate data from Mozilla as of: Tue Apr 13 03:12:04 2021 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates@@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.28.-## SHA256: a831d3bc63ba1f65478afe28038742b7150c0c2efd243ac342b64792a75d2038+## SHA256: f377673fa3c22ba2188a4cea041c7b8c99a4817ffde6821e98325ce89324e5aa ## @@ -132,87 +132,6 @@ tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -GeoTrust Global CA-==================------BEGIN CERTIFICATE------MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK-Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw-MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j-LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB-CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo-BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet-8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc-T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU-vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD-AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk-DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q-zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4-d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2-mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p-XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm-Mw==------END CERTIFICATE-------GeoTrust Universal CA-=====================------BEGIN CERTIFICATE------MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN-R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1-MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu-Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP-ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t-JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e-RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs-7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d-8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V-qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga-Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB-Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu-KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08-ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0-XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB-hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc-aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2-qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL-oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK-xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF-KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2-DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK-xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU-p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI-P/rmMuGNG2+k5o7Y+SlIis5z/iw=------END CERTIFICATE-------GeoTrust Universal CA 2-=======================------BEGIN CERTIFICATE------MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN-R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0-MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg-SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA-A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0-DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17-j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q-JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a-QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2-WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP-20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn-ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC-SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG-8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2-+/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E-BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z-dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ-4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+-mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq-A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg-Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP-pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d-FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp-gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm-X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS------END CERTIFICATE------ Comodo AAA Services root ======================== -----BEGIN CERTIFICATE-----@@ -596,78 +515,6 @@ DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -GeoTrust Primary Certification Authority-========================================------BEGIN CERTIFICATE------MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx-CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ-cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB-CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN-b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9-nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge-RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt-tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD-AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI-hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K-Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN-NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa-Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG-1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=------END CERTIFICATE-------thawte Primary Root CA-======================------BEGIN CERTIFICATE------MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE-BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2-aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv-cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3-MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg-SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv-KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT-FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs-oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ-1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc-q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K-aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p-afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF-AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE-uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89-jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH-z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==------END CERTIFICATE-------VeriSign Class 3 Public Primary Certification Authority - G5-============================================================------BEGIN CERTIFICATE------MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO-ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk-IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp-ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln-biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh-dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw-ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz-j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD-Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/-Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r-fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/-BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv-Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG-SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+-X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE-KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC-Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE-ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq------END CERTIFICATE------ SecureTrust CA ============== -----BEGIN CERTIFICATE-----@@ -871,136 +718,6 @@ TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD -----END CERTIFICATE----- -GeoTrust Primary Certification Authority - G3-=============================================------BEGIN CERTIFICATE------MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE-BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0-IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy-eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz-NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo-YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT-LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI-hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j-K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE-c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C-IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu-dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC-MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr-2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9-cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE-Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s-t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt------END CERTIFICATE-------thawte Primary Root CA - G2-===========================------BEGIN CERTIFICATE------MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC-VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu-IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg-Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV-MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG-b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt-IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS-LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5-8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU-mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN-G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K-rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==------END CERTIFICATE-------thawte Primary Root CA - G3-===========================------BEGIN CERTIFICATE------MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE-BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2-aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv-cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w-ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh-d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD-VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG-A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A-MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At-P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC-+BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY-7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW-vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ-KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK-A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC-8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm-er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=------END CERTIFICATE-------GeoTrust Primary Certification Authority - G2-=============================================------BEGIN CERTIFICATE------MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC-VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu-Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1-OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg-MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl-b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG-BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc-KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+-EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m-ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2-npaqBA+K------END CERTIFICATE-------VeriSign Universal Root Certification Authority-===============================================------BEGIN CERTIFICATE------MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE-BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO-ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk-IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u-IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv-cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl-IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0-aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj-1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP-MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72-9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I-AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR-tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G-CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O-a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3-Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx-Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx-P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P-wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4-mJO37M2CYfE45k+XmCpajQ==------END CERTIFICATE-------VeriSign Class 3 Public Primary Certification Authority - G4-============================================================------BEGIN CERTIFICATE------MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC-VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3-b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz-ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj-YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU-cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo-b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5-IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8-Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz-rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB-/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw-HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u-Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD-A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx-AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==------END CERTIFICATE------ NetLock Arany (Class Gold) Főtanúsítvány ======================================== -----BEGIN CERTIFICATE-----@@ -2218,36 +1935,6 @@ yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- -Staat der Nederlanden Root CA - G3-==================================------BEGIN CERTIFICATE------MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE-CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g-Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC-TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l-ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y-olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t-x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy-EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K-Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur-mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5-1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp-07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo-FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE-41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB-AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu-yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD-U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq-KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1-v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA-8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b-8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r-mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq-1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI-JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV-tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=------END CERTIFICATE------ Staat der Nederlanden EV Root CA ================================ -----BEGIN CERTIFICATE-----@@ -3432,4 +3119,96 @@ HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw==+-----END CERTIFICATE-----++NAVER Global Root Certification Authority+=========================================+-----BEGIN CERTIFICATE-----+MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG+A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD+DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4+NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT+UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv+biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb+UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW++j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7+XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2+aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4+Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z+VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B+A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai+cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy+YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV+HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB+Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK+21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB+jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx+hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg+E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH+D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ+A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY+qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG+I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg+kpzNNIaRkPpkUZ3+/uul9XXeifdy+-----END CERTIFICATE-----++AC RAIZ FNMT-RCM SERVIDORES SEGUROS+===================================+-----BEGIN CERTIFICATE-----+MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF+UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy+NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4+MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt+UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB+QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA+BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2+LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG+SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD+zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c=+-----END CERTIFICATE-----++GlobalSign Root R46+===================+-----BEGIN CERTIFICATE-----+MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV+BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv+b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX+BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es+CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/+r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje+2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt+bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj+K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4+12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on+ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls+eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9+vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM+BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg+JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy+gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92+CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm+OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq+JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye+qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz+nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7+DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3+QEUxeCp6+-----END CERTIFICATE-----++GlobalSign Root E46+===================+-----BEGIN CERTIFICATE-----+MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT+AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg+RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV+BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq+hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB+jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj+QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL+gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk+vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP++CAezNIm8BZ/3Hobui3A= -----END CERTIFICATE-----