1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
$Id$
Python RPKI production tools.
Requires Python 2.5.
External Python packages required:
- lxml, which in turn requires the libxml2 C libraries.
FreeBSD: /usr/ports/devel/py-lxml
- MySQLdb, which in turn requires MySQL client and server. I'm
testing with MySQL 5.1.
FreeBSD: /usr/ports/databases/py-MySQLdb
- TLSLite, which pulls in other crypto packages.
FreeBSD: /usr/ports/security/py-tlslite
- Cryptlib, at the moment just to support TLSlite but may end up using
it for other things later.
FreeBSD: /usr/ports/security/cryptlib
...but the FreeBSD port doesn't (yet?) install the Python bindings,
sigh, so at the moment you have to do that by hand:
# cd /usr/ports/security/cryptlib
# make install
# cd work/bindings
# python setup.py install
# cd ../..
# make clean
- Eventually I expect that this will require an event-handling package
like Twisted, but I'm not there yet.
- The testpoke tool (up-down protocol command line test client) also
uses PyYAML, mostly for compatability with APNIC's equivalent tool.
FreeBSD: /usr/ports/devel/py-yaml
We also use a hacked copy of the Python OpenSSL Wrappers (POW)
package, but our copy has enough modifications that it's expanded in
the Subversion tree. Depending on how this all works out, I may end
up splitting the POW.pkix module out of the POW package and using it
with Cryptlib, as the POW.pkix package is 98% about doing ASN.1 in
pure Python and only 2% about any kind of crypto.
Current TO DO list:
- Representation of timestamps is a mess. We have four different
kinds already: seconds from epoch, the the two flavors of timestamps
used in ASN.1, and the timestamps used in MySQL. Need a unifying
class to hide all this nastiness.
- Subsetting (req_* attributes in up-down protocol)
- Revocation and CRL generation
- Need to keep data on unexpired revoked certs to generate CRL
(added a timestamp for this, sufficient?)
- Do we ever need to delay revocation of old certs to give their
replacements time to propegate?
These two imply that we need fields in child_cert table to
indicate whether a cert is dead, eg, a date field which is NULL if
the cert is still live, otherwise is the date after which it should
be added to the CRL.
- Publication protocol and implementation thereof. Defer until core
functionality in the main engine is done.
As an interim measure, hack some kind of stub publication (not real
protocol yet, just dump to local filesystem so can see outputs and
maybe rcynic against them); this is a stop-gap to let me concentrate
on the main engine and defer work on the publication protocol and
engine.
- Publication hooks everywhere - need not wait for protocol, can just
log what would happen for now, or write to local file store (perhaps
even in a form that we can use with rcynic as a relying party).
Hooks for this go into:
- Cert publication
- CRL publication
- Manifest publication
- Withdrawal of any of the above
- Child batch processing loop, eg, regeneration or removal of expired
certs, CRL update, manifest update, etc. This should probably be an
iteration over CA objects, as the CA is the actor in pretty much
everything that might need to be done.
Figuring out whether to regenerate or remove expired certs requires
some of the same data as CRL generation.
- Code to clean up expired certs
- Code to revoke certs -- need to sort out when we do this
automatically vs waiting for explicit revoke PDU from child
- Code to generate CRLs
- Haven't done anything about db.commit() and db.rollback() yet, for
that matter haven't yet whacked MySQL to enable those features.
- In theory, all access to object data attributes ought to be through
accessor methods so that the .set() method can mark teh object as
SQL-dirty automagically. Not done yet. One way of hiding the
grotty bits here might be to make attributes look like elements of a
dict(), ie, implement __getitem__() and __setitem__() methods,
probably along with the other "container type" special methods for
completeness. An even easier way to do this would be to subclass
dict() and just customize __setitem__().
But all of this assumes that we really want automagic SQL-dirty, and
I'm less convinced of that now than when I made the above note.
- Whack expiration dates of certs to match irdb valid_until value when
issuing -- valid_until is optional, what do we do if it's not set?
Default period in self object seems obvious answer, neither Randy
nor I has thought of anything better yet.
- Test with larger data set -- Tim gave me plenty of data and I have
the low-level tools, just haven't written the glue logic to create
child objects for all the entities in the IRDB, poll on behalf of
each of them, and check the result for sanity
Once this lot is done we'll be close to something that shows at least
the basics of normal operation, albiet in a form that's not yet usable
in production.
Follow-up after that will be getting rid of remaining synchronous code
(make daemon fully event-driven, except perhaps for SQL queries),
address rollback, commit, and other data integrity issues, and see how
well the resulting code handles hosting (multiple self objects in same
daemon).
Somewhere along the way I'll need to update to the new model of trust
anchors we ended up with in Amsterdam, first step for which will
involve writing it down (well, RobK was supposed to do that, but I was
supposed to convert some pencil sketches into graphviz for him so
we're both lame on this so far).
|