| 
									
										
										
										
											2009-02-28 20:54:37 -05:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							|  |  |  | # The contents of this file are dedicated to the public domain.  To | 
					
						
							|  |  |  | # the extent that dedication to the public domain is not available, | 
					
						
							|  |  |  | # everyone is granted a worldwide, perpetual, royalty-free, | 
					
						
							|  |  |  | # non-exclusive license to exercise all rights associated with the | 
					
						
							|  |  |  | # contents of this file for any purpose whatsoever. | 
					
						
							|  |  |  | # No rights are reserved. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  | # SOFTWARE. | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  | from Crypto.Util.asn1 import (DerSequence, DerInteger, DerBitString, | 
					
						
							|  |  |  |                              DerObjectId, DerNull) | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  | def _expand_subject_public_key_info(encoded): | 
					
						
							|  |  |  |     """Parse a SubjectPublicKeyInfo structure.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     It returns a triple with: | 
					
						
							|  |  |  |         * OID (string) | 
					
						
							|  |  |  |         * encoded public key (bytes) | 
					
						
							| 
									
										
										
										
											2016-01-24 15:13:22 +01:00
										 |  |  |         * Algorithm parameters (bytes or None) | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # SubjectPublicKeyInfo  ::=  SEQUENCE  { | 
					
						
							|  |  |  |     #   algorithm         AlgorithmIdentifier, | 
					
						
							|  |  |  |     #   subjectPublicKey  BIT STRING | 
					
						
							|  |  |  |     # } | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  |     # AlgorithmIdentifier  ::=  SEQUENCE  { | 
					
						
							|  |  |  |     #   algorithm   OBJECT IDENTIFIER, | 
					
						
							|  |  |  |     #   parameters  ANY DEFINED BY algorithm OPTIONAL | 
					
						
							|  |  |  |     # } | 
					
						
							|  |  |  |     # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spki = DerSequence().decode(encoded, nr_elements=2) | 
					
						
							|  |  |  |     algo = DerSequence().decode(spki[0], nr_elements=(1,2)) | 
					
						
							|  |  |  |     algo_oid = DerObjectId().decode(algo[0]) | 
					
						
							|  |  |  |     spk = DerBitString().decode(spki[1]).value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if len(algo) == 1: | 
					
						
							|  |  |  |         algo_params = None | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  |             DerNull().decode(algo[1]) | 
					
						
							|  |  |  |             algo_params = None | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             algo_params = algo[1] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 15:13:22 +01:00
										 |  |  |     return algo_oid.value, spk, algo_params | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-15 00:15:48 +02:00
										 |  |  | def _create_subject_public_key_info(algo_oid, public_key, params): | 
					
						
							| 
									
										
										
										
											2016-01-27 08:33:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if params is None: | 
					
						
							| 
									
										
										
										
											2022-04-15 00:15:48 +02:00
										 |  |  |         algorithm = DerSequence([DerObjectId(algo_oid)]) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         algorithm = DerSequence([DerObjectId(algo_oid), params]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spki = DerSequence([algorithm, | 
					
						
							|  |  |  |                         DerBitString(public_key) | 
					
						
							|  |  |  |                         ]) | 
					
						
							| 
									
										
										
										
											2016-01-27 08:33:55 +01:00
										 |  |  |     return spki.encode() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  | def _extract_subject_public_key_info(x509_certificate): | 
					
						
							|  |  |  |     """Extract subjectPublicKeyInfo from a DER X.509 certificate.""" | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  |     certificate = DerSequence().decode(x509_certificate, nr_elements=3) | 
					
						
							|  |  |  |     tbs_certificate = DerSequence().decode(certificate[0], | 
					
						
							|  |  |  |                                            nr_elements=range(6, 11)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     index = 5 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         tbs_certificate[0] + 1 | 
					
						
							|  |  |  |         # Version not present | 
					
						
							|  |  |  |         version = 1 | 
					
						
							|  |  |  |     except TypeError: | 
					
						
							|  |  |  |         version = DerInteger(explicit=0).decode(tbs_certificate[0]).value | 
					
						
							|  |  |  |         if version not in (2, 3): | 
					
						
							|  |  |  |             raise ValueError("Incorrect X.509 certificate version") | 
					
						
							|  |  |  |         index = 6 | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-23 13:33:08 +01:00
										 |  |  |     return tbs_certificate[index] |