• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

namib-project / dcaf-rs / 11935120896

20 Nov 2024 02:11PM UTC coverage: 86.555% (+1.3%) from 85.242%
11935120896

Pull #27

github

web-flow
Merge d2b3d706b into 383248641
Pull Request #27: ci: update grcov to latest stable version

6116 of 7066 relevant lines covered (86.56%)

167.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/src/token/cose/crypto_impl/openssl/mod.rs
1
/*
2
 * Copyright (c) 2022-2024 The NAMIB Project Developers.
3
 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6
 * option. This file may not be copied, modified, or distributed
7
 * except according to those terms.
8
 *
9
 * SPDX-License-Identifier: MIT OR Apache-2.0
10
 */
11
mod encrypt;
12
mod key_distribution;
13
mod mac;
14
mod sign;
15

16
use crate::error::CoseCipherError;
17
use crate::token::cose::CryptoBackend;
18
use coset::{iana, Algorithm};
19
use openssl::cipher::CipherRef;
20
use openssl::error::ErrorStack;
21
use openssl::hash::MessageDigest;
22
use strum_macros::Display;
23
/// Represents an error caused by the OpenSSL cryptographic backend.
24
#[derive(Debug, Display)]
25
#[non_exhaustive]
26
pub enum CoseOpensslCipherError {
27
    /// Standard OpenSSL error (represented as an [`ErrorStack`] in the openssl library crate).
28
    OpensslError(ErrorStack),
29
    /// AES key error.
30
    AesKeyError(openssl::aes::KeyError),
31
    /// Other error (error message is provided as a string).
32
    Other(&'static str),
33
}
34

35
impl From<ErrorStack> for CoseOpensslCipherError {
36
    fn from(value: ErrorStack) -> Self {
180✔
37
        CoseOpensslCipherError::OpensslError(value)
180✔
38
    }
180✔
39
}
40

41
impl From<openssl::aes::KeyError> for CoseOpensslCipherError {
42
    fn from(value: openssl::aes::KeyError) -> Self {
82✔
43
        CoseOpensslCipherError::AesKeyError(value)
82✔
44
    }
82✔
45
}
46

47
impl From<ErrorStack> for CoseCipherError<CoseOpensslCipherError> {
48
    fn from(value: ErrorStack) -> Self {
180✔
49
        CoseCipherError::Other(value.into())
180✔
50
    }
180✔
51
}
52

53
impl From<openssl::aes::KeyError> for CoseCipherError<CoseOpensslCipherError> {
54
    fn from(value: openssl::aes::KeyError) -> Self {
82✔
55
        CoseCipherError::Other(value.into())
82✔
56
    }
82✔
57
}
58

59
/// Context for the OpenSSL cryptographic backend.
60
///
61
/// Can be used as a [`CryptoBackend`] for COSE operations.
62
///
63
/// Generic properties of this backend:
64
/// - [ ] Can derive EC public key components if only the private component (d) is present.
65
/// - [ ] Can work with compressed EC public keys (EC keys using point compression)
66
///
67
/// Algorithm support:
68
/// - Signature Algorithms (for COSE_Sign and COSE_Sign1)
69
///     - [x] ECDSA
70
///         - [x] ES256
71
///         - [x] ES384
72
///         - [x] ES512
73
///         - [ ] ES256K
74
///     - [ ] EdDSA
75
/// - Message Authentication Code Algorithms (for COSE_Mac and COSE_Mac0)
76
///     - [x] HMAC
77
///         - [ ] HMAC 256/64
78
///         - [x] HMAC 256/256
79
///         - [x] HMAC 384/384
80
///         - [x] HMAC 512/512
81
///     - [ ] AES-CBC-MAC
82
///         - [ ] AES-MAC 128/64
83
///         - [ ] AES-MAC 256/64
84
///         - [ ] AES-MAC 128/128
85
///         - [ ] AES-MAC 256/128
86
/// - Content Encryption Algorithms (for COSE_Encrypt and COSE_Encrypt0)
87
///     - [x] AES-GCM
88
///         - [x] A128GCM
89
///         - [x] A192GCM
90
///         - [x] A256GCM
91
///     - [x] AES-CCM
92
///         - [x] AES-CCM-16-64-128
93
///         - [x] AES-CCM-16-64-256
94
///         - [x] AES-CCM-64-64-128
95
///         - [x] AES-CCM-64-64-256
96
///         - [x] AES-CCM-16-128-128
97
///         - [x] AES-CCM-16-128-256
98
///         - [x] AES-CCM-64-128-128
99
///         - [x] AES-CCM-64-128-256
100
///     - [ ] ChaCha20/Poly1305
101
/// - Content Key Distribution Methods (for COSE_Recipients)
102
///     - Direct Encryption
103
///         - [ ] Direct Key with KDF
104
///             - [ ] direct+HKDF-SHA-256
105
///             - [ ] direct+HKDF-SHA-512
106
///             - [ ] direct+HKDF-AES-128
107
///             - [ ] direct+HKDF-AES-256
108
///     - Key Wrap
109
///         - [x] AES Key Wrap
110
///             - [x] A128KW
111
///             - [x] A192KW
112
///             - [x] A256KW
113
///     - Direct Key Agreement
114
///         - [ ] Direct ECDH
115
///             - [ ] ECDH-ES + HKDF-256
116
///             - [ ] ECDH-ES + HKDF-512
117
///             - [ ] ECDH-SS + HKDF-256
118
///             - [ ] ECDH-SS + HKDF-512
119
///     - Key Agreement with Key Wrap
120
///         - [ ] ECDH with Key Wrap
121
///             - [ ] ECDH-ES + A128KW
122
///             - [ ] ECDH-ES + A192KW
123
///             - [ ] ECDH-ES + A256KW
124
///             - [ ] ECDH-SS + A128KW
125
///             - [ ] ECDH-SS + A192KW
126
///             - [ ] ECDH-SS + A256KW
127
///
128
/// Elliptic Curve support (for EC algorithms):
129
/// - ES256/ES384/ES512 [^1]
130
///     - [x] P-256
131
///     - [x] P-384
132
///     - [x] P-521
133
/// - ES256K
134
///     - [ ] secp256k1
135
/// - EdDSA
136
///     - [ ] Ed448
137
///     - [ ] Ed25519
138
/// - ECDH
139
///     - [ ] X448
140
///     - [ ] X25519
141
///
142
/// [^1]: RFC 9053, Section 2.1 suggests using ES256 only with curve P-256, ES384 with curve P-384
143
///       and ES512 only with curve P-521.
144
#[derive(Default)]
145
pub struct OpensslContext {}
146

147
impl OpensslContext {
148
    /// Creates a new OpenSSL context for use with COSE algorithms.
149
    #[must_use]
150
    pub fn new() -> OpensslContext {
2,836✔
151
        OpensslContext {}
2,836✔
152
    }
2,836✔
153
}
154

155
impl CryptoBackend for OpensslContext {
156
    type Error = CoseOpensslCipherError;
157

158
    fn generate_rand(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> {
1,940✔
159
        openssl::rand::rand_bytes(buf).map_err(CoseOpensslCipherError::from)
1,940✔
160
    }
1,940✔
161
}
162

163
/// Converts the provided [`iana::Algorithm`] to an OpenSSL [`CipherRef`] that can be used for a
164
/// symmetric [`CipherCtx`](openssl::cipher_ctx::CipherCtx).
165
fn algorithm_to_cipher(
1,453✔
166
    algorithm: iana::Algorithm,
1,453✔
167
) -> Result<&'static CipherRef, CoseCipherError<CoseOpensslCipherError>> {
1,453✔
168
    match algorithm {
1,453✔
169
        iana::Algorithm::A128GCM => Ok(openssl::cipher::Cipher::aes_128_gcm()),
480✔
170
        iana::Algorithm::A192GCM => Ok(openssl::cipher::Cipher::aes_192_gcm()),
15✔
171
        iana::Algorithm::A256GCM => Ok(openssl::cipher::Cipher::aes_256_gcm()),
908✔
172
        iana::Algorithm::A128KW => Ok(openssl::cipher::Cipher::aes_128_ecb()),
×
173
        iana::Algorithm::A192KW => Ok(openssl::cipher::Cipher::aes_192_ecb()),
×
174
        iana::Algorithm::A256KW => Ok(openssl::cipher::Cipher::aes_256_ecb()),
×
175
        iana::Algorithm::AES_CCM_16_64_128
176
        | iana::Algorithm::AES_CCM_64_64_128
177
        | iana::Algorithm::AES_CCM_16_128_128
178
        | iana::Algorithm::AES_CCM_64_128_128 => Ok(openssl::cipher::Cipher::aes_128_ccm()),
26✔
179
        iana::Algorithm::AES_CCM_16_64_256
180
        | iana::Algorithm::AES_CCM_64_64_256
181
        | iana::Algorithm::AES_CCM_16_128_256
182
        | iana::Algorithm::AES_CCM_64_128_256 => Ok(openssl::cipher::Cipher::aes_256_ccm()),
24✔
183
        v => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned(
×
184
            v,
×
185
        ))),
×
186
    }
187
}
1,453✔
188

189
/// Determine the hash function (represented in OpenSSL as a [`MessageDigest`]) that should be used
190
/// for a given [`iana::Algorithm`].
191
fn get_algorithm_hash_function(
2,678✔
192
    alg: iana::Algorithm,
2,678✔
193
) -> Result<MessageDigest, CoseCipherError<CoseOpensslCipherError>> {
2,678✔
194
    match alg {
2,678✔
195
        iana::Algorithm::ES256 | iana::Algorithm::HMAC_256_256 => Ok(MessageDigest::sha256()),
2,484✔
196
        iana::Algorithm::ES384 | iana::Algorithm::HMAC_384_384 => Ok(MessageDigest::sha384()),
176✔
197
        iana::Algorithm::ES512 | iana::Algorithm::HMAC_512_512 => Ok(MessageDigest::sha512()),
18✔
198
        v => Err(CoseCipherError::UnsupportedAlgorithm(Algorithm::Assigned(
×
199
            v,
×
200
        ))),
×
201
    }
202
}
2,678✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc