1 use test_setup as test;
2 use {CoseError, SignatureAlgorithm};
3 use decoder::{COSE_HEADER_ALG, COSE_HEADER_KID, COSE_SIGN_TAG, COSE_TYPE_ES256, decode_signature};
4 use cbor::CborType;
5 use std::collections::BTreeMap;
6 
7 #[test]
test_cose_decode()8 fn test_cose_decode() {
9     let payload = b"This is the content.";
10     let cose_signatures = decode_signature(&test::COSE_SIGNATURE_BYTES, payload).unwrap();
11     assert_eq!(cose_signatures.len(), 1);
12     assert_eq!(cose_signatures[0].signature_type, SignatureAlgorithm::ES256);
13     assert_eq!(cose_signatures[0].signature, test::SIGNATURE_BYTES.to_vec());
14     assert_eq!(cose_signatures[0].certs[0], test::P256_ROOT.to_vec());
15     assert_eq!(cose_signatures[0].certs[1], test::P256_INT.to_vec());
16 }
17 
test_cose_format_error(bytes: &[u8], expected_error: CoseError)18 fn test_cose_format_error(bytes: &[u8], expected_error: CoseError) {
19     let payload = vec![0];
20     let result = decode_signature(bytes, &payload);
21     assert!(result.is_err());
22     assert_eq!(result.err(), Some(expected_error));
23 }
24 
25 // Helper function to take a `Vec<CborType>`, wrap it in a `CborType::Array`, tag it with the
26 // COSE_Sign tag (COSE_SIGN_TAG = 98), and serialize it to a `Vec<u8>`.
wrap_tag_and_encode_array(array: Vec<CborType>) -> Vec<u8>27 fn wrap_tag_and_encode_array(array: Vec<CborType>) -> Vec<u8> {
28     CborType::Tag(COSE_SIGN_TAG, Box::new(CborType::Array(array))).serialize()
29 }
30 
31 // Helper function to create an encoded protected header for a COSE_Sign or COSE_Signature
32 // structure.
encode_test_protected_header(keys: Vec<CborType>, values: Vec<CborType>) -> Vec<u8>33 fn encode_test_protected_header(keys: Vec<CborType>, values: Vec<CborType>) -> Vec<u8> {
34     assert_eq!(keys.len(), values.len());
35     let mut map: BTreeMap<CborType, CborType> = BTreeMap::new();
36     for (key, value) in keys.iter().zip(values) {
37         map.insert(key.clone(), value.clone());
38     }
39     CborType::Map(map).serialize()
40 }
41 
42 // Helper function to create a test COSE_Signature structure with the given protected header.
build_test_cose_signature(protected_header: Vec<u8>) -> CborType43 fn build_test_cose_signature(protected_header: Vec<u8>) -> CborType {
44     CborType::Array(vec![CborType::Bytes(protected_header),
45          CborType::Map(BTreeMap::new()),
46          CborType::Bytes(Vec::new())])
47 }
48 
49 // Helper function to create the minimally-valid COSE_Sign (i.e. "body") protected header.
make_minimally_valid_cose_sign_protected_header() -> Vec<u8>50 fn make_minimally_valid_cose_sign_protected_header() -> Vec<u8> {
51     encode_test_protected_header(
52         vec![CborType::Integer(COSE_HEADER_KID)],
53         vec![CborType::Array(Vec::new())],
54     )
55 }
56 
57 // Helper function to create a minimally-valid COSE_Signature (i.e. "body").
make_minimally_valid_cose_signature_protected_header() -> Vec<u8>58 fn make_minimally_valid_cose_signature_protected_header() -> Vec<u8> {
59     encode_test_protected_header(
60         vec![CborType::Integer(COSE_HEADER_ALG),
61              CborType::Integer(COSE_HEADER_KID)],
62         vec![CborType::SignedInteger(COSE_TYPE_ES256),
63              CborType::Bytes(Vec::new())],
64     )
65 }
66 
67 // This tests the minimally-valid COSE_Sign structure according to this implementation.
68 // The structure must be a CBOR array of length 4 tagged with the integer 98.
69 // The COSE_Sign protected header must have the `kid` integer key and no others. The value for `kid`
70 // must be an array (although it may be empty). Each element of the array must be of type bytes.
71 // The COSE_Sign unprotected header must be an empty map.
72 // The COSE_Sign payload must be nil.
73 // The COSE_Sign signatures must be an array with at least one COSE_Signature.
74 // Each COSE_Signature must be an array of length 3.
75 // Each COSE_Signature protected header must have the `alg` and `kid` integer keys and no others.
76 // The value for `alg` must be a valid algorithm identifier. The value for `kid` must be bytes,
77 // although it may be empty.
78 // Each COSE_Signature unprotected header must be an empty map.
79 // Each COSE_Signature signature must be of type bytes (although it may be empty).
80 #[test]
test_cose_sign_minimally_valid()81 fn test_cose_sign_minimally_valid() {
82     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
83     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
84     let signature = build_test_cose_signature(signature_protected_header);
85     let values = vec![CborType::Bytes(body_protected_header),
86                       CborType::Map(BTreeMap::new()),
87                       CborType::Null,
88                       CborType::Array(vec![signature])];
89     let bytes = wrap_tag_and_encode_array(values);
90     let payload = vec![0];
91     let result = decode_signature(&bytes, &payload);
92     assert!(result.is_ok());
93     let decoded = result.unwrap();
94     assert_eq!(decoded.len(), 1);
95     assert_eq!(decoded[0].signer_cert.len(), 0);
96     assert_eq!(decoded[0].certs.len(), 0);
97 }
98 
99 #[test]
test_cose_sign_not_tagged()100 fn test_cose_sign_not_tagged() {
101     let bytes = CborType::Array(vec![CborType::Integer(0)]).serialize();
102     test_cose_format_error(&bytes, CoseError::UnexpectedType);
103 }
104 
105 #[test]
test_cose_sign_wrong_tag()106 fn test_cose_sign_wrong_tag() {
107     // The expected COSE_Sign tag is 98.
108     let bytes = CborType::Tag(99, Box::new(CborType::Integer(0))).serialize();
109     test_cose_format_error(&bytes, CoseError::UnexpectedTag);
110 }
111 
112 #[test]
test_cose_sign_right_tag_wrong_contents()113 fn test_cose_sign_right_tag_wrong_contents() {
114     // The COSE_Sign tag is 98, but the contents should be an array.
115     let bytes = CborType::Tag(98, Box::new(CborType::Integer(0))).serialize();
116     test_cose_format_error(&bytes, CoseError::UnexpectedType);
117 }
118 
119 #[test]
test_cose_sign_too_small()120 fn test_cose_sign_too_small() {
121     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
122     let values = vec![CborType::Bytes(body_protected_header),
123                       CborType::Map(BTreeMap::new()),
124                       CborType::Null];
125     let bytes = wrap_tag_and_encode_array(values);
126     test_cose_format_error(&bytes, CoseError::MalformedInput);
127 }
128 
129 #[test]
test_cose_sign_too_large()130 fn test_cose_sign_too_large() {
131     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
132     let values = vec![CborType::Bytes(body_protected_header),
133                       CborType::Map(BTreeMap::new()),
134                       CborType::Null,
135                       CborType::Array(Vec::new()),
136                       CborType::Array(Vec::new())];
137     let bytes = wrap_tag_and_encode_array(values);
138     test_cose_format_error(&bytes, CoseError::MalformedInput);
139 }
140 
141 #[test]
test_cose_sign_protected_header_empty()142 fn test_cose_sign_protected_header_empty() {
143     let body_protected_header = encode_test_protected_header(Vec::new(), Vec::new());
144     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
145     let signature = build_test_cose_signature(signature_protected_header);
146     let values = vec![CborType::Bytes(body_protected_header),
147                       CborType::Map(BTreeMap::new()),
148                       CborType::Null,
149                       CborType::Array(vec![signature])];
150     let bytes = wrap_tag_and_encode_array(values);
151     test_cose_format_error(&bytes, CoseError::MalformedInput);
152 }
153 
154 #[test]
test_cose_sign_protected_header_missing_kid()155 fn test_cose_sign_protected_header_missing_kid() {
156     let body_protected_header =
157         encode_test_protected_header(vec![CborType::Integer(2)], vec![CborType::Integer(2)]);
158     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
159     let signature = build_test_cose_signature(signature_protected_header);
160     let values = vec![CborType::Bytes(body_protected_header),
161                       CborType::Map(BTreeMap::new()),
162                       CborType::Null,
163                       CborType::Array(vec![signature])];
164     let bytes = wrap_tag_and_encode_array(values);
165     test_cose_format_error(&bytes, CoseError::MissingHeader);
166 }
167 
168 #[test]
test_cose_sign_protected_header_kid_wrong_type()169 fn test_cose_sign_protected_header_kid_wrong_type() {
170     let body_protected_header = encode_test_protected_header(
171         vec![CborType::Integer(COSE_HEADER_KID)],
172         vec![CborType::Integer(2)],
173     );
174     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
175     let signature = build_test_cose_signature(signature_protected_header);
176     let values = vec![CborType::Bytes(body_protected_header),
177                       CborType::Map(BTreeMap::new()),
178                       CborType::Null,
179                       CborType::Array(vec![signature])];
180     let bytes = wrap_tag_and_encode_array(values);
181     test_cose_format_error(&bytes, CoseError::UnexpectedType);
182 }
183 
184 #[test]
test_cose_sign_protected_header_extra_header_key()185 fn test_cose_sign_protected_header_extra_header_key() {
186     let body_protected_header = encode_test_protected_header(
187         vec![CborType::Integer(COSE_HEADER_KID),
188              CborType::Integer(2)],
189         vec![CborType::Bytes(Vec::new()),
190              CborType::Integer(2)],
191     );
192     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
193     let signature = build_test_cose_signature(signature_protected_header);
194     let values = vec![CborType::Bytes(body_protected_header),
195                       CborType::Map(BTreeMap::new()),
196                       CborType::Null,
197                       CborType::Array(vec![signature])];
198     let bytes = wrap_tag_and_encode_array(values);
199     test_cose_format_error(&bytes, CoseError::MalformedInput);
200 }
201 
202 #[test]
test_cose_sign_unprotected_header_wrong_type()203 fn test_cose_sign_unprotected_header_wrong_type() {
204     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
205     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
206     let signature = build_test_cose_signature(signature_protected_header);
207     let values = vec![CborType::Bytes(body_protected_header),
208                       CborType::Integer(1),
209                       CborType::Null,
210                       CborType::Array(vec![signature])];
211     let bytes = wrap_tag_and_encode_array(values);
212     test_cose_format_error(&bytes, CoseError::UnexpectedType);
213 }
214 
215 #[test]
test_cose_sign_unprotected_header_not_empty()216 fn test_cose_sign_unprotected_header_not_empty() {
217     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
218     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
219     let signature = build_test_cose_signature(signature_protected_header);
220     let mut unprotected_header_map: BTreeMap<CborType, CborType> = BTreeMap::new();
221     unprotected_header_map.insert(CborType::Integer(0), CborType::SignedInteger(-1));
222     let values = vec![CborType::Bytes(body_protected_header),
223                       CborType::Map(unprotected_header_map),
224                       CborType::Null,
225                       CborType::Array(vec![signature])];
226     let bytes = wrap_tag_and_encode_array(values);
227     test_cose_format_error(&bytes, CoseError::MalformedInput);
228 }
229 
230 #[test]
test_cose_sign_payload_not_null()231 fn test_cose_sign_payload_not_null() {
232     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
233     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
234     let signature = build_test_cose_signature(signature_protected_header);
235     let values = vec![CborType::Bytes(body_protected_header),
236                       CborType::Map(BTreeMap::new()),
237                       CborType::Integer(0),
238                       CborType::Array(vec![signature])];
239     let bytes = wrap_tag_and_encode_array(values);
240     test_cose_format_error(&bytes, CoseError::UnexpectedType);
241 }
242 
243 #[test]
test_cose_signatures_not_array()244 fn test_cose_signatures_not_array() {
245     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
246     let values = vec![CborType::Bytes(body_protected_header),
247                       CborType::Map(BTreeMap::new()),
248                       CborType::Null,
249                       CborType::Integer(0)];
250     let bytes = wrap_tag_and_encode_array(values);
251     test_cose_format_error(&bytes, CoseError::UnexpectedType);
252 }
253 
254 #[test]
test_cose_signatures_empty()255 fn test_cose_signatures_empty() {
256     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
257     let values = vec![CborType::Bytes(body_protected_header),
258                       CborType::Map(BTreeMap::new()),
259                       CborType::Null,
260                       CborType::Array(Vec::new())];
261     let bytes = wrap_tag_and_encode_array(values);
262     test_cose_format_error(&bytes, CoseError::MalformedInput);
263 }
264 
265 #[test]
test_cose_signature_protected_header_wrong_type()266 fn test_cose_signature_protected_header_wrong_type() {
267     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
268     let signature = CborType::Array(vec![CborType::Null,
269          CborType::Map(BTreeMap::new()),
270          CborType::SignedInteger(-1)]);
271     let values = vec![CborType::Bytes(body_protected_header),
272                       CborType::Map(BTreeMap::new()),
273                       CborType::Null,
274                       CborType::Array(vec![signature])];
275     let bytes = wrap_tag_and_encode_array(values);
276     test_cose_format_error(&bytes, CoseError::UnexpectedType);
277 }
278 
279 #[test]
test_cose_signature_protected_header_empty()280 fn test_cose_signature_protected_header_empty() {
281     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
282     let signature_protected_header = encode_test_protected_header(Vec::new(), Vec::new());
283     let signature = build_test_cose_signature(signature_protected_header);
284     let values = vec![CborType::Bytes(body_protected_header),
285                       CborType::Map(BTreeMap::new()),
286                       CborType::Null,
287                       CborType::Array(vec![signature])];
288     let bytes = wrap_tag_and_encode_array(values);
289     test_cose_format_error(&bytes, CoseError::MalformedInput);
290 }
291 
292 #[test]
test_cose_signature_protected_header_too_large()293 fn test_cose_signature_protected_header_too_large() {
294     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
295     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
296     let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header),
297          CborType::Map(BTreeMap::new()),
298          CborType::Bytes(Vec::new()),
299          CborType::Null]);
300     let values = vec![CborType::Bytes(body_protected_header),
301                       CborType::Map(BTreeMap::new()),
302                       CborType::Null,
303                       CborType::Array(vec![signature])];
304     let bytes = wrap_tag_and_encode_array(values);
305     test_cose_format_error(&bytes, CoseError::MalformedInput);
306 }
307 
308 #[test]
test_cose_signature_protected_header_bad_encoding()309 fn test_cose_signature_protected_header_bad_encoding() {
310     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
311     // The bytes here are a truncated integer encoding.
312     let signature = CborType::Array(vec![CborType::Bytes(vec![0x1a, 0x00, 0x00]),
313          CborType::Map(BTreeMap::new()),
314          CborType::Bytes(Vec::new())]);
315     let values = vec![CborType::Bytes(body_protected_header),
316                       CborType::Map(BTreeMap::new()),
317                       CborType::Null,
318                       CborType::Array(vec![signature])];
319     let bytes = wrap_tag_and_encode_array(values);
320     test_cose_format_error(&bytes, CoseError::DecodingFailure);
321 }
322 
323 #[test]
test_cose_signature_protected_header_missing_alg()324 fn test_cose_signature_protected_header_missing_alg() {
325     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
326     let signature_protected_header = encode_test_protected_header(
327         vec![CborType::Integer(2),
328              CborType::Integer(COSE_HEADER_KID)],
329         vec![CborType::SignedInteger(COSE_TYPE_ES256),
330              CborType::Bytes(Vec::new())],
331     );
332     let signature = build_test_cose_signature(signature_protected_header);
333     let values = vec![CborType::Bytes(body_protected_header),
334                       CborType::Map(BTreeMap::new()),
335                       CborType::Null,
336                       CborType::Array(vec![signature])];
337     let bytes = wrap_tag_and_encode_array(values);
338     test_cose_format_error(&bytes, CoseError::MissingHeader);
339 }
340 
341 #[test]
test_cose_signature_protected_header_missing_kid()342 fn test_cose_signature_protected_header_missing_kid() {
343     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
344     let signature_protected_header = encode_test_protected_header(
345         vec![CborType::Integer(COSE_HEADER_ALG),
346              CborType::Integer(3)],
347         vec![CborType::SignedInteger(COSE_TYPE_ES256),
348              CborType::Bytes(Vec::new())],
349     );
350     let signature = build_test_cose_signature(signature_protected_header);
351     let values = vec![CborType::Bytes(body_protected_header),
352                       CborType::Map(BTreeMap::new()),
353                       CborType::Null,
354                       CborType::Array(vec![signature])];
355     let bytes = wrap_tag_and_encode_array(values);
356     test_cose_format_error(&bytes, CoseError::MissingHeader);
357 }
358 
359 #[test]
test_cose_signature_protected_header_wrong_key_types()360 fn test_cose_signature_protected_header_wrong_key_types() {
361     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
362     let signature_protected_header = encode_test_protected_header(
363         vec![CborType::SignedInteger(-1),
364              CborType::Bytes(vec![0])],
365         vec![CborType::SignedInteger(COSE_TYPE_ES256),
366              CborType::Bytes(Vec::new())],
367     );
368     let signature = build_test_cose_signature(signature_protected_header);
369     let values = vec![CborType::Bytes(body_protected_header),
370                       CborType::Map(BTreeMap::new()),
371                       CborType::Null,
372                       CborType::Array(vec![signature])];
373     let bytes = wrap_tag_and_encode_array(values);
374     test_cose_format_error(&bytes, CoseError::MissingHeader);
375 }
376 
377 #[test]
test_cose_signature_protected_header_unexpected_alg_type()378 fn test_cose_signature_protected_header_unexpected_alg_type() {
379     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
380     let signature_protected_header = encode_test_protected_header(
381         vec![CborType::Integer(COSE_HEADER_ALG),
382              CborType::Integer(COSE_HEADER_KID)],
383         vec![CborType::Integer(10),
384              CborType::Integer(4)],
385     );
386     let signature = build_test_cose_signature(signature_protected_header);
387     let values = vec![CborType::Bytes(body_protected_header),
388                       CborType::Map(BTreeMap::new()),
389                       CborType::Null,
390                       CborType::Array(vec![signature])];
391     let bytes = wrap_tag_and_encode_array(values);
392     test_cose_format_error(&bytes, CoseError::UnexpectedType);
393 }
394 
395 #[test]
test_cose_signature_protected_header_unsupported_alg()396 fn test_cose_signature_protected_header_unsupported_alg() {
397     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
398     let signature_protected_header = encode_test_protected_header(
399         vec![CborType::Integer(COSE_HEADER_ALG),
400              CborType::Integer(COSE_HEADER_KID)],
401         vec![CborType::SignedInteger(-10),
402              CborType::Bytes(Vec::new())],
403     );
404     let signature = build_test_cose_signature(signature_protected_header);
405     let values = vec![CborType::Bytes(body_protected_header),
406                       CborType::Map(BTreeMap::new()),
407                       CborType::Null,
408                       CborType::Array(vec![signature])];
409     let bytes = wrap_tag_and_encode_array(values);
410     test_cose_format_error(&bytes, CoseError::UnexpectedHeaderValue);
411 }
412 
413 #[test]
test_cose_signature_protected_header_unexpected_kid_type()414 fn test_cose_signature_protected_header_unexpected_kid_type() {
415     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
416     let signature_protected_header = encode_test_protected_header(
417         vec![CborType::Integer(COSE_HEADER_ALG),
418              CborType::Integer(COSE_HEADER_KID)],
419         vec![CborType::SignedInteger(COSE_TYPE_ES256),
420              CborType::Integer(0)],
421     );
422     let signature = build_test_cose_signature(signature_protected_header);
423     let values = vec![CborType::Bytes(body_protected_header),
424                       CborType::Map(BTreeMap::new()),
425                       CborType::Null,
426                       CborType::Array(vec![signature])];
427     let bytes = wrap_tag_and_encode_array(values);
428     test_cose_format_error(&bytes, CoseError::UnexpectedType);
429 }
430 
431 #[test]
test_cose_signature_protected_header_extra_key()432 fn test_cose_signature_protected_header_extra_key() {
433     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
434     let signature_protected_header = encode_test_protected_header(
435         vec![CborType::Integer(COSE_HEADER_ALG),
436              CborType::Integer(COSE_HEADER_KID),
437              CborType::Integer(5)],
438         vec![CborType::SignedInteger(COSE_TYPE_ES256),
439              CborType::Bytes(Vec::new()),
440              CborType::Integer(5)],
441     );
442     let signature = build_test_cose_signature(signature_protected_header);
443     let values = vec![CborType::Bytes(body_protected_header),
444                       CborType::Map(BTreeMap::new()),
445                       CborType::Null,
446                       CborType::Array(vec![signature])];
447     let bytes = wrap_tag_and_encode_array(values);
448     test_cose_format_error(&bytes, CoseError::MalformedInput);
449 }
450 
451 #[test]
test_cose_signature_unprotected_header_wrong_type()452 fn test_cose_signature_unprotected_header_wrong_type() {
453     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
454     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
455     let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header),
456          CborType::Integer(1),
457          CborType::Bytes(Vec::new())]);
458     let values = vec![CborType::Bytes(body_protected_header),
459                       CborType::Map(BTreeMap::new()),
460                       CborType::Null,
461                       CborType::Array(vec![signature])];
462     let bytes = wrap_tag_and_encode_array(values);
463     test_cose_format_error(&bytes, CoseError::UnexpectedType);
464 }
465 
466 #[test]
test_cose_signature_unprotected_header_not_empty()467 fn test_cose_signature_unprotected_header_not_empty() {
468     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
469     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
470     let mut unprotected_header_map: BTreeMap<CborType, CborType> = BTreeMap::new();
471     unprotected_header_map.insert(CborType::Integer(0), CborType::SignedInteger(-1));
472     let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header),
473          CborType::Map(unprotected_header_map),
474          CborType::Bytes(Vec::new())]);
475     let values = vec![CborType::Bytes(body_protected_header),
476                       CborType::Map(BTreeMap::new()),
477                       CborType::Null,
478                       CborType::Array(vec![signature])];
479     let bytes = wrap_tag_and_encode_array(values);
480     test_cose_format_error(&bytes, CoseError::MalformedInput);
481 }
482 
483 #[test]
test_cose_signature_signature_wrong_type()484 fn test_cose_signature_signature_wrong_type() {
485     let body_protected_header = make_minimally_valid_cose_sign_protected_header();
486     let signature_protected_header = make_minimally_valid_cose_signature_protected_header();
487     let signature = CborType::Array(vec![CborType::Bytes(signature_protected_header),
488          CborType::Map(BTreeMap::new()),
489          CborType::SignedInteger(-1)]);
490     let values = vec![CborType::Bytes(body_protected_header),
491                       CborType::Map(BTreeMap::new()),
492                       CborType::Null,
493                       CborType::Array(vec![signature])];
494     let bytes = wrap_tag_and_encode_array(values);
495     test_cose_format_error(&bytes, CoseError::UnexpectedType);
496 }
497