blob: 4512df7c823fcf1d247b1a7b39f272685f7f4fb2 [file] [log] [blame]
Aditya Belsareff911b42022-02-04 23:57:51 +00001// 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//! Example program demonstrating signature creation.
18use coset::{iana, CborSerializable};
19
20#[derive(Copy, Clone)]
21struct FakeSigner {}
22
23// Use a fake signer/verifier (to avoid pulling in lots of dependencies).
24impl FakeSigner {
25 fn sign(&self, data: &[u8]) -> Vec<u8> {
26 data.to_vec()
27 }
28
29 fn verify(&self, sig: &[u8], data: &[u8]) -> Result<(), String> {
30 if sig != self.sign(data) {
31 Err("failed to verify".to_owned())
32 } else {
33 Ok(())
34 }
35 }
36}
37
38fn main() {
39 // Build a fake signer/verifier (to avoid pulling in lots of dependencies).
40 let signer = FakeSigner {};
41 let verifier = signer;
42
43 // Inputs.
44 let pt = b"This is the content";
45 let aad = b"this is additional data";
46
47 // Build a `CoseSign1` object.
48 let protected = coset::HeaderBuilder::new()
49 .algorithm(iana::Algorithm::ES256)
50 .key_id(b"11".to_vec())
51 .build();
52 let sign1 = coset::CoseSign1Builder::new()
53 .protected(protected)
54 .payload(pt.to_vec())
55 .create_signature(aad, |pt| signer.sign(pt))
56 .build();
57
58 // Serialize to bytes.
59 let sign1_data = sign1.to_vec().unwrap();
60 println!(
61 "'{}' + '{}' => {}",
62 String::from_utf8_lossy(pt),
63 String::from_utf8_lossy(aad),
64 hex::encode(&sign1_data)
65 );
66
67 // At the receiving end, deserialize the bytes back to a `CoseSign1` object.
68 let mut sign1 = coset::CoseSign1::from_slice(&sign1_data).unwrap();
69
70 // Check the signature, which needs to have the same `aad` provided.
71 let result = sign1.verify_signature(aad, |sig, data| verifier.verify(sig, data));
72 println!("Signature verified: {:?}.", result);
73 assert!(result.is_ok());
74
75 // Changing an unprotected header leaves the signature valid.
76 sign1.unprotected.content_type = Some(coset::ContentType::Text("text/plain".to_owned()));
77 assert!(sign1
78 .verify_signature(aad, |sig, data| verifier.verify(sig, data))
79 .is_ok());
80
81 // Providing a different `aad` means the signature won't validate.
82 assert!(sign1
83 .verify_signature(b"not aad", |sig, data| verifier.verify(sig, data))
84 .is_err());
85
86 // Changing a protected header invalidates the signature.
87 sign1.protected.header.content_type = Some(coset::ContentType::Text("text/plain".to_owned()));
88 assert!(sign1
89 .verify_signature(aad, |sig, data| verifier.verify(sig, data))
90 .is_err());
91}