8296024: Usage of DirectBuffer::address should be guarded
Reviewed-by: mcimadamore, alanb, psandoz, bpb
This commit is contained in:
parent
a9e6c62ba7
commit
84b927a05b
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package com.sun.crypto.provider;
|
package com.sun.crypto.provider;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.security.jca.JCAUtil;
|
import sun.security.jca.JCAUtil;
|
||||||
@ -92,6 +94,8 @@ abstract class GaloisCounterMode extends CipherSpi {
|
|||||||
|
|
||||||
static final byte[] EMPTY_BUF = new byte[0];
|
static final byte[] EMPTY_BUF = new byte[0];
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
private boolean initialized = false;
|
private boolean initialized = false;
|
||||||
|
|
||||||
SymmetricCipher blockCipher;
|
SymmetricCipher blockCipher;
|
||||||
@ -909,6 +913,8 @@ abstract class GaloisCounterMode extends CipherSpi {
|
|||||||
*/
|
*/
|
||||||
ByteBuffer overlapDetection(ByteBuffer src, ByteBuffer dst) {
|
ByteBuffer overlapDetection(ByteBuffer src, ByteBuffer dst) {
|
||||||
if (src.isDirect() && dst.isDirect()) {
|
if (src.isDirect() && dst.isDirect()) {
|
||||||
|
// The use of DirectBuffer::address below need not be guarded as
|
||||||
|
// no access is made to actual memory.
|
||||||
DirectBuffer dsrc = (DirectBuffer) src;
|
DirectBuffer dsrc = (DirectBuffer) src;
|
||||||
DirectBuffer ddst = (DirectBuffer) dst;
|
DirectBuffer ddst = (DirectBuffer) dst;
|
||||||
|
|
||||||
@ -946,7 +952,6 @@ abstract class GaloisCounterMode extends CipherSpi {
|
|||||||
((DirectBuffer) dst).address() - dstaddr + dst.position()) {
|
((DirectBuffer) dst).address() - dstaddr + dst.position()) {
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!src.isDirect() && !dst.isDirect()) {
|
} else if (!src.isDirect() && !dst.isDirect()) {
|
||||||
// if src is read only, then we need a copy
|
// if src is read only, then we need a copy
|
||||||
if (!src.isReadOnly()) {
|
if (!src.isReadOnly()) {
|
||||||
@ -1585,8 +1590,13 @@ abstract class GaloisCounterMode extends CipherSpi {
|
|||||||
int ofs = dst.arrayOffset() + dst.position();
|
int ofs = dst.arrayOffset() + dst.position();
|
||||||
Arrays.fill(dst.array(), ofs , ofs + len, (byte)0);
|
Arrays.fill(dst.array(), ofs , ofs + len, (byte)0);
|
||||||
} else {
|
} else {
|
||||||
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
|
NIO_ACCESS.acquireSession(dst);
|
||||||
len + dst.position(), (byte)0);
|
try {
|
||||||
|
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
|
||||||
|
len + dst.position(), (byte) 0);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(dst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new AEADBadTagException("Tag mismatch");
|
throw new AEADBadTagException("Tag mismatch");
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.lang.foreign.MemorySegment;
|
import java.lang.foreign.MemorySegment;
|
||||||
|
import java.lang.ref.Reference;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Spliterator;
|
import java.util.Spliterator;
|
||||||
|
|
||||||
@ -779,6 +780,7 @@ public abstract sealed class Buffer
|
|||||||
// setup access to this package in SharedSecrets
|
// setup access to this package in SharedSecrets
|
||||||
SharedSecrets.setJavaNioAccess(
|
SharedSecrets.setJavaNioAccess(
|
||||||
new JavaNioAccess() {
|
new JavaNioAccess() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BufferPool getDirectBufferPool() {
|
public BufferPool getDirectBufferPool() {
|
||||||
return Bits.BUFFER_POOL;
|
return Bits.BUFFER_POOL;
|
||||||
@ -824,16 +826,34 @@ public abstract sealed class Buffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Runnable acquireSession(Buffer buffer, boolean async) {
|
public void acquireSession(Buffer buffer) {
|
||||||
var session = buffer.session();
|
var scope = buffer.session();
|
||||||
if (session == null) {
|
if (scope != null) {
|
||||||
return null;
|
scope.acquire0();
|
||||||
}
|
}
|
||||||
if (async && session.ownerThread() != null) {
|
}
|
||||||
throw new IllegalStateException("Confined session not supported");
|
|
||||||
|
@Override
|
||||||
|
public void releaseSession(Buffer buffer) {
|
||||||
|
try {
|
||||||
|
var scope = buffer.session();
|
||||||
|
if (scope != null) {
|
||||||
|
scope.release0();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Reference.reachabilityFence(buffer);
|
||||||
}
|
}
|
||||||
session.acquire0();
|
}
|
||||||
return session::release0;
|
|
||||||
|
@Override
|
||||||
|
public boolean isThreadConfined(Buffer buffer) {
|
||||||
|
var scope = buffer.session();
|
||||||
|
return scope != null && scope.ownerThread() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSession(Buffer buffer) {
|
||||||
|
return buffer.session() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,11 +25,13 @@
|
|||||||
|
|
||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import sun.nio.ch.DirectBuffer;
|
|
||||||
import jdk.internal.util.Preconditions;
|
import jdk.internal.util.Preconditions;
|
||||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||||
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that can be used to compute the Adler-32 checksum of a data
|
* A class that can be used to compute the Adler-32 checksum of a data
|
||||||
@ -96,10 +98,11 @@ public class Adler32 implements Checksum {
|
|||||||
if (rem <= 0)
|
if (rem <= 0)
|
||||||
return;
|
return;
|
||||||
if (buffer.isDirect()) {
|
if (buffer.isDirect()) {
|
||||||
|
NIO_ACCESS.acquireSession(buffer);
|
||||||
try {
|
try {
|
||||||
adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
|
adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(buffer);
|
NIO_ACCESS.releaseSession(buffer);
|
||||||
}
|
}
|
||||||
} else if (buffer.hasArray()) {
|
} else if (buffer.hasArray()) {
|
||||||
adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);
|
adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -33,6 +32,8 @@ import sun.nio.ch.DirectBuffer;
|
|||||||
import jdk.internal.util.Preconditions;
|
import jdk.internal.util.Preconditions;
|
||||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||||
|
|
||||||
|
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that can be used to compute the CRC-32 of a data stream.
|
* A class that can be used to compute the CRC-32 of a data stream.
|
||||||
*
|
*
|
||||||
@ -96,10 +97,11 @@ public class CRC32 implements Checksum {
|
|||||||
if (rem <= 0)
|
if (rem <= 0)
|
||||||
return;
|
return;
|
||||||
if (buffer.isDirect()) {
|
if (buffer.isDirect()) {
|
||||||
|
NIO_ACCESS.acquireSession(buffer);
|
||||||
try {
|
try {
|
||||||
crc = updateByteBuffer(crc, ((DirectBuffer)buffer).address(), pos, rem);
|
crc = updateByteBuffer(crc, ((DirectBuffer)buffer).address(), pos, rem);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(buffer);
|
NIO_ACCESS.releaseSession(buffer);
|
||||||
}
|
}
|
||||||
} else if (buffer.hasArray()) {
|
} else if (buffer.hasArray()) {
|
||||||
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(), rem);
|
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(), rem);
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
@ -33,6 +32,8 @@ import jdk.internal.util.Preconditions;
|
|||||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that can be used to compute the CRC-32C of a data stream.
|
* A class that can be used to compute the CRC-32C of a data stream.
|
||||||
*
|
*
|
||||||
@ -171,11 +172,12 @@ public final class CRC32C implements Checksum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer.isDirect()) {
|
if (buffer.isDirect()) {
|
||||||
|
NIO_ACCESS.acquireSession(buffer);
|
||||||
try {
|
try {
|
||||||
crc = updateDirectByteBuffer(crc, ((DirectBuffer) buffer).address(),
|
crc = updateDirectByteBuffer(crc, ((DirectBuffer)buffer).address(),
|
||||||
pos, limit);
|
pos, limit);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(buffer);
|
NIO_ACCESS.releaseSession(buffer);
|
||||||
}
|
}
|
||||||
} else if (buffer.hasArray()) {
|
} else if (buffer.hasArray()) {
|
||||||
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(),
|
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(),
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.lang.ref.Cleaner.Cleanable;
|
import java.lang.ref.Cleaner.Cleanable;
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ReadOnlyBufferException;
|
import java.nio.ReadOnlyBufferException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
|
|||||||
import jdk.internal.util.Preconditions;
|
import jdk.internal.util.Preconditions;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides support for general purpose compression using the
|
* This class provides support for general purpose compression using the
|
||||||
* popular ZLIB compression library. The ZLIB compression library was
|
* popular ZLIB compression library. The ZLIB compression library was
|
||||||
@ -337,11 +338,12 @@ public class Deflater {
|
|||||||
int remaining = Math.max(dictionary.limit() - position, 0);
|
int remaining = Math.max(dictionary.limit() - position, 0);
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
if (dictionary.isDirect()) {
|
if (dictionary.isDirect()) {
|
||||||
long address = ((DirectBuffer) dictionary).address();
|
NIO_ACCESS.acquireSession(dictionary);
|
||||||
try {
|
try {
|
||||||
|
long address = ((DirectBuffer) dictionary).address();
|
||||||
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(dictionary);
|
NIO_ACCESS.releaseSession(dictionary);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] array = ZipUtils.getBufferArray(dictionary);
|
byte[] array = ZipUtils.getBufferArray(dictionary);
|
||||||
@ -587,6 +589,7 @@ public class Deflater {
|
|||||||
inputPos = input.position();
|
inputPos = input.position();
|
||||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||||
if (input.isDirect()) {
|
if (input.isDirect()) {
|
||||||
|
NIO_ACCESS.acquireSession(input);
|
||||||
try {
|
try {
|
||||||
long inputAddress = ((DirectBuffer) input).address();
|
long inputAddress = ((DirectBuffer) input).address();
|
||||||
result = deflateBufferBytes(zsRef.address(),
|
result = deflateBufferBytes(zsRef.address(),
|
||||||
@ -594,7 +597,7 @@ public class Deflater {
|
|||||||
output, off, len,
|
output, off, len,
|
||||||
flush, params);
|
flush, params);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(input);
|
NIO_ACCESS.releaseSession(input);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||||
@ -709,14 +712,15 @@ public class Deflater {
|
|||||||
if (input == null) {
|
if (input == null) {
|
||||||
inputPos = this.inputPos;
|
inputPos = this.inputPos;
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = ((DirectBuffer) output).address();
|
||||||
result = deflateBytesBuffer(zsRef.address(),
|
result = deflateBytesBuffer(zsRef.address(),
|
||||||
inputArray, inputPos, inputLim - inputPos,
|
inputArray, inputPos, inputLim - inputPos,
|
||||||
outputAddress + outputPos, outputRem,
|
outputAddress + outputPos, outputRem,
|
||||||
flush, params);
|
flush, params);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
@ -730,17 +734,19 @@ public class Deflater {
|
|||||||
inputPos = input.position();
|
inputPos = input.position();
|
||||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||||
if (input.isDirect()) {
|
if (input.isDirect()) {
|
||||||
long inputAddress = ((DirectBuffer) input).address();
|
NIO_ACCESS.acquireSession(input);
|
||||||
try {
|
try {
|
||||||
|
long inputAddress = ((DirectBuffer) input).address();
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = outputPos + ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = outputPos + ((DirectBuffer) output).address();
|
||||||
result = deflateBufferBuffer(zsRef.address(),
|
result = deflateBufferBuffer(zsRef.address(),
|
||||||
inputAddress + inputPos, inputRem,
|
inputAddress + inputPos, inputRem,
|
||||||
outputAddress, outputRem,
|
outputAddress, outputRem,
|
||||||
flush, params);
|
flush, params);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
@ -751,20 +757,21 @@ public class Deflater {
|
|||||||
flush, params);
|
flush, params);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(input);
|
NIO_ACCESS.releaseSession(input);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||||
int inputOffset = ZipUtils.getBufferOffset(input);
|
int inputOffset = ZipUtils.getBufferOffset(input);
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = ((DirectBuffer) output).address();
|
||||||
result = deflateBytesBuffer(zsRef.address(),
|
result = deflateBytesBuffer(zsRef.address(),
|
||||||
inputArray, inputOffset + inputPos, inputRem,
|
inputArray, inputOffset + inputPos, inputRem,
|
||||||
outputAddress + outputPos, outputRem,
|
outputAddress + outputPos, outputRem,
|
||||||
flush, params);
|
flush, params);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package java.util.zip;
|
package java.util.zip;
|
||||||
|
|
||||||
import java.lang.ref.Cleaner.Cleanable;
|
import java.lang.ref.Cleaner.Cleanable;
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ReadOnlyBufferException;
|
import java.nio.ReadOnlyBufferException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
|
|||||||
import jdk.internal.util.Preconditions;
|
import jdk.internal.util.Preconditions;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
|
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides support for general purpose decompression using the
|
* This class provides support for general purpose decompression using the
|
||||||
* popular ZLIB compression library. The ZLIB compression library was
|
* popular ZLIB compression library. The ZLIB compression library was
|
||||||
@ -259,11 +260,12 @@ public class Inflater {
|
|||||||
int remaining = Math.max(dictionary.limit() - position, 0);
|
int remaining = Math.max(dictionary.limit() - position, 0);
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
if (dictionary.isDirect()) {
|
if (dictionary.isDirect()) {
|
||||||
long address = ((DirectBuffer) dictionary).address();
|
NIO_ACCESS.acquireSession(dictionary);
|
||||||
try {
|
try {
|
||||||
|
long address = ((DirectBuffer) dictionary).address();
|
||||||
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(dictionary);
|
NIO_ACCESS.releaseSession(dictionary);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] array = ZipUtils.getBufferArray(dictionary);
|
byte[] array = ZipUtils.getBufferArray(dictionary);
|
||||||
@ -383,13 +385,14 @@ public class Inflater {
|
|||||||
try {
|
try {
|
||||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||||
if (input.isDirect()) {
|
if (input.isDirect()) {
|
||||||
|
NIO_ACCESS.acquireSession(input);
|
||||||
try {
|
try {
|
||||||
long inputAddress = ((DirectBuffer) input).address();
|
long inputAddress = ((DirectBuffer) input).address();
|
||||||
result = inflateBufferBytes(zsRef.address(),
|
result = inflateBufferBytes(zsRef.address(),
|
||||||
inputAddress + inputPos, inputRem,
|
inputAddress + inputPos, inputRem,
|
||||||
output, off, len);
|
output, off, len);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(input);
|
NIO_ACCESS.releaseSession(input);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||||
@ -517,13 +520,14 @@ public class Inflater {
|
|||||||
inputPos = this.inputPos;
|
inputPos = this.inputPos;
|
||||||
try {
|
try {
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = ((DirectBuffer) output).address();
|
||||||
result = inflateBytesBuffer(zsRef.address(),
|
result = inflateBytesBuffer(zsRef.address(),
|
||||||
inputArray, inputPos, inputLim - inputPos,
|
inputArray, inputPos, inputLim - inputPos,
|
||||||
outputAddress + outputPos, outputRem);
|
outputAddress + outputPos, outputRem);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
@ -541,16 +545,18 @@ public class Inflater {
|
|||||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||||
try {
|
try {
|
||||||
if (input.isDirect()) {
|
if (input.isDirect()) {
|
||||||
long inputAddress = ((DirectBuffer) input).address();
|
NIO_ACCESS.acquireSession(input);
|
||||||
try {
|
try {
|
||||||
|
long inputAddress = ((DirectBuffer) input).address();
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = ((DirectBuffer) output).address();
|
||||||
result = inflateBufferBuffer(zsRef.address(),
|
result = inflateBufferBuffer(zsRef.address(),
|
||||||
inputAddress + inputPos, inputRem,
|
inputAddress + inputPos, inputRem,
|
||||||
outputAddress + outputPos, outputRem);
|
outputAddress + outputPos, outputRem);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
@ -560,19 +566,20 @@ public class Inflater {
|
|||||||
outputArray, outputOffset + outputPos, outputRem);
|
outputArray, outputOffset + outputPos, outputRem);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(input);
|
NIO_ACCESS.releaseSession(input);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||||
int inputOffset = ZipUtils.getBufferOffset(input);
|
int inputOffset = ZipUtils.getBufferOffset(input);
|
||||||
if (output.isDirect()) {
|
if (output.isDirect()) {
|
||||||
long outputAddress = ((DirectBuffer) output).address();
|
NIO_ACCESS.acquireSession(output);
|
||||||
try {
|
try {
|
||||||
|
long outputAddress = ((DirectBuffer) output).address();
|
||||||
result = inflateBytesBuffer(zsRef.address(),
|
result = inflateBytesBuffer(zsRef.address(),
|
||||||
inputArray, inputOffset + inputPos, inputRem,
|
inputArray, inputOffset + inputPos, inputRem,
|
||||||
outputAddress + outputPos, outputRem);
|
outputAddress + outputPos, outputRem);
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(output);
|
NIO_ACCESS.releaseSession(output);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||||
|
@ -36,10 +36,14 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import static java.util.zip.ZipConstants.ENDHDR;
|
import static java.util.zip.ZipConstants.ENDHDR;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
class ZipUtils {
|
class ZipUtils {
|
||||||
|
|
||||||
|
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// used to adjust values between Windows and java epoch
|
// used to adjust values between Windows and java epoch
|
||||||
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
|
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
|
||||||
|
|
||||||
|
@ -86,12 +86,26 @@ public interface JavaNioAccess {
|
|||||||
MemorySegment bufferSegment(Buffer buffer);
|
MemorySegment bufferSegment(Buffer buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by I/O operations to make a buffer's session non-closeable
|
* Used by operations to make a buffer's session non-closeable
|
||||||
* (for the duration of the I/O operation) by acquiring the session.
|
* (for the duration of the operation) by acquiring the session.
|
||||||
* Null is returned if the buffer has no scope, or acquiring is not
|
* {@snippet lang = java:
|
||||||
* required to guarantee safety.
|
* acquireSession(buffer);
|
||||||
|
* try {
|
||||||
|
* performOperation(buffer);
|
||||||
|
* } finally {
|
||||||
|
* releaseSession(buffer);
|
||||||
|
* }
|
||||||
|
*}
|
||||||
|
*
|
||||||
|
* @see #releaseSession(Buffer)
|
||||||
*/
|
*/
|
||||||
Runnable acquireSession(Buffer buffer, boolean async);
|
void acquireSession(Buffer buffer);
|
||||||
|
|
||||||
|
void releaseSession(Buffer buffer);
|
||||||
|
|
||||||
|
boolean isThreadConfined(Buffer buffer);
|
||||||
|
|
||||||
|
boolean hasSession(Buffer buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.
|
* Used by {@code jdk.internal.foreign.MappedMemorySegmentImpl} and byte buffer var handle views.
|
||||||
|
@ -166,7 +166,9 @@ module java.base {
|
|||||||
jdk.jartool,
|
jdk.jartool,
|
||||||
jdk.jlink,
|
jdk.jlink,
|
||||||
jdk.jfr,
|
jdk.jfr,
|
||||||
jdk.net;
|
jdk.net,
|
||||||
|
jdk.sctp,
|
||||||
|
jdk.crypto.cryptoki;
|
||||||
exports jdk.internal.foreign to
|
exports jdk.internal.foreign to
|
||||||
jdk.incubator.vector;
|
jdk.incubator.vector;
|
||||||
exports jdk.internal.event to
|
exports jdk.internal.event to
|
||||||
|
@ -71,6 +71,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.ref.CleanerFactory;
|
import jdk.internal.ref.CleanerFactory;
|
||||||
import sun.net.ResourceManager;
|
import sun.net.ResourceManager;
|
||||||
import sun.net.ext.ExtendedSocketOptions;
|
import sun.net.ext.ExtendedSocketOptions;
|
||||||
@ -87,6 +89,8 @@ class DatagramChannelImpl
|
|||||||
// Used to make native read and write calls
|
// Used to make native read and write calls
|
||||||
private static final NativeDispatcher nd = new DatagramDispatcher();
|
private static final NativeDispatcher nd = new DatagramDispatcher();
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// true if interruptible (can be false to emulate legacy DatagramSocket)
|
// true if interruptible (can be false to emulate legacy DatagramSocket)
|
||||||
private final boolean interruptible;
|
private final boolean interruptible;
|
||||||
|
|
||||||
@ -780,13 +784,18 @@ class DatagramChannelImpl
|
|||||||
boolean connected)
|
boolean connected)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
int n = receive0(fd,
|
NIO_ACCESS.acquireSession(bb);
|
||||||
((DirectBuffer)bb).address() + pos, rem,
|
try {
|
||||||
sourceSockAddr.address(),
|
int n = receive0(fd,
|
||||||
connected);
|
((DirectBuffer)bb).address() + pos, rem,
|
||||||
if (n > 0)
|
sourceSockAddr.address(),
|
||||||
bb.position(pos + n);
|
connected);
|
||||||
return n;
|
if (n > 0)
|
||||||
|
bb.position(pos + n);
|
||||||
|
return n;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -930,6 +939,7 @@ class DatagramChannelImpl
|
|||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
|
||||||
int written;
|
int written;
|
||||||
|
NIO_ACCESS.acquireSession(bb);
|
||||||
try {
|
try {
|
||||||
int addressLen = targetSocketAddress(target);
|
int addressLen = targetSocketAddress(target);
|
||||||
written = send0(fd, ((DirectBuffer)bb).address() + pos, rem,
|
written = send0(fd, ((DirectBuffer)bb).address() + pos, rem,
|
||||||
@ -938,6 +948,8 @@ class DatagramChannelImpl
|
|||||||
if (isConnected())
|
if (isConnected())
|
||||||
throw pue;
|
throw pue;
|
||||||
written = rem;
|
written = rem;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
}
|
}
|
||||||
if (written > 0)
|
if (written > 0)
|
||||||
bb.position(pos + written);
|
bb.position(pos + written);
|
||||||
|
@ -30,6 +30,13 @@ import jdk.internal.ref.Cleaner;
|
|||||||
|
|
||||||
public interface DirectBuffer {
|
public interface DirectBuffer {
|
||||||
|
|
||||||
|
// Use of the returned address must be guarded if this DirectBuffer
|
||||||
|
// is backed by a memory session that is explicitly closeable.
|
||||||
|
//
|
||||||
|
// Failure to do this means the outcome is undefined including
|
||||||
|
// silent unrelated memory mutation and JVM crashes.
|
||||||
|
//
|
||||||
|
// See JavaNioAccess for methods to safely acquire/release resources.
|
||||||
public long address();
|
public long address();
|
||||||
|
|
||||||
public Object attachment();
|
public Object attachment();
|
||||||
|
@ -31,12 +31,13 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import jdk.internal.access.JavaNioAccess;
|
import jdk.internal.access.JavaNioAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
|
import jdk.internal.foreign.MemorySessionImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File-descriptor based I/O utilities that are shared by NIO classes.
|
* File-descriptor based I/O utilities that are shared by NIO classes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class IOUtil {
|
public final class IOUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Max number of iovec structures that readv/writev supports
|
* Max number of iovec structures that readv/writev supports
|
||||||
@ -128,7 +129,7 @@ public class IOUtil {
|
|||||||
int written = 0;
|
int written = 0;
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
return 0;
|
return 0;
|
||||||
var handle = acquireScope(bb, async);
|
acquireScope(bb, async);
|
||||||
try {
|
try {
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
written = nd.pwrite(fd, bufferAddress(bb) + pos, rem, position);
|
written = nd.pwrite(fd, bufferAddress(bb) + pos, rem, position);
|
||||||
@ -136,7 +137,7 @@ public class IOUtil {
|
|||||||
written = nd.write(fd, bufferAddress(bb) + pos, rem);
|
written = nd.write(fd, bufferAddress(bb) + pos, rem);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
releaseScope(handle);
|
releaseScope(bb);
|
||||||
}
|
}
|
||||||
if (written > 0)
|
if (written > 0)
|
||||||
bb.position(pos + written);
|
bb.position(pos + written);
|
||||||
@ -181,9 +182,9 @@ public class IOUtil {
|
|||||||
int i = offset;
|
int i = offset;
|
||||||
while (i < count && iov_len < IOV_MAX && writevLen < WRITEV_MAX) {
|
while (i < count && iov_len < IOV_MAX && writevLen < WRITEV_MAX) {
|
||||||
ByteBuffer buf = bufs[i];
|
ByteBuffer buf = bufs[i];
|
||||||
var h = acquireScope(buf, async);
|
acquireScope(buf, async);
|
||||||
if (h != null) {
|
if (NIO_ACCESS.hasSession(buf)) {
|
||||||
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
|
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
|
||||||
}
|
}
|
||||||
int pos = buf.position();
|
int pos = buf.position();
|
||||||
int lim = buf.limit();
|
int lim = buf.limit();
|
||||||
@ -331,7 +332,7 @@ public class IOUtil {
|
|||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
return 0;
|
return 0;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
var handle = acquireScope(bb, async);
|
acquireScope(bb, async);
|
||||||
try {
|
try {
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
n = nd.pread(fd, bufferAddress(bb) + pos, rem, position);
|
n = nd.pread(fd, bufferAddress(bb) + pos, rem, position);
|
||||||
@ -339,7 +340,7 @@ public class IOUtil {
|
|||||||
n = nd.read(fd, bufferAddress(bb) + pos, rem);
|
n = nd.read(fd, bufferAddress(bb) + pos, rem);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
releaseScope(handle);
|
releaseScope(bb);
|
||||||
}
|
}
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
bb.position(pos + n);
|
bb.position(pos + n);
|
||||||
@ -393,9 +394,9 @@ public class IOUtil {
|
|||||||
ByteBuffer buf = bufs[i];
|
ByteBuffer buf = bufs[i];
|
||||||
if (buf.isReadOnly())
|
if (buf.isReadOnly())
|
||||||
throw new IllegalArgumentException("Read-only buffer");
|
throw new IllegalArgumentException("Read-only buffer");
|
||||||
var h = acquireScope(buf, async);
|
acquireScope(buf, async);
|
||||||
if (h != null) {
|
if (NIO_ACCESS.hasSession(buf)) {
|
||||||
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
|
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
|
||||||
}
|
}
|
||||||
int pos = buf.position();
|
int pos = buf.position();
|
||||||
int lim = buf.limit();
|
int lim = buf.limit();
|
||||||
@ -474,15 +475,16 @@ public class IOUtil {
|
|||||||
|
|
||||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
static Runnable acquireScope(ByteBuffer bb, boolean async) {
|
static void acquireScope(ByteBuffer bb, boolean async) {
|
||||||
return NIO_ACCESS.acquireSession(bb, async);
|
if (async && NIO_ACCESS.isThreadConfined(bb)) {
|
||||||
|
throw new IllegalStateException("Confined session not supported");
|
||||||
|
}
|
||||||
|
NIO_ACCESS.acquireSession(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void releaseScope(Runnable handle) {
|
private static void releaseScope(ByteBuffer bb) {
|
||||||
if (handle == null)
|
|
||||||
return;
|
|
||||||
try {
|
try {
|
||||||
handle.run();
|
NIO_ACCESS.releaseSession(bb);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
@ -495,15 +497,14 @@ public class IOUtil {
|
|||||||
static Runnable acquireScopes(ByteBuffer buf, ByteBuffer[] buffers) {
|
static Runnable acquireScopes(ByteBuffer buf, ByteBuffer[] buffers) {
|
||||||
if (buffers == null) {
|
if (buffers == null) {
|
||||||
assert buf != null;
|
assert buf != null;
|
||||||
return IOUtil.Releaser.ofNullable(IOUtil.acquireScope(buf, true));
|
IOUtil.acquireScope(buf, true);
|
||||||
|
return IOUtil.Releaser.of(buf);
|
||||||
} else {
|
} else {
|
||||||
assert buf == null;
|
assert buf == null;
|
||||||
Runnable handleReleasers = null;
|
Runnable handleReleasers = null;
|
||||||
for (var b : buffers) {
|
for (var b : buffers) {
|
||||||
var h = IOUtil.acquireScope(b, true);
|
IOUtil.acquireScope(b, true);
|
||||||
if (h != null) {
|
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(b), handleReleasers);
|
||||||
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(h), handleReleasers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return handleReleasers;
|
return handleReleasers;
|
||||||
}
|
}
|
||||||
@ -514,12 +515,11 @@ public class IOUtil {
|
|||||||
releasers.run();
|
releasers.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
static record LinkedRunnable(Runnable node, Runnable next)
|
record LinkedRunnable(Runnable node, Runnable next) implements Runnable {
|
||||||
implements Runnable
|
|
||||||
{
|
|
||||||
LinkedRunnable {
|
LinkedRunnable {
|
||||||
Objects.requireNonNull(node);
|
Objects.requireNonNull(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -529,20 +529,28 @@ public class IOUtil {
|
|||||||
next.run();
|
next.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LinkedRunnable of(Runnable first, Runnable second) {
|
static LinkedRunnable of(Runnable first, Runnable second) {
|
||||||
return new LinkedRunnable(first, second);
|
return new LinkedRunnable(first, second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static record Releaser(Runnable handle) implements Runnable {
|
record Releaser(ByteBuffer bb) implements Runnable {
|
||||||
Releaser { Objects.requireNonNull(handle) ; }
|
Releaser {
|
||||||
@Override public void run() { releaseScope(handle); }
|
Objects.requireNonNull(bb);
|
||||||
static Runnable of(Runnable handle) { return new Releaser(handle); }
|
|
||||||
static Runnable ofNullable(Runnable handle) {
|
|
||||||
if (handle == null)
|
|
||||||
return () -> { };
|
|
||||||
return new Releaser(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
releaseScope(bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Runnable of(ByteBuffer bb) {
|
||||||
|
return NIO_ACCESS.hasSession(bb)
|
||||||
|
? new Releaser(bb)
|
||||||
|
: () -> {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long bufferAddress(ByteBuffer buf) {
|
static long bufferAddress(ByteBuffer buf) {
|
||||||
|
@ -134,6 +134,7 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" {
|
|||||||
permission java.lang.RuntimePermission
|
permission java.lang.RuntimePermission
|
||||||
"accessClassInPackage.com.sun.crypto.provider";
|
"accessClassInPackage.com.sun.crypto.provider";
|
||||||
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
|
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.access";
|
||||||
permission java.lang.RuntimePermission
|
permission java.lang.RuntimePermission
|
||||||
"accessClassInPackage.sun.security.*";
|
"accessClassInPackage.sun.security.*";
|
||||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
||||||
|
@ -25,11 +25,13 @@
|
|||||||
|
|
||||||
package sun.nio.fs;
|
package sun.nio.fs;
|
||||||
|
|
||||||
import java.lang.ref.Reference;
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.misc.Unsafe;
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
import static sun.nio.fs.UnixConstants.*;
|
import static sun.nio.fs.UnixConstants.*;
|
||||||
@ -43,6 +45,8 @@ abstract class UnixUserDefinedFileAttributeView
|
|||||||
{
|
{
|
||||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// namespace for extended user attributes
|
// namespace for extended user attributes
|
||||||
private static final String USER_NAMESPACE = "user.";
|
private static final String USER_NAMESPACE = "user.";
|
||||||
|
|
||||||
@ -174,14 +178,15 @@ abstract class UnixUserDefinedFileAttributeView
|
|||||||
assert (pos <= lim);
|
assert (pos <= lim);
|
||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
|
||||||
if (dst instanceof sun.nio.ch.DirectBuffer buf) {
|
if (dst instanceof sun.nio.ch.DirectBuffer ddst) {
|
||||||
|
NIO_ACCESS.acquireSession(dst);
|
||||||
try {
|
try {
|
||||||
long address = buf.address() + pos;
|
long address = ddst.address() + pos;
|
||||||
int n = read(name, address, rem);
|
int n = read(name, address, rem);
|
||||||
dst.position(pos + n);
|
dst.position(pos + n);
|
||||||
return n;
|
return n;
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(buf);
|
NIO_ACCESS.releaseSession(dst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||||
@ -237,13 +242,14 @@ abstract class UnixUserDefinedFileAttributeView
|
|||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
|
||||||
if (src instanceof sun.nio.ch.DirectBuffer buf) {
|
if (src instanceof sun.nio.ch.DirectBuffer buf) {
|
||||||
|
NIO_ACCESS.acquireSession(src);
|
||||||
try {
|
try {
|
||||||
long address = buf.address() + pos;
|
long address = buf.address() + pos;
|
||||||
write(name, address, rem);
|
write(name, address, rem);
|
||||||
src.position(pos + rem);
|
src.position(pos + rem);
|
||||||
return rem;
|
return rem;
|
||||||
} finally {
|
} finally {
|
||||||
Reference.reachabilityFence(buf);
|
NIO_ACCESS.releaseSession(src);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||||
|
@ -35,6 +35,8 @@ import java.security.spec.*;
|
|||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.*;
|
import javax.crypto.spec.*;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.security.jca.JCAUtil;
|
import sun.security.jca.JCAUtil;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
|||||||
*/
|
*/
|
||||||
final class P11AEADCipher extends CipherSpi {
|
final class P11AEADCipher extends CipherSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// supported AEAD algorithms/transformations
|
// supported AEAD algorithms/transformations
|
||||||
private enum Transformation {
|
private enum Transformation {
|
||||||
AES_GCM("AES", "GCM", "NOPADDING", 16, 16),
|
AES_GCM("AES", "GCM", "NOPADDING", 16, 16),
|
||||||
@ -705,84 +709,94 @@ final class P11AEADCipher extends CipherSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean doCancel = true;
|
boolean doCancel = true;
|
||||||
|
NIO_ACCESS.acquireSession(inBuffer);
|
||||||
try {
|
try {
|
||||||
ensureInitialized();
|
NIO_ACCESS.acquireSession(outBuffer);
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
ensureInitialized();
|
||||||
|
|
||||||
long inAddr = 0;
|
long inAddr = 0;
|
||||||
byte[] in = null;
|
byte[] in = null;
|
||||||
int inOfs = 0;
|
int inOfs = 0;
|
||||||
if (dataBuffer.size() > 0) {
|
if (dataBuffer.size() > 0) {
|
||||||
if (inLen > 0) {
|
if (inLen > 0) {
|
||||||
byte[] temp = new byte[inLen];
|
byte[] temp = new byte[inLen];
|
||||||
inBuffer.get(temp);
|
inBuffer.get(temp);
|
||||||
dataBuffer.write(temp, 0, temp.length);
|
dataBuffer.write(temp, 0, temp.length);
|
||||||
}
|
}
|
||||||
in = dataBuffer.toByteArray();
|
in = dataBuffer.toByteArray();
|
||||||
inOfs = 0;
|
inOfs = 0;
|
||||||
inLen = in.length;
|
inLen = in.length;
|
||||||
} else {
|
|
||||||
if (inBuffer instanceof DirectBuffer) {
|
|
||||||
inAddr = ((DirectBuffer) inBuffer).address();
|
|
||||||
inOfs = inBuffer.position();
|
|
||||||
} else {
|
|
||||||
if (inBuffer.hasArray()) {
|
|
||||||
in = inBuffer.array();
|
|
||||||
inOfs = inBuffer.position() + inBuffer.arrayOffset();
|
|
||||||
} else {
|
} else {
|
||||||
in = new byte[inLen];
|
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||||
inBuffer.get(in);
|
inAddr = dInBuffer.address();
|
||||||
|
inOfs = inBuffer.position();
|
||||||
|
} else {
|
||||||
|
if (inBuffer.hasArray()) {
|
||||||
|
in = inBuffer.array();
|
||||||
|
inOfs = inBuffer.position() + inBuffer.arrayOffset();
|
||||||
|
} else {
|
||||||
|
in = new byte[inLen];
|
||||||
|
inBuffer.get(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long outAddr = 0;
|
||||||
|
byte[] outArray = null;
|
||||||
|
int outOfs = 0;
|
||||||
|
if (outBuffer instanceof DirectBuffer dOutBuffer) {
|
||||||
|
outAddr = dOutBuffer.address();
|
||||||
|
outOfs = outBuffer.position();
|
||||||
|
} else {
|
||||||
|
if (outBuffer.hasArray()) {
|
||||||
|
outArray = outBuffer.array();
|
||||||
|
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
||||||
|
} else {
|
||||||
|
outArray = new byte[outLen];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
long outAddr = 0;
|
|
||||||
byte[] outArray = null;
|
|
||||||
int outOfs = 0;
|
|
||||||
if (outBuffer instanceof DirectBuffer) {
|
|
||||||
outAddr = ((DirectBuffer) outBuffer).address();
|
|
||||||
outOfs = outBuffer.position();
|
|
||||||
} else {
|
|
||||||
if (outBuffer.hasArray()) {
|
|
||||||
outArray = outBuffer.array();
|
|
||||||
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
|
||||||
} else {
|
|
||||||
outArray = new byte[outLen];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int k = 0;
|
int k = 0;
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||||
outAddr, outArray, outOfs, outLen);
|
outAddr, outArray, outOfs, outLen);
|
||||||
doCancel = false;
|
doCancel = false;
|
||||||
} else {
|
} else {
|
||||||
// Special handling to match SunJCE provider behavior
|
// Special handling to match SunJCE provider behavior
|
||||||
if (inLen == 0) {
|
if (inLen == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||||
|
outAddr, outArray, outOfs, outLen);
|
||||||
|
doCancel = false;
|
||||||
|
}
|
||||||
|
inBuffer.position(inBuffer.limit());
|
||||||
|
outBuffer.position(outBuffer.position() + k);
|
||||||
|
return k;
|
||||||
|
} catch (PKCS11Exception e) {
|
||||||
|
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
|
||||||
|
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
|
||||||
|
// successful calls to determine the output length. However,
|
||||||
|
// these cases are not expected here because the output length
|
||||||
|
// is checked in the OpenJDK side before making the PKCS#11 call.
|
||||||
|
// Thus, doCancel can safely be 'false'.
|
||||||
|
doCancel = false;
|
||||||
|
handleException(e);
|
||||||
|
throw new ProviderException("doFinal() failed", e);
|
||||||
|
} finally {
|
||||||
|
if (encrypt) {
|
||||||
|
lastEncKey = this.p11Key;
|
||||||
|
lastEncIv = this.iv;
|
||||||
|
requireReinit = true;
|
||||||
|
}
|
||||||
|
reset(doCancel);
|
||||||
}
|
}
|
||||||
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
|
} finally {
|
||||||
outAddr, outArray, outOfs, outLen);
|
NIO_ACCESS.releaseSession(outBuffer);
|
||||||
doCancel = false;
|
|
||||||
}
|
}
|
||||||
inBuffer.position(inBuffer.limit());
|
|
||||||
outBuffer.position(outBuffer.position() + k);
|
|
||||||
return k;
|
|
||||||
} catch (PKCS11Exception e) {
|
|
||||||
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
|
|
||||||
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
|
|
||||||
// successful calls to determine the output length. However,
|
|
||||||
// these cases are not expected here because the output length
|
|
||||||
// is checked in the OpenJDK side before making the PKCS#11 call.
|
|
||||||
// Thus, doCancel can safely be 'false'.
|
|
||||||
doCancel = false;
|
|
||||||
handleException(e);
|
|
||||||
throw new ProviderException("doFinal() failed", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (encrypt) {
|
NIO_ACCESS.releaseSession(inBuffer);
|
||||||
lastEncKey = this.p11Key;
|
|
||||||
lastEncIv = this.iv;
|
|
||||||
requireReinit = true;
|
|
||||||
}
|
|
||||||
reset(doCancel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ import java.security.spec.*;
|
|||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.*;
|
import javax.crypto.spec.*;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.security.jca.JCAUtil;
|
import sun.security.jca.JCAUtil;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
@ -56,6 +58,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
|||||||
*/
|
*/
|
||||||
final class P11Cipher extends CipherSpi {
|
final class P11Cipher extends CipherSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// mode constant for ECB mode
|
// mode constant for ECB mode
|
||||||
private static final int MODE_ECB = 3;
|
private static final int MODE_ECB = 3;
|
||||||
// mode constant for CBC mode
|
// mode constant for CBC mode
|
||||||
@ -678,115 +682,123 @@ final class P11Cipher extends CipherSpi {
|
|||||||
throw new ShortBufferException();
|
throw new ShortBufferException();
|
||||||
}
|
}
|
||||||
int origPos = inBuffer.position();
|
int origPos = inBuffer.position();
|
||||||
|
NIO_ACCESS.acquireSession(inBuffer);
|
||||||
try {
|
try {
|
||||||
ensureInitialized();
|
NIO_ACCESS.acquireSession(outBuffer);
|
||||||
|
try {
|
||||||
|
ensureInitialized();
|
||||||
|
|
||||||
long inAddr = 0;
|
long inAddr = 0;
|
||||||
int inOfs = 0;
|
int inOfs = 0;
|
||||||
byte[] inArray = null;
|
byte[] inArray = null;
|
||||||
|
|
||||||
if (inBuffer instanceof DirectBuffer) {
|
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||||
inAddr = ((DirectBuffer) inBuffer).address();
|
inAddr = dInBuffer.address();
|
||||||
inOfs = origPos;
|
inOfs = origPos;
|
||||||
} else if (inBuffer.hasArray()) {
|
} else if (inBuffer.hasArray()) {
|
||||||
inArray = inBuffer.array();
|
inArray = inBuffer.array();
|
||||||
inOfs = (origPos + inBuffer.arrayOffset());
|
inOfs = (origPos + inBuffer.arrayOffset());
|
||||||
}
|
|
||||||
|
|
||||||
long outAddr = 0;
|
|
||||||
int outOfs = 0;
|
|
||||||
byte[] outArray = null;
|
|
||||||
if (outBuffer instanceof DirectBuffer) {
|
|
||||||
outAddr = ((DirectBuffer) outBuffer).address();
|
|
||||||
outOfs = outBuffer.position();
|
|
||||||
} else {
|
|
||||||
if (outBuffer.hasArray()) {
|
|
||||||
outArray = outBuffer.array();
|
|
||||||
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
|
|
||||||
} else {
|
|
||||||
outArray = new byte[outLen];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int k = 0;
|
long outAddr = 0;
|
||||||
int newPadBufferLen = 0;
|
int outOfs = 0;
|
||||||
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
|
byte[] outArray = null;
|
||||||
if (padBufferLen != 0) {
|
if (outBuffer instanceof DirectBuffer dOutBuffer) {
|
||||||
if (padBufferLen != padBuffer.length) {
|
outAddr = dOutBuffer.address();
|
||||||
int bufCapacity = padBuffer.length - padBufferLen;
|
outOfs = outBuffer.position();
|
||||||
if (inLen > bufCapacity) {
|
} else {
|
||||||
bufferInputBytes(inBuffer, bufCapacity);
|
if (outBuffer.hasArray()) {
|
||||||
inOfs += bufCapacity;
|
outArray = outBuffer.array();
|
||||||
inLen -= bufCapacity;
|
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
|
||||||
} else {
|
} else {
|
||||||
bufferInputBytes(inBuffer, inLen);
|
outArray = new byte[outLen];
|
||||||
return 0;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int k = 0;
|
||||||
|
int newPadBufferLen = 0;
|
||||||
|
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
|
||||||
|
if (padBufferLen != 0) {
|
||||||
|
if (padBufferLen != padBuffer.length) {
|
||||||
|
int bufCapacity = padBuffer.length - padBufferLen;
|
||||||
|
if (inLen > bufCapacity) {
|
||||||
|
bufferInputBytes(inBuffer, bufCapacity);
|
||||||
|
inOfs += bufCapacity;
|
||||||
|
inLen -= bufCapacity;
|
||||||
|
} else {
|
||||||
|
bufferInputBytes(inBuffer, inLen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (encrypt) {
|
||||||
|
k = token.p11.C_EncryptUpdate(session.id(), 0,
|
||||||
|
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||||
|
outOfs, outLen);
|
||||||
|
} else {
|
||||||
|
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||||
|
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||||
|
outOfs, outLen);
|
||||||
|
}
|
||||||
|
padBufferLen = 0;
|
||||||
|
}
|
||||||
|
newPadBufferLen = inLen & (blockSize - 1);
|
||||||
|
if (!encrypt && newPadBufferLen == 0) {
|
||||||
|
// While decrypting with implUpdate, the last encrypted block
|
||||||
|
// is always held in a buffer. If it's the final one (unknown
|
||||||
|
// at this point), it may contain padding bytes and need further
|
||||||
|
// processing. In implDoFinal (where we know it's the final one)
|
||||||
|
// the buffer is decrypted, unpadded and returned.
|
||||||
|
newPadBufferLen = padBuffer.length;
|
||||||
|
}
|
||||||
|
inLen -= newPadBufferLen;
|
||||||
|
}
|
||||||
|
if (inLen > 0) {
|
||||||
|
if (inAddr == 0 && inArray == null) {
|
||||||
|
inArray = new byte[inLen];
|
||||||
|
inBuffer.get(inArray);
|
||||||
|
} else {
|
||||||
|
inBuffer.position(inBuffer.position() + inLen);
|
||||||
}
|
}
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
k = token.p11.C_EncryptUpdate(session.id(), 0,
|
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
|
||||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
inArray, inOfs, inLen, outAddr, outArray,
|
||||||
outOfs, outLen);
|
(outOfs + k), (outLen - k));
|
||||||
} else {
|
} else {
|
||||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
||||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
inArray, inOfs, inLen, outAddr, outArray,
|
||||||
outOfs, outLen);
|
(outOfs + k), (outLen - k));
|
||||||
}
|
}
|
||||||
padBufferLen = 0;
|
|
||||||
}
|
}
|
||||||
newPadBufferLen = inLen & (blockSize - 1);
|
// update 'padBuffer' if using our own padding impl.
|
||||||
if (!encrypt && newPadBufferLen == 0) {
|
if (paddingObj != null && newPadBufferLen > 0) {
|
||||||
// While decrypting with implUpdate, the last encrypted block
|
bufferInputBytes(inBuffer, newPadBufferLen);
|
||||||
// is always held in a buffer. If it's the final one (unknown
|
|
||||||
// at this point), it may contain padding bytes and need further
|
|
||||||
// processing. In implDoFinal (where we know it's the final one)
|
|
||||||
// the buffer is decrypted, unpadded and returned.
|
|
||||||
newPadBufferLen = padBuffer.length;
|
|
||||||
}
|
}
|
||||||
inLen -= newPadBufferLen;
|
bytesBuffered += (inLen - k);
|
||||||
}
|
if (!(outBuffer instanceof DirectBuffer) &&
|
||||||
if (inLen > 0) {
|
!outBuffer.hasArray()) {
|
||||||
if (inAddr == 0 && inArray == null) {
|
outBuffer.put(outArray, outOfs, k);
|
||||||
inArray = new byte[inLen];
|
|
||||||
inBuffer.get(inArray);
|
|
||||||
} else {
|
} else {
|
||||||
inBuffer.position(inBuffer.position() + inLen);
|
outBuffer.position(outBuffer.position() + k);
|
||||||
}
|
}
|
||||||
if (encrypt) {
|
return k;
|
||||||
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
|
} catch (PKCS11Exception e) {
|
||||||
inArray, inOfs, inLen, outAddr, outArray,
|
// Reset input buffer to its original position for
|
||||||
(outOfs + k), (outLen - k));
|
inBuffer.position(origPos);
|
||||||
} else {
|
if (e.match(CKR_BUFFER_TOO_SMALL)) {
|
||||||
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
throw (ShortBufferException)
|
||||||
inArray, inOfs, inLen, outAddr, outArray,
|
(new ShortBufferException().initCause(e));
|
||||||
(outOfs + k), (outLen - k));
|
|
||||||
}
|
}
|
||||||
|
// Some implementations such as the NSS Software Token do not
|
||||||
|
// cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
|
||||||
|
// failure (as required by the PKCS#11 standard). See JDK-8258833
|
||||||
|
// for further information.
|
||||||
|
reset(true);
|
||||||
|
throw new ProviderException("update() failed", e);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(outBuffer);
|
||||||
}
|
}
|
||||||
// update 'padBuffer' if using our own padding impl.
|
} finally {
|
||||||
if (paddingObj != null && newPadBufferLen > 0) {
|
NIO_ACCESS.releaseSession(inBuffer);
|
||||||
bufferInputBytes(inBuffer, newPadBufferLen);
|
|
||||||
}
|
|
||||||
bytesBuffered += (inLen - k);
|
|
||||||
if (!(outBuffer instanceof DirectBuffer) &&
|
|
||||||
!outBuffer.hasArray()) {
|
|
||||||
outBuffer.put(outArray, outOfs, k);
|
|
||||||
} else {
|
|
||||||
outBuffer.position(outBuffer.position() + k);
|
|
||||||
}
|
|
||||||
return k;
|
|
||||||
} catch (PKCS11Exception e) {
|
|
||||||
// Reset input buffer to its original position for
|
|
||||||
inBuffer.position(origPos);
|
|
||||||
if (e.match(CKR_BUFFER_TOO_SMALL)) {
|
|
||||||
throw (ShortBufferException)
|
|
||||||
(new ShortBufferException().initCause(e));
|
|
||||||
}
|
|
||||||
// Some implementations such as the NSS Software Token do not
|
|
||||||
// cancel the operation upon a C_EncryptUpdate/C_DecryptUpdate
|
|
||||||
// failure (as required by the PKCS#11 standard). See JDK-8258833
|
|
||||||
// for further information.
|
|
||||||
reset(true);
|
|
||||||
throw new ProviderException("update() failed", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,99 +889,104 @@ final class P11Cipher extends CipherSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean doCancel = true;
|
boolean doCancel = true;
|
||||||
|
NIO_ACCESS.acquireSession(outBuffer);
|
||||||
try {
|
try {
|
||||||
ensureInitialized();
|
try {
|
||||||
|
ensureInitialized();
|
||||||
|
|
||||||
long outAddr = 0;
|
long outAddr = 0;
|
||||||
byte[] outArray = null;
|
byte[] outArray = null;
|
||||||
int outOfs = 0;
|
int outOfs = 0;
|
||||||
if (outBuffer instanceof DirectBuffer) {
|
if (outBuffer instanceof DirectBuffer dOutBuffer) {
|
||||||
outAddr = ((DirectBuffer) outBuffer).address();
|
outAddr = dOutBuffer.address();
|
||||||
outOfs = outBuffer.position();
|
outOfs = outBuffer.position();
|
||||||
} else {
|
|
||||||
if (outBuffer.hasArray()) {
|
|
||||||
outArray = outBuffer.array();
|
|
||||||
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
|
||||||
} else {
|
} else {
|
||||||
outArray = new byte[outLen];
|
if (outBuffer.hasArray()) {
|
||||||
}
|
outArray = outBuffer.array();
|
||||||
}
|
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
||||||
|
} else {
|
||||||
int k = 0;
|
outArray = new byte[outLen];
|
||||||
|
|
||||||
if (encrypt) {
|
|
||||||
if (paddingObj != null) {
|
|
||||||
int startOff = 0;
|
|
||||||
if (reqBlockUpdates) {
|
|
||||||
// call C_EncryptUpdate first if the padBuffer is full
|
|
||||||
// to make room for padding bytes
|
|
||||||
if (padBufferLen == padBuffer.length) {
|
|
||||||
k = token.p11.C_EncryptUpdate(session.id(),
|
|
||||||
0, padBuffer, 0, padBufferLen,
|
|
||||||
outAddr, outArray, outOfs, outLen);
|
|
||||||
} else {
|
|
||||||
startOff = padBufferLen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
|
||||||
startOff, requiredOutLen - bytesBuffered);
|
|
||||||
k += token.p11.C_EncryptUpdate(session.id(),
|
|
||||||
0, padBuffer, 0, startOff + actualPadLen,
|
|
||||||
outAddr, outArray, outOfs + k, outLen - k);
|
|
||||||
}
|
|
||||||
// Some implementations such as the NSS Software Token do not
|
|
||||||
// cancel the operation upon a C_EncryptUpdate failure (as
|
|
||||||
// required by the PKCS#11 standard). Cancel is not needed
|
|
||||||
// only after this point. See JDK-8258833 for further
|
|
||||||
// information.
|
|
||||||
doCancel = false;
|
|
||||||
k += token.p11.C_EncryptFinal(session.id(),
|
|
||||||
outAddr, outArray, (outOfs + k), (outLen - k));
|
|
||||||
} else {
|
|
||||||
// Special handling to match SunJCE provider behavior
|
|
||||||
if (bytesBuffered == 0 && padBufferLen == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paddingObj != null) {
|
int k = 0;
|
||||||
if (padBufferLen != 0) {
|
|
||||||
k = token.p11.C_DecryptUpdate(session.id(),
|
if (encrypt) {
|
||||||
0, padBuffer, 0, padBufferLen,
|
if (paddingObj != null) {
|
||||||
0, padBuffer, 0, padBuffer.length);
|
int startOff = 0;
|
||||||
padBufferLen = 0;
|
if (reqBlockUpdates) {
|
||||||
|
// call C_EncryptUpdate first if the padBuffer is full
|
||||||
|
// to make room for padding bytes
|
||||||
|
if (padBufferLen == padBuffer.length) {
|
||||||
|
k = token.p11.C_EncryptUpdate(session.id(),
|
||||||
|
0, padBuffer, 0, padBufferLen,
|
||||||
|
outAddr, outArray, outOfs, outLen);
|
||||||
|
} else {
|
||||||
|
startOff = padBufferLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
||||||
|
startOff, requiredOutLen - bytesBuffered);
|
||||||
|
k += token.p11.C_EncryptUpdate(session.id(),
|
||||||
|
0, padBuffer, 0, startOff + actualPadLen,
|
||||||
|
outAddr, outArray, outOfs + k, outLen - k);
|
||||||
}
|
}
|
||||||
// Some implementations such as the NSS Software Token do not
|
// Some implementations such as the NSS Software Token do not
|
||||||
// cancel the operation upon a C_DecryptUpdate failure (as
|
// cancel the operation upon a C_EncryptUpdate failure (as
|
||||||
// required by the PKCS#11 standard). Cancel is not needed
|
// required by the PKCS#11 standard). Cancel is not needed
|
||||||
// only after this point. See JDK-8258833 for further
|
// only after this point. See JDK-8258833 for further
|
||||||
// information.
|
// information.
|
||||||
doCancel = false;
|
doCancel = false;
|
||||||
k += token.p11.C_DecryptFinal(session.id(),
|
k += token.p11.C_EncryptFinal(session.id(),
|
||||||
0, padBuffer, k, padBuffer.length - k);
|
outAddr, outArray, (outOfs + k), (outLen - k));
|
||||||
|
|
||||||
int actualPadLen = paddingObj.unpad(padBuffer, k);
|
|
||||||
k -= actualPadLen;
|
|
||||||
outArray = padBuffer;
|
|
||||||
outOfs = 0;
|
|
||||||
} else {
|
} else {
|
||||||
doCancel = false;
|
// Special handling to match SunJCE provider behavior
|
||||||
k = token.p11.C_DecryptFinal(session.id(),
|
if (bytesBuffered == 0 && padBufferLen == 0) {
|
||||||
outAddr, outArray, outOfs, outLen);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paddingObj != null) {
|
||||||
|
if (padBufferLen != 0) {
|
||||||
|
k = token.p11.C_DecryptUpdate(session.id(),
|
||||||
|
0, padBuffer, 0, padBufferLen,
|
||||||
|
0, padBuffer, 0, padBuffer.length);
|
||||||
|
padBufferLen = 0;
|
||||||
|
}
|
||||||
|
// Some implementations such as the NSS Software Token do not
|
||||||
|
// cancel the operation upon a C_DecryptUpdate failure (as
|
||||||
|
// required by the PKCS#11 standard). Cancel is not needed
|
||||||
|
// only after this point. See JDK-8258833 for further
|
||||||
|
// information.
|
||||||
|
doCancel = false;
|
||||||
|
k += token.p11.C_DecryptFinal(session.id(),
|
||||||
|
0, padBuffer, k, padBuffer.length - k);
|
||||||
|
|
||||||
|
int actualPadLen = paddingObj.unpad(padBuffer, k);
|
||||||
|
k -= actualPadLen;
|
||||||
|
outArray = padBuffer;
|
||||||
|
outOfs = 0;
|
||||||
|
} else {
|
||||||
|
doCancel = false;
|
||||||
|
k = token.p11.C_DecryptFinal(session.id(),
|
||||||
|
outAddr, outArray, outOfs, outLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if ((!encrypt && paddingObj != null) ||
|
||||||
|
(!(outBuffer instanceof DirectBuffer) &&
|
||||||
|
!outBuffer.hasArray())) {
|
||||||
|
outBuffer.put(outArray, outOfs, k);
|
||||||
|
} else {
|
||||||
|
outBuffer.position(outBuffer.position() + k);
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
} catch (PKCS11Exception e) {
|
||||||
|
handleException(e);
|
||||||
|
throw new ProviderException("doFinal() failed", e);
|
||||||
|
} finally {
|
||||||
|
reset(doCancel);
|
||||||
}
|
}
|
||||||
if ((!encrypt && paddingObj != null) ||
|
|
||||||
(!(outBuffer instanceof DirectBuffer) &&
|
|
||||||
!outBuffer.hasArray())) {
|
|
||||||
outBuffer.put(outArray, outOfs, k);
|
|
||||||
} else {
|
|
||||||
outBuffer.position(outBuffer.position() + k);
|
|
||||||
}
|
|
||||||
return k;
|
|
||||||
} catch (PKCS11Exception e) {
|
|
||||||
handleException(e);
|
|
||||||
throw new ProviderException("doFinal() failed", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
reset(doCancel);
|
NIO_ACCESS.releaseSession(outBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,14 @@
|
|||||||
|
|
||||||
package sun.security.pkcs11;
|
package sun.security.pkcs11;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
import sun.security.util.MessageDigestSpi2;
|
import sun.security.util.MessageDigestSpi2;
|
||||||
@ -55,6 +56,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
|||||||
final class P11Digest extends MessageDigestSpi implements Cloneable,
|
final class P11Digest extends MessageDigestSpi implements Cloneable,
|
||||||
MessageDigestSpi2 {
|
MessageDigestSpi2 {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
/* fields initialized, no session acquired */
|
/* fields initialized, no session acquired */
|
||||||
private static final int S_BLANK = 1;
|
private static final int S_BLANK = 1;
|
||||||
|
|
||||||
@ -268,13 +271,12 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(byteBuffer instanceof DirectBuffer)) {
|
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||||
super.engineUpdate(byteBuffer);
|
super.engineUpdate(byteBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchSession();
|
fetchSession();
|
||||||
long addr = ((DirectBuffer)byteBuffer).address();
|
|
||||||
int ofs = byteBuffer.position();
|
int ofs = byteBuffer.position();
|
||||||
try {
|
try {
|
||||||
if (state == S_BUFFERED) {
|
if (state == S_BUFFERED) {
|
||||||
@ -285,7 +287,12 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
|
|||||||
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
|
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
|
||||||
bufOfs = 0;
|
bufOfs = 0;
|
||||||
}
|
}
|
||||||
token.p11.C_DigestUpdate(session.id(), addr + ofs, null, 0, len);
|
NIO_ACCESS.acquireSession(byteBuffer);
|
||||||
|
try {
|
||||||
|
token.p11.C_DigestUpdate(session.id(), dByteBuffer.address() + ofs, null, 0, len);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(byteBuffer);
|
||||||
|
}
|
||||||
byteBuffer.position(ofs + len);
|
byteBuffer.position(ofs + len);
|
||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
engineReset();
|
engineReset();
|
||||||
|
@ -37,13 +37,14 @@ import javax.crypto.spec.*;
|
|||||||
|
|
||||||
import java.util.HexFormat;
|
import java.util.HexFormat;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.security.jca.JCAUtil;
|
import sun.security.jca.JCAUtil;
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||||
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||||
import static sun.security.pkcs11.TemplateManager.*;
|
import static sun.security.pkcs11.TemplateManager.*;
|
||||||
import static sun.security.pkcs11.P11Cipher.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* P11 KeyWrap Cipher implementation class for native impl which only support
|
* P11 KeyWrap Cipher implementation class for native impl which only support
|
||||||
@ -58,6 +59,8 @@ import static sun.security.pkcs11.P11Cipher.*;
|
|||||||
*/
|
*/
|
||||||
final class P11KeyWrapCipher extends CipherSpi {
|
final class P11KeyWrapCipher extends CipherSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
private static final int BLK_SIZE = 8;
|
private static final int BLK_SIZE = 8;
|
||||||
|
|
||||||
// supported mode and padding with AES cipher
|
// supported mode and padding with AES cipher
|
||||||
@ -552,78 +555,88 @@ final class P11KeyWrapCipher extends CipherSpi {
|
|||||||
|
|
||||||
boolean doCancel = true;
|
boolean doCancel = true;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
NIO_ACCESS.acquireSession(inBuffer);
|
||||||
try {
|
try {
|
||||||
ensureInitialized();
|
NIO_ACCESS.acquireSession(outBuffer);
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
ensureInitialized();
|
||||||
|
|
||||||
long inAddr = 0;
|
long inAddr = 0;
|
||||||
byte[] in = null;
|
byte[] in = null;
|
||||||
int inOfs = 0;
|
int inOfs = 0;
|
||||||
|
|
||||||
if (dataBuffer.size() > 0) {
|
if (dataBuffer.size() > 0) {
|
||||||
if (inBuffer != null && inLen > 0) {
|
if (inBuffer != null && inLen > 0) {
|
||||||
byte[] temp = new byte[inLen];
|
byte[] temp = new byte[inLen];
|
||||||
inBuffer.get(temp);
|
inBuffer.get(temp);
|
||||||
dataBuffer.write(temp, 0, temp.length);
|
dataBuffer.write(temp, 0, temp.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
in = dataBuffer.toByteArray();
|
in = dataBuffer.toByteArray();
|
||||||
inOfs = 0;
|
inOfs = 0;
|
||||||
inLen = in.length;
|
inLen = in.length;
|
||||||
} else {
|
|
||||||
if (inBuffer instanceof DirectBuffer) {
|
|
||||||
inAddr = ((DirectBuffer) inBuffer).address();
|
|
||||||
inOfs = inBuffer.position();
|
|
||||||
} else {
|
|
||||||
if (inBuffer.hasArray()) {
|
|
||||||
in = inBuffer.array();
|
|
||||||
inOfs = inBuffer.position() + inBuffer.arrayOffset();
|
|
||||||
} else {
|
} else {
|
||||||
in = new byte[inLen];
|
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||||
inBuffer.get(in);
|
inAddr = dInBuffer.address();
|
||||||
|
inOfs = inBuffer.position();
|
||||||
|
} else {
|
||||||
|
if (inBuffer.hasArray()) {
|
||||||
|
in = inBuffer.array();
|
||||||
|
inOfs = inBuffer.position() + inBuffer.arrayOffset();
|
||||||
|
} else {
|
||||||
|
in = new byte[inLen];
|
||||||
|
inBuffer.get(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long outAddr = 0;
|
||||||
|
byte[] outArray = null;
|
||||||
|
int outOfs = 0;
|
||||||
|
if (outBuffer instanceof DirectBuffer dOutBuffer) {
|
||||||
|
outAddr = dOutBuffer.address();
|
||||||
|
outOfs = outBuffer.position();
|
||||||
|
} else {
|
||||||
|
if (outBuffer.hasArray()) {
|
||||||
|
outArray = outBuffer.array();
|
||||||
|
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
||||||
|
} else {
|
||||||
|
outArray = new byte[outLen];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
long outAddr = 0;
|
|
||||||
byte[] outArray = null;
|
|
||||||
int outOfs = 0;
|
|
||||||
if (outBuffer instanceof DirectBuffer) {
|
|
||||||
outAddr = ((DirectBuffer) outBuffer).address();
|
|
||||||
outOfs = outBuffer.position();
|
|
||||||
} else {
|
|
||||||
if (outBuffer.hasArray()) {
|
|
||||||
outArray = outBuffer.array();
|
|
||||||
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
|
||||||
} else {
|
|
||||||
outArray = new byte[outLen];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opmode == Cipher.ENCRYPT_MODE) {
|
if (opmode == Cipher.ENCRYPT_MODE) {
|
||||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||||
outAddr, outArray, outOfs, outLen);
|
outAddr, outArray, outOfs, outLen);
|
||||||
doCancel = false;
|
doCancel = false;
|
||||||
} else {
|
} else {
|
||||||
// Special handling to match SunJCE provider behavior
|
// Special handling to match SunJCE provider behavior
|
||||||
if (inLen == 0) {
|
if (inLen == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||||
|
outAddr, outArray, outOfs, outLen);
|
||||||
|
doCancel = false;
|
||||||
|
}
|
||||||
|
inBuffer.position(inBuffer.limit());
|
||||||
|
outBuffer.position(outBuffer.position() + k);
|
||||||
|
} catch (PKCS11Exception e) {
|
||||||
|
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
|
||||||
|
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
|
||||||
|
// successful calls to determine the output length. However,
|
||||||
|
// these cases are not expected here because the output length
|
||||||
|
// is checked in the OpenJDK side before making the PKCS#11 call.
|
||||||
|
// Thus, doCancel can safely be 'false'.
|
||||||
|
doCancel = false;
|
||||||
|
handleEncException("doFinal() failed", e);
|
||||||
|
} finally {
|
||||||
|
reset(doCancel);
|
||||||
}
|
}
|
||||||
k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
|
} finally {
|
||||||
outAddr, outArray, outOfs, outLen);
|
NIO_ACCESS.releaseSession(outBuffer);
|
||||||
doCancel = false;
|
|
||||||
}
|
}
|
||||||
inBuffer.position(inBuffer.limit());
|
|
||||||
outBuffer.position(outBuffer.position() + k);
|
|
||||||
} catch (PKCS11Exception e) {
|
|
||||||
// As per the PKCS#11 standard, C_Encrypt and C_Decrypt may only
|
|
||||||
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
|
|
||||||
// successful calls to determine the output length. However,
|
|
||||||
// these cases are not expected here because the output length
|
|
||||||
// is checked in the OpenJDK side before making the PKCS#11 call.
|
|
||||||
// Thus, doCancel can safely be 'false'.
|
|
||||||
doCancel = false;
|
|
||||||
handleEncException("doFinal() failed", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
reset(doCancel);
|
NIO_ACCESS.releaseSession(inBuffer);
|
||||||
}
|
}
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ import java.security.spec.AlgorithmParameterSpec;
|
|||||||
|
|
||||||
import javax.crypto.MacSpi;
|
import javax.crypto.MacSpi;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
import sun.security.pkcs11.wrapper.*;
|
import sun.security.pkcs11.wrapper.*;
|
||||||
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
|||||||
*/
|
*/
|
||||||
final class P11Mac extends MacSpi {
|
final class P11Mac extends MacSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// token instance
|
// token instance
|
||||||
private final Token token;
|
private final Token token;
|
||||||
|
|
||||||
@ -246,13 +250,17 @@ final class P11Mac extends MacSpi {
|
|||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(byteBuffer instanceof DirectBuffer directBuffer)) {
|
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||||
super.engineUpdate(byteBuffer);
|
super.engineUpdate(byteBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long addr = directBuffer.address();
|
|
||||||
int ofs = byteBuffer.position();
|
int ofs = byteBuffer.position();
|
||||||
token.p11.C_SignUpdate(session.id(), addr + ofs, null, 0, len);
|
NIO_ACCESS.acquireSession(byteBuffer);
|
||||||
|
try {
|
||||||
|
token.p11.C_SignUpdate(session.id(), dByteBuffer.address() + ofs, null, 0, len);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(byteBuffer);
|
||||||
|
}
|
||||||
byteBuffer.position(ofs + len);
|
byteBuffer.position(ofs + len);
|
||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
throw new ProviderException("update() failed", e);
|
throw new ProviderException("update() failed", e);
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
|
|
||||||
package sun.security.pkcs11;
|
package sun.security.pkcs11;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.MGF1ParameterSpec;
|
import java.security.spec.MGF1ParameterSpec;
|
||||||
@ -68,6 +68,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
|||||||
*/
|
*/
|
||||||
final class P11PSSSignature extends SignatureSpi {
|
final class P11PSSSignature extends SignatureSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
// mappings of digest algorithms and their output length in bytes
|
// mappings of digest algorithms and their output length in bytes
|
||||||
@ -613,14 +615,15 @@ final class P11PSSSignature extends SignatureSpi {
|
|||||||
isActive = true;
|
isActive = true;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case T_UPDATE -> {
|
case T_UPDATE -> {
|
||||||
if (byteBuffer instanceof DirectBuffer == false) {
|
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||||
// cannot do better than default impl
|
// cannot do better than default impl
|
||||||
super.engineUpdate(byteBuffer);
|
super.engineUpdate(byteBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long addr = ((DirectBuffer) byteBuffer).address();
|
|
||||||
int ofs = byteBuffer.position();
|
int ofs = byteBuffer.position();
|
||||||
|
NIO_ACCESS.acquireSession(byteBuffer);
|
||||||
try {
|
try {
|
||||||
|
long addr = dByteBuffer.address();
|
||||||
if (mode == M_SIGN) {
|
if (mode == M_SIGN) {
|
||||||
if (DEBUG) System.out.println(this + ": Calling C_SignUpdate");
|
if (DEBUG) System.out.println(this + ": Calling C_SignUpdate");
|
||||||
token.p11.C_SignUpdate
|
token.p11.C_SignUpdate
|
||||||
@ -635,6 +638,8 @@ final class P11PSSSignature extends SignatureSpi {
|
|||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
reset(false);
|
reset(false);
|
||||||
throw new ProviderException("Update failed", e);
|
throw new ProviderException("Update failed", e);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(byteBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case T_DIGEST -> {
|
case T_DIGEST -> {
|
||||||
|
@ -32,10 +32,12 @@ import java.nio.ByteBuffer;
|
|||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.interfaces.*;
|
import java.security.interfaces.*;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
|
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
|
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
import sun.security.x509.AlgorithmId;
|
|
||||||
|
|
||||||
import sun.security.rsa.RSAUtil;
|
import sun.security.rsa.RSAUtil;
|
||||||
import sun.security.rsa.RSAPadding;
|
import sun.security.rsa.RSAPadding;
|
||||||
@ -98,6 +100,8 @@ import sun.security.util.KeyUtil;
|
|||||||
*/
|
*/
|
||||||
final class P11Signature extends SignatureSpi {
|
final class P11Signature extends SignatureSpi {
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
// token instance
|
// token instance
|
||||||
private final Token token;
|
private final Token token;
|
||||||
|
|
||||||
@ -575,14 +579,15 @@ final class P11Signature extends SignatureSpi {
|
|||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case T_UPDATE -> {
|
case T_UPDATE -> {
|
||||||
if (!(byteBuffer instanceof DirectBuffer)) {
|
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||||
// cannot do better than default impl
|
// cannot do better than default impl
|
||||||
super.engineUpdate(byteBuffer);
|
super.engineUpdate(byteBuffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long addr = ((DirectBuffer) byteBuffer).address();
|
|
||||||
int ofs = byteBuffer.position();
|
int ofs = byteBuffer.position();
|
||||||
|
NIO_ACCESS.acquireSession(byteBuffer);
|
||||||
try {
|
try {
|
||||||
|
long addr = dByteBuffer.address();
|
||||||
if (mode == M_SIGN) {
|
if (mode == M_SIGN) {
|
||||||
token.p11.C_SignUpdate
|
token.p11.C_SignUpdate
|
||||||
(session.id(), addr + ofs, null, 0, len);
|
(session.id(), addr + ofs, null, 0, len);
|
||||||
@ -595,6 +600,8 @@ final class P11Signature extends SignatureSpi {
|
|||||||
} catch (PKCS11Exception e) {
|
} catch (PKCS11Exception e) {
|
||||||
reset(false);
|
reset(false);
|
||||||
throw new ProviderException("Update failed", e);
|
throw new ProviderException("Update failed", e);
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(byteBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case T_DIGEST -> {
|
case T_DIGEST -> {
|
||||||
|
@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
|
|||||||
import com.sun.nio.sctp.NotificationHandler;
|
import com.sun.nio.sctp.NotificationHandler;
|
||||||
import com.sun.nio.sctp.SctpChannel;
|
import com.sun.nio.sctp.SctpChannel;
|
||||||
import com.sun.nio.sctp.SctpSocketOption;
|
import com.sun.nio.sctp.SctpSocketOption;
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.net.util.IPAddressUtil;
|
import sun.net.util.IPAddressUtil;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.nio.ch.IOStatus;
|
import sun.nio.ch.IOStatus;
|
||||||
@ -74,6 +76,9 @@ import static sun.nio.ch.sctp.ResultContainer.SHUTDOWN;
|
|||||||
public class SctpChannelImpl extends SctpChannel
|
public class SctpChannelImpl extends SctpChannel
|
||||||
implements SelChImpl
|
implements SelChImpl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
private final FileDescriptor fd;
|
private final FileDescriptor fd;
|
||||||
|
|
||||||
private final int fdVal;
|
private final int fdVal;
|
||||||
@ -839,11 +844,16 @@ public class SctpChannelImpl extends SctpChannel
|
|||||||
boolean peek)
|
boolean peek)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
|
NIO_ACCESS.acquireSession(bb);
|
||||||
|
try {
|
||||||
|
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem, peek);
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
bb.position(pos + n);
|
bb.position(pos + n);
|
||||||
return n;
|
return n;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InternalNotificationHandler internalNotificationHandler =
|
private InternalNotificationHandler internalNotificationHandler =
|
||||||
@ -1028,11 +1038,16 @@ public class SctpChannelImpl extends SctpChannel
|
|||||||
assert (pos <= lim);
|
assert (pos <= lim);
|
||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
|
||||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
NIO_ACCESS.acquireSession(bb);
|
||||||
port, -1 /*121*/, streamNumber, unordered, ppid);
|
try {
|
||||||
if (written > 0)
|
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||||
bb.position(pos + written);
|
port, -1 /*121*/, streamNumber, unordered, ppid);
|
||||||
return written;
|
if (written > 0)
|
||||||
|
bb.position(pos + written);
|
||||||
|
return written;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
|
|||||||
import com.sun.nio.sctp.SctpChannel;
|
import com.sun.nio.sctp.SctpChannel;
|
||||||
import com.sun.nio.sctp.SctpMultiChannel;
|
import com.sun.nio.sctp.SctpMultiChannel;
|
||||||
import com.sun.nio.sctp.SctpSocketOption;
|
import com.sun.nio.sctp.SctpSocketOption;
|
||||||
|
import jdk.internal.access.JavaNioAccess;
|
||||||
|
import jdk.internal.access.SharedSecrets;
|
||||||
import sun.net.util.IPAddressUtil;
|
import sun.net.util.IPAddressUtil;
|
||||||
import sun.nio.ch.DirectBuffer;
|
import sun.nio.ch.DirectBuffer;
|
||||||
import sun.nio.ch.NativeThread;
|
import sun.nio.ch.NativeThread;
|
||||||
@ -71,6 +73,8 @@ import static sun.nio.ch.sctp.ResultContainer.*;
|
|||||||
public class SctpMultiChannelImpl extends SctpMultiChannel
|
public class SctpMultiChannelImpl extends SctpMultiChannel
|
||||||
implements SelChImpl
|
implements SelChImpl
|
||||||
{
|
{
|
||||||
|
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||||
|
|
||||||
private final FileDescriptor fd;
|
private final FileDescriptor fd;
|
||||||
|
|
||||||
private final int fdVal;
|
private final int fdVal;
|
||||||
@ -583,10 +587,15 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
|
|||||||
int rem,
|
int rem,
|
||||||
int pos)
|
int pos)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
|
NIO_ACCESS.acquireSession(bb);
|
||||||
if (n > 0)
|
try {
|
||||||
bb.position(pos + n);
|
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
|
||||||
return n;
|
if (n > 0)
|
||||||
|
bb.position(pos + n);
|
||||||
|
return n;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private InternalNotificationHandler internalNotificationHandler =
|
private InternalNotificationHandler internalNotificationHandler =
|
||||||
@ -908,11 +917,16 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
|
|||||||
assert (pos <= lim);
|
assert (pos <= lim);
|
||||||
int rem = (pos <= lim ? lim - pos : 0);
|
int rem = (pos <= lim ? lim - pos : 0);
|
||||||
|
|
||||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
NIO_ACCESS.acquireSession(bb);
|
||||||
port, assocId, streamNumber, unordered, ppid);
|
try {
|
||||||
if (written > 0)
|
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||||
bb.position(pos + written);
|
port, assocId, streamNumber, unordered, ppid);
|
||||||
return written;
|
if (written > 0)
|
||||||
|
bb.position(pos + written);
|
||||||
|
return written;
|
||||||
|
} finally {
|
||||||
|
NIO_ACCESS.releaseSession(bb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user