Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "slauth"
version = "0.7.19"
version = "0.8.0"
authors = [
"richer <richer.arc@gmail.com>",
"LucFauvel <luc.fauvel@hotmail.com>",
Expand Down
2 changes: 1 addition & 1 deletion examples/web-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,5 @@ pub fn gen_challenge(len: usize) -> String {
let value = (0..len)
.map(|_| charset.chars().choose(&mut rng).unwrap() as u8)
.collect::<Vec<u8>>();
BASE64_URLSAFE_NOPAD.encode(value.as_slice())
BASE64_URL_SAFE_NO_PAD.encode(value.as_slice())
}
2 changes: 1 addition & 1 deletion src/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ const CONFIG_NO_PAD: GeneralPurposeConfig = GeneralPurposeConfig::new()
.with_decode_allow_trailing_bits(true);

pub const BASE64: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, CONFIG);
pub const BASE64_URLSAFE_NOPAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, CONFIG_NO_PAD);
pub const BASE64_URL_SAFE_NO_PAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, CONFIG_NO_PAD);
12 changes: 6 additions & 6 deletions src/u2f/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ pub mod client {
Ok((
Response::Register(U2fRegisterResponse {
version: U2F_V2_VERSION_STR.to_string(),
client_data: BASE64_URLSAFE_NOPAD.encode(&client_data_str),
registration_data: BASE64_URLSAFE_NOPAD.encode(&raw_rsp_byte),
client_data: BASE64_URL_SAFE_NO_PAD.encode(&client_data_str),
registration_data: BASE64_URL_SAFE_NO_PAD.encode(&raw_rsp_byte),
}),
signing_key,
))
Expand Down Expand Up @@ -167,8 +167,8 @@ pub mod client {

Ok(Response::Sign(U2fSignResponse {
key_handle: signing_key.key_handle.clone(),
signature_data: BASE64_URLSAFE_NOPAD.encode(&raw_rsp_byte),
client_data: BASE64_URLSAFE_NOPAD.encode(&client_data_str),
signature_data: BASE64_URL_SAFE_NO_PAD.encode(&raw_rsp_byte),
client_data: BASE64_URL_SAFE_NO_PAD.encode(&client_data_str),
}))
}
}
Expand Down Expand Up @@ -393,7 +393,7 @@ pub mod client {
pub unsafe extern "C" fn signing_key_to_string(s: *mut SigningKey) -> *mut c_char {
let SigningKey { key_handle, private_key } = &*s;

strings::string_to_c_char(format!("{}.{}", key_handle, BASE64_URLSAFE_NOPAD.encode(private_key)))
strings::string_to_c_char(format!("{}.{}", key_handle, BASE64_URL_SAFE_NO_PAD.encode(private_key)))
}

#[no_mangle]
Expand All @@ -409,7 +409,7 @@ pub mod client {
let mut parts = s.split('.');
let l = parts.next().and_then(|key_handle| parts.next().map(|b64| (key_handle, b64)));

l.and_then(|(k, b64)| BASE64_URLSAFE_NOPAD.decode(b64).ok().map(|b64_v| (k.to_string(), b64_v)))
l.and_then(|(k, b64)| BASE64_URL_SAFE_NO_PAD.decode(b64).ok().map(|b64_v| (k.to_string(), b64_v)))
})
.map(|(key_handle, key)| {
Box::into_raw(Box::new(SigningKey {
Expand Down
10 changes: 5 additions & 5 deletions src/u2f/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl U2fRequestBuilder {
registered_keys,
} = self;

let challenge = BASE64_URLSAFE_NOPAD.encode(
let challenge = BASE64_URL_SAFE_NO_PAD.encode(
challenge
.as_ref()
.ok_or_else(|| Error::Other("Unable to build a U2F request without a challenge".to_string()))?,
Expand Down Expand Up @@ -153,13 +153,13 @@ impl U2fRegisterResponse {
}

// Validate that input is consistent with what's expected
let registration_data_bytes = BASE64_URLSAFE_NOPAD
let registration_data_bytes = BASE64_URL_SAFE_NO_PAD
.decode(registration_data)
.map_err(|e| Error::Registration(e.to_string()))?;
let raw_rsp = raw_message::apdu::Response::read_from(&registration_data_bytes)?;
let raw_u2f_reg = raw_message::RegisterResponse::from_apdu(raw_rsp)?;

let client_data_bytes = BASE64_URLSAFE_NOPAD
let client_data_bytes = BASE64_URL_SAFE_NO_PAD
.decode(client_data)
.map_err(|e| Error::Registration(e.to_string()))?;

Expand Down Expand Up @@ -219,13 +219,13 @@ impl U2fSignResponse {
..
} = &self;

let signature_data_byte = BASE64_URLSAFE_NOPAD
let signature_data_byte = BASE64_URL_SAFE_NO_PAD
.decode(signature_data)
.map_err(|e| Error::Registration(e.to_string()))?;
let raw_rsp = raw_message::apdu::Response::read_from(&signature_data_byte)?;
let raw_u2f_sign = raw_message::AuthenticateResponse::from_apdu(raw_rsp)?;

let client_data_bytes = BASE64_URLSAFE_NOPAD
let client_data_bytes = BASE64_URL_SAFE_NO_PAD
.decode(client_data)
.map_err(|e| Error::Registration(e.to_string()))?;

Expand Down
26 changes: 13 additions & 13 deletions src/webauthn/authenticator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,20 @@ impl WebauthnAuthenticator {

let challenge = match BASE64.decode(credential_creation_options.challenge.as_str()) {
Ok(challenge) => challenge,
Err(_) => BASE64_URLSAFE_NOPAD.decode(credential_creation_options.challenge)?,
Err(_) => BASE64_URL_SAFE_NO_PAD.decode(credential_creation_options.challenge)?,
};

let collected_client_data = CollectedClientData {
request_type: WEBAUTHN_REQUEST_TYPE_CREATE.to_owned(),
challenge: BASE64_URLSAFE_NOPAD.encode(challenge),
challenge: BASE64_URL_SAFE_NO_PAD.encode(challenge),
origin: origin.as_ref().unwrap_or(rp_id).clone(),
cross_origin: false,
token_binding: None,
};

let auth_data = attestation_object.auth_data.clone();
let credential = PublicKeyCredentialRaw {
id: BASE64_URLSAFE_NOPAD.encode(credential_id.clone()),
id: BASE64_URL_SAFE_NO_PAD.encode(credential_id.clone()),
raw_id: credential_id,
response: Some(AuthenticatorAttestationResponseRaw {
attestation_object: Some(attestation_object.to_bytes()?),
Expand Down Expand Up @@ -322,10 +322,10 @@ impl WebauthnAuthenticator {

let challenge = BASE64
.decode(credential_request_options.challenge.as_str())
.or(BASE64_URLSAFE_NOPAD.decode(credential_request_options.challenge))?;
.or(BASE64_URL_SAFE_NO_PAD.decode(credential_request_options.challenge))?;
let collected_client_data = CollectedClientData {
request_type: WEBAUTHN_REQUEST_TYPE_GET.to_owned(),
challenge: BASE64_URLSAFE_NOPAD.encode(challenge),
challenge: BASE64_URL_SAFE_NO_PAD.encode(challenge),
origin: origin.as_ref().unwrap_or(rp_id).clone(),
cross_origin: false,
token_binding: None,
Expand All @@ -338,7 +338,7 @@ impl WebauthnAuthenticator {
let signature = Self::generate_signature(auth_data_bytes.as_slice(), hash.as_slice(), private_key)?;

Ok(PublicKeyCredentialRaw {
id: BASE64_URLSAFE_NOPAD.encode(credential_id.clone()),
id: BASE64_URL_SAFE_NO_PAD.encode(credential_id.clone()),
raw_id: credential_id,
response: Some(AuthenticatorAttestationResponseRaw {
attestation_object: None,
Expand Down Expand Up @@ -380,7 +380,7 @@ impl WebauthnAuthenticator {
let private_key_response: PrivateKeyResponse = serde_cbor::from_slice(
&BASE64
.decode(private_key.as_str())
.or(BASE64_URLSAFE_NOPAD.decode(private_key.as_str()))?,
.or(BASE64_URL_SAFE_NO_PAD.decode(private_key.as_str()))?,
)?;

match private_key_response.key_alg {
Expand Down Expand Up @@ -410,26 +410,26 @@ impl WebauthnAuthenticator {
let private_key_response: PrivateKeyResponse = serde_cbor::from_slice(
&BASE64
.decode(private_key.as_str())
.or(BASE64_URLSAFE_NOPAD.decode(private_key.as_str()))?,
.or(BASE64_URL_SAFE_NO_PAD.decode(private_key.as_str()))?,
)?;

match private_key_response.key_alg {
CoseAlgorithmIdentifier::Ed25519 => {
let key = ed25519_dalek::SigningKey::try_from(private_key_response.private_key.as_slice()).or(
ed25519_dalek::SigningKey::from_pkcs8_der(private_key_response.private_key.as_slice()),
)?;
Ok(BASE64_URLSAFE_NOPAD.encode(key.to_pkcs8_der()?.as_bytes()))
Ok(BASE64_URL_SAFE_NO_PAD.encode(key.to_pkcs8_der()?.as_bytes()))
}
CoseAlgorithmIdentifier::ES256 => {
let key = p256::ecdsa::SigningKey::from_pkcs8_der(private_key_response.private_key.as_slice())
.or(p256::ecdsa::SigningKey::try_from(private_key_response.private_key.as_slice()))?;
Ok(BASE64_URLSAFE_NOPAD.encode(key.to_pkcs8_der()?.as_bytes()))
Ok(BASE64_URL_SAFE_NO_PAD.encode(key.to_pkcs8_der()?.as_bytes()))
}
CoseAlgorithmIdentifier::RSA => {
let key = rsa::RsaPrivateKey::from_pkcs1_der(&private_key_response.private_key)
.or(rsa::RsaPrivateKey::from_pkcs8_der(&private_key_response.private_key))?;
let signing_key = rsa::pkcs1v15::SigningKey::<Sha256>::new(key);
Ok(BASE64_URLSAFE_NOPAD.encode(signing_key.to_pkcs8_der()?.as_bytes()))
Ok(BASE64_URL_SAFE_NO_PAD.encode(signing_key.to_pkcs8_der()?.as_bytes()))
}
_ => Err(WebauthnCredentialRequestError::AlgorithmNotSupported),
}
Expand All @@ -438,7 +438,7 @@ impl WebauthnAuthenticator {
pub fn convert_pkcs8_der_to_custom_private_key(private_key: String) -> Result<String, WebauthnCredentialRequestError> {
let private_key_bytes = BASE64
.decode(private_key.as_str())
.or(BASE64_URLSAFE_NOPAD.decode(private_key.as_str()))?;
.or(BASE64_URL_SAFE_NO_PAD.decode(private_key.as_str()))?;

match PrivateKeyInfo::try_from(private_key_bytes.as_slice())?.algorithm.oid {
OID_ED25519 => {
Expand Down Expand Up @@ -581,7 +581,7 @@ fn test_credential_generation() {
rp_id: Some("localhost".to_owned()),
allow_credentials: vec![PublicKeyCredentialDescriptor {
cred_type: PublicKeyCredentialType::PublicKey,
id: BASE64_URLSAFE_NOPAD.encode(&cred_uuid),
id: BASE64_URL_SAFE_NO_PAD.encode(&cred_uuid),
transports: None,
}],
extensions: Extensions::default(),
Expand Down
8 changes: 4 additions & 4 deletions src/webauthn/authenticator/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ pub mod android {
authenticator_attachment: Some("cross-platform".to_owned()),
client_extension_results: HashMap::new(),
response: raw.response.map(|response| AuthenticatorAttestationResponse {
attestation_object: response.attestation_object.map(|ad| BASE64_URLSAFE_NOPAD.encode(ad)),
attestation_object: response.attestation_object.map(|ad| BASE64_URL_SAFE_NO_PAD.encode(ad)),
client_data_json: BASE64.encode(&response.client_data_json),
authenticator_data: response.authenticator_data.map(|ad| BASE64_URLSAFE_NOPAD.encode(ad)),
signature: response.signature.map(|ad| BASE64_URLSAFE_NOPAD.encode(ad)),
user_handle: response.user_handle.map(|ad| BASE64_URLSAFE_NOPAD.encode(ad)),
authenticator_data: response.authenticator_data.map(|ad| BASE64_URL_SAFE_NO_PAD.encode(ad)),
signature: response.signature.map(|ad| BASE64_URL_SAFE_NO_PAD.encode(ad)),
user_handle: response.user_handle.map(|ad| BASE64_URL_SAFE_NO_PAD.encode(ad)),
}),
credential_type: Some("public-key".to_owned()),
error: None,
Expand Down
4 changes: 2 additions & 2 deletions src/webauthn/proto/raw_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -617,15 +617,15 @@ impl Display for Coordinates {
_ => {}
}

write!(f, "{}", BASE64_URLSAFE_NOPAD.encode(&key))
write!(f, "{}", BASE64_URL_SAFE_NO_PAD.encode(&key))
}
}

impl FromStr for Coordinates {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let key = BASE64_URLSAFE_NOPAD.decode(s).map_err(Error::Base64Error)?;
let key = BASE64_URL_SAFE_NO_PAD.decode(s).map_err(Error::Base64Error)?;

match key[0] {
ECDSA_Y_PREFIX_UNCOMPRESSED => {
Expand Down
4 changes: 2 additions & 2 deletions src/webauthn/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ impl CredentialRequestBuilder {

pub fn prf_credential<T: Into<Option<Vec<u8>>>>(mut self, credential_id: Vec<u8>, first: Vec<u8>, second: T) -> Self {
if let Some(prf) = self.prf.as_mut() {
let encoded_credential_id = BASE64_URLSAFE_NOPAD.encode(credential_id);
let encoded_credential_id = BASE64_URL_SAFE_NO_PAD.encode(credential_id);
prf.eval_by_credential.insert(
encoded_credential_id,
AuthenticationExtensionsPRFValues {
Expand Down Expand Up @@ -470,7 +470,7 @@ impl CredentialRequestBuilder {
let prf = self.prf.as_mut().expect("initialized above");

for (credential_id, first, second) in credentials {
let encoded_credential_id = BASE64_URLSAFE_NOPAD.encode(&credential_id);
let encoded_credential_id = BASE64_URL_SAFE_NO_PAD.encode(&credential_id);
prf.eval_by_credential
.insert(encoded_credential_id, AuthenticationExtensionsPRFValues { first, second });
}
Expand Down