You are viewing information archived from Mozilla.org on 2014-10-02.
Package nss
[hide private]
[frames] | no frames]

Source Code for Package nss

  1  # This Source Code Form is subject to the terms of the Mozilla Public 
  2  # License, v. 2.0. If a copy of the MPL was not distributed with this 
  3  # file, You can obtain one at http://mozilla.org/MPL/2.0/. 
  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