Test key generation, signature and verification from the keystore

This commit is contained in:
Quentin Gliech
2022-10-18 10:13:16 +02:00
parent 1229a2c872
commit 2ff194ffec
18 changed files with 196 additions and 2 deletions

3
Cargo.lock generated
View File

@@ -2152,6 +2152,7 @@ dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"serde",
"similar",
"yaml-rust",
]
@@ -2699,6 +2700,7 @@ dependencies = [
"ecdsa",
"elliptic-curve",
"generic-array",
"insta",
"k256",
"mas-iana",
"mas-jose",
@@ -2708,6 +2710,7 @@ dependencies = [
"pkcs1",
"pkcs8",
"rand",
"rand_chacha",
"rsa",
"sec1",
"spki",

View File

@@ -1,4 +1,6 @@
[workspace]
default-members = ["crates/cli"]
members = ["crates/*"]
[profile.dev.package.num-bigint-dig]
opt-level = 3

View File

@@ -30,3 +30,7 @@ base64ct = "1.5.2"
mas-iana = { path = "../iana" }
mas-jose = { path = "../jose" }
[dev-dependencies]
insta = { version = "1.21.0", features = ["yaml"] }
rand_chacha = "0.3.1"

View File

@@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use der::pem::LineEnding;
use mas_iana::jose::JsonWebSignatureAlg;
use mas_jose::{
jwk::ParametersInfo,
jwt::{JsonWebSignatureHeader, Jwt},
};
use mas_keystore::PrivateKey;
use mas_keystore::{JsonWebKey, JsonWebKeySet, Keystore, PrivateKey};
use rand::SeedableRng;
static PASSWORD: &str = "hunter2";
@@ -166,3 +169,56 @@ fn load_unencrypted_as_encrypted_error() {
.unwrap_err()
.is_unencrypted());
}
#[test]
fn generate_sign_and_verify() {
// Use a seeded RNG to keep the snapshot stable
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(42);
let rsa = PrivateKey::generate_rsa(&mut rng).expect("Failed to generate RSA key");
insta::assert_snapshot!(rsa.to_pem(LineEnding::LF).unwrap());
let ec_p256 = PrivateKey::generate_ec_p256(&mut rng);
insta::assert_snapshot!(ec_p256.to_pem(LineEnding::LF).unwrap());
let ec_p384 = PrivateKey::generate_ec_p384(&mut rng);
insta::assert_snapshot!(ec_p384.to_pem(LineEnding::LF).unwrap());
let ec_k256 = PrivateKey::generate_ec_k256(&mut rng);
insta::assert_snapshot!(ec_k256.to_pem(LineEnding::LF).unwrap());
// Create a keystore out of the keys
let keyset = Keystore::new(JsonWebKeySet::new(vec![
JsonWebKey::new(rsa),
JsonWebKey::new(ec_p256),
JsonWebKey::new(ec_p384),
JsonWebKey::new(ec_k256),
]));
// And extract the public JWKS
let jwks = keyset.public_jwks();
insta::assert_yaml_snapshot!(jwks);
// Try signing for each supported algorithm
for alg in [
JsonWebSignatureAlg::Rs256,
JsonWebSignatureAlg::Rs384,
JsonWebSignatureAlg::Rs512,
JsonWebSignatureAlg::Ps256,
JsonWebSignatureAlg::Ps384,
JsonWebSignatureAlg::Ps512,
JsonWebSignatureAlg::Es256,
JsonWebSignatureAlg::Es384,
JsonWebSignatureAlg::Es256K,
] {
// Find a matching key and sign with it
let key = keyset.signing_key_for_algorithm(&alg).unwrap();
let signer = key.params().signing_key_for_alg(&alg).unwrap();
let header = JsonWebSignatureHeader::new(alg.clone());
let token = Jwt::sign_with_rng(&mut rng, header, "", &signer).unwrap();
insta::assert_snapshot!(format!("jwt_{alg}"), token.as_str());
// Then try to verify from the public JWKS
token.verify_with_jwks(&jwks).unwrap();
}
}

View File

@@ -0,0 +1,10 @@
---
source: crates/keystore/tests/keystore.rs
expression: "ec_p256.to_pem(LineEnding::LF).unwrap()"
---
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIH3L+ZYgfEaJtclP07qPQBrmkHEhYkyYooxvU8AlSW+CoAoGCCqGSM49
AwEHoUQDQgAEXcA+X+lhDCmmzaUQFh7i7gkT7mwdrRUsMl9RSfyWh93n+xq3O4/m
vMmUnlvy7tBoHkcAdTJ+Zkv+loLw+mkcBA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,11 @@
---
source: crates/keystore/tests/keystore.rs
expression: "ec_p384.to_pem(LineEnding::LF).unwrap()"
---
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDAl3R97SR8hWLuMH6737YdvXVb7P7T9pKSIhQozmzN+r+V5Ncvjn+DQ
Q/QxYr9nLwOgBwYFK4EEACKhZANiAASa86XQW7CDF9GhvcBY53sJ4lP0z9rfrjwo
nwixQJIWBROjlpsm5hdIwLfj46IUPYCNEoD8VP8eR2s/uzlgEv1hnz/2wmLlMqU0
2R5QcY7Gc9CyDTO1bh5V2FFYjks4xfs=
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,10 @@
---
source: crates/keystore/tests/keystore.rs
expression: "ec_k256.to_pem(LineEnding::LF).unwrap()"
---
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBcikq9QkV39T8VFZWD4j5wO9xm0FWxhuAmvDRpix8XUoAcGBSuBBAAK
oUQDQgAEf4htTtPsdxlZn1htWE3ueHT4JB/4n4lxVOQdT/3RFuCS5aKQ04oS9pKM
QAHAn1bjbLRQ88Yxi3CgHuCitS+RrA==
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,21 @@
---
source: crates/keystore/tests/keystore.rs
expression: jwks
---
keys:
- kty: RSA
n: vClyfM076hWBZonjThx_PX46UQUWb2LfOpUV1655ZGoKMKgqanLMMfLBPjW9ouY6UtrZ7BxEgl01xLZ1dLdD2Ggb2IpwW56PUuZD2w9hJMungjR0ImymFBwjA9j2ucr0eIHdVQoOakEsrB0dqEC-3R7ax7piGCj9YB6uGZbDVfIJUv40o1pb-hvmmyQHwpoU4jR1y_V-OhrdFMPtwCXov2nlrqDb_e-T7TQlu4FN0URI6VxLNcSkgZfJH50PdJPr7AHqtnWhOGBfLaC9jDpGxfbjmC1iSMSzOt6WyVdcnqHv_JpzXu0SzFqpUSm3OI_l2DUjwTJBL1TOIRTVsjQN1w
e: AQAB
- kty: EC
crv: P-256
x: XcA-X-lhDCmmzaUQFh7i7gkT7mwdrRUsMl9RSfyWh90
y: 5_satzuP5rzJlJ5b8u7QaB5HAHUyfmZL_paC8PppHAQ
- kty: EC
crv: P-384
x: mvOl0FuwgxfRob3AWOd7CeJT9M_a3648KJ8IsUCSFgUTo5abJuYXSMC34-OiFD2A
y: jRKA_FT_HkdrP7s5YBL9YZ8_9sJi5TKlNNkeUHGOxnPQsg0ztW4eVdhRWI5LOMX7
- kty: EC
crv: secp256k1
x: f4htTtPsdxlZn1htWE3ueHT4JB_4n4lxVOQdT_3RFuA
y: kuWikNOKEvaSjEABwJ9W42y0UPPGMYtwoB7gorUvkaw

View File

@@ -0,0 +1,32 @@
---
source: crates/keystore/tests/keystore.rs
expression: "rsa.to_pem(LineEnding::LF).unwrap()"
---
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvClyfM076hWBZonjThx/PX46UQUWb2LfOpUV1655ZGoKMKgq
anLMMfLBPjW9ouY6UtrZ7BxEgl01xLZ1dLdD2Ggb2IpwW56PUuZD2w9hJMungjR0
ImymFBwjA9j2ucr0eIHdVQoOakEsrB0dqEC+3R7ax7piGCj9YB6uGZbDVfIJUv40
o1pb+hvmmyQHwpoU4jR1y/V+OhrdFMPtwCXov2nlrqDb/e+T7TQlu4FN0URI6VxL
NcSkgZfJH50PdJPr7AHqtnWhOGBfLaC9jDpGxfbjmC1iSMSzOt6WyVdcnqHv/Jpz
Xu0SzFqpUSm3OI/l2DUjwTJBL1TOIRTVsjQN1wIDAQABAoIBAD4bcC7Bj4U0lAHE
gcLGpTkm8RjNFRqvB//ONed7L5Z1aeelmlqIid3ywtZF5tJeK+ItWsEUk4h0O8sy
bpKX600DEC3phCy5qZUzbDJiYS5ECoZvyeWS9z6sCuK6OrYYx5j/RI9NQnTQDm7B
LYjb1iQmixBh9P8EiJ2xgsXvfYpgSDv2nUBVywp8HUmadAqE89cBsyurvMpR6eY4
HI0Wge+vIbh0KHj5h7sJ7C8mWBcnjkJ9hWSCumMth3wufEpfs4lCUjhojTkr6ioT
9Mok8VpZvsxzDw3Ubnut1lX7II2EYwNEfgm/Tcw4/NC2eLc1AjoshxLVLg5JWy85
RGj7FAECgYEAyLTpdQjD0PrQBi6O5HWQnVMVvJQz6bihdKUrjwJOfWvqgKVpAVVQ
IbLUT3J6ooe4Tei6xc7viNA7JZ+KyRvaQuZT4nWW2AkOCOnaxH3NKI4cDpWsdNdC
jNBHnIUUvDU4c4CkgIc8f1Gezm9epDVsgb1+wxwSbB8Je4S7M8is1WUCgYEA7//M
f1UPl32yaXH7ag8DbWHMzeNRw5T+F3zTagp93mCM0mPYyjggMfwPFr7167ISWrG4
6DfHHABqhjnAkKfrrFMN5Xm8oup60XXIox1FB4Ew4K0VzyMTnSMPMMEGJZx6VQJP
TlGpexs4t+1N/gWgcGv1OgZ+fw7hjcaFtTMAcIsCgYBY/W3tyF8aT7rgotAUl9Px
DZ+7p3KFFKnx0DJKDFnE3o5xT+YJA0yuRF5Cg53AZrDfSmtVvXUTklBHVD/y/3h8
5ScYZ87kJs+kQBwRtz2515i1FsQKYk9NpCO8UH1rHaXUAJvvqQa35PamzVaHNHDR
7bVAyTeZ3QEVVTqzsSyAyQKBgQDDIcL+QIW10VBPJYqZ9+z8cUkYmVuwXqKdLDOk
gzVFqlC0+tOXzzx2B4+pGchPQ3Bi5x8FR9yOqtPxoGEt/CnE6Z5h1rIF8Am95jsk
TDcE3AiGlJQn30giOhAuvrIlwG1CUudyMTlQS5i5Cquf/qks3sn6zK7q1YmUQTYT
Vo1j8wKBgQCgSISkWgRrQhEdZKBBzcxkWyUXUMieZa+pPTooZGY1VAqyTSXHUlLi
mrWtJ4temNK6OE7xAWJMWL6cVAxQUrs8C11DS//IGMxlMF/7uMU6pOFmMqq52G3D
k3NkZSJmC1liFiu3Q6Q2UqGHRX8CS5MeLncReuNUnFOiX8X2fcjoRw==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJFUzI1NiJ9.IiI.Yvudbc_oPln_H02H9woFZurQrgzsuWGnRK2kZzat_rp2HYFZtYobvMw9LqPDgeqq9a1HiL_Hx796SqyobiTXJg

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJFUzI1NksifQ.IiI.4q4ua7R-we5m58rKtLQDHJmQJb15dEUhj7A_H5kh591mrScXFmCYXVQI5iKKXGFHBV_AFISrJF4YjWCHDnLPeQ

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJFUzM4NCJ9.IiI.p9Otttjs3JOxZCeuIKwkql3YM-nfdxo__EVt84sex_PcokYjY47sa0qsvCqUUhpUoLSBihdchynuYqc5lOFuAM3Pi2pjg-ZrTqrzI23UlzFonlr4Zag9Qo3IYD10HKFq

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJQUzI1NiJ9.IiI.HlJaOfS2PMi4mWzE8-0EgXt06-MeqzaLRy_04gs4HTS7FugbSJ0rJiwUwhss6O1KWT9TvDqo6AQBO_2hV1DKDiBIIh5Z6M92uC4MJNVLbAVQo6dSBt2DfSzioBI5MoDOBvgbIwSZAIFMqKTbYDa9rQ3XRAaClpqrIN-ACa3gz99ds5mYvUyiYsL5uuEBuWrp8DRk6WKjduhpOi4sMvylZbnfop1uHbvg6_dk5lzXt-1MKIW1QJW_63cFn7vdap5T9U4DBsEkCzYtuwgU-UCmsC8W07QEfcrJhHIlYoPQPHePKF0A4dVHKrgRmf1ik2p6e-VNw129JMvx0KO6v_JBww

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJQUzM4NCJ9.IiI.AHBo1kZW72IQfs7NvjfrD_WpDa9avLdKyf_rqcCp0mJtGID60cgOG5RDTmI6K7TwzykW6l6LjEuYXDR8hemri6mQrtpQ6rMVTJwqJ6D8M92vH4b2gDBwSwbKz427bGdd_fnqm5K2ntwZGC7pceYg1zbcUQ6NJXs3vqKI6YSKustmm9yA1iMfugFG4eLAPrpfTtLmT1sSWYTYWHVT-6G5q7Bfk7Yu5aHiGDQTo427-Y9YF2fabIuDyCGG48UrBp0ajlm1MHKCBuOvK6NI5Jojd9IWDIf7tvAArsrKVR8QRvDXqqPInJEEZ5x7H1YEEZ5Qrh4XKVhRh9b3O-grDMxMng

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJQUzUxMiJ9.IiI.o_-UDhc26qYAstuaFJQUz8OKw3UeMc4N7b3U4qcLM-84dxRdw-wBw1rf94jX71vsrFQ2bEh6J5fc4_VtYgKBb2P6QvoL55c7Gqr-5JBw8BkoiiCzlvKIsi_j41FH5Gb4ZBE5Nf9vZD7DnD9BhYXadxaiksx20oNRKIKQ3oMiJxH1w0c-miCSoIR0jnS1QLlKoHYVb7wnkCiR2SOYQ42Je8B8REVzWm2GrqS2cRWnpi3nHihrapruL_BA161Ip1uH4lUFdZLXeG-R6pAlg1OJ_QXSZlP16nzT6MAW_-IFXfioR1QKT8AFNBodY8zlQCGglMyppZi5Y9i7YaMxFgnM4A

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJSUzI1NiJ9.IiI.H_iz_ry505dPMNxQIi4raU88i3wu7DS0Rre6Qm_LJz0Ee_gd5C_t92fBcrFkber1XL_p8AvlXx4DT2Zr_PMBL_2IblJ7t0Od5wnGC__twarj0v1t6KfUkLXcJ3Jy-StnHNbFTmdFnLuGGWIO7xG9h6xgKIvTroVoLJekMzYCc0wSFiyCfaow4yuKesQHUO-N9VDDPoYhkCPqbhVI_d0y6u7KmQy97FbCdCIxvPGHWrwxWcmYbTh4K9xhGDspDUUEubjYTg3t-oaMc2TJqWvu2FE8jyD02A8OCgca6bCU3NmV_Qr6LSUpFNsL4c-0sIp3-L9ndEWzGnN-ZeeGKur-FQ

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJSUzM4NCJ9.IiI.bxKYTQQ4RlxOUvxbU_kuwJKGXXiuIPeRgO78a_3zHjvxIzDNKDvQK3w4DUVTlibR-iTVOASRSycWifBJZx_tsU7-BSqrBcjMtgP7mW-HwZ6pANO071iPkkiQU7gqMzbc2tz4uqGI0Z0izkX0_9dOOFSb7jKIUMzzW1O14fBPhZ4kPqkj07A9S9LW9lauQUTXrFgyEaT6G372cyNxi3-T55u9lkjjiiVN4TAhkaXUSN79IE2rNstU8DtKKs725WNUFy30f1-Ftc-J2uGEOsMZ9CQvEVPwOKbvFY2Uh1S8-FT4ahhwj1fxrmUwDH2lSmz6Rj5zf9-FF-IzivSVq4Z4ig

View File

@@ -0,0 +1,5 @@
---
source: crates/keystore/tests/keystore.rs
expression: token.as_str()
---
eyJhbGciOiJSUzUxMiJ9.IiI.nFsZ3X8GCgpPEojuEktc9a4C-YGQYx8XpbzhOkgnMVrw_wpqIQgWI--4r6BYV6TYAH8NBdQ8Dkdw6POh1Ni-vAtE2rAzjU19ySth5mfP7WEJXRxA1oEV3-dOqCgUI2JJEM13DuLlWFsUaOCbc1_kCkiziTcLtNap__EPGp5koRy-ZyVa1p_mQSQ4NlhJ3hZfHMGnQ0k3RWnpBn3AqERWllQllLniWGQ4l7rZStsD8PRr-rg7P7W7CRIyjrDqy_3bNJyKQCzs_oUrxO-Z7CU6-KfAeyM2U80TQvhZb-Z8_1dJ8e9WsfudQMLtHgO4tlD678Ywezjvr5ackZdn4QEEEA