1 /** 2 * Keypair Checks 3 * 4 * Copyright: 5 * (C) 1999-2010 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.pubkey.algo.keypair; 12 13 import botan.constants; 14 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO): 15 import botan.rng.rng; 16 public import botan.pubkey.pk_keys; 17 public import botan.pubkey.pubkey; 18 import botan.utils.types; 19 import botan.utils.mem_ops; 20 21 /** 22 * Tests whether the key is consistent for encryption; whether 23 * encrypting and then decrypting gives to the original plaintext. 24 * Params: 25 * rng = the rng to use 26 * key = the key to test 27 * padding = the encryption padding method to use 28 * Returns: true if consistent otherwise false 29 */ 30 bool encryptionConsistencyCheck(RandomNumberGenerator rng, 31 in PrivateKey key, 32 in string padding) 33 { 34 //logTrace("Encryption consistency check"); 35 auto encryptor = scoped!PKEncryptorEME(key, padding); 36 auto decryptor = scoped!PKDecryptorEME(key, padding); 37 38 /* 39 Weird corner case, if the key is too small to encrypt anything at 40 all. This can happen with very small RSA keys with PSS 41 */ 42 if (encryptor.maximumInputSize() == 0) 43 return true; 44 45 Vector!ubyte plaintext = unlock(rng.randomVec(encryptor.maximumInputSize() - 1)); 46 Vector!ubyte ciphertext = encryptor.encrypt(plaintext, rng); 47 if (ciphertext == plaintext) 48 return false; 49 50 Vector!ubyte decrypted = unlock(decryptor.decrypt(ciphertext)); 51 52 return (plaintext == decrypted); 53 } 54 55 /** 56 * Tests whether the key is consistent for signatures; whether a 57 * signature can be created and then verified 58 * Params: 59 * rng = the rng to use 60 * key = the key to test 61 * padding = the signature padding method to use 62 * Returns: true if consistent otherwise false 63 */ 64 bool signatureConsistencyCheck(RandomNumberGenerator rng, 65 in PrivateKey key, 66 in string padding) 67 { 68 //logTrace("Signature consistency check"); 69 //logTrace("key: ", key.algoName); 70 //logTrace("Pad: ", padding); 71 PKSigner signer = PKSigner(key, padding); 72 PKVerifier verifier = PKVerifier(key, padding); 73 Vector!ubyte message = unlock(rng.randomVec(16)); 74 75 Vector!ubyte signature; 76 try 77 { 78 signature = signer.signMessage(message, rng); 79 } 80 catch(EncodingError) 81 { 82 return false; 83 } 84 if (!verifier.verifyMessage(message, signature)) 85 return false; 86 87 // Now try to check a corrupt signature, ensure it does not succeed 88 ++message[0]; 89 90 if (verifier.verifyMessage(message, signature)) 91 return false; 92 93 return true; 94 }