Skip to content

Commit 2c30637

Browse files
authored
Merge pull request #2 from zjkmxy/master
Add more code snippets
2 parents af48283 + 4e9a1d6 commit 2c30637

File tree

9 files changed

+248
-14
lines changed

9 files changed

+248
-14
lines changed

docs/communication.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ Make sure to start NFD on your development machine before running this example.
6262
--8<-- "snippets/communication/producer.py"
6363
```
6464

65+
=== "NDNts"
66+
67+
``` typescript
68+
--8<-- "snippets/communication/producer.ts"
69+
```
70+
6571
## Faces
6672

6773
!!! warning "Under Construction"

docs/security.md renamed to docs/ndn-security.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,19 @@ Digital signing is done by a pair of asymmetric keys, which consists of a privat
1313
The _private key_ is known only by the producer, used to generate signatures.
1414
Anyone who knows the _public key_ can verify the signature.
1515

16-
(Code snippet to be added)
16+
17+
=== "python-ndn"
18+
19+
``` python
20+
--8<-- "snippets/security/key-gen.py"
21+
```
22+
23+
=== "NDNts"
24+
25+
``` typescript
26+
--8<-- "snippets/security/key-gen.ts"
27+
```
28+
1729

1830
In a system, security is more than cryptographically verifying the signature.
1931
For example, we also need to
@@ -56,7 +68,17 @@ The entity (member or process) that owns the trust anchor has the power to contr
5668
Entities managing the trust relationship of the trust domain (including memberships and roles) are called _controllers_.
5769
The owner of the trust anchor is always a controller.
5870

59-
(Code snippet to be added)
71+
=== "python-ndn"
72+
73+
``` python
74+
--8<-- "snippets/security/trust-domain.py"
75+
```
76+
77+
=== "NDNts"
78+
79+
``` typescript
80+
--8<-- "snippets/security/trust-domain.ts"
81+
```
6082

6183
An application may involve multiple trust domains. _Inter-domain trust relations_ will be established by the controller.
6284
In the case where pure peer-to-peer trust relation is established, every member is its own controller.

docs/testbed.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,16 @@
44

55
The NDN research testbed is a shared resource created for research purposes, that include software routers at several participating institutions, application host nodes, and other devices. The testbed is used for research and development of NDN software, and for experiments that require a shared NDN infrastructure. It is not intended for production use.
66

7-
[https://named-data.net/ndn-testbed/](https://named-data.net/ndn-testbed/)
7+
[https://named-data.net/ndn-testbed/](https://named-data.net/ndn-testbed/)
8+
9+
## Obtain a testbed certificate
10+
11+
See [User Guide to Obtain a Testbed Certificate](https://named-data.net/ndn-testbed/user-guide-to-obtain-a-testbed-certificate/)
12+
13+
## Connect to testbed using local NFD
14+
15+
TBD
16+
17+
## Connect to testbed from application
18+
19+
TBD

mkdocs.yml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ plugins:
2121
csl_file: acm-sig-proceedings.csl
2222

2323
nav:
24-
- "index.md"
25-
- "getting-started.md"
26-
- "packets.md"
27-
- "communication.md"
28-
- "security.md"
29-
- "sync.md"
30-
- "storage.md"
31-
- "forwarding.md"
32-
- "routing.md"
33-
- "testbed.md"
34-
- "debugging.md"
24+
- 'index.md'
25+
- 'getting-started.md'
26+
- 'packets.md'
27+
- 'communication.md'
28+
- 'ndn-security.md'
29+
- 'sync.md'
30+
- 'storage.md'
31+
- 'forwarding.md'
32+
- 'routing.md'
33+
- 'testbed.md'
34+
- 'debugging.md'
3535

3636
markdown_extensions:
3737
- admonition

snippets/communication/producer.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Data, digestSigning } from '@ndn/packet';
2+
import { WsTransport } from '@ndn/ws-transport';
3+
import { Endpoint } from '@ndn/endpoint';
4+
import { toUtf8 } from '@ndn/util';
5+
6+
// Code running in the browser cannot connect to a local Unix socket.
7+
// In this example, we connect to a remote NFD instance, running as
8+
// a part of the global NDN testbed.
9+
const uplink = await WsTransport.createFace({}, "wss://suns.cs.ucla.edu/ws/");
10+
console.log(`Connected to NFD at ${uplink.remoteAddress}`);
11+
12+
// Construct an Endpoint on the default forwarder instance.
13+
const endpoint = new Endpoint();
14+
15+
// Start one producer
16+
const myProducer = endpoint.produce('/edu/ucla/cs/118/notes', async (interest) => {
17+
console.log(`Received Interest packet for ${interest.name.toString()}`);
18+
// Create the content bytes for the Data packet
19+
const content = toUtf8("Hello, NDN!");
20+
// Sign and send the Data packet back to the network
21+
const data = new Data(interest.name, Data.FreshnessPeriod(10000), content);
22+
await digestSigning.sign(data);
23+
return data;
24+
});

snippets/security/key-gen.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import ndn.encoding as enc
2+
import ndn.security as sec
3+
from Cryptodome.PublicKey import ECC
4+
5+
# Generate key pairs (Recommend 'P-256' for ECDSA and 'ed25519' for EdDSA)
6+
priv_key = ECC.generate(curve='ed25519')
7+
pub_key = priv_key.public_key()
8+
# Create a signer
9+
signer = sec.Ed25519Signer('/edu/ucla/xinyu.ma', priv_key.export_key(format='DER'))
10+
# Sign a data with it
11+
data_wire = enc.make_data(
12+
# String can be directly used as Name in most cases
13+
name='/edu/ucla/cs/118/notes',
14+
# Set the Interest packet's FreshnessPeriod to 10 seconds
15+
meta_info=enc.MetaInfo(freshness_period=10000),
16+
# Set the Data packet's content to "Hello, NDN!"
17+
content=b'Hello, NDN!',
18+
signer=signer
19+
)
20+
print('Data:', data_wire.hex())
21+
22+
# Export public keys
23+
pub_key_bits = pub_key.export_key(format='DER')
24+
print('Public Key bits:', pub_key_bits.hex())
25+
# Can be imported by: ECC.import_key(pub_key_bits)
26+
27+
# Then verify the Data packet using it
28+
_, _, _, sig_ptrs = enc.parse_data(data_wire)
29+
if sec.verify_ed25519(pub_key, sig_ptrs):
30+
print('Data verified')
31+
else:
32+
print('Data not verified')

snippets/security/key-gen.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Data, Name } from '@ndn/packet';
2+
import { Decoder, Encoder } from '@ndn/tlv';
3+
import { toHex, toUtf8 } from '@ndn/util';
4+
import { Ed25519, generateSigningKey } from '@ndn/keychain';
5+
6+
// Generate key pairs (Recommend ECDSA and Ed25519 for EdDSA)
7+
const identityName = new Name('/edu/ucla/xinyu.ma');
8+
const [signer, verifier] = await generateSigningKey(identityName, Ed25519);
9+
// Sign a Data with it
10+
const data = new Data(
11+
new Name('/edu/ucla/cs/118/notes'),
12+
Data.FreshnessPeriod(10000),
13+
toUtf8('Hello, NDN!'));
14+
await signer.sign(data);
15+
// Print the Data wire
16+
const wire = Encoder.encode(data);
17+
console.log('Data:', toHex(wire));
18+
19+
// Export public keys
20+
const publicKeyBits = verifier.spki!;
21+
console.log('Public Key bits:', toHex(publicKeyBits));
22+
// Importing a public key in NDNts is very complicated
23+
// so I recommend to use a certificate instead.
24+
// I will show you how to do it later.
25+
26+
// Then verify the Data packet using it
27+
const decodedData = Decoder.decode(wire, Data); // Be the same as `data`
28+
try {
29+
await verifier.verify(decodedData);
30+
console.log('Data verified');
31+
} catch {
32+
console.log('Data not verified');
33+
}

snippets/security/trust-domain.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from datetime import datetime, timedelta, timezone
2+
import ndn.encoding as enc
3+
import ndn.security as sec
4+
import ndn.app_support.security_v2 as secv2
5+
from Cryptodome.PublicKey import ECC
6+
from Cryptodome.Random import get_random_bytes
7+
8+
9+
# Generate trust anchor of admin
10+
admin_priv = ECC.generate(curve='ed25519')
11+
admin_pub = admin_priv.public_key()
12+
admin_pub_bits = admin_pub.export_key(format='DER')
13+
admin_identity_name = enc.Name.from_str('/lab/admin')
14+
# Key name is <IdentityName>/KEY/<keyId>, here we use random value as key ID.
15+
# You can also use timestamp, sequencial number, or hash.
16+
admin_key_name = enc.Name.normalize(
17+
admin_identity_name + ['KEY', enc.Component.from_bytes(get_random_bytes(8))])
18+
# Self signer is used to sign the self-signed certificate only.
19+
admin_self_signer = sec.Ed25519Signer(
20+
admin_key_name, admin_priv.export_key(format='DER'))
21+
anchor_name, anchor = secv2.self_sign(
22+
admin_key_name, admin_pub_bits, admin_self_signer)
23+
# We create a new signer with this certificate's name for further use
24+
admin_signer = sec.Ed25519Signer(
25+
anchor_name, admin_priv.export_key(format='DER'))
26+
print(f'Admin trust anchor name: {enc.Name.to_str(anchor_name)}')
27+
print(f'Admin trust anchor hex: {bytes(anchor).hex()}')
28+
print()
29+
30+
# Generate the student's key and issue him a certificate
31+
stu_priv = ECC.generate(curve='ed25519')
32+
stu_pub = stu_priv.public_key()
33+
stu_pub_bits = stu_pub.export_key(format='DER')
34+
stu_identity_name = enc.Name.from_str('/lab/student/xinyu.ma')
35+
stu_key_name = enc.Name.normalize(
36+
stu_identity_name + ['KEY', enc.Component.from_bytes(get_random_bytes(8))])
37+
stu_cert_name, stu_cert = secv2.new_cert(
38+
stu_key_name,
39+
'admin',
40+
stu_pub_bits,
41+
admin_signer,
42+
start_time=datetime.now(timezone.utc),
43+
end_time=datetime.now(timezone.utc) + timedelta(days=365),
44+
)
45+
stu_signer = sec.Ed25519Signer(
46+
stu_cert_name, stu_priv.export_key(format='DER'))
47+
print(f'Student certificate name: {enc.Name.to_str(stu_cert_name)}')
48+
print(f'Student certificate hex: {bytes(stu_cert).hex()}')
49+
print()
50+
51+
# Sign the paper's data with the student's certificate
52+
data_wire = enc.make_data(
53+
name='/lab/paper/ndn/change/1',
54+
meta_info=enc.MetaInfo(freshness_period=10000),
55+
content=b'Hello, NDN!',
56+
signer=stu_signer
57+
)
58+
print('Data:', data_wire.hex())

snippets/security/trust-domain.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Component, Data, Name } from '@ndn/packet';
2+
import { Encoder } from '@ndn/tlv';
3+
import { toHex, toUtf8 } from '@ndn/util';
4+
import { Certificate, Ed25519, generateSigningKey, ValidityPeriod } from '@ndn/keychain';
5+
6+
// Generate trust anchor of admin
7+
const adminIdentityName = new Name('/lab/admin');
8+
const [adminSelfSigner, adminVerifier] = await generateSigningKey(adminIdentityName, Ed25519);
9+
const anchor = await Certificate.selfSign({
10+
privateKey: adminSelfSigner,
11+
publicKey: adminVerifier,
12+
});
13+
const adminSigner = adminSelfSigner.withKeyLocator(anchor.name);
14+
const anchorWire = Encoder.encode(anchor.data);
15+
console.log(`Admin trust anchor name: ${anchor.name.toString()}`);
16+
console.log(`Admin trust anchor hex: ${toHex(anchorWire)}`);
17+
console.log('');
18+
// The following line create the verifier from certificate
19+
// const anchor = Certificate.fromData(Decoder.decode(anchorWire, Data));
20+
// const adminVerifier = await createVerifier(anchor, {algoList: [Ed25519]});
21+
22+
// Generate the student's key and issue him a certificate
23+
const stuIdentityName = new Name('/lab/student/xinyu.ma');
24+
const [stuSelfSigner, stuVerifier] = await generateSigningKey(stuIdentityName, Ed25519);
25+
const stuCert = await Certificate.issue({
26+
issuerPrivateKey: adminSigner,
27+
publicKey: stuVerifier,
28+
issuerId: new Component(8, 'admin'),
29+
// Equivalent to the following:
30+
// validity: new ValidityPeriod(Date.now(), Date.now() + 365 * 86400000),
31+
validity: ValidityPeriod.daysFromNow(365),
32+
});
33+
const stuSigner = stuSelfSigner.withKeyLocator(stuCert.name);
34+
const stuCertWire = Encoder.encode(stuCert.data);
35+
console.log(`Student certificate name: ${stuCert.name.toString()}`);
36+
console.log(`Student certificate hex: ${toHex(stuCertWire)}`);
37+
console.log('');
38+
39+
// Sign the paper's data with the student's certificate
40+
const data = new Data(
41+
new Name('/lab/paper/ndn/change/1'),
42+
Data.FreshnessPeriod(10000),
43+
toUtf8('Hello, NDN!'),
44+
);
45+
await stuSigner.sign(data);
46+
const dataWire = Encoder.encode(data);
47+
console.log('Data:', toHex(dataWire));

0 commit comments

Comments
 (0)