417 }
418
419 handshakeLock.lock();
420 try {
421 // double check the context status
422 if (conContext.isBroken || conContext.isInboundClosed() ||
423 conContext.isOutboundClosed()) {
424 throw new SocketException("Socket has been closed or broken");
425 }
426
427 try {
428 conContext.kickstart();
429
430 // All initial handshaking goes through this operation until we
431 // have a valid SSL connection.
432 //
433 // Handle handshake messages only, need no application data.
434 if (!conContext.isNegotiated) {
435 readHandshakeRecord();
436 }
437 } catch (IOException ioe) {
438 throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
439 "Couldn't kickstart handshaking", ioe);
440 } catch (Exception oe) { // including RuntimeException
441 handleException(oe);
442 }
443 } finally {
444 handshakeLock.unlock();
445 }
446 }
447
448 @Override
449 public void setUseClientMode(boolean mode) {
450 socketLock.lock();
451 try {
452 conContext.setUseClientMode(mode);
453 } finally {
454 socketLock.unlock();
455 }
456 }
1278 try {
1279 return conContext.sslConfig.socketAPSelector;
1280 } finally {
1281 socketLock.unlock();
1282 }
1283 }
1284
1285 /**
1286 * Read the initial handshake records.
1287 */
1288 private int readHandshakeRecord() throws IOException {
1289 while (!conContext.isInboundClosed()) {
1290 try {
1291 Plaintext plainText = decode(null);
1292 if ((plainText.contentType == ContentType.HANDSHAKE.id) &&
1293 conContext.isNegotiated) {
1294 return 0;
1295 }
1296 } catch (SSLException ssle) {
1297 throw ssle;
1298 } catch (IOException ioe) {
1299 if (!(ioe instanceof SSLException)) {
1300 throw new SSLException("readHandshakeRecord", ioe);
1301 } else {
1302 throw ioe;
1303 }
1304 }
1305 }
1306
1307 return -1;
1308 }
1309
1310 /**
1311 * Read application data record. Used by AppInputStream only, but defined
1312 * here so as to use the socket level synchronization.
1313 *
1314 * Note that the connection guarantees that handshake, alert, and change
1315 * cipher spec data streams are handled as they arrive, so we never see
1316 * them here.
1317 *
1318 * Note: Please be careful about the synchronization, and don't use this
1319 * method other than in the AppInputStream class!
1320 */
1321 private ByteBuffer readApplicationRecord(
1322 ByteBuffer buffer) throws IOException {
1323 while (!conContext.isInboundClosed()) {
1344 }
1345
1346 if (inLen > buffer.remaining()) {
1347 buffer = ByteBuffer.allocate(inLen);
1348 }
1349
1350 try {
1351 Plaintext plainText;
1352 socketLock.lock();
1353 try {
1354 plainText = decode(buffer);
1355 } finally {
1356 socketLock.unlock();
1357 }
1358 if (plainText.contentType == ContentType.APPLICATION_DATA.id &&
1359 buffer.position() > 0) {
1360 return buffer;
1361 }
1362 } catch (SSLException ssle) {
1363 throw ssle;
1364 } catch (IOException ioe) {
1365 if (!(ioe instanceof SSLException)) {
1366 throw new SSLException("readApplicationRecord", ioe);
1367 } else {
1368 throw ioe;
1369 }
1370 }
1371 }
1372
1373 //
1374 // couldn't read, due to some kind of error
1375 //
1376 return null;
1377 }
1378
1379 private Plaintext decode(ByteBuffer destination) throws IOException {
1380 Plaintext plainText;
1381 try {
1382 if (destination == null) {
1383 plainText = SSLTransport.decode(conContext,
|
417 }
418
419 handshakeLock.lock();
420 try {
421 // double check the context status
422 if (conContext.isBroken || conContext.isInboundClosed() ||
423 conContext.isOutboundClosed()) {
424 throw new SocketException("Socket has been closed or broken");
425 }
426
427 try {
428 conContext.kickstart();
429
430 // All initial handshaking goes through this operation until we
431 // have a valid SSL connection.
432 //
433 // Handle handshake messages only, need no application data.
434 if (!conContext.isNegotiated) {
435 readHandshakeRecord();
436 }
437 } catch (InterruptedIOException iioe) {
438 handleException(iioe);
439 } catch (IOException ioe) {
440 throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
441 "Couldn't kickstart handshaking", ioe);
442 } catch (Exception oe) { // including RuntimeException
443 handleException(oe);
444 }
445 } finally {
446 handshakeLock.unlock();
447 }
448 }
449
450 @Override
451 public void setUseClientMode(boolean mode) {
452 socketLock.lock();
453 try {
454 conContext.setUseClientMode(mode);
455 } finally {
456 socketLock.unlock();
457 }
458 }
1280 try {
1281 return conContext.sslConfig.socketAPSelector;
1282 } finally {
1283 socketLock.unlock();
1284 }
1285 }
1286
1287 /**
1288 * Read the initial handshake records.
1289 */
1290 private int readHandshakeRecord() throws IOException {
1291 while (!conContext.isInboundClosed()) {
1292 try {
1293 Plaintext plainText = decode(null);
1294 if ((plainText.contentType == ContentType.HANDSHAKE.id) &&
1295 conContext.isNegotiated) {
1296 return 0;
1297 }
1298 } catch (SSLException ssle) {
1299 throw ssle;
1300 } catch (InterruptedIOException iioe) {
1301 // don't change exception in case of timeouts or interrupts
1302 throw iioe;
1303 } catch (IOException ioe) {
1304 throw new SSLException("readHandshakeRecord", ioe);
1305 }
1306 }
1307
1308 return -1;
1309 }
1310
1311 /**
1312 * Read application data record. Used by AppInputStream only, but defined
1313 * here so as to use the socket level synchronization.
1314 *
1315 * Note that the connection guarantees that handshake, alert, and change
1316 * cipher spec data streams are handled as they arrive, so we never see
1317 * them here.
1318 *
1319 * Note: Please be careful about the synchronization, and don't use this
1320 * method other than in the AppInputStream class!
1321 */
1322 private ByteBuffer readApplicationRecord(
1323 ByteBuffer buffer) throws IOException {
1324 while (!conContext.isInboundClosed()) {
1345 }
1346
1347 if (inLen > buffer.remaining()) {
1348 buffer = ByteBuffer.allocate(inLen);
1349 }
1350
1351 try {
1352 Plaintext plainText;
1353 socketLock.lock();
1354 try {
1355 plainText = decode(buffer);
1356 } finally {
1357 socketLock.unlock();
1358 }
1359 if (plainText.contentType == ContentType.APPLICATION_DATA.id &&
1360 buffer.position() > 0) {
1361 return buffer;
1362 }
1363 } catch (SSLException ssle) {
1364 throw ssle;
1365 } catch (InterruptedIOException iioe) {
1366 // don't change exception in case of timeouts or interrupts
1367 throw iioe;
1368 } catch (IOException ioe) {
1369 if (!(ioe instanceof SSLException)) {
1370 throw new SSLException("readApplicationRecord", ioe);
1371 } else {
1372 throw ioe;
1373 }
1374 }
1375 }
1376
1377 //
1378 // couldn't read, due to some kind of error
1379 //
1380 return null;
1381 }
1382
1383 private Plaintext decode(ByteBuffer destination) throws IOException {
1384 Plaintext plainText;
1385 try {
1386 if (destination == null) {
1387 plainText = SSLTransport.decode(conContext,
|