bb.get(buf); bb.position(pos); bb.put(buf); bb.limit(limit - blockSize); } // reset the position to the end of the decrypted data limit = bb.limit(); bb.position(limit); } } return newLen; } catch (ShortBufferException e) { RuntimeException exc = new RuntimeException(e.toString()); exc.initCause(e); throw exc; } } private static int addPadding(byte[] buf, int offset, int len, int blockSize) { int newlen = len + 1; byte pad; int i; if ((newlen % blockSize) != 0) { newlen += blockSize - 1; newlen -= newlen % blockSize; } pad = (byte) (newlen - len); if (buf.length < (newlen + offset)) { throw new IllegalArgumentException("no space to pad buffer"); } /* * TLS version of the padding works for both SSLv3 and TLSv1 */ for (i = 0, offset += len; i < pad; i++) { buf [offset++] = (byte) (pad - 1); } return newlen; } /* * Apply the padding to the buffer. * * Limit is advanced to the new buffer length. * Position is equal to limit. */ private static int addPadding(ByteBuffer bb, int blockSize) { int len = bb.remaining(); int offset = bb.position(); int newlen = len + 1; byte pad; int i; if ((newlen % blockSize) != 0) { newlen += blockSize - 1; newlen -= newlen % blockSize; } pad = (byte) (newlen - len); /* * Update the limit to what will be padded. */ bb.limit(newlen + offset); /* * TLS version of the padding works for both SSLv3 and TLSv1 */ for (i = 0, offset += len; i < pad; i++) { bb.put(offset++, (byte) (pad - 1)); } bb.position(offset); bb.limit(offset); return newlen; } /* * Typical TLS padding format for a 64 bit block cipher is as follows: * xx xx xx xx xx xx xx 00 * xx xx xx xx xx xx 01 01 * ... * xx 06 06 06 06 06 06 06 * 07 07 07 07 07 07 07 07 * TLS also allows any amount of padding from 1 and 256 bytes as long * as it makes the data a multiple of the block size */ private static int removePadding(byte[] buf, int offset, int len, int blockSize, ProtocolVersion protocolVersion) throws BadPaddingException { // last byte is length byte (i.e. actual padding length - 1) int padOffset = offset + len - 1; int pad = buf[padOffset] & 0x0ff; int newlen = len - (pad + 1); if (newlen < 0) { throw new BadPaddingException("Padding length invalid: " + pad); } if (protocolVersion.v >= ProtocolVersion.TLS10.v) { for (int i = 1; i <= pad; i++) { int val = buf[padOffset - i] & 0xff; if (val != pad) { throw new BadPaddingException ("Invalid TLS padding: " + val); } } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size // some implementations do 1 <= length byte <= block size, // so accept that as well // v3 does not require any particular value for the other bytes if (pad > blockSize) { throw new BadPaddingException("Invalid SSLv3 padding: " + pad); } } return newlen; } /* * Position/limit is equal the removed padding. */ private static int removePadding(ByteBuffer bb, int blockSize, ProtocolVersion protocolVersion) throws BadPaddingException { int len = bb.remaining(); int offset = bb.position(); // last byte is length byte (i.e. actual padding length - 1) int padOffset = offset + len - 1; int pad = bb.get(padOffset) & 0x0ff; int newlen = len - (pad + 1); if (newlen < 0) { throw new BadPaddingException("Padding length invalid: " + pad); } /* * We could zero the padding area, but not much useful * information there. */ if (protocolVersion.v >= ProtocolVersion.TLS10.v) { bb.put(padOffset, (byte)0); // zero the padding. for (int i = 1; i <= pad; i++) { int val = bb.get(padOffset - i) & 0xff; if (val != pad) { throw new BadPaddingException ("Invalid TLS padding: " + val); } } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size // some implementations do 1 <= length byte <= block size, // so accept that as well // v3 does not require any particular value for the other bytes if (pad > blockSize) { throw new BadPaddingException("Invalid SSLv3 padding: " + pad); } } /* * Reset buffer limit to remove padding. */ bb.position(offset + newlen); bb.limit(offset + newlen); return newlen; } /* * Dispose of any intermediate state in the underlying cipher. * For PKCS11 ciphers, this will release any attached sessions, and * thus make finalization faster. */ void dispose() { try { if (cipher != null) { // ignore return value. cipher.doFinal(); } } catch (GeneralSecurityException e) { // swallow for now. } } }Lines 501–694 of 694. Previous lines
bb.get(buf); bb.position(pos); bb.put(buf); bb.limit(limit - blockSize); } // reset the position to the end of the decrypted data limit = bb.limit(); bb.position(limit); } } return newLen; } catch (ShortBufferException e) { RuntimeException exc = new RuntimeException(e.toString()); exc.initCause(e); throw exc; } } private static int addPadding(byte[] buf, int offset, int len, int blockSize) { int newlen = len + 1; byte pad; int i; if ((newlen % blockSize) != 0) { newlen += blockSize - 1; newlen -= newlen % blockSize; } pad = (byte) (newlen - len); if (buf.length < (newlen + offset)) { throw new IllegalArgumentException("no space to pad buffer"); } /* * TLS version of the padding works for both SSLv3 and TLSv1 */ for (i = 0, offset += len; i < pad; i++) { buf [offset++] = (byte) (pad - 1); } return newlen; } /* * Apply the padding to the buffer. * * Limit is advanced to the new buffer length. * Position is equal to limit. */ private static int addPadding(ByteBuffer bb, int blockSize) { int len = bb.remaining(); int offset = bb.position(); int newlen = len + 1; byte pad; int i; if ((newlen % blockSize) != 0) { newlen += blockSize - 1; newlen -= newlen % blockSize; } pad = (byte) (newlen - len); /* * Update the limit to what will be padded. */ bb.limit(newlen + offset); /* * TLS version of the padding works for both SSLv3 and TLSv1 */ for (i = 0, offset += len; i < pad; i++) { bb.put(offset++, (byte) (pad - 1)); } bb.position(offset); bb.limit(offset); return newlen; } /* * Typical TLS padding format for a 64 bit block cipher is as follows: * xx xx xx xx xx xx xx 00 * xx xx xx xx xx xx 01 01 * ... * xx 06 06 06 06 06 06 06 * 07 07 07 07 07 07 07 07 * TLS also allows any amount of padding from 1 and 256 bytes as long * as it makes the data a multiple of the block size */ private static int removePadding(byte[] buf, int offset, int len, int blockSize, ProtocolVersion protocolVersion) throws BadPaddingException { // last byte is length byte (i.e. actual padding length - 1) int padOffset = offset + len - 1; int pad = buf[padOffset] & 0x0ff; int newlen = len - (pad + 1); if (newlen < 0) { throw new BadPaddingException("Padding length invalid: " + pad); } if (protocolVersion.v >= ProtocolVersion.TLS10.v) { for (int i = 1; i <= pad; i++) { int val = buf[padOffset - i] & 0xff; if (val != pad) { throw new BadPaddingException ("Invalid TLS padding: " + val); } } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size // some implementations do 1 <= length byte <= block size, // so accept that as well // v3 does not require any particular value for the other bytes if (pad > blockSize) { throw new BadPaddingException("Invalid SSLv3 padding: " + pad); } } return newlen; } /* * Position/limit is equal the removed padding. */ private static int removePadding(ByteBuffer bb, int blockSize, ProtocolVersion protocolVersion) throws BadPaddingException { int len = bb.remaining(); int offset = bb.position(); // last byte is length byte (i.e. actual padding length - 1) int padOffset = offset + len - 1; int pad = bb.get(padOffset) & 0x0ff; int newlen = len - (pad + 1); if (newlen < 0) { throw new BadPaddingException("Padding length invalid: " + pad); } /* * We could zero the padding area, but not much useful * information there. */ if (protocolVersion.v >= ProtocolVersion.TLS10.v) { bb.put(padOffset, (byte)0); // zero the padding. for (int i = 1; i <= pad; i++) { int val = bb.get(padOffset - i) & 0xff; if (val != pad) { throw new BadPaddingException ("Invalid TLS padding: " + val); } } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size // some implementations do 1 <= length byte <= block size, // so accept that as well // v3 does not require any particular value for the other bytes if (pad > blockSize) { throw new BadPaddingException("Invalid SSLv3 padding: " + pad); } } /* * Reset buffer limit to remove padding. */ bb.position(offset + newlen); bb.limit(offset + newlen); return newlen; } /* * Dispose of any intermediate state in the underlying cipher. * For PKCS11 ciphers, this will release any attached sessions, and * thus make finalization faster. */ void dispose() { try { if (cipher != null) { // ignore return value. cipher.doFinal(); } } catch (GeneralSecurityException e) { // swallow for now. } } }