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 }