1 // Copyright 2015-2017 Brian Smith.
2 //
3 // Permission to use, copy, modify, and/or distribute this software for any
4 // purpose with or without fee is hereby granted, provided that the above
5 // copyright notice and this permission notice appear in all copies.
6 //
7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
10 // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 
15 #![forbid(
16     anonymous_parameters,
17     box_pointers,
18     missing_copy_implementations,
19     missing_debug_implementations,
20     missing_docs,
21     trivial_casts,
22     trivial_numeric_casts,
23     unsafe_code,
24     unstable_features,
25     unused_extern_crates,
26     unused_import_braces,
27     unused_qualifications,
28     unused_results,
29     variant_size_differences,
30     warnings
31 )]
32 
33 use ring::{
34     signature::{self, Ed25519KeyPair, KeyPair},
35     test, test_file,
36 };
37 
38 /// Test vectors from BoringSSL.
39 #[test]
test_signature_ed25519()40 fn test_signature_ed25519() {
41     test::run(test_file!("ed25519_tests.txt"), |section, test_case| {
42         assert_eq!(section, "");
43         let seed = test_case.consume_bytes("SEED");
44         assert_eq!(32, seed.len());
45 
46         let public_key = test_case.consume_bytes("PUB");
47         assert_eq!(32, public_key.len());
48 
49         let msg = test_case.consume_bytes("MESSAGE");
50 
51         let expected_sig = test_case.consume_bytes("SIG");
52 
53         {
54             let key_pair = Ed25519KeyPair::from_seed_and_public_key(&seed, &public_key).unwrap();
55             let actual_sig = key_pair.sign(&msg);
56             assert_eq!(&expected_sig[..], actual_sig.as_ref());
57         }
58 
59         // Test PKCS#8 generation, parsing, and private-to-public calculations.
60         let rng = test::rand::FixedSliceRandom { bytes: &seed };
61         let pkcs8 = Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
62         let key_pair = Ed25519KeyPair::from_pkcs8(pkcs8.as_ref()).unwrap();
63         assert_eq!(public_key, key_pair.public_key().as_ref());
64 
65         // Test Signature generation.
66         let actual_sig = key_pair.sign(&msg);
67         assert_eq!(&expected_sig[..], actual_sig.as_ref());
68 
69         // Test Signature verification.
70 
71         assert!(
72             signature::UnparsedPublicKey::new(&signature::ED25519, &public_key)
73                 .verify(&msg, &expected_sig)
74                 .is_ok()
75         );
76 
77         let mut tampered_sig = expected_sig;
78         tampered_sig[0] ^= 1;
79 
80         assert!(
81             signature::UnparsedPublicKey::new(&signature::ED25519, &public_key)
82                 .verify(&msg, &tampered_sig)
83                 .is_err()
84         );
85 
86         Ok(())
87     });
88 }
89 
90 #[test]
test_ed25519_from_seed_and_public_key_misuse()91 fn test_ed25519_from_seed_and_public_key_misuse() {
92     const PRIVATE_KEY: &[u8] = include_bytes!("ed25519_test_private_key.bin");
93     const PUBLIC_KEY: &[u8] = include_bytes!("ed25519_test_public_key.bin");
94 
95     assert!(Ed25519KeyPair::from_seed_and_public_key(PRIVATE_KEY, PUBLIC_KEY).is_ok());
96 
97     // Truncated private key.
98     assert!(Ed25519KeyPair::from_seed_and_public_key(&PRIVATE_KEY[..31], PUBLIC_KEY).is_err());
99 
100     // Truncated public key.
101     assert!(Ed25519KeyPair::from_seed_and_public_key(PRIVATE_KEY, &PUBLIC_KEY[..31]).is_err());
102 
103     // Swapped public and private key.
104     assert!(Ed25519KeyPair::from_seed_and_public_key(PUBLIC_KEY, PRIVATE_KEY).is_err());
105 }
106 
107 #[test]
test_ed25519_from_pkcs8_unchecked()108 fn test_ed25519_from_pkcs8_unchecked() {
109     // Just test that we can parse the input.
110     test::run(
111         test_file!("ed25519_from_pkcs8_unchecked_tests.txt"),
112         |section, test_case| {
113             assert_eq!(section, "");
114             let input = test_case.consume_bytes("Input");
115             let error = test_case.consume_optional_string("Error");
116 
117             match (
118                 Ed25519KeyPair::from_pkcs8_maybe_unchecked(&input),
119                 error.clone(),
120             ) {
121                 (Ok(_), None) => (),
122                 (Err(e), None) => panic!("Failed with error \"{}\", but expected to succeed", e),
123                 (Ok(_), Some(e)) => panic!("Succeeded, but expected error \"{}\"", e),
124                 (Err(actual), Some(expected)) => assert_eq!(actual.description_(), expected),
125             };
126 
127             Ok(())
128         },
129     );
130 }
131 
132 #[test]
test_ed25519_from_pkcs8()133 fn test_ed25519_from_pkcs8() {
134     // Just test that we can parse the input.
135     test::run(
136         test_file!("ed25519_from_pkcs8_tests.txt"),
137         |section, test_case| {
138             assert_eq!(section, "");
139             let input = test_case.consume_bytes("Input");
140             let error = test_case.consume_optional_string("Error");
141 
142             match (Ed25519KeyPair::from_pkcs8(&input), error.clone()) {
143                 (Ok(_), None) => (),
144                 (Err(e), None) => panic!("Failed with error \"{}\", but expected to succeed", e),
145                 (Ok(_), Some(e)) => panic!("Succeeded, but expected error \"{}\"", e),
146                 (Err(actual), Some(expected)) => assert_eq!(actual.description_(), expected),
147             };
148 
149             Ok(())
150         },
151     );
152 }
153 
154 #[test]
ed25519_test_public_key_coverage()155 fn ed25519_test_public_key_coverage() {
156     const PRIVATE_KEY: &[u8] = include_bytes!("ed25519_test_private_key.p8");
157     const PUBLIC_KEY: &[u8] = include_bytes!("ed25519_test_public_key.der");
158     const PUBLIC_KEY_DEBUG: &str =
159         "PublicKey(\"5809e9fef6dcec58f0f2e3b0d67e9880a11957e083ace85835c3b6c8fbaf6b7d\")";
160 
161     let key_pair = signature::Ed25519KeyPair::from_pkcs8(PRIVATE_KEY).unwrap();
162 
163     // Test `AsRef<[u8]>`
164     assert_eq!(key_pair.public_key().as_ref(), PUBLIC_KEY);
165 
166     // Test `Clone`.
167     #[allow(clippy::clone_on_copy)]
168     let _: <Ed25519KeyPair as KeyPair>::PublicKey = key_pair.public_key().clone();
169 
170     // Test `Copy`.
171     let _: <Ed25519KeyPair as KeyPair>::PublicKey = *key_pair.public_key();
172 
173     // Test `Debug`.
174     assert_eq!(PUBLIC_KEY_DEBUG, format!("{:?}", key_pair.public_key()));
175     assert_eq!(
176         format!(
177             "Ed25519KeyPair {{ public_key: {:?} }}",
178             key_pair.public_key()
179         ),
180         format!("{:?}", key_pair)
181     );
182 }
183