Skip to content

Commit a5c326d

Browse files
authored
Merge pull request #1407 from EYBlockchain/westlad/x509-add-real-certs
Westlad/x509 add real certs
2 parents 5b21f3f + f40a6aa commit a5c326d

File tree

62 files changed

+4603
-230
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+4603
-230
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ node_modules/*
22
**/node_modules/*
33
**/migrations/*
44
**/doc/*
5+
mumbai/
56
cli/build/*
67
wallet/cli/*
78
mumbai/

.github/workflows/on-pull-request-master.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ jobs:
714714
adversary-test:
715715
env:
716716
CONFIRMATIONS: 1
717+
NF_SERVICES_TO_START: blockchain,client,deployer,mongodb,optimist,rabbitmq,worker,lazy-optimist,bad-client
717718
runs-on: ubuntu-20.04
718719
steps:
719720
- uses: actions/checkout@v3
@@ -965,7 +966,7 @@ jobs:
965966
curl -i http://localhost:8092/healthcheck
966967
attempt_limit: 10
967968
attempt_delay: 30000
968-
969+
969970
- name: 'Check challenger liveliness'
970971
uses: Wandalen/wretry.action@v1.0.36
971972
with:

bin/polygonpos-deployment.env

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#! /bin/bash
2+
set -o allexport
3+
BLOCKCHAIN_URL="$2"
4+
ETH_NETWORK=polygonPos
5+
ETH_PRIVATE_KEY="$1"
6+
MULTISIG_APPROVERS='0x0000000000000000000000000000000000000001,0x0000000000000000000000000000000000000002,0x0000000000000000000000000000000000000003,0x0000000000000000000000000000000000000004'
7+
WHITELISTING=enable
8+
NF_SERVICES_TO_START='deployer,worker'
9+
DEPLOY_MOCK_TOKENS=false
10+
ENVIRONMENT=mumbai
11+
FEE_L2_TOKEN_ID=WMATIC
12+
DEPLOY_MOCKED_SANCTIONS_CONTRACT=true
13+
GAS_PRICE=500000000000
14+
RESTRICT_TOKENS=disable
15+
set +o allexport

cli/lib/nf3.mjs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import axios from 'axios';
66
import Queue from 'queue';
77
import Web3 from 'web3';
88
import WebSocket from 'ws';
9-
import crypto from 'crypto';
109
import ReconnectingWebSocket from 'reconnecting-websocket';
1110
import EventEmitter from 'events';
1211
import logger from '@polygon-nightfall/common-files/utils/logger.mjs';
@@ -1642,29 +1641,23 @@ class Nf3 {
16421641
/**
16431642
Validates an X509 (RSA) certificate
16441643
*/
1645-
async validateCertificate(certificate, ethereumAddress, derPrivateKey, oidGroup = 0) {
1646-
// sign the ethereum address
1647-
let ethereumAddressSignature = null;
1648-
if (derPrivateKey) {
1649-
const privateKey = crypto.createPrivateKey({
1650-
key: derPrivateKey,
1651-
format: 'der',
1652-
type: 'pkcs1',
1653-
});
1654-
ethereumAddressSignature = crypto.sign(
1655-
'sha256',
1656-
Buffer.from(ethereumAddress.toLowerCase().slice(2), 'hex'),
1657-
{
1658-
key: privateKey,
1659-
padding: crypto.constants.RSA_PKCS1_PADDING,
1660-
},
1661-
);
1662-
}
1644+
async validateCertificate(
1645+
certificate,
1646+
ethereumAddressSignature,
1647+
isEndUser,
1648+
checkOnly,
1649+
oidGroup = 0,
1650+
address,
1651+
) {
16631652
// now validate the cert
1653+
if (!address) address = '0x0000000000000000000000000000000000000000';
16641654
const res = await axios.post(`${this.clientBaseUrl}/x509/validate`, {
16651655
certificate,
16661656
ethereumAddressSignature,
1657+
isEndUser,
1658+
checkOnly,
16671659
oidGroup,
1660+
address,
16681661
});
16691662
const txDataToSign = res.data;
16701663
return this.submitTransaction(txDataToSign, this.x509ContractAddress);

config/default.js

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,24 @@ function configureAWSBucket() {
88
function getDefaultX509Params() {
99
return {
1010
RSA_TRUST_ROOTS: [
11+
// test root
1112
{
1213
modulus:
1314
'0x00c6cdaeb44c7b8fe697a3b8a269799176078ae3cb065010f55a1f1a839ff203b1e785d6782eb9c04e0e1cf63ec7ef21c6d3201c818647b8cea476112463caa8339f03e678212f0214c4a50de21cabc8001ef269eef4930fcd1dd2911ba40d505fcee5508bd91a79aadc70cc33c77be14908b1c32f880a8bb8e2d863838cfa6bd444c47dd30f78650caf1dd947adcf48b427536d294240d40335eaee5db31399b04b3893936cc41c04602b713603526a1e003112bf213e6f5a99830fa821783340c46597e481e1ee4c0c6b3aca32628b70886a396d737537bcfae5ba51dfd6add1728aa6bde5aeb8c27289fb8e911569a41c3e3f48b9b2671c673faac7f085a195',
1415
exponent: 65537,
15-
authorityKeyIdentifier: `0x${'ef355558d6fdee0d5d02a22d078e057b74644e5f'.padStart(64, '0')}`,
16+
authorityKeyIdentifier: '0xef355558d6fdee0d5d02a22d078e057b74644e5f',
17+
},
18+
// entrust/digicert mock root
19+
{
20+
modulus:
21+
'0x00ba84b672db9e0c6be299e93001a776ea32b895411ac9da614e5872cffef68279bf7361060aa527d8b35fd3454e1c72d64e32f2728a0ff78319d06a808000451eb0c7e79abf1257271ca3682f0a87bd6a6b0e5e65f31c77d5d4858d7021b4b332e78ba2d5863902b1b8d247cee4c949c43ba7defb547d57bef0e86ec279b23a0b55e250981632135c2f7856c1c294b3f25ae4279a9f24d7c6ecd09b2582e3ccc2c445c58c977a066b2a119fa90a6e483b6fdbd4111942f78f07bff5535f9c3ef4172ce669ac4e324c6277eab7e8e5bb34bc198bae9c51e7b77eb553b13322e56dcf703c1afae29b67b683f48da5af624c4de058ac64341203f8b68d946324a471',
22+
exponent: 65537,
23+
authorityKeyIdentifier: '0x6a72267ad01eef7de73b6951d46c8d9f901266ab',
1624
},
1725
],
1826
// the certificatePoliciesOIDs and the extendedKeyUseageOIDS should contain the full tlv encoding (not just the value)
1927
certificatePoliciesOIDs: [
20-
// made up
28+
// test
2129
[
2230
'0x06032a0304000000000000000000000000000000000000000000000000000000',
2331
'0x06032d0607000000000000000000000000000000000000000000000000000000',
@@ -31,7 +39,7 @@ function getDefaultX509Params() {
3139
['0x060a6086480186fa6c0a01060000000000000000000000000000000000000000'],
3240
],
3341
extendedKeyUsageOIDs: [
34-
// made up
42+
// test
3543
[
3644
'0x06082b0601050507030300000000000000000000000000000000000000000000',
3745
'0x06082b0601050507030400000000000000000000000000000000000000000000',
@@ -48,6 +56,68 @@ function getDefaultX509Params() {
4856
};
4957
}
5058

59+
function getLiveX509Params() {
60+
return {
61+
RSA_TRUST_ROOTS: [
62+
// Entrust G2 root
63+
{
64+
modulus:
65+
'0x00ba84b672db9e0c6be299e93001a776ea32b895411ac9da614e5872cffef68279bf7361060aa527d8b35fd3454e1c72d64e32f2728a0ff78319d06a808000451eb0c7e79abf1257271ca3682f0a87bd6a6b0e5e65f31c77d5d4858d7021b4b332e78ba2d5863902b1b8d247cee4c949c43ba7defb547d57bef0e86ec279b23a0b55e250981632135c2f7856c1c294b3f25ae4279a9f24d7c6ecd09b2582e3ccc2c445c58c977a066b2a119fa90a6e483b6fdbd4111942f78f07bff5535f9c3ef4172ce669ac4e324c6277eab7e8e5bb34bc198bae9c51e7b77eb553b13322e56dcf703c1afae29b67b683f48da5af624c4de058ac64341203f8b68d946324a471',
66+
exponent: 65537,
67+
authorityKeyIdentifier: '0x6a72267ad01eef7de73b6951d46c8d9f901266ab',
68+
},
69+
// Entrust 2048 root
70+
{
71+
modulus:
72+
'0x00ad4d4ba91286b2eaa320071516642a2b4bd1bf0b4a4d8eed8076a567b77840c07342c868c0db532bdd5eb8769835938b1a9d7c133a0e1f5bb71ecfe524141eb181a98d7db8cc6b4b03f1020cdcaba54024007f7494a19d0829b3880bf587779d55cde4c37ed76a64ab851486955b9732506f3dc8ba660ce3fcbdb849c176894919fdc0a8bd89a3672fc69fbc711960b82de92cc99076667b94e2af78d665535d3cd69cb2cf2903f92fa450b2d448ce0532558afdb2644c0ee4980775db7fdfb9085560853029f97b48a46986e3353f1e865d7a7a15bdef008e1522541700902693bc0e496891bff847d39d9542c10e4ddf6f26cfc3182162664370d6d5c007e1',
73+
exponent: 65537,
74+
authorityKeyIdentifier: '0x55e481d11180bed889b908a331f9a1240916b970',
75+
},
76+
// EY 4096 root
77+
{
78+
modulus:
79+
'0x00f2d3e67057da14c9245d2dbacb52dd8de93f5d1a7c2ebc523cd22681b3fa098f21c3a3662de98fc45f6962958e37bc603f9805e2a5de300fc604ff6633facd705ef1787eeac66a69c32fa932b56f2d26be758bcfe5451f80e799a6ed5ed704dadf2481e3998069f2c1dc207d8f9828cd24a85f31e7162ed56c0797e82dec8e8341b6cd3a7aac0b03ca1b9fd8a1e370fe8bc5c26e30d9f790521f829d8946dd4001ca295d83cc315b31083156ad9df834be615a633611d949e4aa7041be5ae81d42b3cf8306860886bf9e0f274012fd149a25c712f880637ff33a9aadcb637accce4f85241c46675aca8d07660c03576d294b7f09997139e26a9f9cb00ce652a403e3509b5ab24d7d950537d8cd652a716678d5c78c961ba6dbd892104b891e1dec68a472055d2e5d525ad6005e60fdd0065d3062e62d720320b9c05e7a16dde3bbb898d2c45d1266b37a91bcde0f4159df56fd3aff795f8e77f63b68252735e788923f50f11592e07e7a5e8b5c220d7249d1874fcdcfd1a7bd3ea52d0a5fb9545a6398dd21e966c05dc269e4dbe5e95b0935361cef525403727d02f13a7701c8f3b3e69806b09b19912bd58e8cb9eb0a0274ebe682f94cb2f3de97e3e3b79161ab05a1ab6bfc3807760102a27e8a38a2dddcfbc2aad789a4f60cf37bb473b213c6203a82982a7478964fccfa662bf1dbf44b3ef8bbf2f38c942e972815c1424b',
80+
exponent: 65537,
81+
authorityKeyIdentifier: '0x148e058f14da7f94e7b0e5dd232885c4dbc9f722',
82+
},
83+
{
84+
// DigiCert High Assurance EV Root CA
85+
modulus:
86+
'0x00c6cce573e6fbd4bbe52d2d32a6dfe5813fc9cd2549b6712ac3d5943467a20a1cb05f69a640b1c4b7b28fd098a4a941593ad3dc94d63cdb7438a44acc4d2582f74aa5531238eef3496d71917e63b6aba65fc3a484f84f6251bef8c5ecdb3892e306e508910cc4284155fbcb5a89157e71e835bf4d72093dbe3a38505b77311b8db3c724459aa7ac6d00145a04b7ba13eb510a984141224e656187814150a6795c89de194a57d52ee65d1c532c7e98cd1a0616a46873d03404135ca171d35a7c55db5e64e13787305604e511b4298012f1793988a202117c2766b788b778f2ca0aa838ab0a64c2bf665d9584c1a1251e875d1a500b2012cc41bb6e0b5138b84bcb',
87+
exponent: 65537,
88+
authorityKeyIdentifier: '0xb13ec36903f8bf4701d498261a0802ef63642bc3',
89+
},
90+
],
91+
// the certificatePoliciesOIDs and the extendedKeyUseageOIDS should contain the full tlv encoding (not just the value)
92+
certificatePoliciesOIDs: [
93+
// Entrust EV code signer (OID Group 0)
94+
[
95+
'0x060a6086480186fa6c0a01020000000000000000000000000000000000000000',
96+
'0x060567810c010300000000000000000000000000000000000000000000000000',
97+
],
98+
// Entrust EV Document Signer (OID Group 1)
99+
['0x060a6086480186fa6c0a01060000000000000000000000000000000000000000'],
100+
// EY end user
101+
['0x060a2b060104018f752a01020000000000000000000000000000000000000000'],
102+
// Digicert EV code signer
103+
['0x060567810c010300000000000000000000000000000000000000000000000000'],
104+
],
105+
extendedKeyUsageOIDs: [
106+
// Entrust EV code signer (OID Group 0)
107+
['0x06082b0601050507030300000000000000000000000000000000000000000000'],
108+
// Entrust EV Document Signer (OID Group 1)
109+
[
110+
'0x06096086480186fa6b280b000000000000000000000000000000000000000000',
111+
'0x060a2b0601040182370a030c0000000000000000000000000000000000000000',
112+
],
113+
// EY end user
114+
['0x060a2b060104018f752a01010000000000000000000000000000000000000000'],
115+
// Digicert EV code signer (code siging OID)
116+
['0x06082b0601050507030300000000000000000000000000000000000000000000'],
117+
],
118+
};
119+
}
120+
51121
module.exports = {
52122
COMMITMENTS_DB: process.env.COMMITMENTS_DB || 'nightfall_commitments',
53123
OPTIMIST_DB: process.env.OPTIMIST_DB || 'optimist_data',
@@ -227,6 +297,29 @@ module.exports = {
227297
PROPOSER_KEY: process.env.PROPOSER_KEY,
228298
CHALLENGER_KEY: process.env.CHALLENGER_KEY,
229299
},
300+
polygonPos: {
301+
name: 'polygonPos',
302+
chainId: 137,
303+
clientApiUrl: process.env.CLIENT_HOST
304+
? `http://${process.env.CLIENT_HOST}:${process.env.CLIENT_PORT}`
305+
: 'http://localhost:8080',
306+
optimistApiUrl: process.env.OPTIMIST_HOST
307+
? `http://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_PORT}`
308+
: 'http://localhost:8081',
309+
optimistWsUrl: process.env.OPTIMIST_HOST
310+
? `ws://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_WS_PORT}`
311+
: 'ws://localhost:8082',
312+
proposerBaseUrl: process.env.PROPOSER_HOST
313+
? `http://${process.env.PROPOSER_HOST}:${process.env.PROPOSER_PORT}`
314+
: 'http://localhost:8092',
315+
adversarialOptimistApiUrl: 'http://localhost:8088',
316+
adversarialOptimistWsUrl: 'ws://localhost:8089',
317+
adversarialClientApiUrl: 'http://localhost:8093',
318+
adversarialClientWsUrl: 'ws://localhost:8094',
319+
web3WsUrl: process.env.BLOCKCHAIN_URL,
320+
PROPOSER_KEY: process.env.PROPOSER_KEY,
321+
CHALLENGER_KEY: process.env.CHALLENGER_KEY,
322+
},
230323
localhost: {
231324
name: 'Localhost',
232325
chainId: 1337,
@@ -403,6 +496,7 @@ module.exports = {
403496
},
404497
},
405498
RESTRICTIONS: {
499+
restrict: !(process.env.RESTRICT_TOKENS === 'disable'),
406500
signingKeys: {
407501
bootProposerKey:
408502
process.env.BOOT_PROPOSER_KEY ||
@@ -545,6 +639,18 @@ module.exports = {
545639
amount: process.env.MATIC_RESTRICT || '1000000000000000000000',
546640
},
547641
],
642+
polygonPos: [
643+
{
644+
name: 'USDC',
645+
address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174',
646+
amount: process.env.USDC_RESTRICT || -1,
647+
},
648+
{
649+
name: 'WMATIC',
650+
address: '0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270',
651+
amount: process.env.MATIC_RESTRICT || -1,
652+
},
653+
],
548654
localhost: [
549655
{
550656
name: 'WETH',
@@ -593,6 +699,7 @@ module.exports = {
593699
mumbai: getDefaultX509Params(),
594700
mainnet: getDefaultX509Params(),
595701
localhost: getDefaultX509Params(),
702+
polygonPos: getLiveX509Params(),
596703
},
597704

598705
// for Browser use

doc/adding_certificates.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ You will need to do some editing to turn the key modulus and Subject Key Identif
8787

8888
These can then be added to the Smart contract using the setter:
8989

90-
```
90+
```sol
9191
function setTrustedPublicKey(
9292
RSAPublicKey calldata trustedPublicKey,
9393
bytes32 authorityKeyIdentifier) external onlyOwner;
@@ -120,9 +120,11 @@ The encoding of OIDs is a little tricky but there is a good utility [here](https
120120
```sh
121121
2.16.840.1.114412.3.21.2
122122
```
123+
123124
becomes
125+
124126
```sh
125127
0x060a6086480186fd6c0315020000000000000000000000000000000000000000
126128
```
127129

128-
This is in the correct form to add to the contract.
130+
This is in the correct form to add to the contract.

doc/random-beacon.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# How the Random Beacon value was generated
2+
3+
For the MPC Phase 2 setup, we use a random beacon to finalise the contributions. This was done by posting the number of a future Ethereum mainnet block into the data field of a transaction, and then using the blockhash of the future block as the random beacon when the block came into being.
4+
5+
The transaction recording the posting of the blocknumber was [0x26c0872cd302b5eccd6e0e7451a5a608fdba82c9091238629b435130de3e3844](https://etherscan.io/tx/0x26c0872cd302b5eccd6e0e7451a5a608fdba82c9091238629b435130de3e3844) in block 16776388 and the future block number was 16776480 (0xfffd20).
6+
7+
The hash of the future block was: [0x1e0c4ac8bb3127e12c05b172c2498f5e6932bf4174b8d73e7f826d078bbe5295](https://etherscan.io/block/16776480)

nightfall-client/src/routes/x509.mjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@ const router = express.Router();
1313
the certificate. We might want to do this for an intermediate certificate for example.
1414
*/
1515
router.post('/validate', async (req, res, next) => {
16-
const { certificate, ethereumAddressSignature, oidGroup } = req.body;
16+
const { certificate, ethereumAddressSignature, isEndUser, checkOnly, oidGroup, address } =
17+
req.body;
1718
if (!certificate) next(new Error('Certificate was null or undefined'));
1819
if (!certificate.type === 'Buffer') next(new Error('Certificate is not a buffer'));
1920
try {
2021
const txDataToSign = await validateCertificate(
2122
Buffer.from(certificate.data),
2223
ethereumAddressSignature ? Buffer.from(ethereumAddressSignature) : null,
24+
isEndUser,
25+
checkOnly,
2326
oidGroup,
27+
address,
2428
);
2529
res.json(txDataToSign);
2630
} catch (err) {

nightfall-client/src/services/x509.mjs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ import { waitForContract } from '@polygon-nightfall/common-files/utils/contract.
77

88
const { X509_CONTRACT_NAME } = constants;
99

10-
async function validateCertificate(certificate, ethereumAddressSignature, oidGroup) {
10+
async function validateCertificate(
11+
certificate,
12+
ethereumAddressSignature,
13+
isEndUser,
14+
checkOnly,
15+
oidGroup,
16+
address,
17+
) {
1118
const x509ContractInstance = await waitForContract(X509_CONTRACT_NAME);
1219
const numberOfTlvs = await x509ContractInstance.methods
1320
.computeNumberOfTlvs(certificate, 0)
@@ -17,8 +24,10 @@ async function validateCertificate(certificate, ethereumAddressSignature, oidGro
1724
certificate,
1825
numberOfTlvs,
1926
ethereumAddressSignature || 0,
20-
!!ethereumAddressSignature,
27+
isEndUser,
28+
checkOnly,
2129
oidGroup,
30+
address,
2231
)
2332
.encodeABI();
2433
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: CC0-1.0
2+
3+
pragma solidity ^0.8.0;
4+
5+
import './Ownable.sol';
6+
import './Structures.sol';
7+
import './X509Interface.sol';
8+
import './SanctionsListInterface.sol';
9+
10+
contract Certified is Ownable {
11+
X509Interface x509;
12+
SanctionsListInterface sanctionsList;
13+
14+
function initialize() public virtual override initializer {
15+
Ownable.initialize();
16+
}
17+
18+
function setAuthorities(address sanctionsListAddress, address x509Address) public onlyOwner {
19+
x509 = X509Interface(x509Address);
20+
sanctionsList = SanctionsListInterface(sanctionsListAddress);
21+
}
22+
23+
// this modifier checks all of the 'authorisation' contract interfaces to see if we are allowed to transact
24+
modifier onlyCertified() {
25+
require(
26+
x509.x509Check(msg.sender),
27+
'Certified: You are not authorised to transact using Nightfall'
28+
);
29+
require(
30+
!sanctionsList.isSanctioned(msg.sender),
31+
'Certified: You are on the Chainalysis sanctions list'
32+
);
33+
_;
34+
}
35+
}

0 commit comments

Comments
 (0)