Commit Graph

586 Commits

Author SHA1 Message Date
Dastan-glitch
a1328cf745 update Cargo.lock 2023-08-07 03:38:20 +03:00
aggstam
41c77f0706 validator:consensus: minor functions rename 2023-08-01 19:51:29 +03:00
parazyd
c045210763 chore: Update crate dependencies. 2023-07-31 08:05:13 +02:00
parazyd
acc9453cfa fud: Fresh impl with routing 2023-07-29 11:46:24 +02:00
aggstam
51910ba346 chore: updated sled-overlay package 2023-07-25 17:23:24 +03:00
aggstam
9ad9685464 darkirc: restored libsqlite3-sys dependency 2023-07-25 12:32:37 +03:00
parazyd
f4a54d21ec sdk: Remove unused sha2 dependency. 2023-07-22 17:59:01 +02:00
parazyd
d34b9cbb03 chore: Update crate dependencies 2023-07-22 13:16:16 +02:00
parazyd
3d5896b89b contract/money: Replace token pedersen commitment with a poseidon hash. 2023-07-22 08:56:04 +02:00
parazyd
a701d40a84 darkirc: Remove unused dependencies. 2023-07-22 08:56:04 +02:00
parazyd
8d07dc2258 chore: Update crate dependencies 2023-07-20 12:23:58 +02:00
aggstam
9f81e693ed darkfid2/rpc: basic tx methods added 2023-07-18 19:00:52 +03:00
aggstam
48057c25b0 darkfid2/rpc: misc and blockchain methods added 2023-07-18 18:03:42 +03:00
aggstam
21970aed0e darkfid2: networking foundation added 2023-07-18 17:04:23 +03:00
parazyd
d7c994b679 chore: Update crate dependencies. 2023-07-13 19:22:32 +02:00
parazyd
c359b02dd7 contract/dao: Rewrite integration test using the test harness. 2023-07-13 19:22:32 +02:00
aggstam
dce1fb929d darkfid2: calculate genesis txs total and use that for genesis block validation 2023-07-12 20:23:31 +03:00
parazyd
9c8e60cd2a tau: Port to crypto_box 0.9 and use chacha20 ciphers. 2023-07-10 15:42:13 +02:00
parazyd
cf307669aa chore: Update crate dependencies. 2023-07-10 15:19:41 +02:00
parazyd
cec104f1a7 chore: Update wasmer to 4.0.0 2023-07-08 20:32:57 +02:00
parazyd
98ef7c834e chore: Update project dependencies. 2023-07-08 20:17:47 +02:00
parazyd
363a6cd998 vanityaddr: Remove indicatif dependency. 2023-07-08 18:01:23 +02:00
parazyd
a654341ea4 Remove some unnecessary dependencies. 2023-07-04 23:52:30 +02:00
parazyd
4ec2bcd815 fixup! Replace bundled-sqlcipher with bundled-sqlcipher-vendored-openssl 2023-07-04 22:00:03 +02:00
aggstam
997f6015cf repo: updated all bins to use new signals handling 2023-07-04 16:21:25 +03:00
aggstam
a63a808992 util/cli/async_daemonize: use log_file to explicitly write to, impl signal handler using async signal hooks 2023-07-04 13:17:40 +03:00
parazyd
6c0b5ea2bb chore: Try building with bundled libsqlite 2023-07-04 12:10:32 +02:00
parazyd
23b8ee1ca2 chore: Update Arti dependency. 2023-07-04 11:58:39 +02:00
parazyd
3546af6c79 lilith: Support versioning of spawned networks. 2023-07-03 17:35:33 +02:00
aggstam
0d00179abd darkfid2: further extend tests foundation | repo: fmt 2023-07-03 16:50:44 +03:00
aggstam
a3d04e0b46 bin/darkfid2: set foundation for implementing new darkfid 2023-07-03 14:35:56 +03:00
aggstam
b4d28da805 ircd: dropped 2023-06-29 15:29:25 +03:00
aggstam
611bd9734b Missing rustqlite bundled-sqlcipher feature added 2023-06-29 15:06:47 +03:00
parazyd
648e0de0ed net/hosts: Verify pluggable transport address correctness. 2023-06-29 13:13:16 +02:00
parazyd
55ee919906 net: Perform full p2p code cleanup and improve certain pieces.
Notable changes:

