Skip to content

Commit 05f212c

Browse files
authored
Updated dependencies (#104)
* Updated dependencies * Remove useless rustflag * fmt * Clippy * Bumped rand_core
1 parent 595bb1d commit 05f212c

File tree

17 files changed

+210
-164
lines changed

17 files changed

+210
-164
lines changed

.cargo/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ linker = "i686-linux-android21-clang"
1212

1313
[target.x86_64-linux-android]
1414
ar = "x86_64-linux-android-ar"
15-
linker = "x86_64-linux-android21-clang"
15+
linker = "x86_64-linux-android21-clang"

Cargo.toml

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ sha2 = { version = "0.10", features = ["oid"] }
5050
hmac = { version = "0.12", features = ["reset"] }
5151
sha-1 = { version = "0.10", features = ["oid"] }
5252
time = "0.3"
53-
base32 = "0.4"
53+
base32 = "0.5"
5454
hex = "0.4"
55-
rsa = "0.9.2"
56-
rand = "0.8.5"
57-
x509-parser = "0.15.0"
55+
rsa = "0.9.8"
56+
rand_core = "0.6.4"
57+
x509-parser = "0.17.0"
5858

59-
base64 = { version = "0.13", optional = true }
60-
byteorder = { version = "1.4", optional = true }
61-
ring = { version = "0.16", optional = true }
59+
base64 = { version = "0.22", optional = true }
60+
byteorder = { version = "1.5", optional = true }
61+
ring = { version = "0.17", optional = true }
6262
untrusted = { version = "0.9.0", optional = true }
6363
serde = { version = "1.0", optional = true }
6464
serde_repr = { version = "0.1", optional = true }
@@ -67,32 +67,32 @@ serde_bytes = { version = "0.11", optional = true }
6767
serde_json = { version = "1.0", optional = true }
6868
serde_cbor = { version = "0.11", optional = true }
6969
webpki = { version = "0.22", optional = true, features = ["alloc"] }
70-
bytes = { version = "1.2", optional = true }
71-
http = { version = "1.0", optional = true }
72-
uuid = { version = "1.6", optional = true }
73-
ed25519-dalek = { version = "2.1.0", features = [
70+
bytes = { version = "1.10", optional = true }
71+
http = { version = "1.3", optional = true }
72+
uuid = { version = "1.16", optional = true }
73+
ed25519-dalek = { version = "2.1.1", features = [
7474
"rand_core",
7575
"pkcs8",
7676
], optional = true }
7777
p256 = { version = "0.13.2", optional = true }
78-
indexmap = { version = "2.2.6", features = ["serde"], optional = true }
78+
indexmap = { version = "2.9.0", features = ["serde"], optional = true }
7979

8080
[target.'cfg(target_os = "android")'.dependencies]
8181
jni = { version = "0.21.1", optional = true }
8282

8383
[target.'cfg(target_arch="wasm32")'.dependencies]
84-
wasm-bindgen = { version = "0.2.91" }
85-
js-sys = "0.3.37"
84+
wasm-bindgen = { version = "0.2.100" }
85+
js-sys = "0.3.77"
8686
# FIXME: https://docs.rs/getrandom/0.2.2/getrandom/#webassembly-support
8787
# let `getrandom` know that JavaScript is available for our targets
8888
# `getrandom` is not used directly, but by adding the right feature here
8989
# it will be compiled with it in our dependencies as well (since union of
9090
# all the features selected is used when building a Cargo project)
9191
getrandom = { version = "0.2", features = ["js"] }
92-
serde-wasm-bindgen = "0.6.3"
92+
serde-wasm-bindgen = "0.6.5"
9393

9494
[target.'cfg(target_arch="wasm32")'.dev-dependencies]
95-
wasm-bindgen-test = "0.3.10"
95+
wasm-bindgen-test = "0.3.50"
9696

9797
[target.'cfg(not(target_arch="wasm32"))'.dev-dependencies]
9898
saphir = { version = "3.1.0", git = "https://github.com/richerarc/saphir.git", tag = "v3.1.0", features = [
@@ -104,9 +104,9 @@ async-stream = ">= 0.3, < 0.3.4" # 0.3.4 and up currently break saphir
104104
[dev-dependencies]
105105
serde_json = "1.0"
106106
serde_cbor = "0.11"
107-
uuid = "1.2"
108-
rand = "0.8"
109-
bytes = "1.2"
107+
uuid = "1.16"
108+
rand = "0.9"
109+
bytes = "1.10"
110110

111111
#[package.metadata.wasm-pack.profile.release]
112112
#wasm-opt = false

examples/web-server.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use rand::seq::IteratorRandom;
22
use saphir::prelude::*;
33
use serde_json::{json, Value};
4-
use slauth::webauthn::{
5-
error::{CredentialError as CredE, Error::CredentialError},
6-
proto::{
7-
constants::WEBAUTHN_CHALLENGE_LENGTH,
8-
raw_message::CredentialPublicKey,
9-
web_message::{PublicKeyCredential, PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions},
4+
use slauth::{
5+
base64::*,
6+
webauthn::{
7+
error::{CredentialError as CredE, Error::CredentialError},
8+
proto::{
9+
constants::WEBAUTHN_CHALLENGE_LENGTH,
10+
raw_message::CredentialPublicKey,
11+
web_message::{PublicKeyCredential, PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions},
12+
},
13+
server::{CredentialCreationBuilder, CredentialCreationVerifier, CredentialRequestBuilder, CredentialRequestVerifier},
1014
},
11-
server::{CredentialCreationBuilder, CredentialCreationVerifier, CredentialRequestBuilder, CredentialRequestVerifier},
1215
};
1316
use std::{collections::HashMap, sync::RwLock};
1417

@@ -53,7 +56,7 @@ impl Responder for TestError {
5356
impl TestController {
5457
#[get("/register")]
5558
async fn register_request(&self) -> Result<Json<Value>, TestError> {
56-
let uuid = base64::encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
59+
let uuid = BASE64.encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
5760
let builder = CredentialCreationBuilder::new()
5861
.challenge(gen_challenge(WEBAUTHN_CHALLENGE_LENGTH))
5962
.user(uuid.clone(), "lfauvel@devolutions.net".to_string(), "Luc Fauvel".to_string(), None)
@@ -77,7 +80,7 @@ impl TestController {
7780
#[post("/register")]
7881
async fn complete_register(&self, cred: Json<PublicKeyCredential>) -> Result<(), TestError> {
7982
let cred = cred.into_inner();
80-
let uuid = base64::encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
83+
let uuid = BASE64.encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
8184
if let Some(context) = self.reg_contexts.read().expect("should be ok").get(&uuid) {
8285
let mut verifier = CredentialCreationVerifier::new(cred.clone(), context.clone(), "http://localhost");
8386
if let Ok(result) = verifier.verify() {
@@ -93,7 +96,7 @@ impl TestController {
9396
let mut builder = CredentialRequestBuilder::new()
9497
.rp("localhost".to_string())
9598
.challenge(gen_challenge(WEBAUTHN_CHALLENGE_LENGTH));
96-
let uuid = base64::encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
99+
let uuid = BASE64.encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
97100
for (cred, _) in self.creds.read().unwrap().iter() {
98101
builder = builder.allow_credential(cred.clone());
99102
}
@@ -112,7 +115,7 @@ impl TestController {
112115
#[post("/sign")]
113116
async fn complete_sign(&self, req: Json<PublicKeyCredential>) -> Result<(u16, String), TestError> {
114117
let cred = req.into_inner();
115-
let uuid = base64::encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
118+
let uuid = BASE64.encode("e1aea4d6-d2ee-4218-9f1c-5ccddadaa1a7");
116119

117120
let ctx_lock = self
118121
.sign_contexts
@@ -209,9 +212,9 @@ async fn main() -> Result<(), SaphirError> {
209212
pub fn gen_challenge(len: usize) -> String {
210213
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
211214

212-
let mut rng = rand::thread_rng();
215+
let mut rng = rand::rng();
213216
let value = (0..len)
214217
.map(|_| charset.chars().choose(&mut rng).unwrap() as u8)
215218
.collect::<Vec<u8>>();
216-
base64::encode_config(value.as_slice(), base64::URL_SAFE_NO_PAD)
219+
BASE64_URLSAFE_NOPAD.encode(value.as_slice())
217220
}

src/base64.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
pub use base64::Engine as _;
2+
use base64::{
3+
alphabet,
4+
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
5+
};
6+
7+
const CONFIG: GeneralPurposeConfig = GeneralPurposeConfig::new()
8+
.with_encode_padding(true)
9+
.with_decode_padding_mode(DecodePaddingMode::Indifferent)
10+
.with_decode_allow_trailing_bits(true);
11+
12+
const CONFIG_NO_PAD: GeneralPurposeConfig = GeneralPurposeConfig::new()
13+
.with_encode_padding(false)
14+
.with_decode_padding_mode(DecodePaddingMode::Indifferent)
15+
.with_decode_allow_trailing_bits(true);
16+
17+
pub const BASE64: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, CONFIG);
18+
pub const BASE64_URLSAFE_NOPAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, CONFIG_NO_PAD);

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub mod webauthn;
1818
#[cfg(target_arch = "wasm32")]
1919
pub mod wasm;
2020

21+
pub mod base64;
22+
2123
#[cfg(feature = "native-bindings")]
2224
pub mod strings {
2325
use std::{

src/oath/hotp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl OtpAuth for HOTPContext {
139139
let mut uri = format!(
140140
"otpauth://hotp/{}?secret={}&algorithm={}&digits={}&counter={}",
141141
label.unwrap_or("slauth"),
142-
base32::encode(base32::Alphabet::RFC4648 { padding: false }, self.secret.as_slice()),
142+
base32::encode(base32::Alphabet::Rfc4648 { padding: false }, self.secret.as_slice()),
143143
self.alg,
144144
self.digits,
145145
self.counter
@@ -174,7 +174,7 @@ impl OtpAuth for HOTPContext {
174174

175175
let param_it_opt = type_label_it
176176
.next()
177-
.and_then(|label_param| label_param.split('?').last().map(|s| s.split('&')));
177+
.and_then(|label_param| label_param.split('?').next_back().map(|s| s.split('&')));
178178

179179
param_it_opt
180180
.ok_or_else(|| "Otpauth uri is malformed, missing parameters".to_string())

src/oath/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub(crate) fn dt(hmac_res: &[u8]) -> u32 {
101101
#[inline]
102102
pub(crate) fn decode_hex_or_base_32(encoded: &str) -> Option<Vec<u8>> {
103103
// Try base32 first then is it does not follows RFC4648, try HEX
104-
base32::decode(base32::Alphabet::RFC4648 { padding: false }, encoded).or_else(|| hex::decode(encoded).ok())
104+
base32::decode(base32::Alphabet::Rfc4648 { padding: false }, encoded).or_else(|| hex::decode(encoded).ok())
105105
}
106106

107107
#[cfg(target_arch = "wasm32")]

src/oath/totp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl OtpAuth for TOTPContext {
202202
let mut uri = format!(
203203
"otpauth://totp/{}?secret={}&algorithm={}&digits={}&period={}",
204204
label.unwrap_or("slauth"),
205-
base32::encode(base32::Alphabet::RFC4648 { padding: false }, self.secret.as_slice()),
205+
base32::encode(base32::Alphabet::Rfc4648 { padding: false }, self.secret.as_slice()),
206206
self.alg,
207207
self.digits,
208208
self.period
@@ -237,7 +237,7 @@ impl OtpAuth for TOTPContext {
237237

238238
let param_it_opt = type_label_it
239239
.next()
240-
.and_then(|label_param| label_param.split('?').last().map(|s| s.split('&')));
240+
.and_then(|label_param| label_param.split('?').next_back().map(|s| s.split('&')));
241241

242242
param_it_opt
243243
.ok_or_else(|| "Otpauth uri is malformed, missing parameters".to_string())

src/u2f/client/mod.rs

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@ pub struct SigningKey {
99
pub mod client {
1010
use sha2::{Digest, Sha256};
1111

12-
use crate::u2f::{
13-
client::{token, SigningKey},
14-
error::Error,
15-
proto::{
16-
constants::{MAX_RESPONSE_LEN_EXTENDED, U2F_AUTHENTICATE, U2F_AUTH_DONT_ENFORCE, U2F_REGISTER, U2F_V2_VERSION_STR},
17-
raw_message::{
18-
self,
19-
apdu::{ApduFrame, Request as RawRequest},
20-
Message as RawMessageTrait,
21-
},
22-
web_message::{
23-
ClientData, ClientDataType, ClientError, Request, Response, U2fRegisterResponse, U2fRequest, U2fRequestType,
24-
U2fResponse as WebResponse, U2fResponseType, U2fSignResponse,
12+
use crate::{
13+
base64::*,
14+
u2f::{
15+
client::{token, SigningKey},
16+
error::Error,
17+
proto::{
18+
constants::{MAX_RESPONSE_LEN_EXTENDED, U2F_AUTHENTICATE, U2F_AUTH_DONT_ENFORCE, U2F_REGISTER, U2F_V2_VERSION_STR},
19+
raw_message::{
20+
self,
21+
apdu::{ApduFrame, Request as RawRequest},
22+
Message as RawMessageTrait,
23+
},
24+
web_message::{
25+
ClientData, ClientDataType, ClientError, Request, Response, U2fRegisterResponse, U2fRequest, U2fRequestType,
26+
U2fResponse as WebResponse, U2fResponseType, U2fSignResponse,
27+
},
2528
},
2629
},
2730
};
@@ -90,8 +93,8 @@ pub mod client {
9093
Ok((
9194
Response::Register(U2fRegisterResponse {
9295
version: U2F_V2_VERSION_STR.to_string(),
93-
client_data: base64::encode_config(&client_data_str, base64::URL_SAFE_NO_PAD),
94-
registration_data: base64::encode_config(&raw_rsp_byte, base64::URL_SAFE_NO_PAD),
96+
client_data: BASE64_URLSAFE_NOPAD.encode(&client_data_str),
97+
registration_data: BASE64_URLSAFE_NOPAD.encode(&raw_rsp_byte),
9598
}),
9699
signing_key,
97100
))
@@ -156,8 +159,8 @@ pub mod client {
156159

157160
Ok(Response::Sign(U2fSignResponse {
158161
key_handle: signing_key.key_handle.clone(),
159-
signature_data: base64::encode_config(&raw_rsp_byte, base64::URL_SAFE_NO_PAD),
160-
client_data: base64::encode_config(&client_data_str, base64::URL_SAFE_NO_PAD),
162+
signature_data: BASE64_URLSAFE_NOPAD.encode(&raw_rsp_byte),
163+
client_data: BASE64_URLSAFE_NOPAD.encode(&client_data_str),
161164
}))
162165
}
163166
}
@@ -382,11 +385,7 @@ pub mod client {
382385
pub unsafe extern "C" fn signing_key_to_string(s: *mut SigningKey) -> *mut c_char {
383386
let SigningKey { key_handle, private_key } = &*s;
384387

385-
strings::string_to_c_char(format!(
386-
"{}.{}",
387-
key_handle,
388-
base64::encode_config(private_key, base64::URL_SAFE_NO_PAD)
389-
))
388+
strings::string_to_c_char(format!("{}.{}", key_handle, BASE64_URLSAFE_NOPAD.encode(private_key)))
390389
}
391390

392391
#[no_mangle]
@@ -402,11 +401,7 @@ pub mod client {
402401
let mut parts = s.split('.');
403402
let l = parts.next().and_then(|key_handle| parts.next().map(|b64| (key_handle, b64)));
404403

405-
l.and_then(|(k, b64)| {
406-
base64::decode_config(b64, base64::URL_SAFE_NO_PAD)
407-
.ok()
408-
.map(|b64_v| (k.to_string(), b64_v))
409-
})
404+
l.and_then(|(k, b64)| BASE64_URLSAFE_NOPAD.decode(b64).ok().map(|b64_v| (k.to_string(), b64_v)))
410405
})
411406
.map(|(key_handle, key)| {
412407
Box::into_raw(Box::new(SigningKey {

src/u2f/client/token.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
};
66

77
use ring::{
8-
rand,
8+
rand::{self, SystemRandom},
99
signature::{self, KeyPair},
1010
};
1111

@@ -24,7 +24,7 @@ pub(crate) fn gen_key_handle(app_id: &[u8], chall: &[u8]) -> String {
2424
let mut data = Vec::with_capacity(app_id.len() + chall.len());
2525
data.extend_from_slice(app_id);
2626
data.extend_from_slice(chall);
27-
base32::encode(base32::Alphabet::RFC4648 { padding: false }, &data)
27+
base32::encode(base32::Alphabet::Rfc4648 { padding: false }, &data)
2828
}
2929

3030
pub fn register(req: RegisterRequest, attestation_cert: &[u8], attestation_key: &[u8]) -> Result<(RegisterResponse, SigningKey), Error> {
@@ -38,7 +38,9 @@ pub fn register(req: RegisterRequest, attestation_cert: &[u8], attestation_key:
3838

3939
let key_handle = gen_key_handle(&application, &challenge);
4040

41-
let registered_key_pair = signature::EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, registered_key_pkcs8_bytes)?;
41+
let random = SystemRandom::new();
42+
let registered_key_pair =
43+
signature::EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, registered_key_pkcs8_bytes, &random)?;
4244
let registered_pub_key = registered_key_pair.public_key();
4345
let mut user_public_key = [0u8; U2F_EC_POINT_SIZE];
4446

@@ -54,7 +56,7 @@ pub fn register(req: RegisterRequest, attestation_cert: &[u8], attestation_key:
5456
tbs_vec.extend_from_slice(key_handle.as_bytes());
5557
tbs_vec.extend_from_slice(&user_public_key);
5658

57-
let att_key_pair = signature::EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, attestation_key)?;
59+
let att_key_pair = signature::EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, attestation_key, &random)?;
5860

5961
let sig = att_key_pair.sign(&rng, tbs_vec.as_slice())?;
6062

@@ -94,8 +96,11 @@ pub fn sign(req: AuthenticateRequest, signing_key: &SigningKey, counter: u32, us
9496
U2F_AUTH_CHECK_ONLY => Err(Error::U2FErrorCode(U2F_SW_CONDITIONS_NOT_SATISFIED)),
9597
U2F_AUTH_ENFORCE | U2F_AUTH_DONT_ENFORCE => {
9698
let rng = rand::SystemRandom::new();
97-
let key_pair =
98-
signature::EcdsaKeyPair::from_pkcs8(&signature::ECDSA_P256_SHA256_ASN1_SIGNING, signing_key.private_key.as_slice())?;
99+
let key_pair = signature::EcdsaKeyPair::from_pkcs8(
100+
&signature::ECDSA_P256_SHA256_ASN1_SIGNING,
101+
signing_key.private_key.as_slice(),
102+
&SystemRandom::new(),
103+
)?;
99104

100105
let mut tbs_vec = Vec::with_capacity(U2F_AUTH_MAX_DATA_TBS_SIZE);
101106
tbs_vec.extend_from_slice(&application);

src/u2f/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ pub mod server;
77

88
#[test]
99
fn test() {
10-
use crate::u2f::proto::web_message::{Response, U2fRequest};
10+
use crate::{
11+
base64::*,
12+
u2f::proto::web_message::{Response, U2fRequest},
13+
};
1114
use server::*;
1215
const ATT_PKEY: &str = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgzgUSoDttmryF0C+ck4GppKwssha7ngah0dfezfTBzDOhRANCAATXk8CelRQjNuArEPpEW40yOOX9wPTq8pEG2XRf8KI3NzeKBOHWpxzTRAgKABBTF28dKf4NpJGSL+Qj04nyWQ8a";
1316
const ATT_CERT: &str = "MIICODCCAd6gAwIBAgIJAKsa9WC9HvEuMAoGCCqGSM49BAMCMFoxDzANBgNVBAMMBlNsYXV0aDELMAkGA1UEBhMCQ0ExDzANBgNVBAgMBlF1ZWJlYzETMBEGA1UEBwwKTGF2YWx0cm91ZTEUMBIGA1UECgwLRGV2b2x1dGlvbnMwHhcNMTkwNzAyMTgwMTUyWhcNMzEwNjI5MTgwMTUyWjBaMQ8wDQYDVQQDDAZTbGF1dGgxCzAJBgNVBAYTAkNBMQ8wDQYDVQQIDAZRdWViZWMxEzARBgNVBAcMCkxhdmFsdHJvdWUxFDASBgNVBAoMC0Rldm9sdXRpb25zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE15PAnpUUIzbgKxD6RFuNMjjl/cD06vKRBtl0X/CiNzc3igTh1qcc00QICgAQUxdvHSn+DaSRki/kI9OJ8lkPGqOBjDCBiTAdBgNVHQ4EFgQU7iZ4JceUHOuWoMymFGm+ZBUmwwgwHwYDVR0jBBgwFoAU7iZ4JceUHOuWoMymFGm+ZBUmwwgwDgYDVR0PAQH/BAQDAgWgMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAVBgNVHREEDjAMggpzbGF1dGgub3JnMAoGCCqGSM49BAMCA0gAMEUCIEdjPFNsund4FXs/1HpK4AXWQ0asfY6ERhNlg29VGS6pAiEAx8f2lrlVV1tASWbC/edTgH9JsCbANuXW/9FZcWHGl2E=";
@@ -29,8 +32,8 @@ fn test() {
2932
let (rsp, signing_key) = web_req
3033
.register(
3134
origin.to_string(),
32-
base64::decode(ATT_CERT).unwrap().as_slice(),
33-
base64::decode(ATT_PKEY).unwrap().as_slice(),
35+
BASE64.decode(ATT_CERT).unwrap().as_slice(),
36+
BASE64.decode(ATT_PKEY).unwrap().as_slice(),
3437
)
3538
.expect("Unable to register");
3639

0 commit comments

Comments
 (0)