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

Source Code for Package nss

  1  # ***** BEGIN LICENSE BLOCK ***** 
  2  # Version: MPL 1.1/GPL 2.0/LGPL 2.1 
  3  # 
  4  # The contents of this file are subject to the Mozilla Public License Version 
  5  # 1.1 (the "License"); you may not use this file except in compliance with 
  6  # the License. You may obtain a copy of the License at 
  7  # http://www.mozilla.org/MPL/ 
  8  # 
  9  # Software distributed under the License is distributed on an "AS IS" basis, 
 10  # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 11  # for the specific language governing rights and limitations under the 
 12  # License. 
 13  # 
 14  # The Original Code is a Python binding for Network Security Services (NSS). 
 15  # 
 16  # The Initial Developer of the Original Code is Red Hat, Inc. 
 17  #   (Author: John Dennis <jdennis@redhat.com>)  
 18  #  
 19  # Portions created by the Initial Developer are Copyright (C) 2008,2009 
 20  # the Initial Developer. All Rights Reserved. 
 21  # 
 22  # Contributor(s): 
 23  # 
 24  # Alternatively, the contents of this file may be used under the terms of 
 25  # either the GNU General Public License Version 2 or later (the "GPL"), or 
 26  # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 
 27  # in which case the provisions of the GPL or the LGPL are applicable instead 
 28  # of those above.  If you wish to allow use of your version of this file only 
 29  # under the terms of either the GPL or the LGPL, and not to allow others to 
 30  # use your version of this file under the terms of the MPL, indicate your 
 31  # decision by deleting the provisions above and replace them with the notice 
 32  # and other provisions required by the GPL or the LGPL. If you do not delete 
 33  # the provisions above, a recipient may use your version of this file under 
 34  # the terms of any one of the MPL, the GPL or the LGPL. 
 35  # 
 36  # ***** END LICENSE BLOCK ***** 
 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  Deprecated Functionality 
 74  ======================== 
 75   
 76  Some elements of the binding have been deprecated because of lessons 
 77  learned along the way. The following emit deprecation warnings and 
 78  should not be used, they will be removed in a subsequent release. 
 79   
 80  `io.NetworkAddress()` 
 81      `NetworkAddress` initialization from a string parameter only works 
 82      for IPv4, use `AddrInfo` instead. 
 83   
 84  `io.NetworkAddress.set_from_string()` 
 85      `NetworkAddress` initialization from a string parameter only works 
 86      for IPv4, use `AddrInfo` instead. 
 87   
 88  `io.NetworkAddress.hostentry` 
 89      `HostEntry` objects only support IPv4, this property will be 
 90      removed, use `AddrInfo` instead. 
 91   
 92  `io.HostEntry.get_network_addresses()` 
 93      Use iteration instead (e.g. for net_adder in hostentry), the port 
 94      parameter is not respected, port will be value when `HostEntry` 
 95      object was created. 
 96   
 97  `io.HostEntry.get_network_address()` 
 98      Use indexing instead (e.g. hostentry[i]), the port parameter is 
 99      not respected, port will be value when `HostEntry` object was 
