1 package civitas.crypto.rsapublickey.tests;
2
3 import static org.junit.jupiter.api.Assertions.assertFalse;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5 import static org.junit.jupiter.api.Assertions.assertTrue;
6 import static org.mockito.Mockito.verify;
7
8 import java.security.InvalidKeyException;
9 import java.security.SignatureException;
10
11 import org.bouncycastle.crypto.CryptoException;
12 import org.junit.jupiter.api.DisplayName;
13 import org.junit.jupiter.api.Test;
14 import org.mockito.InjectMocks;
15 import org.mockito.Mock;
16
17 import civitas.common.tests.RandomAwareTestBase;
18 import civitas.crypto.CryptoBase;
19 import civitas.crypto.messagedigest.CryptoHash;
20 import civitas.crypto.rsapublickey.ConvertStringToPublicKey;
21 import civitas.crypto.rsapublickey.VerifyPublicKeySignature;
22 import civitas.crypto.signature.tests.SignatureTestData;
23 import civitas.util.tests.BasicValuesTestData;
24
25 class VerifyPublicKeySignatureTest extends RandomAwareTestBase implements SignatureTestData, BasicValuesTestData {
26 @InjectMocks
27 VerifyPublicKeySignature verifyPublicKeySignature;
28
29 @Mock
30 CryptoBase cryptoBase;
31
32 @Mock
33 ConvertStringToPublicKey convertStringToPublicKey;
34
35 @Mock
36 CryptoHash cryptoHash;
37
38 @Test
39 @DisplayName("verifies that the signature bytes are the signature of the bytes using the given public key")
40 void test() throws CryptoException, InvalidKeyException, SignatureException, IllegalAccessException {
41 assertTrue(verifyPublicKeySignature.apply(
42 SIGNATURE_OF_AUTH_NONCE_WITH_KEY, PUBLIC_KEY, AUTHENTICATION_NONCE.getBytes()));
43 verify(cryptoBase.rsaSigner).initVerify(PUBLIC_KEY);
44 verify(cryptoBase.rsaSigner).update(AUTHENTICATION_NONCE.getBytes());
45 verify(cryptoBase.rsaSigner).verify(SIGNATURE_OF_AUTH_NONCE_WITH_KEY_BYTES);
46 }
47
48 @Test
49 @DisplayName("if the verification fails, returns false")
50 void test_1() throws CryptoException {
51 assertFalse(
52 verifyPublicKeySignature.apply(SIGNATURE_BAD_WITH_KEY, PUBLIC_KEY, AUTHENTICATION_NONCE.getBytes()));
53 }
54
55 @Test
56 @DisplayName("if the key or the signature is bad, a CryptoException is thrown")
57 void test2() {
58 assertThrows(
59 CryptoException.class,
60 () -> verifyPublicKeySignature.apply(
61 SIGNATURE_OF_AUTH_NONCE_WITH_KEY, PUBLIC_KEY_BAD, AUTHENTICATION_NONCE.getBytes()));
62 }
63
64 @Test
65 @DisplayName("in case no public key given, the one in the signature is used"
66 + "- converts the string in the sigature to a public key\n"
67 + "- uses the check expecting the public key")
68 void test1() throws CryptoException, IllegalAccessException {
69 assertTrue(verifyPublicKeySignature.apply(SIGNATURE_OF_AUTH_NONCE_WITH_KEY, AUTHENTICATION_NONCE.getBytes()));
70 verify(convertStringToPublicKey).apply(PUBLIC_KEY_BASE64);
71 }
72
73 @Test
74 @DisplayName("bad signature does not check in case no public key given")
75 void test1_1() throws CryptoException {
76 assertFalse(verifyPublicKeySignature.apply(SIGNATURE_OF_AUTH_NONCE_WITH_KEY2, AUTHENTICATION_NONCE.getBytes()));
77 }
78
79 @Test
80 @DisplayName("when the message is a string, its hash is computed, and the signature of the hash is verified")
81 void test3() throws CryptoException, InvalidKeyException, SignatureException, IllegalAccessException {
82 boolean expected = verifyPublicKeySignature.apply(SIGNATURE_OF_SOMESTRING_WITH_KEY, PUBLIC_KEY, SOMESTRING);
83 verify(cryptoHash).apply(SOMESTRING.getBytes());
84 verify(cryptoBase.rsaSigner).initVerify(PUBLIC_KEY);
85 verify(cryptoBase.rsaSigner).update(SOMESTRING_HASH);
86 verify(cryptoBase.rsaSigner).verify(SIGNATURE_OF_SOMESTRING_WITH_KEY_BYTES);
87 assertTrue(expected);
88 }
89
90 @Test
91 @DisplayName("bad signature does not check when the message is a string")
92 void test3_1() throws CryptoException {
93 assertFalse(verifyPublicKeySignature.apply(SIGNATURE_BAD_WITH_KEY, PUBLIC_KEY, SOMESTRING));
94 }
95
96 @Test
97 @DisplayName(
98 "when the message is a string and no explicit public key is given, then the check uses the hash of the string and the public key from the signature")
99 void test4() throws CryptoException, IllegalAccessException {
100 boolean expected = verifyPublicKeySignature.apply(SIGNATURE_OF_SOMESTRING_WITH_KEY, SOMESTRING);
101 verify(cryptoHash).apply(SOMESTRING.getBytes());
102 assertTrue(expected);
103 }
104
105 @Test
106 @DisplayName("bad signature does not check when the message is a string and no explicit public key is given")
107 void test4_1() throws CryptoException {
108 assertFalse(verifyPublicKeySignature.apply(SIGNATURE_BAD_WITH_KEY, SOMESTRING_BASE64));
109 }
110 }