4 个版本
0.2.0 | 2024年8月14日 |
---|---|
0.1.2 | 2024年1月11日 |
0.1.1 | 2023年11月20日 |
0.1.0 | 2023年6月21日 |
#265 在 编码
每月146次下载
在 ccatoken 中使用
155KB
3.5K SLoC
这是对 EAT Attestation Results 和 Attestation Results for Secure Interactions (AR4SI) 的实现。
示例
签名
use std::collections::BTreeMap;
use ear::{Ear, VerifierID, Algorithm, Appraisal};
const SIGNING_KEY: &str = "-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgPp4XZRnRHSMhGg0t
6yjQCRV35J4TUY4idLgiCu6EyLqhRANCAAQbx8C533c2AKDwL/RtjVipVnnM2WRv
5w2wZNCJrubSK0StYKJ71CikDgkhw8M90ojfRIowqpl0uLA3kW3PEZy9
-----END PRIVATE KEY-----
";
fn main() {
let token = Ear{
profile: "test".to_string(),
iat: 1,
vid: VerifierID {
build: "vsts 0.0.1".to_string(),
developer: "https://veraison-project.org".to_string(),
},
raw_evidence: None,
nonce: None,
submods: BTreeMap::from([("test".to_string(), Appraisal::new())]),
};
let signed = token.sign_jwt_pem(Algorithm::ES256, SIGNING_KEY.as_bytes()).unwrap();
}
验证
use ear::{Ear, Algorithm};
const VERIF_KEY: &str = r#"
{
"kty":"EC",
"crv":"P-256",
"x":"G8fAud93NgCg8C_0bY1YqVZ5zNlkb-cNsGTQia7m0is",
"y":"RK1gonvUKKQOCSHDwz3SiN9EijCqmXS4sDeRbc8RnL0"
}
"#;
fn main() {
let signed = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJlYXRfcHJvZmlsZSI6InRlc3QiLCJpYXQiOjEsImVhci52ZXJpZmllci1pZCI6eyJkZXZlbG9wZXIiOiJodHRwczovL3ZlcmFpc29uLXByb2plY3Qub3JnIiwiYnVpbGQiOiJ2c3RzIDAuMC4xIn0sInN1Ym1vZHMiOnsidGVzdCI6eyJlYXIuc3RhdHVzIjoibm9uZSJ9fX0.G25v0j0NDQhSOcK3Jtfq5vqVxnoWuWf-Q0DCNkCwpyB03DGr25ZDJ3IDSAHVPZrr6TVMwj8RcGEzQnCrucem4Q";
let token = Ear::from_jwt_jwk(signed, Algorithm::ES256, VERIF_KEY.as_bytes()).unwrap();
println!("EAR profiles: {}", token.profile);
}
扩展和配置文件
EAR 支持在顶层(即 Ear
结构体内部)以及 Appraisal
内部进行扩展。扩展是额外的字段定义。可以通过将它们注册到相应结构体的 extensions
字段来定义扩展。在注册扩展时,您必须提供一个字符串名称(用于 JSON),一个整数键(用于 CBOR),以及一个 ExtensionKind
来指示哪些 ExtensionValue
是有效的。
注册单个扩展
可以直接通过相应结构体的 extensions
字段注册扩展。一旦注册,它们的值就可以设置和查询。
use ear::{Ear, Appraisal, ExtensionKind, ExtensionValue};
let mut ear = Ear::new();
ear.extensions.register("ext.company-name", -65537, ExtensionKind::String).unwrap();
let mut appraisal = Appraisal::new();
// extensions for Ear's and Appraisal's have their own namespaces, so it is
// to use the same key in both.
appraisal.extensions.register("ext.timestamp", -65537, ExtensionKind::Integer).unwrap();
ear.extensions.set_by_name(
"ext.company-name",
ExtensionValue::String("Acme Inc.".to_string()),
).unwrap();
appraisal.extensions.set_by_key(
-65537,
ExtensionValue::Integer(1723534859),
).unwrap();
ear.submods.insert("road-runner-trap".to_string(), appraisal);
assert_eq!(
ear.extensions.get_by_key(&-65537).unwrap(),
ExtensionValue::String("Acme Inc.".to_string()),
);
assert_eq!(
ear.submods["road-runner-trap"].extensions.get_by_name("ext.timestamp").unwrap(),
ExtensionValue::Integer(1723534859),
);
注意:如果您通过从 CBOR/JSON 反序列化获得了 Ear
,则 Extensions
结构体将缓存任何意外的字段的值,以便在之后注册扩展时,相应的反序列化值将可访问。
使用配置文件
可以在 Profile
中关联扩展集合。可以注册一个 Profile
,然后在创建新的 Ear
或 Appraisal
时通过其 id
查询。
use ear::{Ear, Appraisal, ExtensionKind, ExtensionValue, Profile, register_profile};
fn init_profile() {
let mut profile = Profile::new("tag:github.com,2023:veraison/ear#acme-profile");
profile.register_ear_extension(
"ext.company-name", -65537, ExtensionKind::String).unwrap();
profile.register_appraisal_extension(
"ext.timestamp", -65537, ExtensionKind::Integer).unwrap();
register_profile(&profile);
}
fn main() {
init_profile();
let mut ear = Ear::new_with_profile(
"tag:github.com,2023:veraison/ear#acme-profile").unwrap();
// these will apply to all submods/appraisals within a profiled EAR
let mut appraisal = Appraisal::new_with_profile(
"tag:github.com,2023:veraison/ear#acme-profile").unwrap();
ear.extensions.set_by_name(
"ext.company-name",
ExtensionValue::String("Acme Inc.".to_string()),
).unwrap();
appraisal.extensions.set_by_key(
-65537,
ExtensionValue::Integer(1723534859),
).unwrap();
ear.submods.insert("road-runner-trap".to_string(), appraisal);
assert_eq!(
ear.extensions.get_by_key(&-65537).unwrap(),
ExtensionValue::String("Acme Inc.".to_string()),
);
assert_eq!(
ear.submods["road-runner-trap"]
.extensions.get_by_name("ext.timestamp").unwrap(),
ExtensionValue::Integer(1723534859),
);
}
在反序列化 Ear
时,其 profile
字段将自动用于查找已注册的配置文件并添加关联的扩展。
限制
- 签名支持 PEM 和 DER 密钥;验证目前仅支持 JWK 密钥。
- JWT 签名目前仅支持 ES256、ES384、EdDSA、PS256、PS384 和 PS512。
- COSE 签名目前仅支持 ES256、ES384、ES512 和 EdDSA。
依赖关系
~4–16MB
~252K SLoC