Repository: google/OpenSK
File: src/ctap/data_formats.rs (Rust)

Code before:
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::status_code::Ctap2StatusCode;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use arrayref::array_ref;
use cbor::{cbor_array_vec, cbor_map, cbor_map_options, destructure_cbor_map};
use core::convert::TryFrom;
use crypto::{ecdh, ecdsa};
#[cfg(test)]
use enum_iterator::IntoEnumIterator;

// This is the algorithm specifier that is supposed to be used in a COSE key
// map in ECDH. CTAP requests -25 which represents ECDH-ES + HKDF-256 here:
// https://www.iana.org/assignments/cose/cose.xhtml#algorithms
const ECDH_ALGORITHM: i64 = -25;
// This is the identifier used for ECDSA and ECDH in OpenSSH.
const ES256_ALGORITHM: i64 = -7;
// The COSE key parameter behind map key 1.
const EC2_KEY_TYPE: i64 = 2;
// The COSE key parameter behind map key -1.
const P_256_CURVE: i64 = 1;

// https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialrpentity
#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))]
pub struct PublicKeyCredentialRpEntity {
    pub rp_id: String,
    pub rp_name: Option<String>,
    pub rp_icon: Option<String>,
}

impl TryFrom<cbor::Value> for PublicKeyCredentialRpEntity {
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        destructure_cbor_map! {
            let {
                "id" => rp_id,
                "icon" => rp_icon,
                "name" => rp_name,
            } = extract_map(cbor_value)?;
        }

        let rp_id = extract_text_string(ok_or_missing(rp_id)?)?;
        let rp_name = rp_name.map(extract_text_string).transpose()?;
        let rp_icon = rp_icon.map(extract_text_string).transpose()?;


Review comment (suggestion):
All of these constants are specific to the COSE specification. It would be worth to either put them in the `CoseKey` namespace (i.e. `impl CoseKey { const FOO: i64 = bar }`, or prefix them with `COSE_`.

Code after:
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::status_code::Ctap2StatusCode;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use arrayref::array_ref;
use cbor::{cbor_array_vec, cbor_map, cbor_map_options, destructure_cbor_map};
use core::convert::TryFrom;
use crypto::{ecdh, ecdsa};
#[cfg(test)]
use enum_iterator::IntoEnumIterator;

// Used as the identifier for ECDSA in assertion signatures and COSE.
const ES256_ALGORITHM: i64 = -7;

// https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialrpentity
#[cfg_attr(any(test, feature = "debug_ctap"), derive(Debug, PartialEq))]
pub struct PublicKeyCredentialRpEntity {
    pub rp_id: String,
    pub rp_name: Option<String>,
    pub rp_icon: Option<String>,
}

impl TryFrom<cbor::Value> for PublicKeyCredentialRpEntity {
    type Error = Ctap2StatusCode;

    fn try_from(cbor_value: cbor::Value) -> Result<Self, Ctap2StatusCode> {
        destructure_cbor_map! {
            let {
                "id" => rp_id,
                "icon" => rp_icon,
                "name" => rp_name,
            } = extract_map(cbor_value)?;
        }

        let rp_id = extract_text_string(ok_or_missing(rp_id)?)?;
        let rp_name = rp_name.map(extract_text_string).transpose()?;
        let rp_icon = rp_icon.map(extract_text_string).transpose()?;

        Ok(Self {
            rp_id,
            rp_name,
            rp_icon,
        })
    }
}