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 Introduction
40 ============
41
42 This package provides a binding for the Network Security Services
43 (NSS) library. Because NSS directly uses the Netscape Portable Runtime
44 (NSPR) the binding also provides support for NSPR. There is an
45 inherent conflict between NSPR and Python, please see the Issues
46 section for more detail.
47
48 General documentation on NSS can be found here:
49
50 http://www.mozilla.org/projects/security/pki/nss
51
52 General documentation on NSPR can be found here:
53
54 http://developer.mozilla.org/en/docs/NSPR_API_Reference
55
56 Please note, the documentation included with this package already
57 encapsultes most of the information at the above two URL's, but is
58 specific to the python binding of NSS/NSPR. It is suggested you refer
59 to the python-nss documentation.
60
61 Most of the names and symbols in the NSS/NSPR C API have been kept in
62 the nss-python binding and should be instantly familar or
63 recognizable. Python has different naming conventions and the
64 nss-python binding has adhered to the python naming convensions,
65 Classes are camel case, otherwise symbols are all lower case with
66 words seperated by underscores. The constants used by NSS/NSPR in C
67 API have been imported literally to add the programmer who might be
68 referring to the Mozilla NSS/NSPR documentation and/or header files or
69 who is porting an existing C application to python. Minor other
70 changes have been made in the interest of being "Pythonic".
71
72 ===============
73 Getting Started
74 ===============
75
76 NSS stores it's certificates and private keys in a security database
77 unlike OpenSSL which references it's certificates and keys via file
78 pathnames. This means unless you already have an NSS Certificate
79 Database (CertDB) the first order of business will be to create
80 one. When a NSS application initializes itself it will need to specify
81 the path to the CertDB (see "Things All NSS programs must do").
82
83 The CertDB is created and manipulated by the command line utilities
84 certutil and modutil. Both of these programs are part of the nss-tools
85 RPM. Documentation for these tools can be found here:
86 http://www.mozilla.org/projects/security/pki/nss/tools
87
88 Here is an example of creating a CertDB and populating it. In the
89 example the CertDB will be created under the directory "./pki", the CA
90 will be called "myca", the database password will be "myca", and the
91 server's hostname will be "myhost.example.com".
92
93 1. Create the database::
94
95 certutil -N -d ./pki
96
97 This creates a new database under the directory ./pki
98
99 2. Create a root CA certificate::
100
101 certutil -d ./pki -S -s "CN=myca" -n myca -x -t "CTu,C,C" -m 1
102
103 This creates an individual certificate and adds it to the
104 certificate database with a subject of "CN=myca", a nickname of
105 "myca", trust flags indicating for SSL indicating it can issue
106 server certificates (C), can issue client certificates (T), and the
107 certificate can be used for authentication and signing (u). For
108 email and object signing it's trusted to create server
109 certificates. The certificate serial number is set to 1.
110
111
112 3. Create a server certificate and sign it. Our example server will
113 use this::
114
115 certutil -d pki -S -c myca -s "CN=myhost.example.com" -n myhost -t "C,C,C" -m 2
116
117 This creates an individual certificate issued by the CA "myca" and
118 adds it to the certificate database with a subject of
119 "CN=myhost.example.com", a nickname of "myhost". The certificate
120 serial number is set to 2.
121
122 4. Import public root CA's::
123
124 modutil -add ca_certs -libfile /usr/lib/libnssckbi.so -dbdir ./pki
125
126 This is necessary to verify certificates presented by a SSL server a
127 NSS client might connect to. When verifying a certificate the NSS
128 library will "walk the certificate chain" back to a root CA which
129 must be trusted. This command imports the well known root CA's as a
130 PKCS #11 module.
131
132
133 ===============================
134 Things All NSS programs must do
135 ===============================
136
137 - Import the NSS/NSPR modules::
138
139 from nss.error import NSPRError
140 import nss.io as io
141 import nss.nss as nss
142 import nss.ssl as ssl
143
144 In the interest of code brevity we drop the leading "nss." from the
145 module namespace.
146
147 - Initialize NSS and indicate the certficate database (CertDB)::
148
149 certdir = './pki'
150 ssl.nssinit(certdir)
151
152 - If you are implementing an SSL server call config_secure_server()
153 (see ssl_example.py)::
154
155 sock = ssl.SSLSocket()
156 sock.config_secure_server(server_cert, priv_key, server_cert_kea)
157
158 **WARNING** you must call config_secure_server() for SSL servers, if
159 you do not call it the most likely result will be the NSS library
160 will segfault (not pretty).
161
162 ========
163 Examples
164 ========
165
166 There are example programs in under "examples" in the documentation
167 directory. On Fedora/RHEL/CentOS systems this will be
168 /usr/share/doc/python-nss.
169
170 The ssl_example.py sample implements both a client and server in one
171 script. You tell it whether to run as a client (-C) or a server (-S)
172 when you invoke it. The sample shows many of the NSS/NSPR calls and
173 fully implements basic non-SSL client/server using NSPR, SSL
174 client/server using NSS, certificate validation, CertDB operations,
175 and client authentication using certificates.
176
177 To get a list of command line options::
178
179 ssl_example.py --help
180
181 Using the above example certificate database server can be run like
182 this::
183
184 ssl_example.py -S -c ./pki -n myhost
185
186 The client can be run like this::
187
188 ssl_example.py -C -c ./pki
189
190 ======
191 Issues
192 ======
193
194 - The current partitioning of the NSS and NSPR API's into Python
195 modules (i.e. the Python namespaces and their symbols) is a first
196 cut and may not be ideal. One should be prepared for name changes as
197 the binding matures.
198
199 - NSPR vs. Python
200
201 An original design goal of NSS was to be portable, however NSS
202 required access to many system level functions which can vary
203 widely between platforms and OS's. Therefore NSPR was written to
204 encapsulate system services such as IO, sockets, threads, timers,
205 etc. into a common API to insulate NSS from the underlying
206 platform.
207
208 In many respects Python and its collection of packages and modules
209 provides the same type of platform independence for applications
210 and libraries and provides it's own implementation of IO, sockets,
211 threads, timers, etc.
212
213 Unfortunately NSPR's and Python's run time abstractions are not
214 the same nor can either be configured to use a different
215 underlying abstraction layer.
216
217 Currently the NSS binding utilizes *only* the NSPR abstraction
218 layer. One consequence of this is it is not possible to create a
219 Python socket and use it as the foundation for any NSS functions
220 expecting a socket, or visa versa.
221
222 You **must** use the nss.io module to create and manipulate a
223 socket used by NSS. You cannot pass this socket to any Python
224 library function expecting a socket. The two are not compatible.
225
226 Here are some reasons for this incompatibility, perhaps in the
227 future we can find a solution but the immediate goal of the NSS
228 Python binding was to expose NSS through Python, not necessarily
229 to solve the larger integration issue of Python run-time and NSPR
230 run-time.
231
232 - NSPR would like to hide the underlying platform socket (in the
233 NSPR code this is called "osfd"). There are NSPR API's which
234 will operate on osfd's
235
236 - One can base a NSPR socket on an existing osfd via:
237
238 - PR_ImportFile()
239 - PR_ImportPipe()
240 - PR_ImportTCPSocket()
241 - PR_ImportUDPSocket()
242
243 - One can obtain the osfd in use by NSPR, either when the
244 osfd was imported or because NSPR created the osfd itself via:
245
246 - PR_FileDesc2NativeHandle();
247
248 But note this function is not meant to be public in the NSPR
249 API and is documented as being deprecated and carries an
250 explicit warning against it's use.
251
252 Once NSPR gets a hold of an osfd it manipulates it in a manner
253 as if it were the only owner of the osfd. Other native code
254 (e.g. the CPython socket code) which operates on the fd may run
255 afoul of NSPR belief it is the only code in the system operating
256 on the fd. For example in CPython the non-blocking flag is
257 directly set on the fd and non-blocking behavior is implemented
258 by the OS. However, NSPR manages non-blocking behavior
259 internally to the NSPR library eschewing direct OS support for
260 non-blocking. Thus CPython and NSPR are in direct conflict over
261 when and how non-blocking is set on an fd. Examples of this
262 problem can be seen in the Python socket.makefile() operation
263 which takes the fd belonging to a system socket, dups it, and
264 calls fdopen() on the dup'ed fd to return a FILE stream (all
265 Python file IO is based on file objects utilizing a FILE
266 stream). However, the dup'ed fd does not share the same
267 non-blocking flag, NSPR explicitly forces the flag off, Python
268 wants to directly manipulate it. Dup'ed fd's share their flags
269 thus if Python operates on the dup'ed fd returned by NSPR it's
270 going to confuse NSPR. Likewise if one sets non-blocking via
271 NSPR then Python won't honor the flag because Python is
272 expecting the flag to be set on the fd, not in some other
273 location (e.g. internal to NSPR).
274
275 - Python's socket implementation is a very thin layer over the
276 Berkely socket API. There is very little abstraction, thus
277 Python and Python program expect to manipulate sockets directly
278 via their fd's.
279
280 - The error and exception model for Python sockets and SSL is an
281 almost direct one-to-one mapping of the Posix and OpenSSL
282 errors. But NSS uses NSPR errors, thus Python code which has
283 exception handlers for sockets and SSL are expecting a complete
284 different set of exceptions.
285
286 - Python's SSL implementation is a very thin layer over the
287 OpenSSL API, there is little abstraction. Thus there is a
288 sizeable body of Python code which expects the OpenSSL model for
289 IO ready and has exception handlers based on OpenSSL.
290
291 ===
292 FAQ
293 ===
294
295 To be added
296
297 """
298 __version__ = '0.9'
299