cose/
keys.rs

1//! Module to encode/decode cose-keys/cose-keySets.
2//!
3//! # cose-keySet example
4//! ```
5//! use cose::keys;
6//! use cose::algs;
7//! use hex;
8//!
9//! fn main() {
10//!     let mut key = keys::CoseKey::new();
11//!     key.kty(keys::EC2);
12//!     key.alg(algs::ES256);
13//!     key.crv(keys::P_256);
14//!     key.d(hex::decode("57c92077664146e876760c9520d054aa93c3afb04e306705db6090308507b4d3").unwrap());
15//!     key.key_ops(vec![keys::KEY_OPS_SIGN]);
16//!
17//!     key.encode().unwrap();
18//!
19//!     let mut decode_key = keys::CoseKey::new();
20//!     decode_key.bytes = key.bytes;
21//!
22//!     decode_key.decode().unwrap();
23//!
24//!     assert_eq!(decode_key.d, key.d);
25//!     assert_eq!(decode_key.kty, key.kty);
26//!     assert_eq!(decode_key.crv, key.crv);
27//!     assert_eq!(decode_key.alg, key.alg);
28//!
29//!     let mut key_set = keys::CoseKeySet::new();
30//!     key_set.add_key(decode_key);
31//!     key_set.encode();
32//!
33//!     let mut decode_key_set = keys::CoseKeySet::new();
34//!     decode_key_set.bytes = key_set.bytes;
35//!     decode_key_set.decode();
36//!
37//!     assert_eq!(decode_key_set.cose_keys[0].d, key.d);
38//!     assert_eq!(decode_key_set.cose_keys[0].kty, key.kty);
39//!     assert_eq!(decode_key_set.cose_keys[0].crv, key.crv);
40//!     assert_eq!(decode_key_set.cose_keys[0].alg, key.alg);
41//! }
42//! ```
43
44use crate::algs;
45use crate::common;
46use crate::errors::{CoseError, CoseResult, CoseResultWithRet};
47use cbor::{decoder::DecodeError, types::Type, Config, Decoder, Encoder};
48use openssl::bn::BigNum;
49use openssl::rsa::Rsa;
50use std::io::Cursor;
51use std::str::from_utf8;
52
53pub(crate) const ECDH_KTY: [i32; 2] = [OKP, EC2];
54
55//COMMON PARAMETERS
56pub const D: i32 = -4;
57pub const Y: i32 = -3;
58pub const X: i32 = -2;
59pub const CRV_K: i32 = -1;
60pub const KTY: i32 = 1;
61pub const KID: i32 = 2;
62pub const ALG: i32 = 3;
63pub const KEY_OPS: i32 = 4;
64pub const BASE_IV: i32 = 5;
65
66//RSA PARAMETERS
67pub const N: i32 = -1;
68pub const E: i32 = -2;
69pub const RSA_D: i32 = -3;
70pub const P: i32 = -4;
71pub const Q: i32 = -5;
72pub const DP: i32 = -6;
73pub const DQ: i32 = -7;
74pub const QINV: i32 = -8;
75pub const OTHER: i32 = -9;
76pub const RI: i32 = -10;
77pub const DI: i32 = -11;
78pub const TI: i32 = -12;
79
80//KEY TYPES
81pub const OKP: i32 = 1;
82pub const EC2: i32 = 2;
83pub const RSA: i32 = 3;
84pub const SYMMETRIC: i32 = 4;
85pub const RESERVED: i32 = 0;
86pub(crate) const KTY_ALL: [i32; 5] = [RESERVED, OKP, EC2, RSA, SYMMETRIC];
87pub(crate) const KTY_NAMES: [&str; 5] = ["Reserved", "OKP", "EC2", "RSA", "Symmetric"];
88
89//KEY OPERATIONS
90pub const KEY_OPS_SIGN: i32 = 1;
91pub const KEY_OPS_VERIFY: i32 = 2;
92pub const KEY_OPS_ENCRYPT: i32 = 3;
93pub const KEY_OPS_DECRYPT: i32 = 4;
94pub const KEY_OPS_WRAP: i32 = 5;
95pub const KEY_OPS_UNWRAP: i32 = 6;
96pub const KEY_OPS_DERIVE: i32 = 7;
97pub const KEY_OPS_DERIVE_BITS: i32 = 8;
98pub const KEY_OPS_MAC: i32 = 9;
99pub const KEY_OPS_MAC_VERIFY: i32 = 10;
100pub(crate) const KEY_OPS_ALL: [i32; 10] = [
101    KEY_OPS_SIGN,
102    KEY_OPS_VERIFY,
103    KEY_OPS_ENCRYPT,
104    KEY_OPS_DECRYPT,
105    KEY_OPS_WRAP,
106    KEY_OPS_UNWRAP,
107    KEY_OPS_DERIVE,
108    KEY_OPS_DERIVE_BITS,
109    KEY_OPS_MAC,
110    KEY_OPS_MAC_VERIFY,
111];
112pub(crate) const KEY_OPS_NAMES: [&str; 10] = [
113    "sign",
114    "verify",
115    "encrypt",
116    "decrypt",
117    "wrap key",
118    "unwrap key",
119    "derive key",
120    "derive bits",
121    "MAC create",
122    "MAC verify",
123];
124
125//CURVES
126pub const P_256: i32 = 1;
127pub const SECP256K1: i32 = 8;
128pub const P_384: i32 = 2;
129pub const P_521: i32 = 3;
130pub const X25519: i32 = 4;
131pub const X448: i32 = 5;
132pub const ED25519: i32 = 6;
133pub const ED448: i32 = 7;
134pub(crate) const CURVES_ALL: [i32; 8] =
135    [P_256, P_384, P_521, X25519, X448, ED25519, ED448, SECP256K1];
136pub(crate) const EC2_CRVS: [i32; 3] = [P_256, P_384, P_521];
137pub(crate) const CURVES_NAMES: [&str; 8] = [
138    "P-256",
139    "P-384",
140    "P-521",
141    "X25519",
142    "X448",
143    "Ed25519",
144    "Ed448",
145    "secp256k1",
146];
147
148/// cose-key structure.
149#[derive(Clone)]
150pub struct CoseKey {
151    /// cose-key encoded bytes.
152    pub bytes: Vec<u8>,
153    used: Vec<i32>,
154    /// Key Type.
155    pub kty: Option<i32>,
156    /// Base Initialization Vector.
157    pub base_iv: Option<Vec<u8>>,
158    /// List of Key Operations.
159    pub key_ops: Vec<i32>,
160    /// COSE Algorithm.
161    pub alg: Option<i32>,
162    /// Public Key X parameter for OKP/EC2 Keys.
163    pub x: Option<Vec<u8>>,
164    /// Public Key Y parameter for EC2 Keys.
165    pub y: Option<Vec<u8>>,
166    /// Private Key D parameter for OKP/EC2 Keys.
167    pub d: Option<Vec<u8>>,
168    /// Key value for Symmetric Keys.
169    pub k: Option<Vec<u8>>,
170    /// Key ID.
171    pub kid: Option<Vec<u8>>,
172    /// COSE curve for OKP/EC2 keys.
173    pub crv: Option<i32>,
174    pub n: Option<Vec<u8>>,
175    pub e: Option<Vec<u8>>,
176    pub rsa_d: Option<Vec<u8>>,
177    pub p: Option<Vec<u8>>,
178    pub q: Option<Vec<u8>>,
179    pub dp: Option<Vec<u8>>,
180    pub dq: Option<Vec<u8>>,
181    pub qinv: Option<Vec<u8>>,
182    pub other: Option<Vec<Vec<u8>>>,
183    pub ri: Option<Vec<u8>>,
184    pub di: Option<Vec<u8>>,
185    pub ti: Option<Vec<u8>>,
186}
187
188impl CoseKey {
189    /// Creates an empty CoseKey structure
190    pub fn new() -> CoseKey {
191        CoseKey {
192            bytes: Vec::new(),
193            used: Vec::new(),
194            key_ops: Vec::new(),
195            base_iv: None,
196            kty: None,
197            alg: None,
198            x: None,
199            y: None,
200            d: None,
201            k: None,
202            kid: None,
203            crv: None,
204            n: None,
205            e: None,
206            rsa_d: None,
207            p: None,
208            q: None,
209            dp: None,
210            dq: None,
211            qinv: None,
212            other: None,
213            ri: None,
214            di: None,
215            ti: None,
216        }
217    }
218
219    fn reg_label(&mut self, label: i32) {
220        self.used.retain(|&x| x != label);
221        self.used.push(label);
222    }
223
224    pub(crate) fn remove_label(&mut self, label: i32) {
225        self.used.retain(|&x| x != label);
226    }
227
228    /// Adds Key Type to the cose-key.
229    pub fn kty(&mut self, kty: i32) {
230        self.reg_label(KTY);
231        self.kty = Some(kty);
232    }
233    /// Adds Key ID to the cose-key.
234    pub fn unset_alg(&mut self) {
235        self.remove_label(ALG);
236        self.alg = None;
237    }
238
239    /// Adds Key ID to the cose-key.
240    pub fn kid(&mut self, kid: Vec<u8>) {
241        self.reg_label(KID);
242        self.kid = Some(kid);
243    }
244
245    /// Adds Algorithm to cose-key.
246    pub fn alg(&mut self, alg: i32) {
247        self.reg_label(ALG);
248        self.alg = Some(alg);
249    }
250
251    /// Adds Key Operations to the cose-key.
252    pub fn key_ops(&mut self, key_ops: Vec<i32>) {
253        self.reg_label(KEY_OPS);
254        self.key_ops = key_ops;
255    }
256
257    /// Adds Base Initialization Vector to the cose-key.
258    pub fn base_iv(&mut self, base_iv: Vec<u8>) {
259        self.reg_label(BASE_IV);
260        self.base_iv = Some(base_iv);
261    }
262
263    /// Adds Curve to the cose-key.
264    pub fn crv(&mut self, crv: i32) {
265        self.reg_label(CRV_K);
266        self.crv = Some(crv);
267    }
268
269    /// Adds X parameter to the cose-key.
270    pub fn x(&mut self, x: Vec<u8>) {
271        self.reg_label(X);
272        self.x = Some(x);
273    }
274
275    /// Adds Y parameter to the cose-key.
276    pub fn y(&mut self, y: Vec<u8>) {
277        self.reg_label(Y);
278        self.y = Some(y);
279    }
280
281    /// Adds D parameter to the cose-key.
282    pub fn d(&mut self, d: Vec<u8>) {
283        self.reg_label(D);
284        self.d = Some(d);
285    }
286
287    /// Adds Symmetric Key value to the cose-key.
288    pub fn k(&mut self, k: Vec<u8>) {
289        self.reg_label(CRV_K);
290        self.k = Some(k);
291    }
292    pub fn n(&mut self, n: Vec<u8>) {
293        self.reg_label(N);
294        self.n = Some(n);
295    }
296    pub fn e(&mut self, e: Vec<u8>) {
297        self.reg_label(E);
298        self.e = Some(e);
299    }
300    pub fn rsa_d(&mut self, rsa_d: Vec<u8>) {
301        self.reg_label(RSA_D);
302        self.rsa_d = Some(rsa_d);
303    }
304    pub fn p(&mut self, p: Vec<u8>) {
305        self.reg_label(P);
306        self.p = Some(p);
307    }
308    pub fn q(&mut self, q: Vec<u8>) {
309        self.reg_label(Q);
310        self.q = Some(q);
311    }
312    pub fn dp(&mut self, dp: Vec<u8>) {
313        self.reg_label(DP);
314        self.dp = Some(dp);
315    }
316    pub fn dq(&mut self, dq: Vec<u8>) {
317        self.reg_label(DQ);
318        self.dq = Some(dq);
319    }
320    pub fn qinv(&mut self, qinv: Vec<u8>) {
321        self.reg_label(QINV);
322        self.qinv = Some(qinv);
323    }
324    pub fn other(&mut self, other: Vec<Vec<u8>>) {
325        self.reg_label(OTHER);
326        self.other = Some(other);
327    }
328    pub fn ri(&mut self, ri: Vec<u8>) {
329        self.reg_label(RI);
330        self.ri = Some(ri);
331    }
332    pub fn di(&mut self, di: Vec<u8>) {
333        self.reg_label(DI);
334        self.di = Some(di);
335    }
336    pub fn ti(&mut self, ti: Vec<u8>) {
337        self.reg_label(TI);
338        self.ti = Some(ti);
339    }
340
341    pub(crate) fn verify_curve(&self) -> CoseResult {
342        let kty = self.kty.ok_or(CoseError::MissingKTY())?;
343        if kty == SYMMETRIC || kty == RSA {
344            return Ok(());
345        }
346        let crv = self.crv.ok_or(CoseError::MissingCRV())?;
347
348        if kty == OKP && [ED25519, ED448, X25519, X448].contains(&crv) {
349            Ok(())
350        } else if kty == EC2 && EC2_CRVS.contains(&crv) {
351            Ok(())
352        } else if self.alg.ok_or(CoseError::MissingAlg())? == algs::ES256K && crv == SECP256K1 {
353            Ok(())
354        } else {
355            Err(CoseError::InvalidCRV())
356        }
357    }
358
359    pub(crate) fn verify_kty(&self) -> CoseResult {
360        if !KTY_ALL.contains(&self.kty.ok_or(CoseError::MissingKTY())?) {
361            return Err(CoseError::InvalidKTY());
362        }
363        self.verify_curve()?;
364        Ok(())
365    }
366
367    /// Method to encode the cose-Key.
368    pub fn encode(&mut self) -> CoseResult {
369        let mut e = Encoder::new(Vec::new());
370        if self.alg != None {
371            self.verify_kty()?;
372        } else {
373            self.verify_curve()?;
374        }
375        self.encode_key(&mut e)?;
376        self.bytes = e.into_writer().to_vec();
377        Ok(())
378    }
379
380    pub(crate) fn encode_key(&self, e: &mut Encoder<Vec<u8>>) -> CoseResult {
381        let kty = self.kty.ok_or(CoseError::MissingKTY())?;
382        let key_ops_len = self.key_ops.len();
383        if key_ops_len > 0 {
384            if kty == EC2 || kty == OKP {
385                if self.key_ops.contains(&KEY_OPS_VERIFY)
386                    || self.key_ops.contains(&KEY_OPS_DERIVE)
387                    || self.key_ops.contains(&KEY_OPS_DERIVE_BITS)
388                {
389                    if self.x == None {
390                        return Err(CoseError::MissingX());
391                    } else if self.crv == None {
392                        return Err(CoseError::MissingCRV());
393                    }
394                }
395                if self.key_ops.contains(&KEY_OPS_SIGN) {
396                    if self.d == None {
397                        return Err(CoseError::MissingD());
398                    } else if self.crv == None {
399                        return Err(CoseError::MissingCRV());
400                    }
401                }
402            } else if kty == SYMMETRIC {
403                if self.key_ops.contains(&KEY_OPS_ENCRYPT)
404                    || self.key_ops.contains(&KEY_OPS_MAC_VERIFY)
405                    || self.key_ops.contains(&KEY_OPS_MAC)
406                    || self.key_ops.contains(&KEY_OPS_DECRYPT)
407                    || self.key_ops.contains(&KEY_OPS_UNWRAP)
408                    || self.key_ops.contains(&KEY_OPS_WRAP)
409                {
410                    if self.x != None {
411                        return Err(CoseError::InvalidX());
412                    } else if self.y != None {
413                        return Err(CoseError::InvalidY());
414                    } else if self.d != None {
415                        return Err(CoseError::InvalidD());
416                    }
417                    if self.k == None {
418                        return Err(CoseError::MissingK());
419                    }
420                }
421            }
422        }
423        e.object(self.used.len())?;
424        for i in &self.used {
425            e.i32(*i)?;
426
427            if *i == KTY {
428                e.i32(kty)?;
429            } else if *i == KEY_OPS {
430                e.array(self.key_ops.len())?;
431                for x in &self.key_ops {
432                    e.i32(*x)?;
433                }
434            } else if *i == CRV_K {
435                if self.crv != None {
436                    e.i32(self.crv.ok_or(CoseError::MissingCRV())?)?;
437                } else {
438                    e.bytes(&self.k.as_ref().ok_or(CoseError::MissingK())?)?;
439                }
440            } else if *i == KID {
441                e.bytes(&self.kid.as_ref().ok_or(CoseError::MissingKID())?)?;
442            } else if *i == ALG {
443                e.i32(self.alg.ok_or(CoseError::MissingAlg())?)?
444            } else if *i == BASE_IV {
445                e.bytes(&self.base_iv.as_ref().ok_or(CoseError::MissingBaseIV())?)?
446            } else if *i == X {
447                e.bytes(&self.x.as_ref().ok_or(CoseError::MissingX())?)?
448            } else if *i == Y {
449                e.bytes(&self.y.as_ref().ok_or(CoseError::MissingY())?)?
450            } else if *i == D {
451                e.bytes(&self.d.as_ref().ok_or(CoseError::MissingD())?)?
452            } else if *i == N {
453                e.bytes(&self.n.as_ref().ok_or(CoseError::MissingN())?)?
454            } else if *i == E {
455                e.bytes(&self.e.as_ref().ok_or(CoseError::MissingE())?)?
456            } else if *i == RSA_D {
457                e.bytes(&self.rsa_d.as_ref().ok_or(CoseError::MissingRsaD())?)?
458            } else if *i == P {
459                e.bytes(&self.p.as_ref().ok_or(CoseError::MissingP())?)?
460            } else if *i == Q {
461                e.bytes(&self.q.as_ref().ok_or(CoseError::MissingQ())?)?
462            } else if *i == DP {
463                e.bytes(&self.dp.as_ref().ok_or(CoseError::MissingDP())?)?
464            } else if *i == DQ {
465                e.bytes(&self.dq.as_ref().ok_or(CoseError::MissingDQ())?)?
466            } else if *i == QINV {
467                e.bytes(&self.qinv.as_ref().ok_or(CoseError::MissingQINV())?)?
468            } else if *i == OTHER {
469                let other = self.other.as_ref().ok_or(CoseError::MissingOther())?;
470                e.array(other.len())?;
471                for i in other {
472                    e.bytes(i)?
473                }
474            } else if *i == RI {
475                e.bytes(&self.ri.as_ref().ok_or(CoseError::MissingRI())?)?
476            } else if *i == DI {
477                e.bytes(&self.di.as_ref().ok_or(CoseError::MissingDI())?)?
478            } else if *i == TI {
479                e.bytes(&self.ti.as_ref().ok_or(CoseError::MissingTI())?)?
480            } else {
481                return Err(CoseError::InvalidLabel(*i));
482            }
483        }
484        Ok(())
485    }
486
487    /// Method to decode a cose-Key.
488    pub fn decode(&mut self) -> CoseResult {
489        let input = Cursor::new(self.bytes.clone());
490        let mut d = Decoder::new(Config::default(), input);
491        self.decode_key(&mut d)?;
492        if self.alg != None {
493            self.verify_kty()?;
494        } else {
495            self.verify_curve()?;
496        }
497        Ok(())
498    }
499
500    pub(crate) fn decode_key(&mut self, d: &mut Decoder<Cursor<Vec<u8>>>) -> CoseResult {
501        let mut label: i32;
502        let mut labels_found = Vec::new();
503        self.used = Vec::new();
504        for _ in 0..d.object()? {
505            label = d.i32()?;
506            if !labels_found.contains(&label) {
507                labels_found.push(label);
508            } else {
509                return Err(CoseError::DuplicateLabel(label));
510            }
511            if label == KTY {
512                let type_info = d.kernel().typeinfo()?;
513                if type_info.0 == Type::Text {
514                    self.kty = Some(common::get_kty_id(
515                        from_utf8(&d.kernel().raw_data(type_info.1, common::MAX_BYTES)?)
516                            .unwrap()
517                            .to_string(),
518                    )?);
519                } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
520                    self.kty = Some(d.kernel().i32(&type_info)?);
521                } else {
522                    return Err(CoseError::InvalidCoseStructure());
523                }
524                self.used.push(label);
525            } else if label == ALG {
526                let type_info = d.kernel().typeinfo()?;
527                if type_info.0 == Type::Text {
528                    self.alg = Some(common::get_alg_id(
529                        from_utf8(&d.kernel().raw_data(type_info.1, common::MAX_BYTES)?)
530                            .unwrap()
531                            .to_string(),
532                    )?);
533                } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
534                    self.alg = Some(d.kernel().i32(&type_info)?);
535                } else {
536                    return Err(CoseError::InvalidCoseStructure());
537                }
538                self.used.push(label);
539            } else if label == KID {
540                self.kid = Some(d.bytes()?);
541                self.used.push(label);
542            } else if label == KEY_OPS {
543                let mut key_ops = Vec::new();
544                for _i in 0..d.array()? {
545                    let type_info = d.kernel().typeinfo()?;
546                    if type_info.0 == Type::Text {
547                        key_ops.push(common::get_key_op_id(
548                            from_utf8(&d.kernel().raw_data(type_info.1, common::MAX_BYTES)?)
549                                .unwrap()
550                                .to_string(),
551                        )?);
552                    } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
553                        key_ops.push(d.kernel().i32(&type_info)?);
554                    } else {
555                        return Err(CoseError::InvalidCoseStructure());
556                    }
557                }
558                self.key_ops = key_ops;
559                self.used.push(label);
560            } else if label == BASE_IV {
561                self.base_iv = Some(d.bytes()?);
562                self.used.push(label);
563            } else if label == CRV_K {
564                let type_info = d.kernel().typeinfo()?;
565                if type_info.0 == Type::Text {
566                    self.crv = Some(common::get_crv_id(
567                        from_utf8(&d.kernel().raw_data(type_info.1, common::MAX_BYTES)?)
568                            .unwrap()
569                            .to_string(),
570                    )?);
571                } else if common::CBOR_NUMBER_TYPES.contains(&type_info.0) {
572                    self.crv = Some(d.kernel().i32(&type_info)?);
573                } else if type_info.0 == Type::Bytes {
574                    self.k = Some(d.kernel().raw_data(type_info.1, common::MAX_BYTES)?);
575                } else {
576                    return Err(CoseError::InvalidCoseStructure());
577                }
578                self.used.push(label);
579            } else if label == X {
580                self.x = Some(d.bytes()?);
581                self.used.push(label);
582            } else if label == Y {
583                self.y = match d.bytes() {
584                    Ok(value) => {
585                        self.used.push(label);
586                        Some(value)
587                    }
588                    Err(ref err) => match err {
589                        DecodeError::UnexpectedType { datatype, info: _ } => {
590                            if *datatype == Type::Bool {
591                                None
592                            } else {
593                                return Err(CoseError::InvalidCoseStructure());
594                            }
595                        }
596                        _ => {
597                            return Err(CoseError::InvalidCoseStructure());
598                        }
599                    },
600                };
601            } else if label == D {
602                self.d = Some(d.bytes()?);
603                self.used.push(label);
604            } else if label == N {
605                self.n = Some(d.bytes()?);
606                self.used.push(label);
607            } else if label == E {
608                self.e = Some(d.bytes()?);
609                self.used.push(label);
610            } else if label == RSA_D {
611                self.rsa_d = Some(d.bytes()?);
612                self.used.push(label);
613            } else if label == P {
614                self.p = Some(d.bytes()?);
615                self.used.push(label);
616            } else if label == Q {
617                self.q = Some(d.bytes()?);
618                self.used.push(label);
619            } else if label == DP {
620                self.dp = Some(d.bytes()?);
621                self.used.push(label);
622            } else if label == DQ {
623                self.dq = Some(d.bytes()?);
624                self.used.push(label);
625            } else if label == QINV {
626                self.qinv = Some(d.bytes()?);
627                self.used.push(label);
628            } else if label == OTHER {
629                let mut other = Vec::new();
630                for _ in 0..d.array()? {
631                    other.push(d.bytes()?);
632                }
633                self.other = Some(other);
634                self.used.push(label);
635            } else if label == RI {
636                self.ri = Some(d.bytes()?);
637                self.used.push(label);
638            } else if label == DI {
639                self.di = Some(d.bytes()?);
640                self.used.push(label);
641            } else if label == TI {
642                self.ti = Some(d.bytes()?);
643                self.used.push(label);
644            } else {
645                return Err(CoseError::InvalidLabel(label));
646            }
647        }
648        Ok(())
649    }
650
651    pub(crate) fn get_s_key(&self) -> CoseResultWithRet<Vec<u8>> {
652        let kty = self.kty.ok_or(CoseError::MissingKTY())?;
653        if kty == EC2 || kty == OKP {
654            let d = self.d.as_ref().ok_or(CoseError::MissingD())?.to_vec();
655            if d.len() <= 0 {
656                return Err(CoseError::MissingD());
657            }
658            Ok(d)
659        } else if kty == RSA {
660            Ok(Rsa::from_private_components(
661                BigNum::from_slice(self.n.as_ref().ok_or(CoseError::MissingN())?)?,
662                BigNum::from_slice(self.e.as_ref().ok_or(CoseError::MissingE())?)?,
663                BigNum::from_slice(self.rsa_d.as_ref().ok_or(CoseError::MissingRsaD())?)?,
664                BigNum::from_slice(self.p.as_ref().ok_or(CoseError::MissingP())?)?,
665                BigNum::from_slice(self.q.as_ref().ok_or(CoseError::MissingQ())?)?,
666                BigNum::from_slice(self.dp.as_ref().ok_or(CoseError::MissingDP())?)?,
667                BigNum::from_slice(self.dq.as_ref().ok_or(CoseError::MissingDQ())?)?,
668                BigNum::from_slice(self.qinv.as_ref().ok_or(CoseError::MissingQINV())?)?,
669            )?
670            .private_key_to_der()?)
671        } else if kty == SYMMETRIC {
672            let k = self.k.as_ref().ok_or(CoseError::MissingK())?.to_vec();
673            if k.len() <= 0 {
674                return Err(CoseError::MissingK());
675            }
676            Ok(k)
677        } else {
678            Err(CoseError::InvalidKTY())
679        }
680    }
681    pub(crate) fn get_pub_key(&self) -> CoseResultWithRet<Vec<u8>> {
682        let kty = self.kty.ok_or(CoseError::MissingKTY())?;
683        if kty == EC2 || kty == OKP {
684            let mut x = self.x.as_ref().ok_or(CoseError::MissingX())?.to_vec();
685            if x.len() <= 0 {
686                return Err(CoseError::MissingX());
687            }
688            let mut pub_key;
689            if kty == EC2 {
690                if self.y != None && self.y.as_ref().unwrap().len() > 0 {
691                    let mut y = self.y.as_ref().unwrap().to_vec();
692                    pub_key = vec![4];
693                    pub_key.append(&mut x);
694                    pub_key.append(&mut y);
695                } else {
696                    pub_key = vec![3];
697                    pub_key.append(&mut x);
698                }
699            } else {
700                pub_key = x;
701            }
702            Ok(pub_key)
703        } else if kty == RSA {
704            Ok(Rsa::from_public_components(
705                BigNum::from_slice(self.n.as_ref().ok_or(CoseError::MissingN())?)?,
706                BigNum::from_slice(self.e.as_ref().ok_or(CoseError::MissingE())?)?,
707            )?
708            .public_key_to_der()?)
709        } else {
710            Err(CoseError::InvalidKTY())
711        }
712    }
713}
714
715/// cose-keySet structure.
716pub struct CoseKeySet {
717    /// List of the cose-keys.
718    pub cose_keys: Vec<CoseKey>,
719    /// COSE encoded key set.
720    pub bytes: Vec<u8>,
721}
722
723impl CoseKeySet {
724    /// Creates a new empty structure.
725    pub fn new() -> CoseKeySet {
726        CoseKeySet {
727            cose_keys: Vec::new(),
728            bytes: Vec::new(),
729        }
730    }
731
732    /// Adds a cose-key to the cose-keySet.
733    pub fn add_key(&mut self, key: CoseKey) {
734        self.cose_keys.push(key);
735    }
736
737    /// Encodes the cose-keySet.
738    pub fn encode(&mut self) -> CoseResult {
739        let mut e = Encoder::new(Vec::new());
740        let len = self.cose_keys.len();
741        if len > 0 {
742            e.array(len)?;
743            for i in 0..len {
744                self.cose_keys[i].encode_key(&mut e)?;
745            }
746            self.bytes = e.into_writer().to_vec();
747            Ok(())
748        } else {
749            Err(CoseError::MissingKey())
750        }
751    }
752
753    /// Decodes an encoded cose-keySet.
754    ///
755    /// The COSE encoded bytes of the cose-keySet must be set with the structure attribute bytes beforehand.
756    pub fn decode(&mut self) -> CoseResult {
757        let input = Cursor::new(self.bytes.clone());
758        let mut d = Decoder::new(Config::default(), input);
759        let len = d.array()?;
760        if len > 0 {
761            for _ in 0..len {
762                let mut cose_key = CoseKey::new();
763                match cose_key.decode_key(&mut d) {
764                    Ok(_v) => self.cose_keys.push(cose_key),
765                    Err(_e) => (),
766                }
767            }
768            Ok(())
769        } else {
770            Err(CoseError::MissingKey())
771        }
772    }
773
774    /// Function that returns a cose-key from the cose-keySet with a given Key ID.
775    pub fn get_key(&self, kid: &Vec<u8>) -> CoseResultWithRet<CoseKey> {
776        for i in 0..self.cose_keys.len() {
777            if self.cose_keys[i]
778                .kid
779                .as_ref()
780                .ok_or(CoseError::MissingKID())?
781                == kid
782            {
783                return Ok(self.cose_keys[i].clone());
784            }
785        }
786        Err(CoseError::MissingKey())
787    }
788}