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 = [
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(0x12345678), Label::Text("ab".to_owned())),
60         (Label::Int(0), Label::Text("ab".to_owned())),
61         (Label::Int(-1), Label::Text("ab".to_owned())),
62         (Label::Int(0), Label::Int(10)),
63         (Label::Int(0), Label::Int(-10)),
64         (Label::Int(10), Label::Int(-1)),
65         (Label::Int(-1), Label::Int(-2)),
66         (Label::Int(0x12), Label::Int(0x1234)),
67         (Label::Int(0x99), Label::Int(0x1234)),
68         (Label::Int(0x1234), Label::Int(0x1235)),
69         (Label::Text("a".to_owned()), Label::Text("ab".to_owned())),
70         (Label::Text("aa".to_owned()), Label::Text("ab".to_owned())),
71         (Label::Int(i64::MAX - 2), Label::Int(i64::MAX - 1)),
72         (Label::Int(i64::MAX - 1), Label::Int(i64::MAX)),
73         (Label::Int(i64::MIN + 2), Label::Int(i64::MIN + 1)),
74         (Label::Int(i64::MIN + 1), Label::Int(i64::MIN)),
75     ];
76     for (left, right) in pairs.into_iter() {
77         let value_cmp = left.cmp(&right);
78         let value_partial_cmp = left.partial_cmp(&right);
79         let left_data = left.clone().to_vec().unwrap();
80         let right_data = right.clone().to_vec().unwrap();
81         let data_cmp = left_data.cmp(&right_data);
82         let reverse_cmp = right.cmp(&left);
83         let equal_cmp = left.cmp(&left);
84 
85         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
86         assert_eq!(
87             value_partial_cmp,
88             Some(Ordering::Less),
89             "{:?} < {:?}",
90             left,
91             right
92         );
93         assert_eq!(
94             data_cmp,
95             Ordering::Less,
96             "{:?}={} < {:?}={}",
97             left,
98             hex::encode(&left_data),
99             right,
100             hex::encode(&right_data)
101         );
102         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
103         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
104     }
105 }
106 
107 #[test]
test_label_canonical_sort()108 fn test_label_canonical_sort() {
109     // Pairs of `Label`s with the "smaller" first, as per RFC7049 "canonical" ordering.
110     let pairs = vec![
111         (Label::Text("a".to_owned()), Label::Int(0x1234)), // different than above
112         (Label::Int(0x1234), Label::Text("ab".to_owned())),
113         (Label::Text("ab".to_owned()), Label::Int(0x12345678)), // different than above
114         (Label::Int(0), Label::Text("ab".to_owned())),
115         (Label::Int(-1), Label::Text("ab".to_owned())),
116         (Label::Int(0), Label::Int(10)),
117         (Label::Int(0), Label::Int(-10)),
118         (Label::Int(10), Label::Int(-1)),
119         (Label::Int(-1), Label::Int(-2)),
120         (Label::Int(0x12), Label::Int(0x1234)),
121         (Label::Int(0x99), Label::Int(0x1234)),
122         (Label::Int(0x1234), Label::Int(0x1235)),
123         (Label::Text("a".to_owned()), Label::Text("ab".to_owned())),
124         (Label::Text("aa".to_owned()), Label::Text("ab".to_owned())),
125     ];
126     for (left, right) in pairs.into_iter() {
127         let value_cmp = left.cmp_canonical(&right);
128 
129         let left_data = left.clone().to_vec().unwrap();
130         let right_data = right.clone().to_vec().unwrap();
131 
132         let len_cmp = left_data.len().cmp(&right_data.len());
133         let data_cmp = left_data.cmp(&right_data);
134         let reverse_cmp = right.cmp_canonical(&left);
135         let equal_cmp = left.cmp_canonical(&left);
136 
137         assert_eq!(
138             value_cmp,
139             Ordering::Less,
140             "{:?} (encoded: {}) < {:?} (encoded: {})",
141             left,
142             hex::encode(&left_data),
143             right,
144             hex::encode(&right_data)
145         );
146         if len_cmp != Ordering::Equal {
147             assert_eq!(
148                 len_cmp,
149                 Ordering::Less,
150                 "{:?}={} < {:?}={} by len",
151                 left,
152                 hex::encode(&left_data),
153                 right,
154                 hex::encode(&right_data)
155             );
156         } else {
157             assert_eq!(
158                 data_cmp,
159                 Ordering::Less,
160                 "{:?}={} < {:?}={} by data",
161                 left,
162                 hex::encode(&left_data),
163                 right,
164                 hex::encode(&right_data)
165             );
166         }
167         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
168         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
169     }
170 }
171 
172 #[test]
test_label_decode_fail()173 fn test_label_decode_fail() {
174     let tests = [
175         ("43010203", "expected int/tstr"),
176         ("", "decode CBOR failure: Io(EndOfFile"),
177         ("1e", "decode CBOR failure: Syntax"),
178         ("0202", "extraneous data"),
179     ];
180     for (label_data, err_msg) in tests.iter() {
181         let data = hex::decode(label_data).unwrap();
182         let result = Label::from_slice(&data);
183         expect_err(result, err_msg);
184     }
185 }
186 
187 #[test]
test_registered_label_encode()188 fn test_registered_label_encode() {
189     let tests = [
190         (RegisteredLabel::Assigned(iana::Algorithm::A192GCM), "02"),
191         (RegisteredLabel::Assigned(iana::Algorithm::EdDSA), "27"),
192         (RegisteredLabel::Text("abc".to_owned()), "63616263"),
193     ];
194 
195     for (i, (label, label_data)) in tests.iter().enumerate() {
196         let got = label.clone().to_vec().unwrap();
197         assert_eq!(*label_data, hex::encode(&got), "case {}", i);
198 
199         let got = RegisteredLabel::from_slice(&got).unwrap();
200         assert_eq!(*label, got);
201     }
202 }
203 
204 #[test]
test_registered_label_sort()205 fn test_registered_label_sort() {
206     use RegisteredLabel::{Assigned, Text};
207     // Pairs of `RegisteredLabel`s with the "smaller" first.
208     let pairs = vec![
209         (Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
210         (Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
211         (Text("ab".to_owned()), Text("cd".to_owned())),
212         (Text("ab".to_owned()), Text("abcd".to_owned())),
213         (
214             Assigned(iana::Algorithm::AES_CCM_16_64_128),
215             Assigned(iana::Algorithm::A128KW),
216         ),
217         (
218             Assigned(iana::Algorithm::A192GCM),
219             Assigned(iana::Algorithm::AES_CCM_16_64_128),
220         ),
221     ];
222     for (left, right) in pairs.into_iter() {
223         let value_cmp = left.cmp(&right);
224         let value_partial_cmp = left.partial_cmp(&right);
225         let left_data = left.clone().to_vec().unwrap();
226         let right_data = right.clone().to_vec().unwrap();
227         let data_cmp = left_data.cmp(&right_data);
228         let reverse_cmp = right.cmp(&left);
229         let equal_cmp = left.cmp(&left);
230 
231         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
232         assert_eq!(
233             value_partial_cmp,
234             Some(Ordering::Less),
235             "{:?} < {:?}",
236             left,
237             right
238         );
239         assert_eq!(
240             data_cmp,
241             Ordering::Less,
242             "{:?}={} < {:?}={}",
243             left,
244             hex::encode(&left_data),
245             right,
246             hex::encode(&right_data)
247         );
248         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
249         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
250     }
251 }
252 
253 #[test]
test_registered_label_decode_fail()254 fn test_registered_label_decode_fail() {
255     let tests = [
256         ("43010203", "expected int/tstr"),
257         ("", "decode CBOR failure: Io(EndOfFile"),
258         ("09", "expected recognized IANA value"),
259         ("394e1f", "expected recognized IANA value"),
260     ];
261     for (label_data, err_msg) in tests.iter() {
262         let data = hex::decode(label_data).unwrap();
263         let result = RegisteredLabel::<iana::EllipticCurve>::from_slice(&data);
264         expect_err(result, err_msg);
265     }
266 }
267 
268 iana_registry! {
269     TestPrivateLabel {
270         Reserved: 0,
271         Something: 1,
272     }
273 }
274 
275 impl WithPrivateRange for TestPrivateLabel {
is_private(i: i64) -> bool276     fn is_private(i: i64) -> bool {
277         i > 10 || i < 1000
278     }
279 }
280 
281 #[test]
test_registered_label_with_private_encode()282 fn test_registered_label_with_private_encode() {
283     let tests = [
284         (
285             RegisteredLabelWithPrivate::Assigned(TestPrivateLabel::Something),
286             "01",
287         ),
288         (
289             RegisteredLabelWithPrivate::Text("abc".to_owned()),
290             "63616263",
291         ),
292         (
293             RegisteredLabelWithPrivate::PrivateUse(-70_000),
294             "3a0001116f",
295         ),
296         (RegisteredLabelWithPrivate::PrivateUse(11), "0b"),
297     ];
298 
299     for (i, (label, label_data)) in tests.iter().enumerate() {
300         let got = label.clone().to_vec().unwrap();
301         assert_eq!(*label_data, hex::encode(&got), "case {}", i);
302 
303         let got = RegisteredLabelWithPrivate::from_slice(&got).unwrap();
304         assert_eq!(*label, got);
305     }
306 }
307 
308 #[test]
test_registered_label_with_private_sort()309 fn test_registered_label_with_private_sort() {
310     use RegisteredLabelWithPrivate::{Assigned, PrivateUse, Text};
311     // Pairs of `RegisteredLabelWithPrivate`s with the "smaller" first.
312     let pairs = vec![
313         (Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
314         (Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
315         (Text("ab".to_owned()), Text("cd".to_owned())),
316         (Text("ab".to_owned()), Text("abcd".to_owned())),
317         (
318             Assigned(iana::Algorithm::AES_CCM_16_64_128),
319             Assigned(iana::Algorithm::A128KW),
320         ),
321         (
322             Assigned(iana::Algorithm::A192GCM),
323             Assigned(iana::Algorithm::AES_CCM_16_64_128),
324         ),
325         (
326             Assigned(iana::Algorithm::AES_CCM_16_64_128),
327             PrivateUse(-70_000),
328         ),
329         (PrivateUse(-70_000), PrivateUse(-70_001)),
330         (PrivateUse(-70_000), Text("a".to_owned())),
331     ];
332     for (left, right) in pairs.into_iter() {
333         let value_cmp = left.cmp(&right);
334         let value_partial_cmp = left.partial_cmp(&right);
335         let left_data = left.clone().to_vec().unwrap();
336         let right_data = right.clone().to_vec().unwrap();
337         let data_cmp = left_data.cmp(&right_data);
338         let reverse_cmp = right.cmp(&left);
339         let equal_cmp = left.cmp(&left);
340 
341         assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
342         assert_eq!(
343             value_partial_cmp,
344             Some(Ordering::Less),
345             "{:?} < {:?}",
346             left,
347             right
348         );
349         assert_eq!(
350             data_cmp,
351             Ordering::Less,
352             "{:?}={} < {:?}={}",
353             left,
354             hex::encode(&left_data),
355             right,
356             hex::encode(&right_data)
357         );
358         assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
359         assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
360     }
361 }
362 
363 #[test]
test_registered_label_with_private_decode_fail()364 fn test_registered_label_with_private_decode_fail() {
365     let tests = [
366         ("43010203", "expected int/tstr"),
367         ("", "decode CBOR failure: Io(EndOfFile"),
368         ("09", "expected value in IANA or private use range"),
369         ("394e1f", "expected value in IANA or private use range"),
370     ];
371     for (label_data, err_msg) in tests.iter() {
372         let data = hex::decode(label_data).unwrap();
373         let result = RegisteredLabelWithPrivate::<iana::Algorithm>::from_slice(&data);
374         expect_err(result, err_msg);
375     }
376 }
377 
378 // The most negative integer value that can be encoded in CBOR is:
379 //    0x3B (0b001_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
380 // which is -18_446_744_073_709_551_616 (-1 - 18_446_744_073_709_551_615).
381 //
382 // However, this crate uses `i64` for all integers, which cannot hold
383 // negative values below `i64::MIN` (=-2^63 = 0x8000000000000000).
384 const CBOR_NINT_MIN_HEX: &str = "3b7fffffffffffffff";
385 const CBOR_NINT_OUT_OF_RANGE_HEX: &str = "3b8000000000000000";
386 
387 // The largest positive integer value that can be encoded in CBOR is:
388 //    0x1B (0b000_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
389 // which is 18_446_744_073_709_551_615.
390 //
391 // However, this crate uses `i64` for all integers, which cannot hold
392 // positive values above `i64::MAX` (=-2^63 - 1 = 0x7fffffffffffffff).
393 const CBOR_INT_MAX_HEX: &str = "1b7fffffffffffffff";
394 const CBOR_INT_OUT_OF_RANGE_HEX: &str = "1b8000000000000000";
395 
396 #[test]
test_large_label_decode()397 fn test_large_label_decode() {
398     let tests = [(CBOR_NINT_MIN_HEX, i64::MIN), (CBOR_INT_MAX_HEX, i64::MAX)];
399     for (label_data, want) in tests.iter() {
400         let data = hex::decode(label_data).unwrap();
401         let got = Label::from_slice(&data).unwrap();
402         assert_eq!(got, Label::Int(*want))
403     }
404 }
405 
406 #[test]
test_large_label_decode_fail()407 fn test_large_label_decode_fail() {
408     let tests = [
409         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
410         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
411     ];
412     for (label_data, err_msg) in tests.iter() {
413         let data = hex::decode(label_data).unwrap();
414         let result = Label::from_slice(&data);
415         expect_err(result, err_msg);
416     }
417 }
418 
419 #[test]
test_large_registered_label_decode_fail()420 fn test_large_registered_label_decode_fail() {
421     let tests = [
422         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
423         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
424     ];
425     for (label_data, err_msg) in tests.iter() {
426         let data = hex::decode(label_data).unwrap();
427         let result = RegisteredLabel::<crate::iana::HeaderParameter>::from_slice(&data);
428         expect_err(result, err_msg);
429     }
430 }
431 
432 #[test]
test_large_registered_label_with_private_decode_fail()433 fn test_large_registered_label_with_private_decode_fail() {
434     let tests = [
435         (CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
436         (CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
437     ];
438     for (label_data, err_msg) in tests.iter() {
439         let data = hex::decode(label_data).unwrap();
440         let result = RegisteredLabelWithPrivate::<crate::iana::HeaderParameter>::from_slice(&data);
441         expect_err(result, err_msg);
442     }
443 }
444 
445 #[test]
test_as_cbor_value()446 fn test_as_cbor_value() {
447     let cases = [
448         Value::Null,
449         Value::Bool(true),
450         Value::Bool(false),
451         Value::from(128),
452         Value::from(-1),
453         Value::Bytes(vec![1, 2]),
454         Value::Text("string".to_owned()),
455         Value::Array(vec![Value::from(0)]),
456         Value::Map(vec![]),
457         Value::Tag(1, Box::new(Value::from(0))),
458         Value::Float(1.054571817),
459     ];
460     for val in cases {
461         assert_eq!(val, Value::from_cbor_value(val.clone()).unwrap());
462         assert_eq!(val, val.clone().to_cbor_value().unwrap());
463     }
464 }
465