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;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.security.jca.JCAUtil;
|
||||
@ -92,6 +94,8 @@ abstract class GaloisCounterMode extends CipherSpi {
|
||||
|
||||
static final byte[] EMPTY_BUF = new byte[0];
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
SymmetricCipher blockCipher;
|
||||
@ -909,6 +913,8 @@ abstract class GaloisCounterMode extends CipherSpi {
|
||||
*/
|
||||
ByteBuffer overlapDetection(ByteBuffer src, ByteBuffer dst) {
|
||||
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 ddst = (DirectBuffer) dst;
|
||||
|
||||
@ -946,7 +952,6 @@ abstract class GaloisCounterMode extends CipherSpi {
|
||||
((DirectBuffer) dst).address() - dstaddr + dst.position()) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
} else if (!src.isDirect() && !dst.isDirect()) {
|
||||
// if src is read only, then we need a copy
|
||||
if (!src.isReadOnly()) {
|
||||
@ -1585,8 +1590,13 @@ abstract class GaloisCounterMode extends CipherSpi {
|
||||
int ofs = dst.arrayOffset() + dst.position();
|
||||
Arrays.fill(dst.array(), ofs , ofs + len, (byte)0);
|
||||
} else {
|
||||
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
|
||||
len + dst.position(), (byte)0);
|
||||
NIO_ACCESS.acquireSession(dst);
|
||||
try {
|
||||
Unsafe.getUnsafe().setMemory(((DirectBuffer)dst).address(),
|
||||
len + dst.position(), (byte) 0);
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(dst);
|
||||
}
|
||||
}
|
||||
throw new AEADBadTagException("Tag mismatch");
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import jdk.internal.vm.annotation.ForceInline;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.lang.foreign.MemorySegment;
|
||||
import java.lang.ref.Reference;
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
|
||||
@ -779,6 +780,7 @@ public abstract sealed class Buffer
|
||||
// setup access to this package in SharedSecrets
|
||||
SharedSecrets.setJavaNioAccess(
|
||||
new JavaNioAccess() {
|
||||
|
||||
@Override
|
||||
public BufferPool getDirectBufferPool() {
|
||||
return Bits.BUFFER_POOL;
|
||||
@ -824,16 +826,34 @@ public abstract sealed class Buffer
|
||||
}
|
||||
|
||||
@Override
|
||||
public Runnable acquireSession(Buffer buffer, boolean async) {
|
||||
var session = buffer.session();
|
||||
if (session == null) {
|
||||
return null;
|
||||
public void acquireSession(Buffer buffer) {
|
||||
var scope = buffer.session();
|
||||
if (scope != 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
|
||||
|
@ -25,11 +25,13 @@
|
||||
|
||||
package java.util.zip;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.ByteBuffer;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import jdk.internal.util.Preconditions;
|
||||
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
|
||||
@ -96,10 +98,11 @@ public class Adler32 implements Checksum {
|
||||
if (rem <= 0)
|
||||
return;
|
||||
if (buffer.isDirect()) {
|
||||
NIO_ACCESS.acquireSession(buffer);
|
||||
try {
|
||||
adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
|
||||
} finally {
|
||||
Reference.reachabilityFence(buffer);
|
||||
NIO_ACCESS.releaseSession(buffer);
|
||||
}
|
||||
} else if (buffer.hasArray()) {
|
||||
adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package java.util.zip;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -33,6 +32,8 @@ import sun.nio.ch.DirectBuffer;
|
||||
import jdk.internal.util.Preconditions;
|
||||
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.
|
||||
*
|
||||
@ -96,10 +97,11 @@ public class CRC32 implements Checksum {
|
||||
if (rem <= 0)
|
||||
return;
|
||||
if (buffer.isDirect()) {
|
||||
NIO_ACCESS.acquireSession(buffer);
|
||||
try {
|
||||
crc = updateByteBuffer(crc, ((DirectBuffer)buffer).address(), pos, rem);
|
||||
} finally {
|
||||
Reference.reachabilityFence(buffer);
|
||||
NIO_ACCESS.releaseSession(buffer);
|
||||
}
|
||||
} else if (buffer.hasArray()) {
|
||||
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(), rem);
|
||||
|
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package java.util.zip;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@ -33,6 +32,8 @@ import jdk.internal.util.Preconditions;
|
||||
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 CRC-32C of a data stream.
|
||||
*
|
||||
@ -171,11 +172,12 @@ public final class CRC32C implements Checksum {
|
||||
}
|
||||
|
||||
if (buffer.isDirect()) {
|
||||
NIO_ACCESS.acquireSession(buffer);
|
||||
try {
|
||||
crc = updateDirectByteBuffer(crc, ((DirectBuffer) buffer).address(),
|
||||
crc = updateDirectByteBuffer(crc, ((DirectBuffer)buffer).address(),
|
||||
pos, limit);
|
||||
} finally {
|
||||
Reference.reachabilityFence(buffer);
|
||||
NIO_ACCESS.releaseSession(buffer);
|
||||
}
|
||||
} else if (buffer.hasArray()) {
|
||||
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(),
|
||||
|
@ -26,7 +26,6 @@
|
||||
package java.util.zip;
|
||||
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
import java.util.Objects;
|
||||
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
|
||||
import jdk.internal.util.Preconditions;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||
|
||||
/**
|
||||
* This class provides support for general purpose compression using the
|
||||
* popular ZLIB compression library. The ZLIB compression library was
|
||||
@ -337,11 +338,12 @@ public class Deflater {
|
||||
int remaining = Math.max(dictionary.limit() - position, 0);
|
||||
ensureOpen();
|
||||
if (dictionary.isDirect()) {
|
||||
long address = ((DirectBuffer) dictionary).address();
|
||||
NIO_ACCESS.acquireSession(dictionary);
|
||||
try {
|
||||
long address = ((DirectBuffer) dictionary).address();
|
||||
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
||||
} finally {
|
||||
Reference.reachabilityFence(dictionary);
|
||||
NIO_ACCESS.releaseSession(dictionary);
|
||||
}
|
||||
} else {
|
||||
byte[] array = ZipUtils.getBufferArray(dictionary);
|
||||
@ -587,6 +589,7 @@ public class Deflater {
|
||||
inputPos = input.position();
|
||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||
if (input.isDirect()) {
|
||||
NIO_ACCESS.acquireSession(input);
|
||||
try {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
result = deflateBufferBytes(zsRef.address(),
|
||||
@ -594,7 +597,7 @@ public class Deflater {
|
||||
output, off, len,
|
||||
flush, params);
|
||||
} finally {
|
||||
Reference.reachabilityFence(input);
|
||||
NIO_ACCESS.releaseSession(input);
|
||||
}
|
||||
} else {
|
||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||
@ -709,14 +712,15 @@ public class Deflater {
|
||||
if (input == null) {
|
||||
inputPos = this.inputPos;
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
result = deflateBytesBuffer(zsRef.address(),
|
||||
inputArray, inputPos, inputLim - inputPos,
|
||||
outputAddress + outputPos, outputRem,
|
||||
flush, params);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
@ -730,17 +734,19 @@ public class Deflater {
|
||||
inputPos = input.position();
|
||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||
if (input.isDirect()) {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
NIO_ACCESS.acquireSession(input);
|
||||
try {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = outputPos + ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = outputPos + ((DirectBuffer) output).address();
|
||||
result = deflateBufferBuffer(zsRef.address(),
|
||||
inputAddress + inputPos, inputRem,
|
||||
outputAddress, outputRem,
|
||||
flush, params);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
@ -751,20 +757,21 @@ public class Deflater {
|
||||
flush, params);
|
||||
}
|
||||
} finally {
|
||||
Reference.reachabilityFence(input);
|
||||
NIO_ACCESS.releaseSession(input);
|
||||
}
|
||||
} else {
|
||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||
int inputOffset = ZipUtils.getBufferOffset(input);
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
result = deflateBytesBuffer(zsRef.address(),
|
||||
inputArray, inputOffset + inputPos, inputRem,
|
||||
outputAddress + outputPos, outputRem,
|
||||
flush, params);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
|
@ -26,7 +26,6 @@
|
||||
package java.util.zip;
|
||||
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
import java.util.Objects;
|
||||
@ -35,6 +34,8 @@ import jdk.internal.ref.CleanerFactory;
|
||||
import jdk.internal.util.Preconditions;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import static java.util.zip.ZipUtils.NIO_ACCESS;
|
||||
|
||||
/**
|
||||
* This class provides support for general purpose decompression using the
|
||||
* popular ZLIB compression library. The ZLIB compression library was
|
||||
@ -259,11 +260,12 @@ public class Inflater {
|
||||
int remaining = Math.max(dictionary.limit() - position, 0);
|
||||
ensureOpen();
|
||||
if (dictionary.isDirect()) {
|
||||
long address = ((DirectBuffer) dictionary).address();
|
||||
NIO_ACCESS.acquireSession(dictionary);
|
||||
try {
|
||||
long address = ((DirectBuffer) dictionary).address();
|
||||
setDictionaryBuffer(zsRef.address(), address + position, remaining);
|
||||
} finally {
|
||||
Reference.reachabilityFence(dictionary);
|
||||
NIO_ACCESS.releaseSession(dictionary);
|
||||
}
|
||||
} else {
|
||||
byte[] array = ZipUtils.getBufferArray(dictionary);
|
||||
@ -383,13 +385,14 @@ public class Inflater {
|
||||
try {
|
||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||
if (input.isDirect()) {
|
||||
NIO_ACCESS.acquireSession(input);
|
||||
try {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
result = inflateBufferBytes(zsRef.address(),
|
||||
inputAddress + inputPos, inputRem,
|
||||
output, off, len);
|
||||
} finally {
|
||||
Reference.reachabilityFence(input);
|
||||
NIO_ACCESS.releaseSession(input);
|
||||
}
|
||||
} else {
|
||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||
@ -517,13 +520,14 @@ public class Inflater {
|
||||
inputPos = this.inputPos;
|
||||
try {
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
result = inflateBytesBuffer(zsRef.address(),
|
||||
inputArray, inputPos, inputLim - inputPos,
|
||||
outputAddress + outputPos, outputRem);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
@ -541,16 +545,18 @@ public class Inflater {
|
||||
int inputRem = Math.max(input.limit() - inputPos, 0);
|
||||
try {
|
||||
if (input.isDirect()) {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
NIO_ACCESS.acquireSession(input);
|
||||
try {
|
||||
long inputAddress = ((DirectBuffer) input).address();
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
result = inflateBufferBuffer(zsRef.address(),
|
||||
inputAddress + inputPos, inputRem,
|
||||
outputAddress + outputPos, outputRem);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
@ -560,19 +566,20 @@ public class Inflater {
|
||||
outputArray, outputOffset + outputPos, outputRem);
|
||||
}
|
||||
} finally {
|
||||
Reference.reachabilityFence(input);
|
||||
NIO_ACCESS.releaseSession(input);
|
||||
}
|
||||
} else {
|
||||
byte[] inputArray = ZipUtils.getBufferArray(input);
|
||||
int inputOffset = ZipUtils.getBufferOffset(input);
|
||||
if (output.isDirect()) {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
NIO_ACCESS.acquireSession(output);
|
||||
try {
|
||||
long outputAddress = ((DirectBuffer) output).address();
|
||||
result = inflateBytesBuffer(zsRef.address(),
|
||||
inputArray, inputOffset + inputPos, inputRem,
|
||||
outputAddress + outputPos, outputRem);
|
||||
} finally {
|
||||
Reference.reachabilityFence(output);
|
||||
NIO_ACCESS.releaseSession(output);
|
||||
}
|
||||
} else {
|
||||
byte[] outputArray = ZipUtils.getBufferArray(output);
|
||||
|
@ -36,10 +36,14 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.zip.ZipConstants.ENDHDR;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
class ZipUtils {
|
||||
|
||||
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// used to adjust values between Windows and java epoch
|
||||
private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L;
|
||||
|
||||
|
@ -86,12 +86,26 @@ public interface JavaNioAccess {
|
||||
MemorySegment bufferSegment(Buffer buffer);
|
||||
|
||||
/**
|
||||
* Used by I/O operations to make a buffer's session non-closeable
|
||||
* (for the duration of the I/O operation) by acquiring the session.
|
||||
* Null is returned if the buffer has no scope, or acquiring is not
|
||||
* required to guarantee safety.
|
||||
* Used by operations to make a buffer's session non-closeable
|
||||
* (for the duration of the operation) by acquiring the session.
|
||||
* {@snippet lang = java:
|
||||
* 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.
|
||||
|
@ -166,7 +166,9 @@ module java.base {
|
||||
jdk.jartool,
|
||||
jdk.jlink,
|
||||
jdk.jfr,
|
||||
jdk.net;
|
||||
jdk.net,
|
||||
jdk.sctp,
|
||||
jdk.crypto.cryptoki;
|
||||
exports jdk.internal.foreign to
|
||||
jdk.incubator.vector;
|
||||
exports jdk.internal.event to
|
||||
|
@ -71,6 +71,8 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
import sun.net.ResourceManager;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
@ -87,6 +89,8 @@ class DatagramChannelImpl
|
||||
// Used to make native read and write calls
|
||||
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)
|
||||
private final boolean interruptible;
|
||||
|
||||
@ -780,13 +784,18 @@ class DatagramChannelImpl
|
||||
boolean connected)
|
||||
throws IOException
|
||||
{
|
||||
int n = receive0(fd,
|
||||
((DirectBuffer)bb).address() + pos, rem,
|
||||
sourceSockAddr.address(),
|
||||
connected);
|
||||
if (n > 0)
|
||||
bb.position(pos + n);
|
||||
return n;
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
try {
|
||||
int n = receive0(fd,
|
||||
((DirectBuffer)bb).address() + pos, rem,
|
||||
sourceSockAddr.address(),
|
||||
connected);
|
||||
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 written;
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
try {
|
||||
int addressLen = targetSocketAddress(target);
|
||||
written = send0(fd, ((DirectBuffer)bb).address() + pos, rem,
|
||||
@ -938,6 +948,8 @@ class DatagramChannelImpl
|
||||
if (isConnected())
|
||||
throw pue;
|
||||
written = rem;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
}
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
|
@ -30,6 +30,13 @@ import jdk.internal.ref.Cleaner;
|
||||
|
||||
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 Object attachment();
|
||||
|
@ -31,12 +31,13 @@ import java.nio.ByteBuffer;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.foreign.MemorySessionImpl;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -128,7 +129,7 @@ public class IOUtil {
|
||||
int written = 0;
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
var handle = acquireScope(bb, async);
|
||||
acquireScope(bb, async);
|
||||
try {
|
||||
if (position != -1) {
|
||||
written = nd.pwrite(fd, bufferAddress(bb) + pos, rem, position);
|
||||
@ -136,7 +137,7 @@ public class IOUtil {
|
||||
written = nd.write(fd, bufferAddress(bb) + pos, rem);
|
||||
}
|
||||
} finally {
|
||||
releaseScope(handle);
|
||||
releaseScope(bb);
|
||||
}
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
@ -181,9 +182,9 @@ public class IOUtil {
|
||||
int i = offset;
|
||||
while (i < count && iov_len < IOV_MAX && writevLen < WRITEV_MAX) {
|
||||
ByteBuffer buf = bufs[i];
|
||||
var h = acquireScope(buf, async);
|
||||
if (h != null) {
|
||||
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
|
||||
acquireScope(buf, async);
|
||||
if (NIO_ACCESS.hasSession(buf)) {
|
||||
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
|
||||
}
|
||||
int pos = buf.position();
|
||||
int lim = buf.limit();
|
||||
@ -331,7 +332,7 @@ public class IOUtil {
|
||||
if (rem == 0)
|
||||
return 0;
|
||||
int n = 0;
|
||||
var handle = acquireScope(bb, async);
|
||||
acquireScope(bb, async);
|
||||
try {
|
||||
if (position != -1) {
|
||||
n = nd.pread(fd, bufferAddress(bb) + pos, rem, position);
|
||||
@ -339,7 +340,7 @@ public class IOUtil {
|
||||
n = nd.read(fd, bufferAddress(bb) + pos, rem);
|
||||
}
|
||||
} finally {
|
||||
releaseScope(handle);
|
||||
releaseScope(bb);
|
||||
}
|
||||
if (n > 0)
|
||||
bb.position(pos + n);
|
||||
@ -393,9 +394,9 @@ public class IOUtil {
|
||||
ByteBuffer buf = bufs[i];
|
||||
if (buf.isReadOnly())
|
||||
throw new IllegalArgumentException("Read-only buffer");
|
||||
var h = acquireScope(buf, async);
|
||||
if (h != null) {
|
||||
handleReleasers = LinkedRunnable.of(Releaser.of(h), handleReleasers);
|
||||
acquireScope(buf, async);
|
||||
if (NIO_ACCESS.hasSession(buf)) {
|
||||
handleReleasers = LinkedRunnable.of(Releaser.of(buf), handleReleasers);
|
||||
}
|
||||
int pos = buf.position();
|
||||
int lim = buf.limit();
|
||||
@ -474,15 +475,16 @@ public class IOUtil {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
static Runnable acquireScope(ByteBuffer bb, boolean async) {
|
||||
return NIO_ACCESS.acquireSession(bb, async);
|
||||
static void acquireScope(ByteBuffer bb, boolean async) {
|
||||
if (async && NIO_ACCESS.isThreadConfined(bb)) {
|
||||
throw new IllegalStateException("Confined session not supported");
|
||||
}
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
}
|
||||
|
||||
private static void releaseScope(Runnable handle) {
|
||||
if (handle == null)
|
||||
return;
|
||||
private static void releaseScope(ByteBuffer bb) {
|
||||
try {
|
||||
handle.run();
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -495,15 +497,14 @@ public class IOUtil {
|
||||
static Runnable acquireScopes(ByteBuffer buf, ByteBuffer[] buffers) {
|
||||
if (buffers == null) {
|
||||
assert buf != null;
|
||||
return IOUtil.Releaser.ofNullable(IOUtil.acquireScope(buf, true));
|
||||
IOUtil.acquireScope(buf, true);
|
||||
return IOUtil.Releaser.of(buf);
|
||||
} else {
|
||||
assert buf == null;
|
||||
Runnable handleReleasers = null;
|
||||
for (var b : buffers) {
|
||||
var h = IOUtil.acquireScope(b, true);
|
||||
if (h != null) {
|
||||
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(h), handleReleasers);
|
||||
}
|
||||
IOUtil.acquireScope(b, true);
|
||||
handleReleasers = IOUtil.LinkedRunnable.of(IOUtil.Releaser.of(b), handleReleasers);
|
||||
}
|
||||
return handleReleasers;
|
||||
}
|
||||
@ -514,12 +515,11 @@ public class IOUtil {
|
||||
releasers.run();
|
||||
}
|
||||
|
||||
static record LinkedRunnable(Runnable node, Runnable next)
|
||||
implements Runnable
|
||||
{
|
||||
record LinkedRunnable(Runnable node, Runnable next) implements Runnable {
|
||||
LinkedRunnable {
|
||||
Objects.requireNonNull(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@ -529,20 +529,28 @@ public class IOUtil {
|
||||
next.run();
|
||||
}
|
||||
}
|
||||
|
||||
static LinkedRunnable of(Runnable first, Runnable second) {
|
||||
return new LinkedRunnable(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
static record Releaser(Runnable handle) implements Runnable {
|
||||
Releaser { Objects.requireNonNull(handle) ; }
|
||||
@Override public void run() { releaseScope(handle); }
|
||||
static Runnable of(Runnable handle) { return new Releaser(handle); }
|
||||
static Runnable ofNullable(Runnable handle) {
|
||||
if (handle == null)
|
||||
return () -> { };
|
||||
return new Releaser(handle);
|
||||
record Releaser(ByteBuffer bb) implements Runnable {
|
||||
Releaser {
|
||||
Objects.requireNonNull(bb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
releaseScope(bb);
|
||||
}
|
||||
|
||||
static Runnable of(ByteBuffer bb) {
|
||||
return NIO_ACCESS.hasSession(bb)
|
||||
? new Releaser(bb)
|
||||
: () -> {};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static long bufferAddress(ByteBuffer buf) {
|
||||
|
@ -134,6 +134,7 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" {
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.com.sun.crypto.provider";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.misc";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.access";
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.sun.security.*";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
||||
|
@ -25,11 +25,13 @@
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.nio.file.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import static sun.nio.fs.UnixConstants.*;
|
||||
@ -43,6 +45,8 @@ abstract class UnixUserDefinedFileAttributeView
|
||||
{
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// namespace for extended user attributes
|
||||
private static final String USER_NAMESPACE = "user.";
|
||||
|
||||
@ -174,14 +178,15 @@ abstract class UnixUserDefinedFileAttributeView
|
||||
assert (pos <= lim);
|
||||
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 {
|
||||
long address = buf.address() + pos;
|
||||
long address = ddst.address() + pos;
|
||||
int n = read(name, address, rem);
|
||||
dst.position(pos + n);
|
||||
return n;
|
||||
} finally {
|
||||
Reference.reachabilityFence(buf);
|
||||
NIO_ACCESS.releaseSession(dst);
|
||||
}
|
||||
} else {
|
||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||
@ -237,13 +242,14 @@ abstract class UnixUserDefinedFileAttributeView
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
if (src instanceof sun.nio.ch.DirectBuffer buf) {
|
||||
NIO_ACCESS.acquireSession(src);
|
||||
try {
|
||||
long address = buf.address() + pos;
|
||||
write(name, address, rem);
|
||||
src.position(pos + rem);
|
||||
return rem;
|
||||
} finally {
|
||||
Reference.reachabilityFence(buf);
|
||||
NIO_ACCESS.releaseSession(src);
|
||||
}
|
||||
} else {
|
||||
try (NativeBuffer nb = NativeBuffers.getNativeBuffer(rem)) {
|
||||
|
@ -35,6 +35,8 @@ import java.security.spec.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
*/
|
||||
final class P11AEADCipher extends CipherSpi {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// supported AEAD algorithms/transformations
|
||||
private enum Transformation {
|
||||
AES_GCM("AES", "GCM", "NOPADDING", 16, 16),
|
||||
@ -705,84 +709,94 @@ final class P11AEADCipher extends CipherSpi {
|
||||
}
|
||||
|
||||
boolean doCancel = true;
|
||||
NIO_ACCESS.acquireSession(inBuffer);
|
||||
try {
|
||||
ensureInitialized();
|
||||
NIO_ACCESS.acquireSession(outBuffer);
|
||||
try {
|
||||
try {
|
||||
ensureInitialized();
|
||||
|
||||
long inAddr = 0;
|
||||
byte[] in = null;
|
||||
int inOfs = 0;
|
||||
if (dataBuffer.size() > 0) {
|
||||
if (inLen > 0) {
|
||||
byte[] temp = new byte[inLen];
|
||||
inBuffer.get(temp);
|
||||
dataBuffer.write(temp, 0, temp.length);
|
||||
}
|
||||
in = dataBuffer.toByteArray();
|
||||
inOfs = 0;
|
||||
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();
|
||||
long inAddr = 0;
|
||||
byte[] in = null;
|
||||
int inOfs = 0;
|
||||
if (dataBuffer.size() > 0) {
|
||||
if (inLen > 0) {
|
||||
byte[] temp = new byte[inLen];
|
||||
inBuffer.get(temp);
|
||||
dataBuffer.write(temp, 0, temp.length);
|
||||
}
|
||||
in = dataBuffer.toByteArray();
|
||||
inOfs = 0;
|
||||
inLen = in.length;
|
||||
} else {
|
||||
in = new byte[inLen];
|
||||
inBuffer.get(in);
|
||||
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||
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;
|
||||
if (encrypt) {
|
||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} else {
|
||||
// Special handling to match SunJCE provider behavior
|
||||
if (inLen == 0) {
|
||||
return 0;
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} else {
|
||||
// Special handling to match SunJCE provider behavior
|
||||
if (inLen == 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,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(outBuffer);
|
||||
}
|
||||
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);
|
||||
NIO_ACCESS.releaseSession(inBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,8 @@ import java.security.spec.*;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
@ -56,6 +58,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
*/
|
||||
final class P11Cipher extends CipherSpi {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// mode constant for ECB mode
|
||||
private static final int MODE_ECB = 3;
|
||||
// mode constant for CBC mode
|
||||
@ -678,115 +682,123 @@ final class P11Cipher extends CipherSpi {
|
||||
throw new ShortBufferException();
|
||||
}
|
||||
int origPos = inBuffer.position();
|
||||
NIO_ACCESS.acquireSession(inBuffer);
|
||||
try {
|
||||
ensureInitialized();
|
||||
NIO_ACCESS.acquireSession(outBuffer);
|
||||
try {
|
||||
ensureInitialized();
|
||||
|
||||
long inAddr = 0;
|
||||
int inOfs = 0;
|
||||
byte[] inArray = null;
|
||||
long inAddr = 0;
|
||||
int inOfs = 0;
|
||||
byte[] inArray = null;
|
||||
|
||||
if (inBuffer instanceof DirectBuffer) {
|
||||
inAddr = ((DirectBuffer) inBuffer).address();
|
||||
inOfs = origPos;
|
||||
} else if (inBuffer.hasArray()) {
|
||||
inArray = inBuffer.array();
|
||||
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];
|
||||
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||
inAddr = dInBuffer.address();
|
||||
inOfs = origPos;
|
||||
} else if (inBuffer.hasArray()) {
|
||||
inArray = inBuffer.array();
|
||||
inOfs = (origPos + inBuffer.arrayOffset());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
long outAddr = 0;
|
||||
int outOfs = 0;
|
||||
byte[] outArray = null;
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
k = token.p11.C_EncryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
} else {
|
||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
}
|
||||
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;
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen > 0) {
|
||||
bufferInputBytes(inBuffer, newPadBufferLen);
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
if (inAddr == 0 && inArray == null) {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
bytesBuffered += (inLen - k);
|
||||
if (!(outBuffer instanceof DirectBuffer) &&
|
||||
!outBuffer.hasArray()) {
|
||||
outBuffer.put(outArray, outOfs, k);
|
||||
} else {
|
||||
inBuffer.position(inBuffer.position() + inLen);
|
||||
outBuffer.position(outBuffer.position() + k);
|
||||
}
|
||||
if (encrypt) {
|
||||
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
} else {
|
||||
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - 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);
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(outBuffer);
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen > 0) {
|
||||
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);
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(inBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -877,99 +889,104 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
|
||||
boolean doCancel = true;
|
||||
NIO_ACCESS.acquireSession(outBuffer);
|
||||
try {
|
||||
ensureInitialized();
|
||||
try {
|
||||
ensureInitialized();
|
||||
|
||||
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();
|
||||
long outAddr = 0;
|
||||
byte[] outArray = null;
|
||||
int outOfs = 0;
|
||||
if (outBuffer instanceof DirectBuffer dOutBuffer) {
|
||||
outAddr = dOutBuffer.address();
|
||||
outOfs = outBuffer.position();
|
||||
} else {
|
||||
outArray = new byte[outLen];
|
||||
}
|
||||
}
|
||||
|
||||
int k = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
if (outBuffer.hasArray()) {
|
||||
outArray = outBuffer.array();
|
||||
outOfs = outBuffer.position() + outBuffer.arrayOffset();
|
||||
} else {
|
||||
outArray = new byte[outLen];
|
||||
}
|
||||
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) {
|
||||
if (padBufferLen != 0) {
|
||||
k = token.p11.C_DecryptUpdate(session.id(),
|
||||
0, padBuffer, 0, padBufferLen,
|
||||
0, padBuffer, 0, padBuffer.length);
|
||||
padBufferLen = 0;
|
||||
int k = 0;
|
||||
|
||||
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_DecryptUpdate failure (as
|
||||
// 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_DecryptFinal(session.id(),
|
||||
0, padBuffer, k, padBuffer.length - k);
|
||||
|
||||
int actualPadLen = paddingObj.unpad(padBuffer, k);
|
||||
k -= actualPadLen;
|
||||
outArray = padBuffer;
|
||||
outOfs = 0;
|
||||
k += token.p11.C_EncryptFinal(session.id(),
|
||||
outAddr, outArray, (outOfs + k), (outLen - k));
|
||||
} else {
|
||||
doCancel = false;
|
||||
k = token.p11.C_DecryptFinal(session.id(),
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
// Special handling to match SunJCE provider behavior
|
||||
if (bytesBuffered == 0 && padBufferLen == 0) {
|
||||
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 {
|
||||
reset(doCancel);
|
||||
NIO_ACCESS.releaseSession(outBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,13 +25,14 @@
|
||||
|
||||
package sun.security.pkcs11;
|
||||
|
||||
import java.util.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import sun.security.util.MessageDigestSpi2;
|
||||
@ -55,6 +56,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
final class P11Digest extends MessageDigestSpi implements Cloneable,
|
||||
MessageDigestSpi2 {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
/* fields initialized, no session acquired */
|
||||
private static final int S_BLANK = 1;
|
||||
|
||||
@ -268,13 +271,12 @@ final class P11Digest extends MessageDigestSpi implements Cloneable,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(byteBuffer instanceof DirectBuffer)) {
|
||||
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||
super.engineUpdate(byteBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchSession();
|
||||
long addr = ((DirectBuffer)byteBuffer).address();
|
||||
int ofs = byteBuffer.position();
|
||||
try {
|
||||
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);
|
||||
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);
|
||||
} catch (PKCS11Exception e) {
|
||||
engineReset();
|
||||
|
@ -37,13 +37,14 @@ import javax.crypto.spec.*;
|
||||
|
||||
import java.util.HexFormat;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
import static sun.security.pkcs11.TemplateManager.*;
|
||||
import static sun.security.pkcs11.P11Cipher.*;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
private static final int BLK_SIZE = 8;
|
||||
|
||||
// supported mode and padding with AES cipher
|
||||
@ -552,78 +555,88 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
|
||||
boolean doCancel = true;
|
||||
int k = 0;
|
||||
NIO_ACCESS.acquireSession(inBuffer);
|
||||
try {
|
||||
ensureInitialized();
|
||||
NIO_ACCESS.acquireSession(outBuffer);
|
||||
try {
|
||||
try {
|
||||
ensureInitialized();
|
||||
|
||||
long inAddr = 0;
|
||||
byte[] in = null;
|
||||
int inOfs = 0;
|
||||
long inAddr = 0;
|
||||
byte[] in = null;
|
||||
int inOfs = 0;
|
||||
|
||||
if (dataBuffer.size() > 0) {
|
||||
if (inBuffer != null && inLen > 0) {
|
||||
byte[] temp = new byte[inLen];
|
||||
inBuffer.get(temp);
|
||||
dataBuffer.write(temp, 0, temp.length);
|
||||
}
|
||||
if (dataBuffer.size() > 0) {
|
||||
if (inBuffer != null && inLen > 0) {
|
||||
byte[] temp = new byte[inLen];
|
||||
inBuffer.get(temp);
|
||||
dataBuffer.write(temp, 0, temp.length);
|
||||
}
|
||||
|
||||
in = dataBuffer.toByteArray();
|
||||
inOfs = 0;
|
||||
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();
|
||||
in = dataBuffer.toByteArray();
|
||||
inOfs = 0;
|
||||
inLen = in.length;
|
||||
} else {
|
||||
in = new byte[inLen];
|
||||
inBuffer.get(in);
|
||||
if (inBuffer instanceof DirectBuffer dInBuffer) {
|
||||
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) {
|
||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} else {
|
||||
// Special handling to match SunJCE provider behavior
|
||||
if (inLen == 0) {
|
||||
return 0;
|
||||
if (opmode == Cipher.ENCRYPT_MODE) {
|
||||
k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} else {
|
||||
// Special handling to match SunJCE provider behavior
|
||||
if (inLen == 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,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
doCancel = false;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(outBuffer);
|
||||
}
|
||||
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);
|
||||
NIO_ACCESS.releaseSession(inBuffer);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import javax.crypto.MacSpi;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
@ -55,6 +57,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
*/
|
||||
final class P11Mac extends MacSpi {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// token instance
|
||||
private final Token token;
|
||||
|
||||
@ -246,13 +250,17 @@ final class P11Mac extends MacSpi {
|
||||
if (len <= 0) {
|
||||
return;
|
||||
}
|
||||
if (!(byteBuffer instanceof DirectBuffer directBuffer)) {
|
||||
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||
super.engineUpdate(byteBuffer);
|
||||
return;
|
||||
}
|
||||
long addr = directBuffer.address();
|
||||
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);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException("update() failed", e);
|
||||
|
@ -25,13 +25,13 @@
|
||||
|
||||
package sun.security.pkcs11;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Arrays;
|
||||
import java.security.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.MGF1ParameterSpec;
|
||||
@ -68,6 +68,8 @@ import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
*/
|
||||
final class P11PSSSignature extends SignatureSpi {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// mappings of digest algorithms and their output length in bytes
|
||||
@ -613,14 +615,15 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
isActive = true;
|
||||
switch (type) {
|
||||
case T_UPDATE -> {
|
||||
if (byteBuffer instanceof DirectBuffer == false) {
|
||||
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||
// cannot do better than default impl
|
||||
super.engineUpdate(byteBuffer);
|
||||
return;
|
||||
}
|
||||
long addr = ((DirectBuffer) byteBuffer).address();
|
||||
int ofs = byteBuffer.position();
|
||||
NIO_ACCESS.acquireSession(byteBuffer);
|
||||
try {
|
||||
long addr = dByteBuffer.address();
|
||||
if (mode == M_SIGN) {
|
||||
if (DEBUG) System.out.println(this + ": Calling C_SignUpdate");
|
||||
token.p11.C_SignUpdate
|
||||
@ -635,6 +638,8 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
} catch (PKCS11Exception e) {
|
||||
reset(false);
|
||||
throw new ProviderException("Update failed", e);
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(byteBuffer);
|
||||
}
|
||||
}
|
||||
case T_DIGEST -> {
|
||||
|
@ -32,10 +32,12 @@ import java.nio.ByteBuffer;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
|
||||
import sun.security.rsa.RSAUtil;
|
||||
import sun.security.rsa.RSAPadding;
|
||||
@ -98,6 +100,8 @@ import sun.security.util.KeyUtil;
|
||||
*/
|
||||
final class P11Signature extends SignatureSpi {
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
// token instance
|
||||
private final Token token;
|
||||
|
||||
@ -575,14 +579,15 @@ final class P11Signature extends SignatureSpi {
|
||||
}
|
||||
switch (type) {
|
||||
case T_UPDATE -> {
|
||||
if (!(byteBuffer instanceof DirectBuffer)) {
|
||||
if (!(byteBuffer instanceof DirectBuffer dByteBuffer)) {
|
||||
// cannot do better than default impl
|
||||
super.engineUpdate(byteBuffer);
|
||||
return;
|
||||
}
|
||||
long addr = ((DirectBuffer) byteBuffer).address();
|
||||
int ofs = byteBuffer.position();
|
||||
NIO_ACCESS.acquireSession(byteBuffer);
|
||||
try {
|
||||
long addr = dByteBuffer.address();
|
||||
if (mode == M_SIGN) {
|
||||
token.p11.C_SignUpdate
|
||||
(session.id(), addr + ofs, null, 0, len);
|
||||
@ -595,6 +600,8 @@ final class P11Signature extends SignatureSpi {
|
||||
} catch (PKCS11Exception e) {
|
||||
reset(false);
|
||||
throw new ProviderException("Update failed", e);
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(byteBuffer);
|
||||
}
|
||||
}
|
||||
case T_DIGEST -> {
|
||||
|
@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
|
||||
import com.sun.nio.sctp.NotificationHandler;
|
||||
import com.sun.nio.sctp.SctpChannel;
|
||||
import com.sun.nio.sctp.SctpSocketOption;
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.nio.ch.IOStatus;
|
||||
@ -74,6 +76,9 @@ import static sun.nio.ch.sctp.ResultContainer.SHUTDOWN;
|
||||
public class SctpChannelImpl extends SctpChannel
|
||||
implements SelChImpl
|
||||
{
|
||||
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
private final FileDescriptor fd;
|
||||
|
||||
private final int fdVal;
|
||||
@ -839,11 +844,16 @@ public class SctpChannelImpl extends SctpChannel
|
||||
boolean peek)
|
||||
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)
|
||||
bb.position(pos + n);
|
||||
return n;
|
||||
if (n > 0)
|
||||
bb.position(pos + n);
|
||||
return n;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
}
|
||||
}
|
||||
|
||||
private InternalNotificationHandler internalNotificationHandler =
|
||||
@ -1028,11 +1038,16 @@ public class SctpChannelImpl extends SctpChannel
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||
port, -1 /*121*/, streamNumber, unordered, ppid);
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
return written;
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
try {
|
||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||
port, -1 /*121*/, streamNumber, unordered, ppid);
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
return written;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,6 +53,8 @@ import com.sun.nio.sctp.MessageInfo;
|
||||
import com.sun.nio.sctp.SctpChannel;
|
||||
import com.sun.nio.sctp.SctpMultiChannel;
|
||||
import com.sun.nio.sctp.SctpSocketOption;
|
||||
import jdk.internal.access.JavaNioAccess;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.nio.ch.NativeThread;
|
||||
@ -71,6 +73,8 @@ import static sun.nio.ch.sctp.ResultContainer.*;
|
||||
public class SctpMultiChannelImpl extends SctpMultiChannel
|
||||
implements SelChImpl
|
||||
{
|
||||
private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
|
||||
|
||||
private final FileDescriptor fd;
|
||||
|
||||
private final int fdVal;
|
||||
@ -583,10 +587,15 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
|
||||
int rem,
|
||||
int pos)
|
||||
throws IOException {
|
||||
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
|
||||
if (n > 0)
|
||||
bb.position(pos + n);
|
||||
return n;
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
try {
|
||||
int n = receive0(fd, resultContainer, ((DirectBuffer)bb).address() + pos, rem);
|
||||
if (n > 0)
|
||||
bb.position(pos + n);
|
||||
return n;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
}
|
||||
}
|
||||
|
||||
private InternalNotificationHandler internalNotificationHandler =
|
||||
@ -908,11 +917,16 @@ public class SctpMultiChannelImpl extends SctpMultiChannel
|
||||
assert (pos <= lim);
|
||||
int rem = (pos <= lim ? lim - pos : 0);
|
||||
|
||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||
port, assocId, streamNumber, unordered, ppid);
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
return written;
|
||||
NIO_ACCESS.acquireSession(bb);
|
||||
try {
|
||||
int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
|
||||
port, assocId, streamNumber, unordered, ppid);
|
||||
if (written > 0)
|
||||
bb.position(pos + written);
|
||||
return written;
|
||||
} finally {
|
||||
NIO_ACCESS.releaseSession(bb);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user