• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 use super::*;
18 use crate::util::expect_err;
19 use alloc::{borrow::ToOwned, format, vec};
20 use core::cmp::Ordering;
21 
22 #[test]
test_error_convert()23 fn test_error_convert() {
24     let e = CoseError::from(crate::cbor::ser::Error::<String>::Value(
25         "error message lost".to_owned(),
26     ));
27     match e {
28         CoseError::EncodeFailed => {
29             assert!(format!("{:?}", e).contains("encode CBOR failure"));
30             assert!(format!("{}", e).contains("encode CBOR failure"));
31         }
32         _ => panic!("unexpected error enum after conversion"),
33     }
34 }
35 
36 #[test]
test_label_encode()37 fn test_label_encode() {
38     let tests = vec![
39         (Label::Int(2), "02"),
40         (Label::Int(-1), "20"),
41         (Label::Text("abc".to_owned()), "63616263"),
42     ];
43 
44     for (i, (label, label_data)) in tests.iter().enumerate() {
45         let got = label.clone().to_vec().unwrap();
46         assert_eq!(*label_data, hex::encode(&got), "case {}", i);
47 
48         let got = Label::from_slice(&got).unwrap();
49         assert_eq!(*label, got);
50     }
51 }
52 
53 #[test]
test_label_sort()54 fn test_label_sort() {
55     // Pairs of `Label`s with the "smaller" first.
56     let pairs = vec![
57         (Label::Int(0x1234), Label::Text("a".to_owned())),
58         (Label::Int(0x1234), Label::Text("ab".to_owned())),
59         (Label::Int(0), Label::Text("ab".to_owned())),
60         (Label::Int(-1), Label::Text("ab".to_owned())),
61         (Label::Int(0), Label::Int(10)),
62         (Label::Int(0), Label::Int(-10)),
63         (Label::Int(10), Label::Int(-1)),
64         (Label::Int(-1), Label::Int(-2)),
65         (Label::Int(0x12), Label::Int(0x1234)),
66         (Label::Int(0x99), Label::Int(0x1234)),
67         (Label::Int(0x1234), Label::Int(0x1235)),
68         (Label::Text("a".to_owned()), Label::Text("ab".to_owned())),
69         (Label::Text("aa".to_owned()), Label::Text("ab".to_owned())),
70     ];
71     for (left, right) in pairs.into_iter() {
72         let value_cmp = left.cmp(&right);
73         let value_partial_cmp = left.partial_cmp(&right);
74         let left_data = left.clone().to_vec().unwrap();
75         let right_data = right.clone().to_vec().unwrap();
76         let data_cmp = left_data.cmp(&right_data);
77         let reverse_cmp = right.cmp(&left);
78         let equal_cmp = left.cmp(&left);
79 
80         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
81         assert_eq!(
82             value_partial_cmp,
83             Some(Ordering::Less),
84             "{:?} < {:?}",
85             left,
86             right
87         );
88         assert_eq!(
89             data_cmp,
90             Ordering::Less,
91             "{:?}={} < {:?}={}",
92             left,
93             hex::encode(&left_data),
94             right,
95             hex::encode(&right_data)
96         );
97         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
98         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
99     }
100 }
101 
102 #[test]
test_label_decode_fail()103 fn test_label_decode_fail() {
104     let tests = vec![
105         ("43010203", "expected int/tstr"),
106         ("", "decode CBOR failure: Io(EndOfFile"),
107         ("1e", "decode CBOR failure: Syntax"),
108         ("0202", "extraneous data"),
109     ];
110     for (label_data, err_msg) in tests.iter() {
111         let data = hex::decode(label_data).unwrap();
112         let result = Label::from_slice(&data);
113         expect_err(result, err_msg);
114     }
115 }
116 
117 #[test]
test_registered_label_encode()118 fn test_registered_label_encode() {
119     let tests = vec![
120         (RegisteredLabel::Assigned(iana::Algorithm::A192GCM), "02"),
121         (RegisteredLabel::Assigned(iana::Algorithm::EdDSA), "27"),
122         (RegisteredLabel::Text("abc".to_owned()), "63616263"),
123     ];
124 
125     for (i, (label, label_data)) in tests.iter().enumerate() {
126         let got = label.clone().to_vec().unwrap();
127         assert_eq!(*label_data, hex::encode(&got), "case {}", i);
128 
129         let got = RegisteredLabel::from_slice(&got).unwrap();
130         assert_eq!(*label, got);
131     }
132 }
133 
134 #[test]
test_registered_label_sort()135 fn test_registered_label_sort() {
136     use RegisteredLabel::{Assigned, Text};
137     // Pairs of `RegisteredLabel`s with the "smaller" first.
138     let pairs = vec![
139         (Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
140         (Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
141         (Text("ab".to_owned()), Text("cd".to_owned())),
142         (Text("ab".to_owned()), Text("abcd".to_owned())),
143         (
144             Assigned(iana::Algorithm::AES_CCM_16_64_128),
145             Assigned(iana::Algorithm::A128KW),
146         ),
147         (
148             Assigned(iana::Algorithm::A192GCM),
149             Assigned(iana::Algorithm::AES_CCM_16_64_128),
150         ),
151     ];
152     for (left, right) in pairs.into_iter() {
153         let value_cmp = left.cmp(&right);
154         let value_partial_cmp = left.partial_cmp(&right);
155         let left_data = left.clone().to_vec().unwrap();
156         let right_data = right.clone().to_vec().unwrap();
157         let data_cmp = left_data.cmp(&right_data);
158         let reverse_cmp = right.cmp(&left);
159         let equal_cmp = left.cmp(&left);
160 
161         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
162         assert_eq!(
163             value_partial_cmp,
164             Some(Ordering::Less),
165             "{:?} < {:?}",
166             left,
167             right
168         );
169         assert_eq!(
170             data_cmp,
171             Ordering::Less,
172             "{:?}={} < {:?}={}",
173             left,
174             hex::encode(&left_data),
175             right,
176             hex::encode(&right_data)
177         );
178         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
179         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
180     }
181 }
182 
183 #[test]
test_registered_label_decode_fail()184 fn test_registered_label_decode_fail() {
185     let tests = vec![
186         ("43010203", "expected int/tstr"),
187         ("", "decode CBOR failure: Io(EndOfFile"),
188         ("09", "expected recognized IANA value"),
189         ("394e1f", "expected recognized IANA value"),
190     ];
191     for (label_data, err_msg) in tests.iter() {
192         let data = hex::decode(label_data).unwrap();
193         let result = RegisteredLabel::<iana::EllipticCurve>::from_slice(&data);
194         expect_err(result, err_msg);
195     }
196 }
197 
198 iana_registry! {
199     TestPrivateLabel {
200         Reserved: 0,
201         Something: 1,
202     }
203 }
204 
205 impl WithPrivateRange for TestPrivateLabel {
is_private(i: i64) -> bool206     fn is_private(i: i64) -> bool {
207         i > 10 || i < 1000
208     }
209 }
210 
211 #[test]
test_registered_label_with_private_encode()212 fn test_registered_label_with_private_encode() {
213     let tests = vec![
214         (
215             RegisteredLabelWithPrivate::Assigned(TestPrivateLabel::Something),
216             "01",
217         ),
218         (
219             RegisteredLabelWithPrivate::Text("abc".to_owned()),
220             "63616263",
221         ),
222         (
223             RegisteredLabelWithPrivate::PrivateUse(-70_000),
224             "3a0001116f",
225         ),
226         (RegisteredLabelWithPrivate::PrivateUse(11), "0b"),
227     ];
228 
229     for (i, (label, label_data)) in tests.iter().enumerate() {
230         let got = label.clone().to_vec().unwrap();
231         assert_eq!(*label_data, hex::encode(&got), "case {}", i);
232 
233         let got = RegisteredLabelWithPrivate::from_slice(&got).unwrap();
234         assert_eq!(*label, got);
235     }
236 }
237 
238 #[test]
test_registered_label_with_private_sort()239 fn test_registered_label_with_private_sort() {
240     use RegisteredLabelWithPrivate::{Assigned, PrivateUse, Text};
241     // Pairs of `RegisteredLabelWithPrivate`s with the "smaller" first.
242     let pairs = vec![
243         (Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
244         (Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
245         (Text("ab".to_owned()), Text("cd".to_owned())),
246         (Text("ab".to_owned()), Text("abcd".to_owned())),
247         (
248             Assigned(iana::Algorithm::AES_CCM_16_64_128),
249             Assigned(iana::Algorithm::A128KW),
250         ),
251         (
252             Assigned(iana::Algorithm::A192GCM),
253             Assigned(iana::Algorithm::AES_CCM_16_64_128),
254         ),
255         (
256             Assigned(iana::Algorithm::AES_CCM_16_64_128),
257             PrivateUse(-70_000),
258         ),
259         (PrivateUse(-70_000), PrivateUse(-70_001)),
260         (PrivateUse(-70_000), Text("a".to_owned())),
261     ];
262     for (left, right) in pairs.into_iter() {
263         let value_cmp = left.cmp(&right);
264         let value_partial_cmp = left.partial_cmp(&right);
265         let left_data = left.clone().to_vec().unwrap();
266         let right_data = right.clone().to_vec().unwrap();
267         let data_cmp = left_data.cmp(&right_data);
268         let reverse_cmp = right.cmp(&left);
269         let equal_cmp = left.cmp(&left);
270 
271         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
272         assert_eq!(
273             value_partial_cmp,
274             Some(Ordering::Less),
275             "{:?} < {:?}",
276             left,
277             right
278         );
279         assert_eq!(
280             data_cmp,
281             Ordering::Less,
282             "{:?}={} < {:?}={}",
283             left,
284             hex::encode(&left_data),
285             right,
286             hex::encode(&right_data)
287         );
288         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
289         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
290     }
291 }
292 
293 #[test]
test_registered_label_with_private_decode_fail()294 fn test_registered_label_with_private_decode_fail() {
295     let tests = vec![
296         ("43010203", "expected int/tstr"),
297         ("", "decode CBOR failure: Io(EndOfFile"),
298         ("09", "expected value in IANA or private use range"),
299         ("394e1f", "expected value in IANA or private use range"),
300     ];
301     for (label_data, err_msg) in tests.iter() {
302         let data = hex::decode(label_data).unwrap();
303         let result = RegisteredLabelWithPrivate::<iana::Algorithm>::from_slice(&data);
304         expect_err(result, err_msg);
305     }
306 }
307 
308 // The most negative integer value that can be encoded in CBOR is:
309 //    0x3B (0b001_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
310 // which is -18_446_744_073_709_551_616 (-1 - 18_446_744_073_709_551_615).
311 //
312 // However, this crate uses `i64` for all integers, which cannot hold
313 // negative values below `i64::MIN` (=-2^63 = 0x8000000000000000).
314 const CBOR_NINT_MIN_HEX: &str = "3b7fffffffffffffff";
315 const CBOR_NINT_OUT_OF_RANGE_HEX: &str = "3b8000000000000000";
316 
317 // The largest positive integer value that can be encoded in CBOR is:
318 //    0x1B (0b000_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
319 // which is 18_446_744_073_709_551_615.
320 //
321 // However, this crate uses `i64` for all integers, which cannot hold
322 // positive values above `i64::MAX` (=-2^63 - 1 = 0x7fffffffffffffff).
323 const CBOR_INT_MAX_HEX: &str = "1b7fffffffffffffff";
324 const CBOR_INT_OUT_OF_RANGE_HEX: &str = "1b8000000000000000";
325 
326 #[test]
test_large_label_decode()327 fn test_large_label_decode() {
328     let tests = vec![(CBOR_NINT_MIN_HEX, i64::MIN), (CBOR_INT_MAX_HEX, i64::MAX)];
329     for (label_data, want) in tests.iter() {
330         let data = hex::decode(label_data).unwrap();
331         let got = Label::from_slice(&data).unwrap();
332         assert_eq!(got, Label::Int(*want))
333     }
334 }
335 
336 #[test]
test_large_label_decode_fail()337 fn test_large_label_decode_fail() {
338     let tests = vec![
339         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
340         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
341     ];
342     for (label_data, err_msg) in tests.iter() {
343         let data = hex::decode(label_data).unwrap();
344         let result = Label::from_slice(&data);
345         expect_err(result, err_msg);
346     }
347 }
348 
349 #[test]
test_large_registered_label_decode_fail()350 fn test_large_registered_label_decode_fail() {
351     let tests = vec![
352         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
353         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
354     ];
355     for (label_data, err_msg) in tests.iter() {
356         let data = hex::decode(label_data).unwrap();
357         let result = RegisteredLabel::<crate::iana::HeaderParameter>::from_slice(&data);
358         expect_err(result, err_msg);
359     }
360 }
361 
362 #[test]
test_large_registered_label_with_private_decode_fail()363 fn test_large_registered_label_with_private_decode_fail() {
364     let tests = vec![
365         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
366         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
367     ];
368     for (label_data, err_msg) in tests.iter() {
369         let data = hex::decode(label_data).unwrap();
370         let result = RegisteredLabelWithPrivate::<crate::iana::HeaderParameter>::from_slice(&data);
371         expect_err(result, err_msg);
372     }
373 }
374