Skip to content

Commit f89735c

Browse files
dt-iohkminikinLynxLynxx
authored
feat(cat-voices): use simple public key in rbac (#2547)
* feat: make x509 certificate use simple public key * chore: update example * style: formatting * chore: cleanup * chore: reformat --------- Co-authored-by: Oleksandr Prokhorenko <[email protected]> Co-authored-by: Ryszard Schossler <[email protected]>
1 parent 9ec8292 commit f89735c

File tree

7 files changed

+173
-138
lines changed

7 files changed

+173
-138
lines changed

catalyst_voices/packages/internal/catalyst_voices_services/lib/src/registration/registration_transaction_builder.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,7 @@ final class RegistrationTransactionBuilder {
254254

255255
final tbs = X509TBSCertificate(
256256
serialNumber: _randomSerialNumber(),
257-
subjectPublicKey: Bip32Ed25519XPublicKeyFactory.instance.fromBytes(
258-
keyPair.publicKey.bytes,
259-
),
257+
subjectPublicKey: keyPair.publicKey.toEd25519(),
260258
issuer: issuer,
261259
validityNotBefore: DateTime.now().toUtc(),
262260
validityNotAfter: X509TBSCertificate.foreverValid,

catalyst_voices/packages/libs/catalyst_cardano/catalyst_cardano/example/lib/sign_and_submit_rbac_tx.dart

Lines changed: 97 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -8,69 +8,48 @@ final _transactionHash = TransactionHash.fromHex(
88
'4d3f576f26db29139981a69443c2325daa812cc353a31b5a4db794a5bcbb06c2',
99
);
1010

11-
Future<void> _signAndSubmitRbacTx({
12-
required BuildContext context,
13-
required CardanoWalletApi api,
11+
Future<X509Certificate> generateX509Certificate({
12+
required Bip32Ed25519XKeyPair keyPair,
13+
required ShelleyAddress stakeAddress,
1414
}) async {
15-
var result = '';
16-
try {
17-
final changeAddress = await api.getChangeAddress();
18-
final rewardAddresses = await api.getRewardAddresses();
19-
20-
final utxos = await api.getUtxos(
21-
amount: const Balance(
22-
coin: Coin(1000000),
23-
),
24-
);
25-
26-
if (utxos.isEmpty) {
27-
throw Exception('Insufficient balance, please top up your wallet');
28-
}
29-
30-
final x509Envelope = await _buildMetadataEnvelope(
31-
utxos: utxos,
32-
rewardAddress: rewardAddresses.first,
33-
);
34-
35-
final auxiliaryData = AuxiliaryData.fromCbor(
36-
await x509Envelope.toCbor(serializer: (e) => e.toCbor()),
37-
);
38-
39-
final unsignedTx = _buildUnsignedRbacTx(
40-
inputs: utxos,
41-
changeAddress: changeAddress,
42-
rewardAddress: rewardAddresses.first,
43-
auxiliaryData: auxiliaryData,
44-
);
45-
46-
print('unsigned tx: ${hex.encode(cbor.encode(unsignedTx.toCbor()))}');
47-
48-
final witnessSet = await api.signTx(transaction: unsignedTx);
49-
50-
print('Witness set: $witnessSet');
51-
52-
final signedTx = Transaction(
53-
body: unsignedTx.body,
54-
isValid: true,
55-
witnessSet: witnessSet,
56-
auxiliaryData: unsignedTx.auxiliaryData,
57-
);
15+
const maxInt = 4294967296;
5816

59-
print('signed tx: ${hex.encode(cbor.encode(signedTx.toCbor()))}');
17+
/* cSpell:disable */
18+
const issuer = X509DistinguishedName(
19+
countryName: '',
20+
stateOrProvinceName: '',
21+
localityName: '',
22+
organizationName: '',
23+
organizationalUnitName: '',
24+
commonName: '',
25+
);
6026

61-
final txHash = await api.submitTx(transaction: signedTx);
62-
result = 'Tx hash: ${txHash.toHex()}';
63-
} catch (error) {
64-
result = error.toString();
65-
}
27+
final tbs = X509TBSCertificate(
28+
serialNumber: Random().nextInt(maxInt),
29+
subjectPublicKey: keyPair.publicKey.toSerializableEd25519(),
30+
issuer: issuer,
31+
validityNotBefore: DateTime.now().toUtc(),
32+
validityNotAfter: X509TBSCertificate.foreverValid,
33+
subject: issuer,
34+
extensions: X509CertificateExtensions(
35+
subjectAltName: [
36+
const X509String('mydomain.com', tag: X509String.domainNameTag),
37+
const X509String('www.mydomain.com', tag: X509String.domainNameTag),
38+
const X509String('example.com', tag: X509String.domainNameTag),
39+
const X509String('www.example.com', tag: X509String.domainNameTag),
40+
X509String(
41+
'web+cardano://addr/${stakeAddress.toBech32()}',
42+
tag: X509String.uriTag,
43+
),
44+
],
45+
),
46+
);
47+
/* cSpell:enable */
6648

67-
if (context.mounted) {
68-
await _showDialog(
69-
context: context,
70-
title: 'Sign & submit RBAC tx',
71-
message: result,
72-
);
73-
}
49+
return X509Certificate.generateSelfSigned(
50+
tbsCertificate: tbs,
51+
privateKey: keyPair.privateKey,
52+
);
7453
}
7554

7655
Future<X509MetadataEnvelope<RegistrationData>> _buildMetadataEnvelope({
@@ -186,48 +165,69 @@ Transaction _buildUnsignedRbacTx({
186165
);
187166
}
188167

189-
Future<X509Certificate> generateX509Certificate({
190-
required Bip32Ed25519XKeyPair keyPair,
191-
required ShelleyAddress stakeAddress,
168+
Future<void> _signAndSubmitRbacTx({
169+
required BuildContext context,
170+
required CardanoWalletApi api,
192171
}) async {
193-
const maxInt = 4294967296;
172+
var result = '';
173+
try {
174+
final changeAddress = await api.getChangeAddress();
175+
final rewardAddresses = await api.getRewardAddresses();
194176

195-
/* cSpell:disable */
196-
const issuer = X509DistinguishedName(
197-
countryName: '',
198-
stateOrProvinceName: '',
199-
localityName: '',
200-
organizationName: '',
201-
organizationalUnitName: '',
202-
commonName: '',
203-
);
177+
final utxos = await api.getUtxos(
178+
amount: const Balance(
179+
coin: Coin(1000000),
180+
),
181+
);
204182

205-
final tbs = X509TBSCertificate(
206-
serialNumber: Random().nextInt(maxInt),
207-
subjectPublicKey: keyPair.publicKey,
208-
issuer: issuer,
209-
validityNotBefore: DateTime.now().toUtc(),
210-
validityNotAfter: X509TBSCertificate.foreverValid,
211-
subject: issuer,
212-
extensions: X509CertificateExtensions(
213-
subjectAltName: [
214-
const X509String('mydomain.com', tag: X509String.domainNameTag),
215-
const X509String('www.mydomain.com', tag: X509String.domainNameTag),
216-
const X509String('example.com', tag: X509String.domainNameTag),
217-
const X509String('www.example.com', tag: X509String.domainNameTag),
218-
X509String(
219-
'web+cardano://addr/${stakeAddress.toBech32()}',
220-
tag: X509String.uriTag,
221-
),
222-
],
223-
),
224-
);
225-
/* cSpell:enable */
183+
if (utxos.isEmpty) {
184+
throw Exception('Insufficient balance, please top up your wallet');
185+
}
226186

227-
return X509Certificate.generateSelfSigned(
228-
tbsCertificate: tbs,
229-
privateKey: keyPair.privateKey,
230-
);
187+
final x509Envelope = await _buildMetadataEnvelope(
188+
utxos: utxos,
189+
rewardAddress: rewardAddresses.first,
190+
);
191+
192+
final auxiliaryData = AuxiliaryData.fromCbor(
193+
await x509Envelope.toCbor(serializer: (e) => e.toCbor()),
194+
);
195+
196+
final unsignedTx = _buildUnsignedRbacTx(
197+
inputs: utxos,
198+
changeAddress: changeAddress,
199+
rewardAddress: rewardAddresses.first,
200+
auxiliaryData: auxiliaryData,
201+
);
202+
203+
print('unsigned tx: ${hex.encode(cbor.encode(unsignedTx.toCbor()))}');
204+
205+
final witnessSet = await api.signTx(transaction: unsignedTx);
206+
207+
print('Witness set: $witnessSet');
208+
209+
final signedTx = Transaction(
210+
body: unsignedTx.body,
211+
isValid: true,
212+
witnessSet: witnessSet,
213+
auxiliaryData: unsignedTx.auxiliaryData,
214+
);
215+
216+
print('signed tx: ${hex.encode(cbor.encode(signedTx.toCbor()))}');
217+
218+
final txHash = await api.submitTx(transaction: signedTx);
219+
result = 'Tx hash: ${txHash.toHex()}';
220+
} catch (error) {
221+
result = error.toString();
222+
}
223+
224+
if (context.mounted) {
225+
await _showDialog(
226+
context: context,
227+
title: 'Sign & submit RBAC tx',
228+
message: result,
229+
);
230+
}
231231
}
232232

233233
extension on Bip32Ed25519XPublicKey {

catalyst_voices/packages/libs/catalyst_cardano_serialization/lib/src/rbac/x509_certificate.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'dart:typed_data';
33

44
import 'package:asn1lib/asn1lib.dart';
55
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
6-
import 'package:catalyst_key_derivation/catalyst_key_derivation.dart';
6+
import 'package:catalyst_key_derivation/catalyst_key_derivation.dart' hide Ed25519PublicKey;
77
import 'package:equatable/equatable.dart';
88

99
bool _registeredASN1Names = false;
@@ -425,7 +425,7 @@ class X509TBSCertificate with EquatableMixin {
425425
final X509DistinguishedName subject;
426426

427427
/// The public key of the [subject].
428-
final Bip32Ed25519XPublicKey subjectPublicKey;
428+
final Ed25519PublicKey subjectPublicKey;
429429

430430
/// Extra extensions of the certificate.
431431
final X509CertificateExtensions? extensions;
@@ -548,11 +548,11 @@ class X509TBSCertificate with EquatableMixin {
548548
return integer.intValue;
549549
}
550550

551-
static Bip32Ed25519XPublicKey _readSubjectPublicKeyInfo(ASN1Object object) {
551+
static Ed25519PublicKey _readSubjectPublicKeyInfo(ASN1Object object) {
552552
final sequence = object.asSequence;
553553
final string = sequence.elements[1] as ASN1BitString;
554554
final stringBytes = string.contentBytes();
555-
return Bip32Ed25519XPublicKeyFactory.instance.fromBytes(stringBytes);
555+
return Ed25519PublicKey.fromSimpleOrExtendedBytes(stringBytes);
556556
}
557557

558558
static int _readVersion(ASN1Object object) {

0 commit comments

Comments
 (0)