Only in chromium: patches diff -aur tlslite-0.3.8/tlslite/TLSConnection.py chromium/tlslite/TLSConnection.py --- tlslite-0.3.8/tlslite/TLSConnection.py 2004-10-06 01:55:37.000000000 -0400 +++ chromium/tlslite/TLSConnection.py 2010-08-18 22:17:30.962786700 -0400 @@ -931,7 +931,8 @@ def handshakeServer(self, sharedKeyDB=None, verifierDB=None, certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None): + sessionCache=None, settings=None, checker=None, + reqCAs=None): """Perform a handshake in the role of server. This function performs an SSL or TLS handshake. Depending on @@ -997,6 +998,11 @@ invoked to examine the other party's authentication credentials, if the handshake completes succesfully. + @type reqCAs: list of L{array.array} of unsigned bytes + @param reqCAs: A collection of DER-encoded DistinguishedNames that + will be sent along with a certificate request. This does not affect + verification. + @raise socket.error: If a socket error occurs. @raise tlslite.errors.TLSAbruptCloseError: If the socket is closed without a preceding alert. @@ -1006,13 +1012,14 @@ """ for result in self.handshakeServerAsync(sharedKeyDB, verifierDB, certChain, privateKey, reqCert, sessionCache, settings, - checker): + checker, reqCAs): pass def handshakeServerAsync(self, sharedKeyDB=None, verifierDB=None, certChain=None, privateKey=None, reqCert=False, - sessionCache=None, settings=None, checker=None): + sessionCache=None, settings=None, checker=None, + reqCAs=None): """Start a server handshake operation on the TLS connection. This function returns a generator which behaves similarly to @@ -1028,14 +1035,15 @@ sharedKeyDB=sharedKeyDB, verifierDB=verifierDB, certChain=certChain, privateKey=privateKey, reqCert=reqCert, - sessionCache=sessionCache, settings=settings) + sessionCache=sessionCache, settings=settings, + reqCAs=reqCAs) for result in self._handshakeWrapperAsync(handshaker, checker): yield result def _handshakeServerAsyncHelper(self, sharedKeyDB, verifierDB, certChain, privateKey, reqCert, sessionCache, - settings): + settings, reqCAs): self._handshakeStart(client=False) @@ -1045,6 +1053,8 @@ raise ValueError("Caller passed a certChain but no privateKey") if privateKey and not certChain: raise ValueError("Caller passed a privateKey but no certChain") + if reqCAs and not reqCert: + raise ValueError("Caller passed reqCAs but not reqCert") if not settings: settings = HandshakeSettings() @@ -1380,7 +1390,9 @@ msgs.append(ServerHello().create(self.version, serverRandom, sessionID, cipherSuite, certificateType)) msgs.append(Certificate(certificateType).create(serverCertChain)) - if reqCert: + if reqCert and reqCAs: + msgs.append(CertificateRequest().create([], reqCAs)) + elif reqCert: msgs.append(CertificateRequest()) msgs.append(ServerHelloDone()) for result in self._sendMsgs(msgs): diff -aur tlslite-0.3.8/tlslite/X509.py chromium/tlslite/X509.py --- tlslite-0.3.8/tlslite/X509.py 2004-03-19 21:43:19.000000000 -0400 +++ chromium/tlslite/X509.py 2010-08-18 22:17:30.967787000 -0400 @@ -13,11 +13,15 @@ @type publicKey: L{tlslite.utils.RSAKey.RSAKey} @ivar publicKey: The subject public key from the certificate. + + @type subject: L{array.array} of unsigned bytes + @ivar subject: The DER-encoded ASN.1 subject distinguished name. """ def __init__(self): self.bytes = createByteArraySequence([]) self.publicKey = None + self.subject = None def parse(self, s): """Parse a PEM-encoded X.509 certificate. @@ -63,6 +67,10 @@ else: subjectPublicKeyInfoIndex = 5 + #Get the subject + self.subject = tbsCertificateP.getChildBytes(\ + subjectPublicKeyInfoIndex - 1) + #Get the subjectPublicKeyInfo subjectPublicKeyInfoP = tbsCertificateP.getChild(\ subjectPublicKeyInfoIndex) diff -aur tlslite-0.3.8/tlslite/messages.py chromium/tlslite/messages.py --- tlslite-0.3.8/tlslite/messages.py 2004-10-06 01:01:24.000000000 -0400 +++ chromium/tlslite/messages.py 2010-08-18 22:17:30.976787500 -0400 @@ -338,8 +338,7 @@ def __init__(self): self.contentType = ContentType.handshake self.certificate_types = [] - #treat as opaque bytes for now - self.certificate_authorities = createByteArraySequence([]) + self.certificate_authorities = [] def create(self, certificate_types, certificate_authorities): self.certificate_types = certificate_types @@ -349,7 +348,13 @@ def parse(self, p): p.startLengthCheck(3) self.certificate_types = p.getVarList(1, 1) - self.certificate_authorities = p.getVarBytes(2) + ca_list_length = p.get(2) + index = 0 + self.certificate_authorities = [] + while index != ca_list_length: + ca_bytes = p.getVarBytes(2) + self.certificate_authorities.append(ca_bytes) + index += len(ca_bytes)+2 p.stopLengthCheck() return self @@ -357,7 +362,14 @@ w = HandshakeMsg.preWrite(self, HandshakeType.certificate_request, trial) w.addVarSeq(self.certificate_types, 1, 1) - w.addVarSeq(self.certificate_authorities, 1, 2) + caLength = 0 + #determine length + for ca_dn in self.certificate_authorities: + caLength += len(ca_dn)+2 + w.add(caLength, 2) + #add bytes + for ca_dn in self.certificate_authorities: + w.addVarSeq(ca_dn, 1, 2) return HandshakeMsg.postWrite(self, w, trial) class ServerKeyExchange(HandshakeMsg): diff -aur tlslite-0.3.8/tlslite/utils/ASN1Parser.py chromium/tlslite/utils/ASN1Parser.py --- tlslite-0.3.8/tlslite/utils/ASN1Parser.py 2004-10-06 01:02:40.000000000 -0400 +++ chromium/tlslite/utils/ASN1Parser.py 2010-08-18 22:17:30.979787700 -0400 @@ -16,13 +16,16 @@ #Assuming this is a sequence... def getChild(self, which): + return ASN1Parser(self.getChildBytes(which)) + + def getChildBytes(self, which): p = Parser(self.value) for x in range(which+1): markIndex = p.index p.get(1) #skip Type length = self._getASN1Length(p) p.getFixBytes(length) - return ASN1Parser(p.bytes[markIndex : p.index]) + return p.bytes[markIndex : p.index] #Decode the ASN.1 DER length field def _getASN1Length(self, p):