Fix certificate verification#3
Conversation
| #tp_address = "127.0.0.1:8442" | ||
| # Hosted testnet TP | ||
| tp_address = "75.119.150.111:8442" | ||
| tp_authority_public_key = "EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd" No newline at end of file |
There was a problem hiding this comment.
I think we use 3VANfft6ei6jQq1At7d8nmiZzVhBFS4CiQujdgim1ign as a placeholder key everywhere.
There was a problem hiding this comment.
3VANfft6ei6jQq1At7d8nmiZzVhBFS4CiQujdgim1ign is the default value of authority_public_key on the config file.
I thought we wanted tp_authority_public_key to hold a value that's coming from Bitcoin Core logs?
I got this value from:
2024-02-09T16:40:46Z Template Provider authority key: EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd
There was a problem hiding this comment.
It's randomly generated the first time you run the template provider. So it's going to be different for everyone.
There was a problem hiding this comment.
I plan to add support for importing a certificate later, so you'll be able to use an existing authority key. I.e. a pool might want that. I also have to write a tool that lets you generate and sign an arbitrary static key using the authority key.
There was a problem hiding this comment.
ok but we shouldn't really use 3VANfft6ei6jQq1At7d8nmiZzVhBFS4CiQujdgim1ign for tp_authority_public_key, should we?
There was a problem hiding this comment.
question for @Fi3 :
I'm adapting Initiator so that responder_authority_pk is Option<XOnlyPublicKey>
but step_2() returns Result<NoiseCodec, Error>, and I'm not sure how to return a NoiseCodec without a pubkey
There was a problem hiding this comment.
You have Initiator::new(authority_public_key). So you should change the type of initiator.authority_public_key1 to Option<XOnlyPublicKey> and pass an option also to the new function. So that when authority_public_key is Some(authority_public_key) you do the check otherwise you don't.
Footnotes
-
I would call the field name
authority_public_keyratherresponder_authority_pkcauseauthority_public_keyis what we use in the spec, and for this cases stick impl_name = identity(spec_name) can be helpful. ↩
There was a problem hiding this comment.
yeah that's the direction I was going for
but when authority_public_key is None, what do we return for step_2()?
There was a problem hiding this comment.
I still think that adding support for None can be done in a followup PR.
|
This now works for the pool role, but now the Job Declarator client can't connect to the pool, presumably because the pool needs to update the way it signs its certificate. While you're at it, you may want to rename |
|
This did the trick for me: diff --git a/protocols/v2/noise-sv2/src/responder.rs b/protocols/v2/noise-sv2/src/responder.rs
index 15ebe190..f5a3ddcc 100644
--- a/protocols/v2/noise-sv2/src/responder.rs
+++ b/protocols/v2/noise-sv2/src/responder.rs
@@ -27,10 +27,12 @@ pub struct Responder {
h: [u8; 32],
// ephemeral keypair
e: Keypair,
// Static pub keypair
s: Keypair,
+ // Authority pub keypair
+ a: Keypair,
c1: Option<GenericCipher>,
c2: Option<GenericCipher>,
cert_validity: u32,
}
@@ -105,19 +107,20 @@ impl Responder {
} else {
Err(Error::InvalidRawPublicKey)
}
}
- pub fn new(s: Keypair, cert_validity: u32) -> Box<Self> {
+ pub fn new(a: Keypair, cert_validity: u32) -> Box<Self> {
let mut self_ = Self {
handshake_cipher: None,
k: None,
n: 0,
ck: [0; 32],
h: [0; 32],
e: Self::generate_key(),
- s,
+ s: Self::generate_key(),
+ a,
c1: None,
c2: None,
cert_validity,
};
Self::initialize_self(&mut self_);
@@ -268,34 +271,35 @@ impl Responder {
ret[5] = valid_from[3];
ret[6] = not_valid_after[0];
ret[7] = not_valid_after[1];
ret[8] = not_valid_after[2];
ret[9] = not_valid_after[3];
- SignatureNoiseMessage::sign(&mut ret, &self.s);
+ SignatureNoiseMessage::sign(&mut ret, &self.s.x_only_public_key().0, &self.a);
ret
}
fn erase(&mut self) {
if let Some(k) = self.k.as_mut() {
for b in k {
unsafe { ptr::write_volatile(b, 0) };
}
}
for mut b in self.ck {
unsafe { ptr::write_volatile(&mut b, 0) };
}
for mut b in self.h {
unsafe { ptr::write_volatile(&mut b, 0) };
}
if let Some(c1) = self.c1.as_mut() {
c1.erase_k()
}
if let Some(c2) = self.c2.as_mut() {
c2.erase_k()
}
self.e.non_secure_erase();
self.s.non_secure_erase();
+ self.a.non_secure_erase();
}
}
impl Drop for Responder {
fn drop(&mut self) {
diff --git a/protocols/v2/noise-sv2/src/signature_message.rs b/protocols/v2/noise-sv2/src/signature_message.rs
index d58083ba..48bfeace 100644
--- a/protocols/v2/noise-sv2/src/signature_message.rs
+++ b/protocols/v2/noise-sv2/src/signature_message.rs
@@ -42,13 +42,15 @@ impl SignatureNoiseMessage {
secp.verify_schnorr(&s, &m, authority_pk).is_ok()
} else {
false
}
}
- pub fn sign(msg: &mut [u8; 74], kp: &Keypair) {
+ pub fn sign(msg: &mut [u8; 74], static_pk: &XOnlyPublicKey, kp: &Keypair) {
let secp = Secp256k1::signing_only();
- let m = Message::from_hashed_data::<sha256::Hash>(&msg[0..10]);
+ let m = [&msg[0..10], &static_pk.serialize()].concat();
+ let m = Message::from_hashed_data::<sha256::Hash>(&m);
+
let signature = secp.sign_schnorr(&m, kp);
for (i, b) in signature.as_ref().iter().enumerate() {
msg[10 + i] = *b;
}
}
|
|
@jakubtrnka this PR - with my diff above - will break any WIP hardware support (assuming it checks the certificate). So you may want to check if this change is correct (I think it is). |
|
another open question for my end is: so far we are only fixing the pool and JDC roles, but which other roles will also need fixing? |
1d83fa8 to
ee22095
Compare
|
Nice, tested that this works (I rebased your 7 commits on top of of the latest |
As long as all roles use the noise-sv2 responder / initiator they should work. I'm not sure how complete automated test coverage is, so it's probably worth testing different configurations. My testing setup is:
Those all work. I haven't tested a proxy and I haven't tested v2 aware miner firmware. |
7d342fd to
1c42de9
Compare
78ff124 to
ca6d476
Compare
|
I'll work on an update to the Template Provider to make this work since stratum-mining#722 was merged. Right now the Bitcoin Core TP will use the old base58 encoding. stratum-mining#746 is potentially a workaround in the mean time; it you don't set the TP authority key, you can simply merge this without having to wait for me. Of course EllSwift has to be merged first. |
|
I pushed a commit to I got a merge conflict when trying to do that quickly. |
9194e57 to
b6008d4
Compare
|
stratum-mining#737 was just rebased. I was able to resolve the merge conflicts and test. Works! |
|
Here's my rebase: https://github.com/Sjors/stratum/tree/2024/02/cert-fix-rebase |
|
@plebhash can you open a PR against the main repo? |
10acde0 to
84271ab
Compare
Fix releases
Fix releases
Fix cargo toml for bip-32-key-derivation
213d265 to
694e83d
Compare
694e83d to
28df4e1
Compare
|
Maybe close this since it's a duplicate? |
close stratum-mining#717