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