* Rewritten transport protocols into Dialer and Listener (Nym is TODO)

  This simplifies using the transports a lot, as can be seen for example
  in src/rpc, and generally around the p2p library. It also defines features
  for each transport (all of which are enabled by default). We drop the
  socks client for Tor and Nym and use first-class support with the Arti Tor
  library, and nym-sphinx/nym-websockets (to be used with nym-client).

* Outbound session healing

  The outbound session will now poll and try to fill all the requested
  slots more efficiently, and if needed, will activate peer discovery to
  find more peers if we can't connect to any known ones. Also if we're
  unable to connect to any, we shall drop them from our set.

  Additionally, transport mixing is enabled by default, so when we're
  allowing transport mixing, and we use Tor, we will also be able to connect
  to other transports that Tor can connect to (e.g. tcp://).

* Unix socket transport dropped

  We haven't been using this, and it seems we're not going down this path,
  so the code has been obsoleted and removed.

* TLS session verification

  We fully verify server and client TLS certificates upon connection so
  we're able to perform TLS1.3 with forward secrecy.

* lilith pruning

  lilith now periodically prunes known peers from its sets if it's unable
  to connect to them.
2023-06-29 13:13:15 +02:00
parazyd
ee62ec7bd2 net/tls: Implement server certificate verification.
The system works such that the server creates a new TLS certificate
from an ed25519 keypair. The public key is also encoded with base32
and placed into the altName of the certificate so it can easily be
used with other things.

The server certificate verification will parse the certificate, then
look for the altName extension, attempt to parse the public key from
there, make sure that it is the same as the actual certificate pubkey,
and finally it will verify the certificate signature.

We also remove "pem" dependencies and use binary DER encoding where
applicable.

This is a breaking change for existing deployments.

diff --git a/Cargo.lock b/Cargo.lock
index ff543ddedd..893bfa2380 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -177,6 +177,45 @@ version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c"

+[[package]]
+name = "asn1-rs"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0"
+dependencies = [
+ "asn1-rs-derive",
+ "asn1-rs-impl",
+ "displaydoc",
+ "nom",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror",
+ "time 0.3.22",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "synstructure",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "async-attributes"
 version = "1.1.2"
@@ -1332,6 +1371,7 @@ dependencies = [
  "wasmer",
  "wasmer-compiler-singlepass",
  "wasmer-middlewares",
+ "x509-parser",
 ]

 [[package]]
@@ -1735,6 +1775,20 @@ dependencies = [
  "url",
 ]

+[[package]]
+name = "der-parser"
+version = "8.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e"
+dependencies = [
+ "asn1-rs",
+ "displaydoc",
+ "nom",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
 [[package]]
 name = "derivative"
 version = "2.2.0"
@@ -1829,6 +1883,17 @@ dependencies = [
  "winapi",
 ]

+[[package]]
+name = "displaydoc"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.18",
+]
+
 [[package]]
 name = "dlib"
 version = "0.5.2"
@@ -3372,6 +3437,15 @@ dependencies = [
  "cc",
 ]

+[[package]]
+name = "oid-registry"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff"
+dependencies = [
+ "asn1-rs",
+]
+
 [[package]]
 name = "once_cell"
 version = "1.18.0"
@@ -4097,6 +4171,15 @@ dependencies = [
  "semver 0.11.0",
 ]

+[[package]]
+name = "rusticata-macros"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
+dependencies = [
+ "nom",
+]
+
 [[package]]
 name = "rustix"
 version = "0.37.20"
@@ -4734,6 +4817,18 @@ dependencies = [
  "unicode-ident",
 ]

+[[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "unicode-xid",
+]
+
 [[package]]
 name = "tabbycat"
 version = "0.1.2"
@@ -5163,6 +5258,12 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"

+[[package]]
+name = "unicode-xid"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+
 [[package]]
 name = "unicode_categories"
 version = "0.1.1"
@@ -5877,6 +5978,24 @@ dependencies = [
  "zeroize",
 ]

+[[package]]
+name = "x509-parser"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab0c2f54ae1d92f4fcb99c0b7ccf0b1e3451cbd395e5f115ccbdbcb18d4f634"
+dependencies = [
+ "asn1-rs",
+ "data-encoding",
+ "der-parser",
+ "lazy_static",
+ "nom",
+ "oid-registry",
+ "ring",
+ "rusticata-macros",
+ "thiserror",
+ "time 0.3.22",
+]
+
 [[package]]
 name = "xsalsa20poly1305"
 version = "0.9.1"
diff --git a/Cargo.toml b/Cargo.toml
index 1aaf3c1641..4fb39d2603 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -77,9 +77,10 @@ ipnet = {version = "2.7.2", optional = true}
 socket2 = {version = "0.5.3", optional = true, features = ["all"]}

 # TLS cert utilities
-ed25519-compact = {version = "2.0.4", features = ["pem"], optional = true}
-rcgen = {version = "0.10.0", features = ["pem"], optional = true}
+ed25519-compact = {version = "2.0.4", optional = true}
+rcgen = {version = "0.10.0", optional = true}
 rustls-pemfile = {version = "1.0.2", optional = true}
+x509-parser = {version = "0.15.0", features = ["validate", "verify"], optional = true}

 # Encoding
 bs58 = {version = "0.5.0", optional = true}
@@ -213,6 +214,7 @@ net = [
     "rand",
     "rcgen",
     "rustls-pemfile",
+    "x509-parser",
     "serde",
     "serde_json",
     "socket2",
diff --git a/src/net/transport/upgrade_tls.rs b/src/net/transport/upgrade_tls.rs
index 570d5d3b01..8674c25938 100644
--- a/src/net/transport/upgrade_tls.rs
+++ b/src/net/transport/upgrade_tls.rs
@@ -31,9 +31,16 @@ use futures_rustls::{
     },
     TlsAcceptor, TlsConnector, TlsStream,
 };
+use log::error;
 use rustls_pemfile::pkcs8_private_keys;
+use x509_parser::{
+    extensions::{GeneralName, ParsedExtension},
+    parse_x509_certificate,
+    prelude::FromDer,
+    x509::SubjectPublicKeyInfo,
+};

-use crate::Result;
+use crate::{util::encoding::base32, Result};

 const CIPHER_SUITE: &str = "TLS13_CHACHA20_POLY1305_SHA256";

@@ -53,14 +60,82 @@ struct ServerCertificateVerifier;
 impl ServerCertVerifier for ServerCertificateVerifier {
     fn verify_server_cert(
         &self,
-        _end_entity: &Certificate,
+        end_entity: &Certificate,
         _intermediates: &[Certificate],
         _server_name: &ServerName,
         _scrs: &mut dyn Iterator<Item = &[u8]>,
         _ocsp_response: &[u8],
         _now: SystemTime,
     ) -> std::result::Result<ServerCertVerified, rustls::Error> {
-        // TODO: upsycle
+        // Parse the actual end_entity certificate
+        let Ok((_, cert)) = parse_x509_certificate(&end_entity.0) else {
+            error!(target: "net::tls", "Failed parsing server TLS certificate");
+            return Err(rustls::CertificateError::BadEncoding.into())
+        };
+
+        // We keep a public key in the altName, so we need to grab it.
+        // We compare that the actual public key of the certificate is
+        // the same as that one, and we then verify the signature of the
+        // provided certificate.
+        #[rustfmt::skip]
+        let oid = x509_parser::oid_registry::asn1_rs::oid!(2.5.29.17);
+        let Ok(Some(extension)) = cert.get_extension_unique(&oid) else {
+            error!(target: "net::tls", "Could not find OID extension for subjectAltName");
+            return Err(rustls::CertificateError::BadSignature.into())
+        };
+
+        // Parse the actual extension
+        // (ノಠ益ಠ)ノ彡┻━┻
+        let pubkey_bytes = match extension.parsed_extension() {
+            ParsedExtension::SubjectAlternativeName(altname) => {
+                if altname.general_names.len() != 1 {
+                    return Err(rustls::CertificateError::BadEncoding.into())
+                }
+
+                match altname.general_names[0] {
+                    GeneralName::DNSName(a) => base32::decode(a),
+                    _ => return Err(rustls::CertificateError::BadEncoding.into()),
+                }
+            }
+            _ => return Err(rustls::CertificateError::BadEncoding.into()),
+        };
+        let Some(pubkey_bytes) = pubkey_bytes else {
+            error!(target: "net::tls", "Could not decode server pubkey from altName");
+            return Err(rustls::CertificateError::BadSignature.into())
+        };
+        if pubkey_bytes.len() != 32 {
+            error!(target: "net::tls", "Could not decode server pubkey from altName");
+            return Err(rustls::CertificateError::BadSignature.into())
+        }
+        let pubkey_der = ed25519_compact::PublicKey::new(pubkey_bytes.try_into().unwrap()).to_der();
+        let Ok((_, parsed_pubkey)) = SubjectPublicKeyInfo::from_der(&pubkey_der) else {
+            error!(target: "net::tls", "Could not decode server pubkey from altName");
+            return Err(rustls::CertificateError::BadSignature.into())
+        };
+
+        let Ok(parsed_name_pubkey) = parsed_pubkey.parsed() else {
+            error!(target: "net::tls", "Could not parse server altName pubkey");
+            return Err(rustls::CertificateError::BadEncoding.into())
+        };
+
+        let Ok(parsed_cert_pubkey) = cert.public_key().parsed() else {
+            error!(target: "net::tls", "Could not parse server certificate pubkey");
+            return Err(rustls::CertificateError::BadEncoding.into())
+        };
+
+        if parsed_name_pubkey != parsed_cert_pubkey {
+            error!(target: "net::tls", "Server altName pubkey does not match certificate key");
+            return Err(rustls::CertificateError::BadSignature.into())
+        }
+
+        // Finally verify the signature. By passing `None`, it should use
+        // the certificate pubkey, but we also verified that it matches
+        // the one in altNames above.
+        if let Err(e) = cert.verify_signature(None) {
+            error!(target: "net::tls", "Failed verifying server certificate signature: {}", e);
+            return Err(rustls::CertificateError::BadSignature.into())
+        }
+
         Ok(ServerCertVerified::assertion())
     }
 }
@@ -92,11 +167,13 @@ pub struct TlsUpgrade {
 impl TlsUpgrade {
     pub fn new() -> Self {
         // On each instantiation, generate a new keypair and certificate.
-        let keypair_pem = ed25519_compact::KeyPair::generate().to_pem();
+        let keypair = ed25519_compact::KeyPair::generate();
+        let keypair_pem = keypair.to_pem();
         let secret_key = pkcs8_private_keys(&mut keypair_pem.as_bytes()).unwrap();
         let secret_key = rustls::PrivateKey(secret_key[0].clone());

-        let altnames = vec![String::from("dark.fi")];
+        let altname = base32::encode(false, keypair.pk.as_slice()).to_ascii_lowercase();
+        let altnames = vec![altname];
         let mut cert_params = rcgen::CertificateParams::new(altnames);
         cert_params.alg = &rcgen::PKCS_ED25519;
         cert_params.key_pair = Some(rcgen::KeyPair::from_pem(&keypair_pem).unwrap());
2023-06-29 13:06:54 +02:00
aggstam
f37e05e0ec validator/blockchain: added rest overlays needed for validations 2023-06-27 19:23:45 +03:00
aggstam
6ffa0974d5 src/validator: added verify_txs() and receive_slot_checkpoint()
sled-overlay was also updated to v0.0.5
2023-06-23 14:07:33 +03:00
parazyd
4824c84cb5 sdk-py: Minor cleanups 2023-06-15 04:32:16 +00:00
aggstam
410ab42b54 contract/consensus: migrated tests to new contract/test-harness 2023-06-14 19:02:28 +03:00
parazyd
a2ddbcd4f8 contract: WIP implementation of generic test harness for native contracts. 2023-06-14 02:32:56 +02:00
parazyd
b36861fa1d contract/dao: Refactor contract code to match other native contracts. 2023-06-13 14:23:33 +02:00
parazyd
48ce9fd7c5 chore: Update crate dependencies 2023-06-12 14:31:20 +02:00
parazyd
402d0f3874 contract/money: Replace incrementalmerkletree with bridgetree crate. 2023-06-12 14:31:19 +02:00
parazyd
bfc99c79ea chore: Update crate dependencies. 2023-06-06 14:06:36 +02:00
parazyd
88865e2663 drk: Replace "play" with "rodio".
Fun police go away.

This removes the deps on pkgconfig and libmpg123, and should ease the
build process for non GNU/Linux operating systems.
2023-06-06 14:06:36 +02:00
Dastan-glitch
9a2ed787b4 bin/tau: organise deps 2023-06-02 04:45:37 +03:00
parazyd
d59d3cd21a contract/deployooor: Initial impl of non-native smart contract deployment.
This supports (Re)Deployment of smart contracts, and additionally making
them immutable after they have been deployed.
2023-05-30 00:29:13 +02:00
parazyd
7364fdd15e tx: Enable parallelism when hashing transactions with blake3.
txs are usually >128KiB so this could be beneficial.
2023-05-26 09:46:04 +02:00
parazyd
6cddfac05f Replace num_cpus crate with stdlib alternative. 2023-05-19 09:59:55 +02:00