Package nss
[hide private]
[frames] | no frames]

Source Code for Package nss

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