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