CertificateMessageHandler extends HandshakeMessageHandler<CertificateMessage> { @Override public void adjustTLSContext(CertificateMessage message) { switch (selectTypeInternally()) { case OPEN_PGP: throw new UnsupportedOperationException("We do not support OpenPGP keys"); case RAW_PUBLIC_KEY: LOGGER.debug("Adjusting context for RAW PUBLIC KEY ceritifate message"); try { ASN1InputStream asn1Stream = new ASN1InputStream(message.getCertificatesListBytes().getValue()); DLSequence dlSeq = (DLSequence) asn1Stream.readObject(); DLSequence identifier = (DLSequence) dlSeq.getObjectAt(0); NamedGroup group = null; ASN1ObjectIdentifier keyType = (ASN1ObjectIdentifier) identifier.getObjectAt(0); if (keyType.getId().equals("1.2.840.10045.2.1")) { ASN1ObjectIdentifier curveType = (ASN1ObjectIdentifier) identifier.getObjectAt(1); if (curveType.getId().equals("1.2.840.10045.3.1.7")) { group = NamedGroup.SECP256R1; } else { throw new UnsupportedOperationException( "We currently do only support secp256r1 public keys. Sorry..."); } DERBitString publicKey = (DERBitString) dlSeq.getObjectAt(1); byte[] pointBytes = publicKey.getBytes(); Point publicKeyPoint = PointFormatter.formatFromByteArray(group, pointBytes); if (tlsContext.getTalkingConnectionEndType() == ConnectionEndType.SERVER) { tlsContext.setServerEcPublicKey(publicKeyPoint); } else { tlsContext.setClientEcPublicKey(publicKeyPoint); } } else { throw new UnsupportedOperationException( "We currently do only support EC raw public keys. Sorry..."); } asn1Stream.close(); } catch (Exception E) { LOGGER.warn("Could read RAW PublicKey. Not adjusting context", E); } break; case X509: LOGGER.debug("Adjusting context for x509 ceritifate message"); Certificate cert; if (tlsContext.getChooser().getSelectedProtocolVersion().isTLS13()) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); int certificatesLength = 0; try { for (CertificatePair pair : message.getCertificatesList()) { stream.write(ArrayConverter.intToBytes(pair.getCertificateLength().getValue(), HandshakeByteLength.CERTIFICATE_LENGTH)); stream.write(pair.getCertificate().getValue()); certificatesLength += pair.getCertificateLength().getValue() + HandshakeByteLength.CERTIFICATE_LENGTH; } } catch (IOException ex) { throw new AdjustmentException("Could not concatenate certificates bytes", ex); } cert = parseCertificate(certificatesLength, stream.toByteArray()); } else { cert = parseCertificate(message.getCertificatesListLength().getValue(), message .getCertificatesListBytes().getValue()); } if (tlsContext.getTalkingConnectionEndType() == ConnectionEndType.CLIENT) { LOGGER.debug("Setting ClientCertificate in Context"); tlsContext.setClientCertificate(cert); } else { LOGGER.debug("Setting ServerCertificate in Context"); tlsContext.setServerCertificate(cert); } if (message.getCertificateKeyPair() != null) { LOGGER.debug("Found a certificate key pair. Adjusting in context"); message.getCertificateKeyPair().adjustInContext(tlsContext, tlsContext.getTalkingConnectionEndType()); } else if (cert != null) { if (cert.isEmpty()) { LOGGER.debug("Certificate is empty - no adjustments"); } else { LOGGER.debug("No CertificatekeyPair found, creating new one"); CertificateKeyPair pair = new CertificateKeyPair(cert); message.setCertificateKeyPair(pair); message.getCertificateKeyPair().adjustInContext(tlsContext, tlsContext.getTalkingConnectionEndType()); } } else { LOGGER.debug("Ceritificate not parseable - no adjustments"); } if (tlsContext.getChooser().getSelectedProtocolVersion().isTLS13()) { adjustExtensions(message); } break; default: throw new UnsupportedOperationException("Unsupported CertificateType!"); } } CertificateMessageHandler(TlsContext tlsContext); @Override CertificateMessageParser getParser(byte[] message, int pointer); @Override CertificateMessagePreparator getPreparator(CertificateMessage message); @Override CertificateMessageSerializer getSerializer(CertificateMessage message); @Override void adjustTLSContext(CertificateMessage message);  }
@Test public void testAdjustTLSContext() { for (ProtocolVersion version : new ProtocolVersion[] { ProtocolVersion.TLS12 }) { context.setTalkingConnectionEndType(ConnectionEndType.CLIENT); context.setSelectedProtocolVersion(version); CertificateMessage message = new CertificateMessage(); message.setCertificatesListBytes(ArrayConverter .hexStringToByteArray("00023a30820236308201dba0030201020209008812dc4bf7943e2b300a06082a8648ce3d0403023077310b3009060355040613024445310c300a06035504080c034e5257310f300d06035504070c06426f6368756d312f302d060355040a0c263c7363726970743e616c6572742827544c532d41747461636b657227293c2f7363726970743e3118301606035504030c0f746c732d61747461636b65722e6465301e170d3137303232323132353032385a170d3138303232323132353032385a3077310b3009060355040613024445310c300a06035504080c034e5257310f300d06035504070c06426f6368756d312f302d060355040a0c263c7363726970743e616c6572742827544c532d41747461636b657227293c2f7363726970743e3118301606035504030c0f746c732d61747461636b65722e64653059301306072a8648ce3d020106082a8648ce3d03010703420004fbca33b6018a6b244aea13a5332b505daa865026a565f7c7dc3aed6d8b8193248abb4000cf4a1c2c29d94ce1072454ea0a990cd97c863b931f266cc3addad922a350304e301d0603551d0e041604141e9b408ab6236764f8a1d26ed696f009d7b18904301f0603551d230418301680141e9b408ab6236764f8a1d26ed696f009d7b18904300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100c9c06d798bbdf6809a3c9523bb979a64a0565fb1759182d6f6bcf6849cd70c7d022100b8e695c1915f71a348600ca90d48dfead7ea5c97b116b05c270af595c94bfa8d")); message.setCertificatesListLength(573); handler.adjustTLSContext(message); assertNotNull(context.getClientCertificate()); assertNull(context.getServerCertificate()); context = new TlsContext(); context.setTalkingConnectionEndType(ConnectionEndType.SERVER); context.setSelectedProtocolVersion(version); handler = new CertificateMessageHandler(context); handler.adjustTLSContext(message); assertNull(context.getClientCertificate()); assertNotNull(context.getServerCertificate()); } }
@Test public void testAdjustTLSContextWithUnparsableCertificate() { for (ProtocolVersion version : new ProtocolVersion[] { ProtocolVersion.SSL3, ProtocolVersion.TLS10, ProtocolVersion.TLS11, ProtocolVersion.TLS12 }) { context.setTalkingConnectionEndType(ConnectionEndType.CLIENT); context.setSelectedProtocolVersion(version); CertificateMessage message = new CertificateMessage(); message.setCertificatesListBytes(new byte[] { 0, 1, 2, 3, 4 }); message.setCertificatesListLength(5); handler.adjustTLSContext(message); assertNull(context.getClientCertificate()); assertNull(context.getServerCertificate()); context.setTalkingConnectionEndType(ConnectionEndType.SERVER); context.setSelectedProtocolVersion(version); message.setCertificatesListBytes(new byte[] { 0, 1, 2, 3, 4 }); handler.adjustTLSContext(message); assertNull(context.getClientCertificate()); assertNull(context.getServerCertificate()); } }