Skip to content

Commit 1747c61

Browse files
authored
fix(rust/rbac-registration): extract type in CIP509 to its own file and implement conversion (#97)
* fix: extrat type to its own type and impl conversion Signed-off-by: bkioshn <[email protected]> * fix: make util public Signed-off-by: bkioshn <[email protected]> * fix: make cip19 utils public Signed-off-by: bkioshn <[email protected]> * fix: remove uuidv4 and ed25519pubkey type Signed-off-by: bkioshn <[email protected]> * chore: fix naming Signed-off-by: bkioshn <[email protected]> * fix: naming Signed-off-by: bkioshn <[email protected]> * fix: use ShelleyAddress instead of Shelley Payment part Signed-off-by: bkioshn <[email protected]> * fix: naming Signed-off-by: bkioshn <[email protected]> --------- Signed-off-by: bkioshn <[email protected]>
1 parent 47b5514 commit 1747c61

File tree

12 files changed

+141
-146
lines changed

12 files changed

+141
-146
lines changed

rust/rbac-registration/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ bech32 = "0.11.0"
3131
dashmap = "6.1.0"
3232
blake2b_simd = "1.0.2"
3333
tracing = "0.1.40"
34+
ed25519-dalek = "2.1.1"
35+
uuid = "1.11.0"
3436

3537
c509-certificate = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git" , tag = "v0.0.3" }
3638
pallas = { version = "0.30.1", git = "https://github.com/input-output-hk/catalyst-pallas.git", rev = "9b5183c8b90b90fe2cc319d986e933e9518957b3" }

rust/rbac-registration/src/cardano/cip509/mod.rs

+25-71
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
// cspell: words pkix
66

77
pub mod rbac;
8-
pub(crate) mod utils;
8+
pub mod types;
9+
pub mod utils;
910
pub(crate) mod validation;
1011
pub mod x509_chunks;
1112

@@ -15,6 +16,8 @@ use minicbor::{
1516
};
1617
use pallas::{crypto::hash::Hash, ledger::traverse::MultiEraTx};
1718
use strum_macros::FromRepr;
19+
use types::tx_input_hash::TxInputHash;
20+
use uuid::Uuid;
1821
use validation::{
1922
validate_aux, validate_payment_key, validate_role_singing_key, validate_stake_public_key,
2023
validate_txn_inputs_hash,
@@ -35,7 +38,7 @@ pub const LABEL: u64 = 509;
3538
#[derive(Debug, PartialEq, Clone, Default)]
3639
pub struct Cip509 {
3740
/// `UUIDv4` Purpose .
38-
pub purpose: UuidV4, // (bytes .size 16)
41+
pub purpose: Uuid, // (bytes .size 16)
3942
/// Transaction inputs hash.
4043
pub txn_inputs_hash: TxInputHash, // bytes .size 16
4144
/// Optional previous transaction ID.
@@ -51,15 +54,15 @@ pub struct Cip509 {
5154
#[derive(Debug, PartialEq, Clone, Default)]
5255
pub struct Cip509Validation {
5356
/// Boolean value for the validity of the transaction inputs hash.
54-
pub valid_txn_inputs_hash: bool,
57+
pub is_valid_txn_inputs_hash: bool,
5558
/// Boolean value for the validity of the auxiliary data.
56-
pub valid_aux: bool,
57-
/// Boolean value for the validity of the public key.
58-
pub valid_public_key: bool,
59+
pub is_valid_aux: bool,
60+
/// Boolean value for the validity of the stake public key.
61+
pub is_valid_stake_public_key: bool,
5962
/// Boolean value for the validity of the payment key.
60-
pub valid_payment_key: bool,
63+
pub is_valid_payment_key: bool,
6164
/// Boolean value for the validity of the signing key.
62-
pub signing_key: bool,
65+
pub is_valid_signing_key: bool,
6366
/// Additional data from the CIP509 validation..
6467
pub additional_data: AdditionalData,
6568
}
@@ -71,54 +74,6 @@ pub struct AdditionalData {
7174
pub precomputed_aux: Vec<u8>,
7275
}
7376

74-
/// `UUIDv4` representing in 16 bytes.
75-
#[derive(Debug, PartialEq, Clone, Default)]
76-
pub struct UuidV4([u8; 16]);
77-
78-
impl From<[u8; 16]> for UuidV4 {
79-
fn from(bytes: [u8; 16]) -> Self {
80-
UuidV4(bytes)
81-
}
82-
}
83-
84-
impl TryFrom<Vec<u8>> for UuidV4 {
85-
type Error = &'static str;
86-
87-
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
88-
if vec.len() == 16 {
89-
let mut array = [0u8; 16];
90-
array.copy_from_slice(&vec);
91-
Ok(UuidV4(array))
92-
} else {
93-
Err("Input Vec must be exactly 16 bytes")
94-
}
95-
}
96-
}
97-
98-
/// Transaction input hash representing in 16 bytes.
99-
#[derive(Debug, PartialEq, Clone, Default)]
100-
pub struct TxInputHash([u8; 16]);
101-
102-
impl From<[u8; 16]> for TxInputHash {
103-
fn from(bytes: [u8; 16]) -> Self {
104-
TxInputHash(bytes)
105-
}
106-
}
107-
108-
impl TryFrom<Vec<u8>> for TxInputHash {
109-
type Error = &'static str;
110-
111-
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
112-
if vec.len() == 16 {
113-
let mut array = [0u8; 16];
114-
array.copy_from_slice(&vec);
115-
Ok(TxInputHash(array))
116-
} else {
117-
Err("Input Vec must be exactly 16 bytes")
118-
}
119-
}
120-
}
121-
12277
/// Enum of CIP509 metadatum with its associated unsigned integer value.
12378
#[allow(clippy::module_name_repetitions)]
12479
#[derive(FromRepr, Debug, PartialEq)]
@@ -147,7 +102,7 @@ impl Decode<'_, ()> for Cip509 {
147102
match key {
148103
Cip509IntIdentifier::Purpose => {
149104
cip509_metadatum.purpose =
150-
UuidV4::try_from(decode_bytes(d, "CIP509 purpose")?).map_err(|_| {
105+
Uuid::try_from(decode_bytes(d, "CIP509 purpose")?).map_err(|_| {
151106
decode::Error::message("Invalid data size of Purpose")
152107
})?;
153108
},
@@ -217,32 +172,31 @@ impl Cip509 {
217172
pub fn validate(
218173
&self, txn: &MultiEraTx, validation_report: &mut Vec<String>,
219174
) -> Cip509Validation {
220-
let tx_input_validate =
175+
let is_valid_txn_inputs_hash =
221176
validate_txn_inputs_hash(self, txn, validation_report).unwrap_or(false);
222-
let (aux_validate, precomputed_aux) =
177+
let (is_valid_aux, precomputed_aux) =
223178
validate_aux(txn, validation_report).unwrap_or_default();
224-
let mut stake_key_validate = true;
225-
let mut payment_key_validate = true;
226-
let mut signing_key = true;
227-
// Validate the role 0
179+
let mut is_valid_stake_public_key = true;
180+
let mut is_valid_payment_key = true;
181+
let mut is_valid_signing_key = true;
228182
if let Some(role_set) = &self.x509_chunks.0.role_set {
229183
// Validate only role 0
230184
for role in role_set {
231185
if role.role_number == 0 {
232-
stake_key_validate =
186+
is_valid_stake_public_key =
233187
validate_stake_public_key(self, txn, validation_report).unwrap_or(false);
234-
payment_key_validate =
188+
is_valid_payment_key =
235189
validate_payment_key(txn, role, validation_report).unwrap_or(false);
236-
signing_key = validate_role_singing_key(role, validation_report);
190+
is_valid_signing_key = validate_role_singing_key(role, validation_report);
237191
}
238192
}
239193
}
240194
Cip509Validation {
241-
valid_txn_inputs_hash: tx_input_validate,
242-
valid_aux: aux_validate,
243-
valid_public_key: stake_key_validate,
244-
valid_payment_key: payment_key_validate,
245-
signing_key,
195+
is_valid_txn_inputs_hash,
196+
is_valid_aux,
197+
is_valid_stake_public_key,
198+
is_valid_payment_key,
199+
is_valid_signing_key,
246200
additional_data: AdditionalData { precomputed_aux },
247201
}
248202
}

rust/rbac-registration/src/cardano/cip509/rbac/certs.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ impl Decode<'_, ()> for C509Cert {
100100
#[derive(Debug, PartialEq, Clone)]
101101
pub struct C509CertInMetadatumReference {
102102
/// Transaction output field.
103-
txn_output_field: u8,
103+
pub txn_output_field: u8,
104104
/// Transaction output index.
105-
txn_output_index: u64,
105+
pub txn_output_index: u64,
106106
/// Optional certificate reference.
107-
cert_ref: Option<Vec<u64>>,
107+
pub cert_ref: Option<Vec<u64>>,
108108
}
109109

110110
impl Decode<'_, ()> for C509CertInMetadatumReference {

rust/rbac-registration/src/cardano/cip509/rbac/mod.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use pub_key::SimplePublicKeyType;
1515
use role_data::RoleData;
1616
use strum_macros::FromRepr;
1717

18+
use super::types::cert_key_hash::CertKeyHash;
1819
use crate::utils::decode_helper::{
1920
decode_any, decode_array_len, decode_bytes, decode_helper, decode_map_len,
2021
};
@@ -38,16 +39,6 @@ pub struct Cip509RbacMetadata {
3839
pub purpose_key_data: HashMap<u16, Vec<u8>>,
3940
}
4041

41-
/// Certificate key hash use in revocation list.
42-
#[derive(Debug, PartialEq, Clone, Default)]
43-
pub struct CertKeyHash([u8; 16]);
44-
45-
impl From<[u8; 16]> for CertKeyHash {
46-
fn from(bytes: [u8; 16]) -> Self {
47-
CertKeyHash(bytes)
48-
}
49-
}
50-
5142
/// The first valid purpose key.
5243
const FIRST_PURPOSE_KEY: u16 = 200;
5344
/// The last valid purpose key.

rust/rbac-registration/src/cardano/cip509/rbac/pub_key.rs

+6-38
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Public key type for RBAC metadata
22
3+
use ed25519_dalek::VerifyingKey;
34
use minicbor::{decode, Decode, Decoder};
4-
use pallas::codec::utils::Bytes;
55

66
use super::tag::KeyTag;
77
use crate::utils::decode_helper::{decode_bytes, decode_tag};
@@ -15,42 +15,7 @@ pub enum SimplePublicKeyType {
1515
/// Deleted indicates the key is deleted.
1616
Deleted,
1717
/// Ed25519 public key.
18-
Ed25519(Ed25519PublicKey),
19-
}
20-
21-
/// 32 bytes Ed25519 public key.
22-
#[derive(Debug, PartialEq, Clone, Default, Eq, Hash)]
23-
pub struct Ed25519PublicKey([u8; 32]);
24-
25-
impl From<[u8; 32]> for Ed25519PublicKey {
26-
fn from(bytes: [u8; 32]) -> Self {
27-
Ed25519PublicKey(bytes)
28-
}
29-
}
30-
31-
impl TryFrom<Bytes> for Ed25519PublicKey {
32-
type Error = &'static str;
33-
34-
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
35-
let byte_vec: Vec<u8> = bytes.into();
36-
37-
if byte_vec.len() != 32 {
38-
return Err("Invalid length for Ed25519 public key: expected 32 bytes.");
39-
}
40-
41-
let byte_array: [u8; 32] = byte_vec
42-
.try_into()
43-
.map_err(|_| "Failed to convert Vec<u8> to [u8; 32]")?;
44-
45-
Ok(Ed25519PublicKey::from(byte_array))
46-
}
47-
}
48-
49-
impl From<Ed25519PublicKey> for Bytes {
50-
fn from(val: Ed25519PublicKey) -> Self {
51-
let vec: Vec<u8> = val.0.to_vec();
52-
Bytes::from(vec)
53-
}
18+
Ed25519(VerifyingKey),
5419
}
5520

5621
impl Decode<'_, ()> for SimplePublicKeyType {
@@ -65,7 +30,10 @@ impl Decode<'_, ()> for SimplePublicKeyType {
6530
let mut ed25519 = [0u8; 32];
6631
if bytes.len() == 32 {
6732
ed25519.copy_from_slice(&bytes);
68-
Ok(Self::Ed25519(Ed25519PublicKey(ed25519)))
33+
let pubkey = VerifyingKey::from_bytes(&ed25519).map_err(|e| {
34+
decode::Error::message(format!("Failed to convert Ed25519 public key in SimplePublicKeyType {e}"))
35+
})?;
36+
Ok(Self::Ed25519(pubkey))
6937
} else {
7038
Err(decode::Error::message(format!(
7139
"Invalid length for Ed25519 key, got {}",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Certificate key hash type
2+
3+
/// Certificate key hash use in revocation list.
4+
#[derive(Debug, PartialEq, Clone, Default)]
5+
pub struct CertKeyHash([u8; 16]);
6+
7+
impl From<[u8; 16]> for CertKeyHash {
8+
fn from(bytes: [u8; 16]) -> Self {
9+
CertKeyHash(bytes)
10+
}
11+
}
12+
13+
impl TryFrom<Vec<u8>> for CertKeyHash {
14+
type Error = &'static str;
15+
16+
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
17+
if vec.len() == 16 {
18+
let mut array = [0u8; 16];
19+
array.copy_from_slice(&vec);
20+
Ok(CertKeyHash(array))
21+
} else {
22+
Err("Input Vec must be exactly 16 bytes")
23+
}
24+
}
25+
}
26+
27+
impl From<CertKeyHash> for Vec<u8> {
28+
fn from(val: CertKeyHash) -> Self {
29+
val.0.to_vec()
30+
}
31+
}
32+
33+
impl From<CertKeyHash> for [u8; 16] {
34+
fn from(val: CertKeyHash) -> Self {
35+
val.0
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//! Types use in CIP-509
2+
3+
pub mod cert_key_hash;
4+
pub mod tx_input_hash;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//! Transaction input hash type
2+
3+
/// Transaction input hash representing in 16 bytes.
4+
#[derive(Debug, PartialEq, Clone, Default)]
5+
pub struct TxInputHash([u8; 16]);
6+
7+
impl From<[u8; 16]> for TxInputHash {
8+
fn from(bytes: [u8; 16]) -> Self {
9+
TxInputHash(bytes)
10+
}
11+
}
12+
13+
impl TryFrom<Vec<u8>> for TxInputHash {
14+
type Error = &'static str;
15+
16+
fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
17+
if vec.len() == 16 {
18+
let mut array = [0u8; 16];
19+
array.copy_from_slice(&vec);
20+
Ok(TxInputHash(array))
21+
} else {
22+
Err("Input Vec must be exactly 16 bytes")
23+
}
24+
}
25+
}
26+
27+
impl From<TxInputHash> for Vec<u8> {
28+
fn from(val: TxInputHash) -> Self {
29+
val.0.to_vec()
30+
}
31+
}
32+
33+
impl From<TxInputHash> for [u8; 16] {
34+
fn from(val: TxInputHash) -> Self {
35+
val.0
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
//! Utility functions for CIP-509
22
3-
pub(crate) mod cip19;
3+
pub mod cip19;

rust/rbac-registration/src/cardano/cip509/validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub(crate) fn validate_txn_inputs_hash(
9595
return None;
9696
},
9797
};
98-
Some(TxInputHash(inputs_hash) == cip509.txn_inputs_hash)
98+
Some(TxInputHash::from(inputs_hash) == cip509.txn_inputs_hash)
9999
} else {
100100
validation_report.push(format!("{function_name}, Unsupported transaction era for"));
101101
None

0 commit comments

Comments
 (0)