blob: 5cde79824610674a945e6c1124dc8e33eb7db339 [file] [log] [blame]
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
use super::*;
use crate::util::expect_err;
use alloc::{borrow::ToOwned, format, vec};
use core::cmp::Ordering;
#[test]
fn test_error_convert() {
let e = CoseError::from(crate::cbor::ser::Error::<String>::Value(
"error message lost".to_owned(),
));
match e {
CoseError::EncodeFailed => {
assert!(format!("{:?}", e).contains("encode CBOR failure"));
}
_ => panic!("unexpected error enum after conversion"),
}
}
#[test]
fn test_label_encode() {
let tests = vec![
(Label::Int(2), "02"),
(Label::Int(-1), "20"),
(Label::Text("abc".to_owned()), "63616263"),
];
for (i, (label, label_data)) in tests.iter().enumerate() {
let got = label.clone().to_vec().unwrap();
assert_eq!(*label_data, hex::encode(&got), "case {}", i);
let got = Label::from_slice(&got).unwrap();
assert_eq!(*label, got);
}
}
#[test]
fn test_label_sort() {
// Pairs of `Label`s with the "smaller" first.
let pairs = vec![
(Label::Int(0x1234), Label::Text("a".to_owned())),
(Label::Int(0x1234), Label::Text("ab".to_owned())),
(Label::Int(0), Label::Text("ab".to_owned())),
(Label::Int(-1), Label::Text("ab".to_owned())),
(Label::Int(0), Label::Int(10)),
(Label::Int(0), Label::Int(-10)),
(Label::Int(10), Label::Int(-1)),
(Label::Int(-1), Label::Int(-2)),
(Label::Int(0x12), Label::Int(0x1234)),
(Label::Int(0x99), Label::Int(0x1234)),
(Label::Int(0x1234), Label::Int(0x1235)),
(Label::Text("a".to_owned()), Label::Text("ab".to_owned())),
(Label::Text("aa".to_owned()), Label::Text("ab".to_owned())),
];
for (left, right) in pairs.into_iter() {
let value_cmp = left.cmp(&right);
let value_partial_cmp = left.partial_cmp(&right);
let left_data = left.clone().to_vec().unwrap();
let right_data = right.clone().to_vec().unwrap();
let data_cmp = left_data.cmp(&right_data);
let reverse_cmp = right.cmp(&left);
let equal_cmp = left.cmp(&left);
assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
assert_eq!(
value_partial_cmp,
Some(Ordering::Less),
"{:?} < {:?}",
left,
right
);
assert_eq!(
data_cmp,
Ordering::Less,
"{:?}={} < {:?}={}",
left,
hex::encode(&left_data),
right,
hex::encode(&right_data)
);
assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
}
}
#[test]
fn test_label_decode_fail() {
let tests = vec![
("43010203", "expected int/tstr"),
("", "decode CBOR failure: Io(EndOfFile"),
("1e", "decode CBOR failure: Syntax"),
("0202", "extraneous data"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = Label::from_slice(&data);
expect_err(result, err_msg);
}
}
#[test]
fn test_registered_label_encode() {
let tests = vec![
(RegisteredLabel::Assigned(iana::Algorithm::A192GCM), "02"),
(RegisteredLabel::Assigned(iana::Algorithm::EdDSA), "27"),
(RegisteredLabel::Text("abc".to_owned()), "63616263"),
];
for (i, (label, label_data)) in tests.iter().enumerate() {
let got = label.clone().to_vec().unwrap();
assert_eq!(*label_data, hex::encode(&got), "case {}", i);
let got = RegisteredLabel::from_slice(&got).unwrap();
assert_eq!(*label, got);
}
}
#[test]
fn test_registered_label_sort() {
use RegisteredLabel::{Assigned, Text};
// Pairs of `RegisteredLabel`s with the "smaller" first.
let pairs = vec![
(Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
(Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
(Text("ab".to_owned()), Text("cd".to_owned())),
(Text("ab".to_owned()), Text("abcd".to_owned())),
(
Assigned(iana::Algorithm::AES_CCM_16_64_128),
Assigned(iana::Algorithm::A128KW),
),
(
Assigned(iana::Algorithm::A192GCM),
Assigned(iana::Algorithm::AES_CCM_16_64_128),
),
];
for (left, right) in pairs.into_iter() {
let value_cmp = left.cmp(&right);
let value_partial_cmp = left.partial_cmp(&right);
let left_data = left.clone().to_vec().unwrap();
let right_data = right.clone().to_vec().unwrap();
let data_cmp = left_data.cmp(&right_data);
let reverse_cmp = right.cmp(&left);
let equal_cmp = left.cmp(&left);
assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
assert_eq!(
value_partial_cmp,
Some(Ordering::Less),
"{:?} < {:?}",
left,
right
);
assert_eq!(
data_cmp,
Ordering::Less,
"{:?}={} < {:?}={}",
left,
hex::encode(&left_data),
right,
hex::encode(&right_data)
);
assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
}
}
#[test]
fn test_registered_label_decode_fail() {
let tests = vec![
("43010203", "expected int/tstr"),
("", "decode CBOR failure: Io(EndOfFile"),
("09", "expected recognized IANA value"),
("394e1f", "expected recognized IANA value"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = RegisteredLabel::<iana::EllipticCurve>::from_slice(&data);
expect_err(result, err_msg);
}
}
iana_registry! {
TestPrivateLabel {
Reserved: 0,
Something: 1,
}
}
impl WithPrivateRange for TestPrivateLabel {
fn is_private(i: i64) -> bool {
i > 10 || i < 1000
}
}
#[test]
fn test_registered_label_with_private_encode() {
let tests = vec![
(
RegisteredLabelWithPrivate::Assigned(TestPrivateLabel::Something),
"01",
),
(
RegisteredLabelWithPrivate::Text("abc".to_owned()),
"63616263",
),
(
RegisteredLabelWithPrivate::PrivateUse(-70_000),
"3a0001116f",
),
(RegisteredLabelWithPrivate::PrivateUse(11), "0b"),
];
for (i, (label, label_data)) in tests.iter().enumerate() {
let got = label.clone().to_vec().unwrap();
assert_eq!(*label_data, hex::encode(&got), "case {}", i);
let got = RegisteredLabelWithPrivate::from_slice(&got).unwrap();
assert_eq!(*label, got);
}
}
#[test]
fn test_registered_label_with_private_sort() {
use RegisteredLabelWithPrivate::{Assigned, PrivateUse, Text};
// Pairs of `RegisteredLabelWithPrivate`s with the "smaller" first.
let pairs = vec![
(Assigned(iana::Algorithm::A192GCM), Text("a".to_owned())),
(Assigned(iana::Algorithm::WalnutDSA), Text("ab".to_owned())),
(Text("ab".to_owned()), Text("cd".to_owned())),
(Text("ab".to_owned()), Text("abcd".to_owned())),
(
Assigned(iana::Algorithm::AES_CCM_16_64_128),
Assigned(iana::Algorithm::A128KW),
),
(
Assigned(iana::Algorithm::A192GCM),
Assigned(iana::Algorithm::AES_CCM_16_64_128),
),
(
Assigned(iana::Algorithm::AES_CCM_16_64_128),
PrivateUse(-70_000),
),
(PrivateUse(-70_000), PrivateUse(-70_001)),
(PrivateUse(-70_000), Text("a".to_owned())),
];
for (left, right) in pairs.into_iter() {
let value_cmp = left.cmp(&right);
let value_partial_cmp = left.partial_cmp(&right);
let left_data = left.clone().to_vec().unwrap();
let right_data = right.clone().to_vec().unwrap();
let data_cmp = left_data.cmp(&right_data);
let reverse_cmp = right.cmp(&left);
let equal_cmp = left.cmp(&left);
assert_eq!(value_cmp, Ordering::Less, "{:?} < {:?}", left, right);
assert_eq!(
value_partial_cmp,
Some(Ordering::Less),
"{:?} < {:?}",
left,
right
);
assert_eq!(
data_cmp,
Ordering::Less,
"{:?}={} < {:?}={}",
left,
hex::encode(&left_data),
right,
hex::encode(&right_data)
);
assert_eq!(reverse_cmp, Ordering::Greater, "{:?} > {:?}", right, left);
assert_eq!(equal_cmp, Ordering::Equal, "{:?} = {:?}", left, left);
}
}
#[test]
fn test_registered_label_with_private_decode_fail() {
let tests = vec![
("43010203", "expected int/tstr"),
("", "decode CBOR failure: Io(EndOfFile"),
("09", "expected value in IANA or private use range"),
("394e1f", "expected value in IANA or private use range"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = RegisteredLabelWithPrivate::<iana::Algorithm>::from_slice(&data);
expect_err(result, err_msg);
}
}
// The most negative integer value that can be encoded in CBOR is:
// 0x3B (0b001_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
// which is -18_446_744_073_709_551_616 (-1 - 18_446_744_073_709_551_615).
//
// However, this crate uses `i64` for all integers, which cannot hold
// negative values below `i64::MIN` (=-2^63 = 0x8000000000000000).
const CBOR_NINT_MIN_HEX: &str = "3b7fffffffffffffff";
const CBOR_NINT_OUT_OF_RANGE_HEX: &str = "3b8000000000000000";
// The largest positive integer value that can be encoded in CBOR is:
// 0x1B (0b000_11011) 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
// which is 18_446_744_073_709_551_615.
//
// However, this crate uses `i64` for all integers, which cannot hold
// positive values above `i64::MAX` (=-2^63 - 1 = 0x7fffffffffffffff).
const CBOR_INT_MAX_HEX: &str = "1b7fffffffffffffff";
const CBOR_INT_OUT_OF_RANGE_HEX: &str = "1b8000000000000000";
#[test]
fn test_large_label_decode() {
let tests = vec![(CBOR_NINT_MIN_HEX, i64::MIN), (CBOR_INT_MAX_HEX, i64::MAX)];
for (label_data, want) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let got = Label::from_slice(&data).unwrap();
assert_eq!(got, Label::Int(*want))
}
}
#[test]
fn test_large_label_decode_fail() {
let tests = vec![
(CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
(CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = Label::from_slice(&data);
expect_err(result, err_msg);
}
}
#[test]
fn test_large_registered_label_decode_fail() {
let tests = vec![
(CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
(CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = RegisteredLabel::<crate::iana::HeaderParameter>::from_slice(&data);
expect_err(result, err_msg);
}
}
#[test]
fn test_large_registered_label_with_private_decode_fail() {
let tests = vec![
(CBOR_NINT_OUT_OF_RANGE_HEX, "out of range integer value"),
(CBOR_INT_OUT_OF_RANGE_HEX, "out of range integer value"),
];
for (label_data, err_msg) in tests.iter() {
let data = hex::decode(label_data).unwrap();
let result = RegisteredLabelWithPrivate::<crate::iana::HeaderParameter>::from_slice(&data);
expect_err(result, err_msg);
}
}