fn key_handle_to_id()

in key/aziot-keyd/src/lib.rs [573:645]


fn key_handle_to_id(
    handle: &aziot_key_common::KeyHandle,
    keys: &mut keys::Keys,
) -> Result<(KeyId<'static>, std::ffi::CString), Error> {
    // DEVNOTE:
    //
    // Map errors from using the handle validation key to Error::Internal instead of relying on `?`,
    // because all errors from using the handle validation key are internal errors.

    let params = handle.0.split('&');

    let mut sr = None;
    let mut sig = None;

    let engine = base64::engine::general_purpose::STANDARD;

    for param in params {
        if let Some(value) = param.strip_prefix("sr=") {
            let value = base64::Engine::decode(&engine, value.as_bytes())
                .map_err(|_e| Error::invalid_parameter("handle", "invalid handle"))?;
            let value = String::from_utf8(value)
                .map_err(|_e| Error::invalid_parameter("handle", "invalid handle"))?;
            sr = Some(value);
        } else if let Some(value) = param.strip_prefix("sig=") {
            let value = base64::Engine::decode(&engine, value.as_bytes())
                .map_err(|_e| Error::invalid_parameter("handle", "invalid handle"))?;
            sig = Some(value);
        }
    }

    let sr = sr.ok_or_else(|| Error::invalid_parameter("handle", "invalid handle"))?;
    let sig = sig.ok_or_else(|| Error::invalid_parameter("handle", "invalid handle"))?;

    let handle_validation_key = handle_validation_key_id(keys)?;
    let ok = keys
        .verify(
            handle_validation_key,
            keys::sys::AZIOT_KEYS_SIGN_MECHANISM_HMAC_SHA256,
            std::ptr::null(),
            sr.as_bytes(),
            &sig,
        )
        .map_err(|err| Error::Internal(InternalError::Verify(err)))?;
    if !ok {
        return Err(Error::invalid_parameter("handle", "invalid handle"));
    }

    let sr: Sr<'static> = serde_json::from_str(&sr)
        .map_err(|_e| Error::invalid_parameter("handle", "invalid handle"))?;

    let id = sr.key_id;

    let id_cstr = match &id {
        KeyId::KeyPair(id) => {
            let id_cstr = std::ffi::CString::new(id.clone().into_owned())
                .map_err(|err| Error::invalid_parameter("handle", err))?;
            id_cstr
        }

        KeyId::Key(id) => {
            let id_cstr = std::ffi::CString::new(id.clone().into_owned())
                .map_err(|err| Error::invalid_parameter("handle", err))?;
            id_cstr
        }

        KeyId::Derived(base_handle, _) => {
            let (_, base_id_cstr) = key_handle_to_id(base_handle, keys)?;
            base_id_cstr
        }
    };

    Ok((id, id_cstr))
}