Commit 4317ccc7 authored by rsleevi@chromium.org's avatar rsleevi@chromium.org

Support reading PEM files in TLSLite

BUG=none
TEST=none


Review URL: http://codereview.chromium.org/9515015

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124637 0039d316-1c4b-4281-b951-d872f2087c98
parent 88dbeefd
...@@ -120,9 +120,7 @@ class HTTPSServer(tlslite.api.TLSSocketServerMixIn, ...@@ -120,9 +120,7 @@ class HTTPSServer(tlslite.api.TLSSocketServerMixIn,
ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers, ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers,
record_resume_info): record_resume_info):
s = open(cert_path).read() s = open(cert_path).read()
x509 = tlslite.api.X509() self.cert_chain = tlslite.api.X509CertChain().parseChain(s)
x509.parse(s)
self.cert_chain = tlslite.api.X509CertChain([x509])
s = open(cert_path).read() s = open(cert_path).read()
self.private_key = tlslite.api.parsePEMKey(s, private=True) self.private_key = tlslite.api.parsePEMKey(s, private=True)
self.ssl_client_auth = ssl_client_auth self.ssl_client_auth = ssl_client_auth
......
Name: tlslite Name: tlslite
URL: http://trevp.net/tlslite/ URL: http://trevp.net/tlslite/
Version: unknown Version: 0.3.8
Security Critical: No
Local Modifications: Local Modifications:
...@@ -26,3 +27,6 @@ Local Modifications: ...@@ -26,3 +27,6 @@ Local Modifications:
default to a certificate_types of [rsa_sign] in CertificateRequest. Apple's default to a certificate_types of [rsa_sign] in CertificateRequest. Apple's
Secure Transport library rejects an empty list and raises an SSL protocol Secure Transport library rejects an empty list and raises an SSL protocol
error. error.
- patches/parse_chain.patch: tlslite/X509CertChain.py and tlslite/X509.py were
updated to add a parseChain method, that can parse multiple certificates from
a PEM string.
diff -aurb tlslite-0.3.8/tlslite/X509.py chromium/tlslite/X509.py
--- tlslite-0.3.8/tlslite/X509.py Fri Mar 19 18:43:19 2004
+++ chromium/tlslite/X509.py Wed Feb 29 11:53:54 2012
@@ -91,6 +91,7 @@
#Create a public key instance
self.publicKey = _createPublicRSAKey(n, e)
+ return self
def getFingerprint(self):
"""Get the hex-encoded fingerprint of this certificate.
diff -aurb tlslite-0.3.8/tlslite/X509CertChain.py chromium/tlslite/X509CertChain.py
--- tlslite-0.3.8/tlslite/X509CertChain.py Fri Mar 19 18:49:58 2004
+++ chromium/tlslite/X509CertChain.py Wed Feb 29 11:53:42 2012
@@ -1,6 +1,7 @@
"""Class representing an X.509 certificate chain."""
from utils import cryptomath
+from X509 import X509
class X509CertChain:
"""This class represents a chain of X.509 certificates.
@@ -23,6 +24,66 @@
self.x509List = x509List
else:
self.x509List = []
+
+ def parseChain(self, s):
+ """Parse a PEM-encoded X.509 certificate file chain file.
+
+ @type s: str
+ @param s: A PEM-encoded (eg: Base64) X.509 certificate file, with every
+ certificate wrapped within "-----BEGIN CERTIFICATE-----" and
+ "-----END CERTIFICATE-----" tags). Extraneous data outside such tags,
+ such as human readable representations, will be ignored.
+ """
+
+ class PEMIterator(object):
+ """Simple iterator over PEM-encoded certificates within a string.
+
+ @type data: string
+ @ivar data: A string containing PEM-encoded (Base64) certificates,
+ with every certificate wrapped within "-----BEGIN CERTIFICATE-----"
+ and "-----END CERTIFICATE-----" tags). Extraneous data outside such
+ tags, such as human readable representations, will be ignored.
+
+ @type index: integer
+ @ivar index: The current offset within data to begin iterating from.
+ """
+
+ _CERTIFICATE_HEADER = "----BEGIN CERTIFICATE-----"
+ """The PEM encoding block header for X.509 certificates."""
+
+ _CERTIFICATE_FOOTER = "----END CERTIFICATE-----"
+ """The PEM encoding block footer for X.509 certificates."""
+
+ def __init__(self, s):
+ self.data = s
+ self.index = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ """Iterates and returns the next L{tlslite.X509.X509}
+ certificate in data.
+
+ @rtype tlslite.X509.X509
+ """
+
+ self.index = self.data.find(self._CERTIFICATE_HEADER,
+ self.index)
+ if self.index == -1:
+ raise StopIteration
+ end = self.data.find(self._CERTIFICATE_FOOTER, self.index)
+ if end == -1:
+ raise StopIteration
+
+ certStr = self.data[self.index+len(self._CERTIFICATE_HEADER) :
+ end]
+ self.index = end + len(self._CERTIFICATE_FOOTER)
+ bytes = cryptomath.base64ToBytes(certStr)
+ return X509().parseBinary(bytes)
+
+ self.x509List = list(PEMIterator(s))
+ return self
def getNumCerts(self):
"""Get the number of certificates in this chain.
...@@ -99,6 +99,7 @@ class X509: ...@@ -99,6 +99,7 @@ class X509:
#Create a public key instance #Create a public key instance
self.publicKey = _createPublicRSAKey(n, e) self.publicKey = _createPublicRSAKey(n, e)
return self
def getFingerprint(self): def getFingerprint(self):
"""Get the hex-encoded fingerprint of this certificate. """Get the hex-encoded fingerprint of this certificate.
......
"""Class representing an X.509 certificate chain.""" """Class representing an X.509 certificate chain."""
from utils import cryptomath from utils import cryptomath
from X509 import X509
class X509CertChain: class X509CertChain:
"""This class represents a chain of X.509 certificates. """This class represents a chain of X.509 certificates.
...@@ -24,6 +25,66 @@ class X509CertChain: ...@@ -24,6 +25,66 @@ class X509CertChain:
else: else:
self.x509List = [] self.x509List = []
def parseChain(self, s):
"""Parse a PEM-encoded X.509 certificate file chain file.
@type s: str
@param s: A PEM-encoded (eg: Base64) X.509 certificate file, with every
certificate wrapped within "-----BEGIN CERTIFICATE-----" and
"-----END CERTIFICATE-----" tags). Extraneous data outside such tags,
such as human readable representations, will be ignored.
"""
class PEMIterator(object):
"""Simple iterator over PEM-encoded certificates within a string.
@type data: string
@ivar data: A string containing PEM-encoded (Base64) certificates,
with every certificate wrapped within "-----BEGIN CERTIFICATE-----"
and "-----END CERTIFICATE-----" tags). Extraneous data outside such
tags, such as human readable representations, will be ignored.
@type index: integer
@ivar index: The current offset within data to begin iterating from.
"""
_CERTIFICATE_HEADER = "-----BEGIN CERTIFICATE-----"
"""The PEM encoding block header for X.509 certificates."""
_CERTIFICATE_FOOTER = "-----END CERTIFICATE-----"
"""The PEM encoding block footer for X.509 certificates."""
def __init__(self, s):
self.data = s
self.index = 0
def __iter__(self):
return self
def next(self):
"""Iterates and returns the next L{tlslite.X509.X509}
certificate in data.
@rtype tlslite.X509.X509
"""
self.index = self.data.find(self._CERTIFICATE_HEADER,
self.index)
if self.index == -1:
raise StopIteration
end = self.data.find(self._CERTIFICATE_FOOTER, self.index)
if end == -1:
raise StopIteration
certStr = self.data[self.index+len(self._CERTIFICATE_HEADER) :
end]
self.index = end + len(self._CERTIFICATE_FOOTER)
bytes = cryptomath.base64ToBytes(certStr)
return X509().parseBinary(bytes)
self.x509List = list(PEMIterator(s))
return self
def getNumCerts(self): def getNumCerts(self):
"""Get the number of certificates in this chain. """Get the number of certificates in this chain.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment