/** * Parse a {@link CertificateRequest} from an {@link InputStream}. * * @param context the {@link TlsContext} of the current connection. * @param input the {@link InputStream} to parse from. * @return a {@link CertificateRequest} object. * @throws IOException */ public static CertificateRequest parse(TlsContext context, InputStream input) throws IOException { int numTypes = TlsUtils.readUint8(input); short[] certificateTypes = new short[numTypes]; for (int i = 0; i < numTypes; ++i) { certificateTypes[i] = TlsUtils.readUint8(input); } Vector supportedSignatureAlgorithms = null; if (TlsUtils.isTLSv12(context)) { // TODO Check whether SignatureAlgorithm.anonymous is allowed here supportedSignatureAlgorithms = TlsUtils.parseSupportedSignatureAlgorithms(false, input); } Vector certificateAuthorities = new Vector(); byte[] certAuthData = TlsUtils.readOpaque16(input); ByteArrayInputStream bis = new ByteArrayInputStream(certAuthData); while (bis.available() > 0) { byte[] derEncoding = TlsUtils.readOpaque16(bis); ASN1Primitive asn1 = TlsUtils.readDERObject(derEncoding); certificateAuthorities.addElement(X500Name.getInstance(asn1)); } return new CertificateRequest( certificateTypes, supportedSignatureAlgorithms, certificateAuthorities); }
/** * Parse a {@link DigitallySigned} from an {@link InputStream}. * * @param context the {@link TlsContext} of the current connection. * @param input the {@link InputStream} to parse from. * @return a {@link DigitallySigned} object. * @throws IOException */ public static DigitallySigned parse(TlsContext context, InputStream input) throws IOException { SignatureAndHashAlgorithm algorithm = null; if (TlsUtils.isTLSv12(context)) { algorithm = SignatureAndHashAlgorithm.parse(input); } byte[] signature = TlsUtils.readOpaque16(input); return new DigitallySigned(algorithm, signature); }
public byte[] generateCertificateSignature(byte[] hash) throws IOException { try { if (TlsUtils.isTLSv12(context)) { return signer.generateRawSignature(signatureAndHashAlgorithm, privateKey, hash); } else { return signer.generateRawSignature(privateKey, hash); } } catch (CryptoException e) { throw new TlsFatalAlert(AlertDescription.internal_error, e); } }
public DefaultTlsSignerCredentials( TlsContext context, Certificate certificate, AsymmetricKeyParameter privateKey, SignatureAndHashAlgorithm signatureAndHashAlgorithm) { if (certificate == null) { throw new IllegalArgumentException("'certificate' cannot be null"); } if (certificate.isEmpty()) { throw new IllegalArgumentException("'certificate' cannot be empty"); } if (privateKey == null) { throw new IllegalArgumentException("'privateKey' cannot be null"); } if (!privateKey.isPrivate()) { throw new IllegalArgumentException("'privateKey' must be private"); } if (TlsUtils.isTLSv12(context) && signatureAndHashAlgorithm == null) { throw new IllegalArgumentException( "'signatureAndHashAlgorithm' cannot be null for (D)TLS 1.2+"); } if (privateKey instanceof RSAKeyParameters) { this.signer = new TlsRSASigner(); } else if (privateKey instanceof DSAPrivateKeyParameters) { this.signer = new TlsDSSSigner(); } else if (privateKey instanceof ECPrivateKeyParameters) { this.signer = new TlsECDSASigner(); } else { throw new IllegalArgumentException( "'privateKey' type not supported: " + privateKey.getClass().getName()); } this.signer.init(context); this.context = context; this.certificate = certificate; this.privateKey = privateKey; this.signatureAndHashAlgorithm = signatureAndHashAlgorithm; }
protected Signer makeSigner( SignatureAndHashAlgorithm algorithm, boolean raw, boolean forSigning, CipherParameters cp) { if ((algorithm != null) != TlsUtils.isTLSv12(context)) { throw new IllegalStateException(); } if (algorithm != null && algorithm.getSignature() != SignatureAlgorithm.rsa) { throw new IllegalStateException(); } Digest d; if (raw) { d = new NullDigest(); } else if (algorithm == null) { d = new CombinedHash(); } else { d = TlsUtils.createHash(algorithm.getHash()); } Signer s; if (algorithm != null) { /* * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1]. */ s = new RSADigestSigner(d, TlsUtils.getOIDForHashAlgorithm(algorithm.getHash())); } else { /* * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme * that did not include a DigestInfo encoding. */ s = new GenericSigner(createRSAImpl(), d); } s.init(forSigning, cp); return s; }
protected DTLSTransport serverHandshake(ServerHandshakeState state, DTLSRecordLayer recordLayer) throws IOException { SecurityParameters securityParameters = state.serverContext.getSecurityParameters(); DTLSReliableHandshake handshake = new DTLSReliableHandshake(state.serverContext, recordLayer); DTLSReliableHandshake.Message clientMessage = handshake.receiveMessage(); { // NOTE: After receiving a record from the client, we discover the record layer version ProtocolVersion client_version = recordLayer.getDiscoveredPeerVersion(); // TODO Read RFCs for guidance on the expected record layer version number state.serverContext.setClientVersion(client_version); } if (clientMessage.getType() == HandshakeType.client_hello) { processClientHello(state, clientMessage.getBody()); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } { byte[] serverHelloBody = generateServerHello(state); if (state.maxFragmentLength >= 0) { int plainTextLimit = 1 << (8 + state.maxFragmentLength); recordLayer.setPlaintextLimit(plainTextLimit); } securityParameters.cipherSuite = state.selectedCipherSuite; securityParameters.compressionAlgorithm = state.selectedCompressionMethod; securityParameters.prfAlgorithm = TlsProtocol.getPRFAlgorithm(state.serverContext, state.selectedCipherSuite); /* * RFC 5264 7.4.9. Any cipher suite which does not explicitly specify verify_data_length * has a verify_data_length equal to 12. This includes all existing cipher suites. */ securityParameters.verifyDataLength = 12; handshake.sendMessage(HandshakeType.server_hello, serverHelloBody); } handshake.notifyHelloComplete(); Vector serverSupplementalData = state.server.getServerSupplementalData(); if (serverSupplementalData != null) { byte[] supplementalDataBody = generateSupplementalData(serverSupplementalData); handshake.sendMessage(HandshakeType.supplemental_data, supplementalDataBody); } state.keyExchange = state.server.getKeyExchange(); state.keyExchange.init(state.serverContext); state.serverCredentials = state.server.getCredentials(); Certificate serverCertificate = null; if (state.serverCredentials == null) { state.keyExchange.skipServerCredentials(); } else { state.keyExchange.processServerCredentials(state.serverCredentials); serverCertificate = state.serverCredentials.getCertificate(); byte[] certificateBody = generateCertificate(serverCertificate); handshake.sendMessage(HandshakeType.certificate, certificateBody); } // TODO[RFC 3546] Check whether empty certificates is possible, allowed, or excludes // CertificateStatus if (serverCertificate == null || serverCertificate.isEmpty()) { state.allowCertificateStatus = false; } if (state.allowCertificateStatus) { CertificateStatus certificateStatus = state.server.getCertificateStatus(); if (certificateStatus != null) { byte[] certificateStatusBody = generateCertificateStatus(state, certificateStatus); handshake.sendMessage(HandshakeType.certificate_status, certificateStatusBody); } } byte[] serverKeyExchange = state.keyExchange.generateServerKeyExchange(); if (serverKeyExchange != null) { handshake.sendMessage(HandshakeType.server_key_exchange, serverKeyExchange); } if (state.serverCredentials != null) { state.certificateRequest = state.server.getCertificateRequest(); if (state.certificateRequest != null) { state.keyExchange.validateCertificateRequest(state.certificateRequest); byte[] certificateRequestBody = generateCertificateRequest(state, state.certificateRequest); handshake.sendMessage(HandshakeType.certificate_request, certificateRequestBody); TlsUtils.trackHashAlgorithms( handshake.getHandshakeHash(), state.certificateRequest.getSupportedSignatureAlgorithms()); } } handshake.sendMessage(HandshakeType.server_hello_done, TlsUtils.EMPTY_BYTES); handshake.getHandshakeHash().sealHashAlgorithms(); clientMessage = handshake.receiveMessage(); if (clientMessage.getType() == HandshakeType.supplemental_data) { processClientSupplementalData(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); } else { state.server.processClientSupplementalData(null); } if (state.certificateRequest == null) { state.keyExchange.skipClientCredentials(); } else { if (clientMessage.getType() == HandshakeType.certificate) { processClientCertificate(state, clientMessage.getBody()); clientMessage = handshake.receiveMessage(); } else { if (TlsUtils.isTLSv12(state.serverContext)) { /* * RFC 5246 If no suitable certificate is available, the client MUST send a * certificate message containing no certificates. * * NOTE: In previous RFCs, this was SHOULD instead of MUST. */ throw new TlsFatalAlert(AlertDescription.unexpected_message); } notifyClientCertificate(state, Certificate.EMPTY_CHAIN); } } if (clientMessage.getType() == HandshakeType.client_key_exchange) { processClientKeyExchange(state, clientMessage.getBody()); } else { throw new TlsFatalAlert(AlertDescription.unexpected_message); } TlsProtocol.establishMasterSecret(state.serverContext, state.keyExchange); recordLayer.initPendingEpoch(state.server.getCipher()); TlsHandshakeHash prepareFinishHash = handshake.prepareToFinish(); /* * RFC 5246 7.4.8 This message is only sent following a client certificate that has signing * capability (i.e., all certificates except those containing fixed Diffie-Hellman * parameters). */ if (expectCertificateVerifyMessage(state)) { byte[] certificateVerifyBody = handshake.receiveMessageBody(HandshakeType.certificate_verify); processCertificateVerify(state, certificateVerifyBody, prepareFinishHash); } // NOTE: Calculated exclusive of the actual Finished message from the client byte[] expectedClientVerifyData = TlsUtils.calculateVerifyData( state.serverContext, ExporterLabel.client_finished, TlsProtocol.getCurrentPRFHash(state.serverContext, handshake.getHandshakeHash(), null)); processFinished(handshake.receiveMessageBody(HandshakeType.finished), expectedClientVerifyData); if (state.expectSessionTicket) { NewSessionTicket newSessionTicket = state.server.getNewSessionTicket(); byte[] newSessionTicketBody = generateNewSessionTicket(state, newSessionTicket); handshake.sendMessage(HandshakeType.session_ticket, newSessionTicketBody); } // NOTE: Calculated exclusive of the Finished message itself byte[] serverVerifyData = TlsUtils.calculateVerifyData( state.serverContext, ExporterLabel.server_finished, TlsProtocol.getCurrentPRFHash(state.serverContext, handshake.getHandshakeHash(), null)); handshake.sendMessage(HandshakeType.finished, serverVerifyData); handshake.finish(); state.server.notifyHandshakeComplete(); return new DTLSTransport(recordLayer); }