A program that can generate a BAd Rpki RepositorY.
Meant for Relying Party testing.
WIP.
mkdir -p ~/git
cd ~/git
git clone https://github.com/vlm/asn1c.git
cd asn1c
test -f configure || autoreconf -iv
./configure
make
sudo make install
cd ~/git
git clone https://github.com/NICMx/libasn1fort
cd libasn1fort
./autogen.sh
./configure
make
sudo make install
sudo ldconfig
cd ~/git
git clone https://github.com/LACNIC/barry
cd barry
./autogen.sh
./configure
make
sudo make install
Let's say we want to create the following tree:
╔══════╗
║ TA ║
╚══╤═══╝
│
┌─────────────────┼────────────────┐
│ │ │
╔══╧═══╗ ╔══╧═══╗ ╔══╧═══╗
║ CA 1 ║ ║ CA 2 ║ ║ CA 3 ║
╚══╤═══╝ ╚══╤═══╝ ╚══╤═══╝
│ │ │
┌────┴─────┐ │ ┌────┴─────┐
│ │ │ │ │
╔═══╧════╗ ╔═══╧════╗ ╔═══╧════╗ ╔═══╧════╗ ╔═══╧════╗
║ ROA 1A ║ ║ ROA 1B ║ ║ ROA 2 ║ ║ ROA 3A ║ ║ ROA 3B ║
╚════════╝ ╚════════╝ ╚════════╝ ╚════════╝ ╚════════╝
Produce a Repository Descriptor (RD) file named good.repo
, containing the tree drawing in minimal text form:
ta.cer
ca1.cer
roa1A.roa
roa1B.roa
ca2.cer
roa2.roa
ca3.cer
roa3A.roa
roa3B.roa
Whitespace decides familial ties. (A node with a given indentation will be the child of the most recent file with smaller indentation, files with equal indentation and common parent are siblings.) Tabs are valued as 8 spaces, though nothing actually needs to be constrained to multiples of 8.
Feed the RD to barry
:
$ barry good.repo
It'll make a bunch of assumptions and output the following file hierarchy:
./good.tal # Named based on the RD
./rsync/ta.cer
./rsync/ta/ca1.cer # The default name of each Repository Publication Point
./rsync/ta/ca2.cer # is the name of its CA's certificate, minus extension.
./rsync/ta/ca3.cer
./rsync/ta/ta.crl # CRLs & Manifests are spawned and also named automatically after the parent.
./rsync/ta/ta.mft # You can declare them in the tree if you don't want this.
./rsync/ca1/roa1A.roa
./rsync/ca1/roa1B.roa
./rsync/ca1/ca1.crl
./rsync/ca1/ca1.mft
./rsync/ca2/roa2.roa
./rsync/ca2/ca2.crl
./rsync/ca2/ca2.mft
./rsync/ca3/roa3A.roa
./rsync/ca3/roa3B.roa
./rsync/ca3/ca3.crl
./rsync/ca3/ca3.mft
Serve them via rsync, and you've built yourself a "validateable" Repository Instance (assuming your RP can be configured to allow requests to localhost):
$ cat > rsyncd.conf <<\EOF
lock file = lock.lock
log file = log.log
pid file = pid.pid
port = 8873
[rpki]
path = rsync/
hosts = 127.0.0.1
EOF
$ rsync --daemon --config=rsyncd.conf
$ fort --mode=standalone --tal=good.tal --log.level=info | tail -5
Jul 14 13:06:30 INF: Validation finished:
Jul 14 13:06:30 INF: - Valid ROAs: 1
Jul 14 13:06:30 INF: - Valid Router Keys: 0
Jul 14 13:06:30 INF: - Real execution time: 1s
Jul 14 13:06:30 INF: Done.
As you might imagine, this means keys, signatures, serials, names and dates are all automatically generated (the latter default to the current time).
Let's say we want to validate the following RFC 6482 requirement:
3.1. version
The version number of the RouteOriginAttestation MUST be 0.
This tree'll suffice:
╔═════╗
║ TA ║
╚══╤══╝
╔══════╧═══════╗
║ ROA ║
║ (version: 2) ║
╚══════════════╝
That translates into bad.repo
:
ta.cer
roa.roa
[node: roa.roa]
obj.content.encapContentInfo.eContent.version = 2
Basically, you can override fields from the objects by appending an "attributes" section to the RD. Enclose the name of the file in brackets (as a header), then override needed values, key-value style. You can do this for all the declared files in the tree. The keys of the fields are dot-stringified versions of their official names from the RFC ASN.1 definitions (plus an "obj.
" prefix), though there are additional keys we'll discuss later.
Processing that file should result in a repository that might be rejected by a current validator:
$ rm -rf rsync/
$ barry bad.repo
$ find rsync/ -type f # Just to see them
rsync/ta.cer
rsync/ta/roa.roa
rsync/ta/ta.crl
rsync/ta/ta.mft
$ fort --mode=standalone --tal=bad.tal --validation-log.enabled --validation-log.level=info --log.level=info
...
Jul 14 13:26:41 ERR [Validation]: rsync://localhost:8873/rpki/ta/roa.roa: ROA's version (2) is nonzero.
...
Jul 14 13:26:41 INF: Validation finished:
Jul 14 13:26:41 INF: - Valid ROAs: 0
...
With this, you can create some manner of testing mechanism by checking the presence of outputted ROAs, stat querying and/or maybe log grepping.
By default, barry
tries to keep quiet. Add -p (markdown|csv)
to print the objects and all of their values, -v
if you want a general idea of what it's doing, and another -v
for garbage tracing.
$ echo "ta.cer" > minimal.repo
$ barry -p csv minimal.repo > tree.csv
This would be tree.csv
.
Incidentally, this is an okay way to find all the available keys for a given file type.
Reminder: This is a WIP. It's liable to change backwards-incompatibly until barry
version 1.0.0 has been consumated.
The confirmed reserved characters are =
(assignment), ,
(separator), {
and }
(map delimiters), [
and ]
(array/set delimiters) and #
(comment).
The only other token type is String, which is either
- A continuous sequence of unreserved and non-whitespace characters (eg.
10
,0x0100
,potatoes
,192.0.2.0/24-28
), - or a quoted sequence of any character except
"
(eg."also a string"
,"!#$%^&*()[]{}"
). (There is no way to escape"
at the moment.)
The key-value section is a JSON-adjacent hierarchy. Here is an example in which the user has overridden the valid dates of the TA and the addresses it can delegate:
[node: ta.cer]
"obj" = {
"tbsCertificate" = {
"validity" = {
"notBefore" = "2025-06-01T00:00:00Z",
"notAfter" = "2026-06-01T00:00:00Z"
},
"extensions" = {
"ip" = {
"extnValue" = [
"192.0.2.0/24-28",
"2001:db8::/64"
]
}
}
}
}
For clarity, here are some directions:
See Extensions and IP Resources for the remaining fields.
The format differs from JSON in several ways:
- You can comment out the remainder of a line by issuing the
#
character outside of a string, - as you can see above, the assignment reserved character is
=
(not:
), - the last element of any set or map is allowed to be suffixed by a redundant comma (for reduced diff noise),
- if a string (whether key or value) does not contain reserved characters or whitespace, then you can omit the quotes,
- you can reduce stacking by dot-chaining field names as you see fit,
- and quoted strings can contain newlines.
Hence, the example above is equivalent to
[node: ta.cer]
# This line is a comment <-- 1
obj.tbsCertificate = { # <-- 4, 5
validity = {
notBefore = 2025-06-01T00:00:00Z, # <-- 4 (x2)
notAfter = 2026-06-01T00:00:00Z
},
extensions.ip.extnValue = [ # <-- 5
192.0.2.0/24-28,
2001:db8::/64, # <-- 3
], # <-- 3
}
Which is also equivalent to
[node: ta.cer]
obj.tbsCertificate.validity.notBefore = 2025-06-01T00:00:00Z
obj.tbsCertificate.validity.notAfter = 2026-06-01T00:00:00Z
obj.tbsCertificate.extensions.ip.extnValue = [ 192.0.2.0/24-28, 2001:db8::/64 ]
(See Numerics below for an example of 6.)
Because of their numeric natures, INTEGER
, BOOLEAN
s, OCTET STRING
s, BIT STRING
s and ANY
s largely share the same parser:
# INTEGER
obj.tbsCertificate.version = 4660
obj.tbsCertificate.version = 0x1234
obj.tbsCertificate.version = 0b0001001000110100
# BOOLEAN
obj.tbsCertificate.extensions.bc.critical = 9999
# OCTET STRING
obj.content.signerInfos.0.signature = 4660
# BIT STRING
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0x1234
# ANY
obj.tbsCertificate.signature.parameters = 0b0001001000110100
Hexadecimals and binaries are simultaneously integers and byte arrays. They can be very long, and you get one byte every two hexadecimal digits or eight binary ones:
# Array: { 0x12, 0x34, 0x56 }
obj.tbsCertificate.signature.parameters = 0x123456
# BTW: You can use colons or underscores as visual separators.
# If you quote the number, you can also use whitespace.
obj.tbsCertificate.signature.parameters = "0b_0001:0010_0011,0100 0101 0110"
# Note, quoted strings are allowed to span several lines.
obj.tbsCertificate.signature.parameters = "0x
00a1 00a2 00a3 00a4 00a5 00a6 00a7 00a8
80b1 80b2 80b3 80b4 80b5 80b6 80b7 80b8
A0c1 A0c2 A0c3 A0c4 A0c5 00c6 A0c7 A0c8
F0d1 F0d2 F0d3 F0d4 F0d5 F0d6 F0d7 F0
"
Also notice, this is the human-readable value. It later gets DER-encoded, which might result in some mutations, such as truncated leading zeroes on INTEGER
s:
# This INTEGER Becomes { 2, 1, 1 } when encoded.
# (2 = INTEGER type, 1 = length, 1 = value, leading zeroes excluded)
obj.tbsCertificate.version = 0x00000001
# This ANY actually encodes into { 0, 0, 0, 1 }.
obj.tbsCertificate.signature.parameters = 0x00000001
If you want a BIT STRING
whose bit count is not a multiple of 8, use hexadecimal or binary format, then a prefix length (which behaves pretty much like in IP addresses). The following three are equivalent:
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0b:11:11:10
# The /6 chops off the last two bits
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0xF8/6
# The /6 actually adds a zero, because there are only 5 digits
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0b11111/6
(Please note that prefixing swaps the anchoring of the number! As an INTEGER
, 0x1234
equals 0x001234
, but 0x1234/24
equals 0x123400
.)
Prefix lengths give you free padding, I guess. The following two are equivalent:
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0x1000000000000000000000000000000000
obj.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey = 0x10/136
Prefixing is actually also compatible with the other "numeric" data types, but they actually require the length to be a multiple of 8. You may abuse this to produce big numbers:
# Big integer whose hexadecimal representation consists of '1' followed by 248 zeroes.
obj.tbsCertificate.version = 0x01/1000
I haven't implemented negative INTEGER
s yet.
BOOLEAN
s are numeric data types, but they also allow case-sensitive true
and false
:
obj.tbsCertificate.extensions.ip.critical = 0xFF
obj.tbsCertificate.extensions.asn.critical = true
obj.tbsCertificate.extensions.ski.critical = false
Despite access to the numeric parser, booleans are internally managed as int
s. This means you cannot assign big integers to them; your numeric boolean inputs need to be constrained to the range [INT_MIN
, INT_MAX
]. (The values of INT_MIN
and INT_MAX
depend on your system.)
That said, DER defines a very limited boolean range. false
needs to be encoded as 0, and true
needs to be encoded as 0xFF. libasn1fort
currently does not provide a means to encode dirty BER, so for now, any nonzero value you enter will be snapped back to 0xFF.
Only the numerical representation is supported.
obj.content.encapContentInfo.eContentType = 1.2.840.113549.1.9.16.1.26
Only the %Y-%m-%dT%H:%M:%SZ
format is supported right now.
obj.tbsCertificate.validity.notBefore = 2025-07-15T19:39:38Z
Applies to both Time
s and GeneralizedTime
s. Notice the UTC+0 enforcement.
Names consist of a single choice (rdnSequence
) consisting of arrays of arrays of AttributeNameAndValue
s. Formally, an overly-populated certificate name subject
might look like this:
obj.tbsCertificate.subject.rdnSequence = [
[ # RelativeDistinguishedName 1
{ # AttributeTypeAndValue 1
type = 2.5.4.3, # commonName
value = aaa
},
{ # AttributeTypeAndValue 2
type = 2.5.4.5, # serialNumber
value = bbb
},
],
[ # RelativeDistinguishedName 2
{ # AttributeTypeAndValue 1
type = 2.5.4.4, # surname
value = ccc
},
{ # AttributeTypeAndValue 2
type = 2.5.4.42, # givenName
value = ddd
},
{ # AttributeTypeAndValue 3
type = 2.5.4.43, # initials
value = eee
}
]
]
RPKI mostly only requires a single RelativeDistinguishedName
containing commonName
and (optionally) serialNumber
.
By default, your certificates get the following extension lists:
# TAs
obj.tbsCertificate.extensions = [ bc, ski, ku, sia, cp, ip, asn ]
# Regular CAs
obj.tbsCertificate.extensions = [ bc, ski, aki, ku, crldp, aia, sia, cp, ip, asn ]
# End-Entities
obj.content.certificates.0.tbsCertificate.extensions = [
ski, aki, ku, crldp, aia, sia, cp, ip, asn
]
# CRLs
obj.tbsCertList.crlExtensions = [ aki, crln ]
The presently implemented extensions are
Initials | Extension | Reference |
---|---|---|
bc | Basic Constraints | Generic, RPKI |
ski | Subject Key Identifier | Generic, RPKI |
aki | Authority Key Identifier | Generic, RPKI |
ku | Key Usage | Generic, RPKI |
crldp | CRL Distribution Points | Generic, RPKI |
aia | Authority Information Access | Generic, RPKI |
sia | Subject Information Access | Generic, RPKI |
cp | Certificate Policies | Generic, RPKI |
ip | IP Resources | Generic, RPKI |
asn | AS Resources | Generic, RPKI |
crln | CRL Number | Generic |
Every extension gets an extnID
OID, a critical
boolean and a type-dependent extnValue
, all editable through subfields:
obj.tbsCertificate.extensions.ip.extnID = 1.3.6.1.5.5.7.1.28
obj.tbsCertificate.extensions.ip.critical = true
obj.tbsCertificate.extensions.ip.extnValue = [ 192.0.2.0/24, 2001:db8::/96 ]
obj.tbsCertificate.extensions.asn.extnID = 1.3.6.1.5.5.7.1.29
obj.tbsCertificate.extensions.asn.critical = true
obj.tbsCertificate.extensions.asn.extnValue.asnum = [ 0x1234, 0x5678 ]
obj.tbsCertificate.extensions.asn.extnValue.rdi = [ 0x9ABC, 0xDEF0 ]
If you want a different extension list, override it:
# Replaces the extension list with an IP extension (type "ip", name "ip")
# and an ASN extension (type "asn", name "asn").
obj.tbsCertificate.extensions = [ ip, asn ]
# The "ip" label now refers to the first extension (because that's the one named "ip" now),
# not the (now nonexistent) 6th or 9th.
obj.tbsCertificate.extensions.ip.extnID = 1.2.3.4.5
You can customize the extension names by declaring the extensions
object as a map. This is useful if you want to list multiple extensions of the same type:
obj.tbsCertificate.extensions = {
# <name> = <type>
red = ip,
blue = asn,
yellow = ip,
purple = bc,
orange = ip,
green = asn
}
# Overrides the OID of the third ip extension
obj.tbsCertificate.extensions.orange.extnID = 1.2.3.4.5
Whether declared as a set or map, the final list will contain the extensions in the same order in which they were declared.
obj.content.encapContentInfo.eContent.ipAddrBlocks = [
192.0.2.0/24,
203.0.113.0,
2001:db8::/40-48
]
List as many as you need. barry
will automatically detect IP version and drop each entry to the corresponding ROAIPAddressFamily
.
At present, all certificates and ROAs contain
192.0.2.0/24
as their only default IP resource. This is going to change in the future.
TODO this section is probably outdated
By default, barry
populates manifest fileLists with the actual names and hashes of the files it creates. The following RD:
ta.cer
mft.mft
crl.crl
A.cer
B.cer
Implies (with possible hashes)
[node: mft.mft]
obj.content.encapContentInfo.eContent.fileList = {
# <File name> = <Hash>
crl.crl = 0x14A9B4039E1EDC10C1314C435828B418417E8B152CD173696B776EF24D9A9E41,
A.cer = 0x5EBFE949DAB77A1AED18BC7EDE86C0F4CC784A2227385E6F04461EE85BD7F2C9,
B.cer = 0x237FF39E12A09160CC2B365BB155D72A25E1CF9073CD583AADAA35E2872AD104
}
(If you omitted the CRL in the tree, it will be automatically added to the fileList
as the last entry.)
Since the files are fileList
ed in the order in which they were declared in the tree, you can then (for example) override the hash of A.cer
and the name of B.cer
like so:
# Indexing is zero-based
obj.content.encapContentInfo.eContent.fileList.1.hash = 0x010203
obj.content.encapContentInfo.eContent.fileList.2.file = potatoes
Or just override the entire list however you see fit:
obj.content.encapContentInfo.eContent.fileList = {
A.cer = 0x010203,
nonexistent.cer = 0x040506,
mft.mft = 0x112233,
foobar = 0x55555555555555
}
RRDP has two relevant program arguments:
barry
--rrdp-uri=<RRDP-URI> # default: https://localhost:8443/rrdp
--rrdp-path=<RRDP-PATH> # default: rrdp/
...
By default, all the non-TA tree files barry
produces are snapshot'd into <RRDP-PATH>/snapshot.xml
(which is assumed to be served from URL [RRDP-URI]/snapshot.xml
), which is then referenced by <RRDP-PATH>/notification.xml
([RRDP-URI]/notification.xml
). Simply because of inertia, the TA is copied to <RRDP-PATH>/<Name of TA>
([RRDP-URI]/<Name of TA>
). No deltas are produced.
Note: If
--rrdp-uri
is an empty string, RRDP will be completely disabled. (SIAs will not containrpkiNotify
s and RRDP files will not be generated.) Otherwise, ifrrdp-path
is an empty string, the SIAs will contain the correspondingrpkiNotify
s, but no RRDP XMLs will be generated.
Every certificate in the tree has an additional key-value URL named rpp.notification
, which is normally autocomputed early in the repository building process. If you don't override anything else, all of said certificate's descendants will be snapshot'd into the rpp.notification
RRDP context:
ta.cer
A.cer
A1.roa
A2.roa
B.cer
B1.roa
B2.cer
B2a.roa
[node: ta.cer]
rpp.notification = https://potato/rrdp/notification.xml
[node: B.cer]
rpp.notification = https://tomato/rrdp/notification.xml
[node: B2.cer]
rpp.notification = https://lettuce/rrdp/notification.xml
potato
's snapshot will containA.cer
,A1.roa
,A2.roa
andB.cer
.tomato
's snapshot will containB1.roa
andB2.cer
.lettuce
's snapshot will containB2a.roa
.
Note: If the object is the TA, its default
rpp.notification
is[RRDP-URI]/snapshot.xml
. Otherwise, it has no notification.
Note:
rpp.notification
is also copied to the certificate'srpkiNotify
(in its SIA extension), though that can also be overridden.
You can also induce further chaos by overriding the files actually contained by each snapshot, whether it makes sense or not:
[notification: https://tomato/rrdp/notification.xml]
snapshot.files = [ ta.cer, A1.roa, A1.roa, B2a.roa ]
To create deltas, produce two repositories, then feed the resulting RRDP files to the separate program barry-delta
.
Suppose RD old.repo
contains the first version of the repository:
ta.cer
ca1.cer
roa1A.roa
roa1B.roa
ca2.cer
roa2.roa
[node: ta.cer]
rpp.notification = https://your-server.net/rrdp/notif.xml
[notification: https://your-server.net/rrdp/notif.xml]
path = notif.xml
snapshot.uri = https://your-server.net/rrdp/snapshot.xml
snapshot.path = snapshot.xml
RD new.repo
contains a subsequent version of the same repository:
ta.cer
ca1.cer
roa1A.roa
roa1C.roa
ca2.cer
roa2.roa
[node: ta.cer]
rpp.notification = https://your-server.net/rrdp/notif.xml
[notification: https://your-server.net/rrdp/notif.xml]
path = notif.xml
snapshot.uri = https://your-server.net/rrdp/snapshot.xml
snapshot.path = snapshot.xml
First, compile both repositories into separate directories:
mkdir -p keys/
for i in $(seq 0 8); do
openssl genrsa -out "keys/$i.pem" 2048
done
# Consistent shared keys and dates ensure hashes and signatures
# do not change if they don't have to
COMMON_ARGS="--keys keys/ --now 2025-01-01T00:00:00Z --later 2026-01-01T00:00:00Z"
barry $COMMON_ARGS --rsync-path rsync-old/ --rrdp-path rrdp-old/ old.repo
barry $COMMON_ARGS --rsync-path rsync-new/ --rrdp-path rrdp-new/ new.repo
Take a look at Barry's RRDP output:
$ ls rrdp-old/
notif.xml snapshot.xml
$
$ ls rrdp-new/
notif.xml snapshot.xml
Based on that, you can produce a delta between them:
mkdir -p fusion/
barry-delta -v \
--old.notification rrdp-old/notif.xml \
--old.snapshot rrdp-old/snapshot.xml \
--new.notification rrdp-new/notif.xml \
--new.snapshot rrdp-new/snapshot.xml \
--output.notification fusion/notif.xml \
--output.delta.path fusion/delta.xml \
--output.delta.uri https://your-server.net/rrdp/v2/delta.xml
You might want to review barry
's output matches your expectations:
[DBG compute_de:0424] rsync://localhost:8873/rpki/ca1/roa1B.roa disappeared; adding withdraw
[DBG compute_de:0428] rsync://localhost:8873/rpki/ca1/ca1.mft has a different hash; adding publish
[DBG compute_de:0437] rsync://localhost:8873/rpki/ca1/roa1C.roa spawned; adding publish
Find your new notification and delta in fusion/
.
This section is a quick and dirty means to start a local SSL-enabled Apache so it can serve Barry's RRDP output to the RP. Nothing's stopping you from employing other HTTP server or OS.
First, make a sandbox:
SANDBOX=~/tmp/apache-barry
mkdir -p $SANDBOX
cd $SANDBOX
Install Apache:
sudo apt update && sudo apt upgrade
sudo apt install apache2
Create a self-signed certificate for your HTTPS RRDP server, and copy it to the trust store (so the RP will accept it):
# When you fire this up, openssl will give you a few prompts.
# If you want to run with Barry's default `--rrdp-uri`,
# enter "`localhost`" as the common name.
# Otherwise adjust to your needs.
# The other fields don't matter.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout apache-barry.key -out apache-barry.crt
sudo cp apache-barry.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
Create $SANDBOX/apache2.conf
, containing
# Again, assuming --rrdp-uri's default.
ServerName localhost
# Forces Apache to work in the current directory.
# (Cancels out some obnoxious chdir() it does during startup for some reason.)
ServerRoot ${PWD}
# Dumps the process ID to a file named "pid".
# We can later terminate the server with this, by running "kill $(cat pid)".
PidFile pid
# Read this logfile if your server has trouble starting.
ErrorLog logs/main.log
LogLevel info
# Some plugins. Obviously, we need SSL. I'm not sure about the others,
# but things tend to fail when they're delisted.
# You might need to tweak the paths if you installed in a different distro.
LoadModule mpm_event_module /usr/lib/apache2/modules/mod_mpm_event.so
LoadModule authz_core_module /usr/lib/apache2/modules/mod_authz_core.so
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
# Finally, configure the HTTPS service we'll hang to port 8443.
Listen 8443
<VirtualHost *:8443>
DocumentRoot content
# Read this logfile if your requests aren't working
ErrorLog logs/8443.log
SSLEngine on
SSLCertificateFile apache-barry.crt
SSLCertificateKeyFile apache-barry.key
</VirtualHost>
Create $SANDBOX/start.sh
, a script to start the server:
#!/bin/sh
mkdir -p content logs
/usr/sbin/apache2 -f "${PWD}/apache2.conf"
And another one to stop.sh
it:
#!/bin/sh
if [ -f "pid" ]; then
kill $(cat pid)
fi
Start the server:
sh start.sh
Might want to test it:
echo "Test succeeded!" > $SANDBOX/content/test.txt
curl https://localhost:8443/test.txt
Now, when running Barry, ask it to dump the RRDP files into the DocumentRoot
(or mv
them after they're generated):
mkdir -p ~/tmp/barry
cd ~/tmp/barry
echo "ta.cer" > some.repo
echo " A.roa" >> some.repo
barry --rrdp-path $SANDBOX/content/rrdp some.repo
ls $SANDBOX/content/rrdp
RRDP can now be served:
$ fort --mode standalone --log.level info --tal some.tal | tail -5
Sep 2 16:47:19 INF: Validation finished:
Sep 2 16:47:19 INF: - Valid ROAs: 1
Sep 2 16:47:19 INF: - Valid Router Keys: 0
Sep 2 16:47:19 INF: - Real execution time: 0s
Sep 2 16:47:19 INF: Done.
Add Github issues:
- Configuration file section:
[Alias]
include
s is configuration- May want to purge all the memory leaks
- Still unimplemented fields
- Certificates
- issuerUniqueID
- subjectUniqueID
- CRLs
- revokedCertificates
- Certificate/CRL extensions
- AKI authorityCertIssuer
- CRLDP extnValue
- CP extnValue
- Manifests, ROAs
- signedAttrs
- unsignedAttrs
- digestAlgorithms
- crls
- Certificates
- Fields whose values are autocomputed even if overridden in RD
- Several EE certificate extensions
- Document
- Program arguments