100      created. 
101   
102  `ssl.nssinit()` 
103      nssinit has been moved to the nss module, use `nss.nss_init()` 
104      instead of ssl.nssinit 
105   
106  `ssl.nss_init()` 
107      nss_init has been moved to the nss module, use `nss.nss_init()` 
108      instead of ssl.nssinit 
109   
110  `ssl.nss_shutdown()` 
111      nss_shutdown() has been moved to the nss module, use 
112      `nss.nss_shutdown()` instead of ssl.nss_shutdown() 
113   
114  `io.Socket()` and `ssl.SSLSocket()` without explicit family parameter 
115      Socket initialization will require the family parameter in the future. 
116      The default family parameter of PR_AF_INET is deprecated because 
117      when iterating through `NetworkAddress` objects returned by 
118      `AddrInfo` some address may be an IPv6 address. Suggest using the 
119      family property of the NetworkAddress object associated with the 
120      socket, e.g. Socket(net_addr.family) 
121   
122  =============== 
123  Getting Started 
124  =============== 
125   
126  NSS stores it's certificates and private keys in a security database 
127  unlike OpenSSL which references it's certificates and keys via file 
128  pathnames. This means unless you already have an NSS Certificate 
129  Database (CertDB) the first order of business will be to create 
130  one. When a NSS application initializes itself it will need to specify 
131  the path to the CertDB (see "Things All NSS programs must do"). 
132   
133  The CertDB is created and manipulated by the command line utilities 
134  certutil and modutil. Both of these programs are part of the nss-tools 
135  RPM. Documentation for these tools can be found here: 
136  http://www.mozilla.org/projects/security/pki/nss/tools 
137   
138  Here is an example of creating a CertDB and populating it. In the 
139  example the CertDB will be created under the directory "./pki", the CA 
140  will be called "myca", the database password will be "myca", and the 
141  server's hostname will be "myhost.example.com". 
142   
143  1. Create the database:: 
144   
145       certutil -N -d ./pki 
146   
147     This creates a new database under the directory ./pki 
148   
149  2. Create a root CA certificate:: 
150   
151       certutil -d ./pki -S -s "CN=myca" -n myca -x -t "CTu,C,C" -m 1 
152   
153     This creates an individual certificate and adds it to the 
154     certificate database with a subject of "CN=myca", a nickname of 
155     "myca", trust flags indicating for SSL indicating it can issue 
156     server certificates (C), can issue client certificates (T), and the 
157     certificate can be used for authentication and signing (u). For 
158     email and object signing it's trusted to create server 
159     certificates. The certificate serial number is set to 1. 
160   
161   
162  3. Create a server certificate and sign it. Our example server will 
163     use this:: 
164   
165       certutil -d pki -S -c myca -s "CN=myhost.example.com" -n myhost -t "u,u,u" -m 2 
166   
167     This creates an individual certificate issued by the CA "myca" and 
168     adds it to the certificate database with a subject of 
169     "CN=myhost.example.com", a nickname of "myhost". The certificate 
170     serial number is set to 2. 
171   
172  4. Import public root CA's:: 
173   
174       modutil -add ca_certs -libfile /usr/lib/libnssckbi.so -dbdir ./pki 
175   
176     This is necessary to verify certificates presented by a SSL server a 
177     NSS client might connect to. When verifying a certificate the NSS 
178     library will "walk the certificate chain" back to a root CA which 
179     must be trusted. This command imports the well known root CA's as a 
180     PKCS #11 module. 
181   
182   
183  =============================== 
184  Things All NSS programs must do 
185  =============================== 
186   
187  - Import the NSS/NSPR modules:: 
188   
189      from nss.error import NSPRError 
190      import nss.io as io 
191      import nss.nss as nss 
192      import nss.ssl as ssl 
193   
194    In the interest of code brevity we drop the leading "nss." from the 
195    module namespace. 
196   
197  - Initialize NSS and indicate the certficate database (CertDB):: 
198   
199      certdir = './pki' 
200      ssl.nssinit(certdir) 
201   
202  - If you are implementing an SSL server call config_secure_server() 
203    (see ssl_example.py):: 
204   
205      sock = ssl.SSLSocket(net_addr.family) 
206      sock.config_secure_server(server_cert, priv_key, server_cert_kea) 
207   
208    **WARNING** you must call config_secure_server() for SSL servers, if 
209    you do not call it the most likely result will be the NSS library 
210    will segfault (not pretty). 
211   
212  ======== 
213  Examples 
214  ======== 
215   
216  There are example programs in under "examples" in the documentation 
217  directory. On Fedora/RHEL/CentOS systems this will be 
218  /usr/share/doc/python-nss. 
219   
220  The ssl_example.py sample implements both a client and server in one 
221  script. You tell it whether to run as a client (-C) or a server (-S) 
222  when you invoke it. The sample shows many of the NSS/NSPR calls and 
223  fully implements basic non-SSL client/server using NSPR, SSL 
224  client/server using NSS, certificate validation, CertDB operations, 
225  and client authentication using certificates. 
226   
227  To get a list of command line options:: 
228   
229    ssl_example.py --help 
230   
231  Using the above example certificate database server can be run like 
232  this:: 
233   
234    ssl_example.py -S -c ./pki -n myhost 
235   
236  The client can be run like this:: 
237   
238    ssl_example.py -C -c ./pki 
239   
240  ====== 
241  Issues 
242  ====== 
243   
244  - The current partitioning of the NSS and NSPR API's into Python 
245    modules (i.e. the Python namespaces and their symbols) is a first 
246    cut and may not be ideal. One should be prepared for name changes as 
247    the binding matures. 
248   
249  - NSPR vs. Python 
250   
251      An original design goal of NSS was to be portable, however NSS 
252      required access to many system level functions which can vary 
253      widely between platforms and OS's. Therefore NSPR was written to 
254      encapsulate system services such as IO, sockets, threads, timers, 
255      etc. into a common API to insulate NSS from the underlying 
256      platform. 
257   
258      In many respects Python and its collection of packages and modules 
259      provides the same type of platform independence for applications 
260      and libraries and provides it's own implementation of IO, sockets, 
261      threads, timers, etc. 
262   
263      Unfortunately NSPR's and Python's run time abstractions are not 
264      the same nor can either be configured to use a different 
265      underlying abstraction layer. 
266   
267      Currently the NSS binding utilizes *only* the NSPR abstraction 
268      layer. One consequence of this is it is not possible to create a 
269      Python socket and use it as the foundation for any NSS functions 
270      expecting a socket, or visa versa. 
271   
272      You **must** use the nss.io module to create and manipulate a 
273      socket used by NSS. You cannot pass this socket to any Python 
274      library function expecting a socket. The two are not compatible. 
275   
276      Here are some reasons for this incompatibility, perhaps in the 
277      future we can find a solution but the immediate goal of the NSS 
278      Python binding was to expose NSS through Python, not necessarily 
279      to solve the larger integration issue of Python run-time and NSPR 
280      run-time.  
281   
282      - NSPR would like to hide the underlying platform socket (in the 
283        NSPR code this is called "osfd"). There are NSPR API's which 
284        will operate on osfd's 
285   
286        - One can base a NSPR socket on an existing osfd via: 
287   
288          - PR_ImportFile() 
289          - PR_ImportPipe() 
290          - PR_ImportTCPSocket() 
291          - PR_ImportUDPSocket() 
292   
293        - One can obtain the osfd in use by NSPR, either when the 
294          osfd was imported or because NSPR created the osfd itself via: 
295   
296          - PR_FileDesc2NativeHandle(); 
297   
298          But note this function is not meant to be public in the NSPR 
299          API and is documented as being deprecated and carries an 
300          explicit warning against it's use. 
301   
302        Once NSPR gets a hold of an osfd it manipulates it in a manner 
303        as if it were the only owner of the osfd. Other native code 
304        (e.g. the CPython socket code) which operates on the fd may run 
305        afoul of NSPR belief it is the only code in the system operating 
306        on the fd. For example in CPython the non-blocking flag is 
307        directly set on the fd and non-blocking behavior is implemented 
308        by the OS. However, NSPR manages non-blocking behavior 
309        internally to the NSPR library eschewing direct OS support for 
310        non-blocking. Thus CPython and NSPR are in direct conflict over 
311        when and how non-blocking is set on an fd. Examples of this 
312        problem can be seen in the Python socket.makefile() operation 
313        which takes the fd belonging to a system socket, dups it, and 
314        calls fdopen() on the dup'ed fd to return a FILE stream (all 
315        Python file IO is based on file objects utilizing a FILE 
316        stream). However, the dup'ed fd does not share the same 
317        non-blocking flag, NSPR explicitly forces the flag off, Python 
318        wants to directly manipulate it. Dup'ed fd's share their flags 
319        thus if Python operates on the dup'ed fd returned by NSPR it's 
320        going to confuse NSPR. Likewise if one sets non-blocking via 
321        NSPR then Python won't honor the flag because Python is 
322        expecting the flag to be set on the fd, not in some other 
323        location (e.g. internal to NSPR). 
324   
325      - Python's socket implementation is a very thin layer over the 
326        Berkely socket API. There is very little abstraction, thus 
327        Python and Python program expect to manipulate sockets directly 
328        via their fd's. 
329   
330      - The error and exception model for Python sockets and SSL is an 
331        almost direct one-to-one mapping of the Posix and OpenSSL 
332        errors. But NSS uses NSPR errors, thus Python code which has 
333        exception handlers for sockets and SSL are expecting a complete 
334        different set of exceptions. 
335   
336      - Python's SSL implementation is a very thin layer over the 
337        OpenSSL API, there is little abstraction. Thus there is a 
338        sizeable body of Python code which expects the OpenSSL model for 
339        IO ready and has exception handlers based on OpenSSL. 
340   
341  === 
342  FAQ 
343  === 
344   
345  To be added 
346   
347  """ 
348  __version__ = '0.11' 
349