1use std::convert::TryFrom;
7use std::fmt;
8
9use nom::branch::alt;
10use nom::combinator::map;
11use nom::{branch, bytes::complete as bytes, combinator, multi, sequence};
12
13use crate::ocard::algorithm::{AlgorithmAttributes, AlgorithmInformation};
14use crate::ocard::data::{algo_attrs, complete};
15use crate::ocard::tlv;
16use crate::ocard::KeyType;
17
18impl AlgorithmInformation {
19 pub fn for_keytype(&self, kt: KeyType) -> Vec<&AlgorithmAttributes> {
20 self.0
21 .iter()
22 .filter(|(k, _)| *k == kt)
23 .map(|(_, a)| a)
24 .collect()
25 }
26}
27
28impl fmt::Display for AlgorithmInformation {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 for (kt, a) in &self.0 {
31 let kt = match kt {
32 KeyType::Signing => "SIG",
33 KeyType::Decryption => "DEC",
34 KeyType::Authentication => "AUT",
35 KeyType::Attestation => "ATT",
36 };
37 writeln!(f, "{kt}: {a:?} ")?;
38 }
39 Ok(())
40 }
41}
42
43fn key_type(input: &[u8]) -> nom::IResult<&[u8], KeyType> {
44 alt((
45 map(bytes::tag([0xc1]), |_| KeyType::Signing),
46 map(bytes::tag([0xc2]), |_| KeyType::Decryption),
47 map(bytes::tag([0xc3]), |_| KeyType::Authentication),
48 map(bytes::tag([0xda]), |_| KeyType::Attestation),
49 ))(input)
50}
51
52fn unknown(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
53 Ok((&[], AlgorithmAttributes::Unknown(input.to_vec())))
54}
55
56fn parse_one(input: &[u8]) -> nom::IResult<&[u8], AlgorithmAttributes> {
57 let (input, a) = combinator::map(
58 combinator::flat_map(tlv::length::length, bytes::take),
59 |i| alt((combinator::all_consuming(algo_attrs::parse), unknown))(i),
60 )(input)?;
61
62 Ok((input, a?.1))
63}
64
65fn parse_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
66 multi::many0(sequence::pair(key_type, parse_one))(input)
67}
68
69fn parse_tl_list(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
70 let (input, (_, _, list)) =
71 sequence::tuple((bytes::tag([0xfa]), tlv::length::length, parse_list))(input)?;
72
73 Ok((input, list))
74}
75
76fn parse(input: &[u8]) -> nom::IResult<&[u8], Vec<(KeyType, AlgorithmAttributes)>> {
77 branch::alt((
84 combinator::all_consuming(parse_list),
85 combinator::all_consuming(parse_tl_list),
86 ))(input)
87}
88
89impl TryFrom<&[u8]> for AlgorithmInformation {
90 type Error = crate::Error;
91
92 fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
93 Ok(AlgorithmInformation(complete(parse(input))?))
94 }
95}
96
97#[cfg(test)]
100mod test {
101 use std::convert::TryFrom;
102
103 use crate::ocard::algorithm::{
104 AlgorithmAttributes::*, AlgorithmInformation, Curve::*, EccAttributes, RsaAttributes,
105 };
106 use crate::ocard::crypto::EccType::*;
107 use crate::ocard::KeyType::*;
108
109 #[test]
110 fn test_gnuk() {
111 let data = [
112 0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
113 0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b,
114 0x81, 0x4, 0x0, 0xa, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
115 0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0,
116 0xc2, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x13, 0x2b,
117 0x81, 0x4, 0x0, 0xa, 0xc2, 0xb, 0x12, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5,
118 0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
119 0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
120 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
121 0x1,
122 ];
123
124 let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
125
126 assert_eq!(
127 ai,
128 AlgorithmInformation(vec![
129 (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
130 (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
131 (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
132 (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
133 (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
134 (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
135 (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
136 (Decryption, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
137 (Decryption, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
138 (Decryption, Ecc(EccAttributes::new(ECDH, Curve25519, None))),
139 (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
140 (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
141 (
142 Authentication,
143 Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
144 ),
145 (
146 Authentication,
147 Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
148 ),
149 (
150 Authentication,
151 Ecc(EccAttributes::new(EdDSA, Ed25519, None))
152 )
153 ])
154 );
155 }
156
157 #[test]
158 fn test_opgp_card_34() {
159 let data = [
160 0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0,
161 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc1, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce,
162 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc1, 0x6, 0x13,
163 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1,
164 0x7, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13,
165 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc2, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20,
166 0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x20, 0x0, 0xc2, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20,
167 0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc2, 0x6, 0x12,
168 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc2, 0xa,
169 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3,
170 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
171 0x1, 0xd, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0,
172 0x20, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x20, 0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86,
173 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3,
174 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8,
175 0x1, 0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3,
176 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
177 ];
178
179 let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
180
181 assert_eq!(
182 ai,
183 AlgorithmInformation(vec![
184 (Signing, Rsa(RsaAttributes::new(2048, 32, 0))),
185 (Signing, Rsa(RsaAttributes::new(3072, 32, 0))),
186 (Signing, Rsa(RsaAttributes::new(4096, 32, 0))),
187 (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
188 (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
189 (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
190 (
191 Signing,
192 Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
193 ),
194 (
195 Signing,
196 Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
197 ),
198 (
199 Signing,
200 Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
201 ),
202 (Decryption, Rsa(RsaAttributes::new(2048, 32, 0))),
203 (Decryption, Rsa(RsaAttributes::new(3072, 32, 0))),
204 (Decryption, Rsa(RsaAttributes::new(4096, 32, 0))),
205 (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
206 (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
207 (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
208 (
209 Decryption,
210 Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
211 ),
212 (
213 Decryption,
214 Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
215 ),
216 (
217 Decryption,
218 Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
219 ),
220 (Authentication, Rsa(RsaAttributes::new(2048, 32, 0))),
221 (Authentication, Rsa(RsaAttributes::new(3072, 32, 0))),
222 (Authentication, Rsa(RsaAttributes::new(4096, 32, 0))),
223 (
224 Authentication,
225 Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
226 ),
227 (
228 Authentication,
229 Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
230 ),
231 (
232 Authentication,
233 Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
234 ),
235 (
236 Authentication,
237 Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
238 ),
239 (
240 Authentication,
241 Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
242 ),
243 (
244 Authentication,
245 Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
246 )
247 ])
248 );
249 }
250
251 #[test]
252 fn test_yk5() {
253 let data = [
254 0xfa, 0x82, 0x1, 0xe2, 0xc1, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0xc,
255 0x0, 0x0, 0x11, 0x0, 0xc1, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc1, 0x9, 0x13, 0x2a,
256 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22,
257 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc1, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0,
258 0xa, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc1, 0xa, 0x13,
259 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc1, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3,
260 0x2, 0x8, 0x1, 0x1, 0xd, 0xc1, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf,
261 0x1, 0xc1, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc2, 0x6,
262 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x6,
263 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xc2, 0x9, 0x12, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3,
264 0x1, 0x7, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc2, 0x6, 0x12, 0x2b, 0x81,
265 0x4, 0x0, 0x23, 0xc2, 0x6, 0x12, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc2, 0xa, 0x12, 0x2b,
266 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2,
267 0x8, 0x1, 0x1, 0xb, 0xc2, 0xa, 0x12, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd,
268 0xc2, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc2, 0xb, 0x16, 0x2b,
269 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1, 0xc3, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11,
270 0x0, 0xc3, 0x6, 0x1, 0xc, 0x0, 0x0, 0x11, 0x0, 0xc3, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11,
271 0x0, 0xc3, 0x9, 0x13, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xc3, 0x6, 0x13,
272 0x2b, 0x81, 0x4, 0x0, 0x22, 0xc3, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xc3, 0x6,
273 0x13, 0x2b, 0x81, 0x4, 0x0, 0xa, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1,
274 0x1, 0x7, 0xc3, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xc3, 0xa,
275 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xd, 0xc3, 0xa, 0x16, 0x2b, 0x6, 0x1,
276 0x4, 0x1, 0xda, 0x47, 0xf, 0x1, 0xc3, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55,
277 0x1, 0x5, 0x1, 0xda, 0x6, 0x1, 0x8, 0x0, 0x0, 0x11, 0x0, 0xda, 0x6, 0x1, 0xc, 0x0, 0x0,
278 0x11, 0x0, 0xda, 0x6, 0x1, 0x10, 0x0, 0x0, 0x11, 0x0, 0xda, 0x9, 0x13, 0x2a, 0x86,
279 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x22, 0xda,
280 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0x23, 0xda, 0x6, 0x13, 0x2b, 0x81, 0x4, 0x0, 0xa,
281 0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0x7, 0xda, 0xa, 0x13, 0x2b,
282 0x24, 0x3, 0x3, 0x2, 0x8, 0x1, 0x1, 0xb, 0xda, 0xa, 0x13, 0x2b, 0x24, 0x3, 0x3, 0x2,
283 0x8, 0x1, 0x1, 0xd, 0xda, 0xa, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0xda, 0x47, 0xf, 0x1,
284 0xda, 0xb, 0x16, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x97, 0x55, 0x1, 0x5, 0x1,
285 ];
286
287 let ai = AlgorithmInformation::try_from(&data[..]).unwrap();
288
289 assert_eq!(
290 ai,
291 AlgorithmInformation(vec![
292 (Signing, Rsa(RsaAttributes::new(2048, 17, 0))),
293 (Signing, Rsa(RsaAttributes::new(3072, 17, 0))),
294 (Signing, Rsa(RsaAttributes::new(4096, 17, 0))),
295 (Signing, Ecc(EccAttributes::new(ECDSA, NistP256r1, None))),
296 (Signing, Ecc(EccAttributes::new(ECDSA, NistP384r1, None))),
297 (Signing, Ecc(EccAttributes::new(ECDSA, NistP521r1, None))),
298 (Signing, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
299 (
300 Signing,
301 Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
302 ),
303 (
304 Signing,
305 Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
306 ),
307 (
308 Signing,
309 Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
310 ),
311 (Signing, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
312 (Signing, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
313 (Decryption, Rsa(RsaAttributes::new(2048, 17, 0))),
314 (Decryption, Rsa(RsaAttributes::new(3072, 17, 0))),
315 (Decryption, Rsa(RsaAttributes::new(4096, 17, 0))),
316 (Decryption, Ecc(EccAttributes::new(ECDH, NistP256r1, None))),
317 (Decryption, Ecc(EccAttributes::new(ECDH, NistP384r1, None))),
318 (Decryption, Ecc(EccAttributes::new(ECDH, NistP521r1, None))),
319 (Decryption, Ecc(EccAttributes::new(ECDH, Secp256k1, None))),
320 (
321 Decryption,
322 Ecc(EccAttributes::new(ECDH, BrainpoolP256r1, None))
323 ),
324 (
325 Decryption,
326 Ecc(EccAttributes::new(ECDH, BrainpoolP384r1, None))
327 ),
328 (
329 Decryption,
330 Ecc(EccAttributes::new(ECDH, BrainpoolP512r1, None))
331 ),
332 (Decryption, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
333 (Decryption, Ecc(EccAttributes::new(EdDSA, Curve25519, None))),
334 (Authentication, Rsa(RsaAttributes::new(2048, 17, 0))),
335 (Authentication, Rsa(RsaAttributes::new(3072, 17, 0))),
336 (Authentication, Rsa(RsaAttributes::new(4096, 17, 0))),
337 (
338 Authentication,
339 Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
340 ),
341 (
342 Authentication,
343 Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
344 ),
345 (
346 Authentication,
347 Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
348 ),
349 (
350 Authentication,
351 Ecc(EccAttributes::new(ECDSA, Secp256k1, None))
352 ),
353 (
354 Authentication,
355 Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
356 ),
357 (
358 Authentication,
359 Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
360 ),
361 (
362 Authentication,
363 Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
364 ),
365 (
366 Authentication,
367 Ecc(EccAttributes::new(EdDSA, Ed25519, None))
368 ),
369 (
370 Authentication,
371 Ecc(EccAttributes::new(EdDSA, Curve25519, None))
372 ),
373 (Attestation, Rsa(RsaAttributes::new(2048, 17, 0))),
374 (Attestation, Rsa(RsaAttributes::new(3072, 17, 0))),
375 (Attestation, Rsa(RsaAttributes::new(4096, 17, 0))),
376 (
377 Attestation,
378 Ecc(EccAttributes::new(ECDSA, NistP256r1, None))
379 ),
380 (
381 Attestation,
382 Ecc(EccAttributes::new(ECDSA, NistP384r1, None))
383 ),
384 (
385 Attestation,
386 Ecc(EccAttributes::new(ECDSA, NistP521r1, None))
387 ),
388 (Attestation, Ecc(EccAttributes::new(ECDSA, Secp256k1, None))),
389 (
390 Attestation,
391 Ecc(EccAttributes::new(ECDSA, BrainpoolP256r1, None))
392 ),
393 (
394 Attestation,
395 Ecc(EccAttributes::new(ECDSA, BrainpoolP384r1, None))
396 ),
397 (
398 Attestation,
399 Ecc(EccAttributes::new(ECDSA, BrainpoolP512r1, None))
400 ),
401 (Attestation, Ecc(EccAttributes::new(EdDSA, Ed25519, None))),
402 (
403 Attestation,
404 Ecc(EccAttributes::new(EdDSA, Curve25519, None))
405 )
406 ])
407 );
408 }
409}