/hg/release/icedtea7-forest-2.5/jdk: 3 new changesets

andrew at icedtea.classpath.org andrew at icedtea.classpath.org
Tue Jun 3 18:04:04 UTC 2014


changeset e919e34acdc7 in /hg/release/icedtea7-forest-2.5/jdk
details: http://icedtea.classpath.org/hg/release/icedtea7-forest-2.5/jdk?cmd=changeset;node=e919e34acdc7
author: andrew
date: Wed May 21 15:25:53 2014 +0100

	PR1781: NSS PKCS11 provider fails to handle multipart AES encryption


changeset 66dd22301a54 in /hg/release/icedtea7-forest-2.5/jdk
details: http://icedtea.classpath.org/hg/release/icedtea7-forest-2.5/jdk?cmd=changeset;node=66dd22301a54
author: andrew
date: Wed May 21 15:52:15 2014 +0100

	RH905128: [CRASH] OpenJDK-1.7.0 while using NSS security provider and kerberos


changeset 575b3a2fa6c9 in /hg/release/icedtea7-forest-2.5/jdk
details: http://icedtea.classpath.org/hg/release/icedtea7-forest-2.5/jdk?cmd=changeset;node=575b3a2fa6c9
author: andrew
date: Tue Jun 03 18:52:56 2014 +0100

	RH1059925: RFE: Version Java libraries to allow using multiple Java versions with Linux capabilities enabled
	Summary: Add installation location to RPATH so libraries can be found even with privileged binaries
	Contributed-by: Omair Majid <omajid at redhat.com> (original unconditional version)


diffstat:

 make/common/Defs-linux.gmk                           |    5 +
 make/common/Program.gmk                              |   15 +-
 make/java/instrument/Makefile                        |    6 +-
 src/share/classes/sun/security/pkcs11/P11Cipher.java |  388 +++++++++++-------
 4 files changed, 261 insertions(+), 153 deletions(-)

diffs (truncated from 616 to 500 lines):

diff -r 6cb22bfdd98b -r 575b3a2fa6c9 make/common/Defs-linux.gmk
--- a/make/common/Defs-linux.gmk	Fri Apr 18 06:40:58 2014 +0100
+++ b/make/common/Defs-linux.gmk	Tue Jun 03 18:52:56 2014 +0100
@@ -346,8 +346,13 @@
 
   LDFLAG_Z_ORIGIN = $(Z_ORIGIN_FLAG/$(ARCH_FAMILY))
 
+ifneq ($(INSTALL_LOCATION),)
+  LDFLAGS_COMMON += $(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN:$(INSTALL_LOCATION)/jre/lib/$(LIBARCH)
+  LDFLAGS_COMMON += $(LD_RUNPATH_EXTRAS:%=$(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN/:$(INSTALL_LOCATION)/jre/lib/$(LIBARCH)%)
+else
   LDFLAGS_COMMON += $(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN
   LDFLAGS_COMMON += $(LD_RUNPATH_EXTRAS:%=$(LDFLAG_Z_ORIGIN) -Xlinker -rpath -Xlinker \$$ORIGIN/%)
+endif
 
 endif
 
diff -r 6cb22bfdd98b -r 575b3a2fa6c9 make/common/Program.gmk
--- a/make/common/Program.gmk	Fri Apr 18 06:40:58 2014 +0100
+++ b/make/common/Program.gmk	Tue Jun 03 18:52:56 2014 +0100
@@ -110,7 +110,11 @@
   ifeq ($(PLATFORM), linux)
     LDFLAGS += $(LDFLAG_Z_ORIGIN)
     LDFLAGS += -Wl,--allow-shlib-undefined
-    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli
+    ifneq ($(INSTALL_LOCATION),)
+      LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli:$(INSTALL_LOCATION)/jre/lib/$(LIBARCH)/jli
+    else
+      LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)/jli
+    endif
   endif # PLATFORM LINUX
 endif # PLATFORM linux solaris
 
@@ -148,8 +152,13 @@
   endif # ARCH_DATA_MODEL
 endif # PLATFORM SOLARIS
 ifeq ($(PLATFORM), linux)
-  LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)
-  LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)
+  ifneq ($(INSTALL_LOCATION),)
+    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH):$(INSTALL_LOCATION)/lib/$(LIBARCH)
+    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH):$(INSTALL_LOCATION)/jre/lib/$(LIBARCH)
+  else
+    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../lib/$(LIBARCH)
+    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/../jre/lib/$(LIBARCH)
+  endif
 endif # PLATFORM LINUX
 
 
diff -r 6cb22bfdd98b -r 575b3a2fa6c9 make/java/instrument/Makefile
--- a/make/java/instrument/Makefile	Fri Apr 18 06:40:58 2014 +0100
+++ b/make/java/instrument/Makefile	Tue Jun 03 18:52:56 2014 +0100
@@ -123,7 +123,11 @@
   ifeq ($(PLATFORM), linux)
     LDFLAGS += $(LDFLAG_Z_ORIGIN)
     LDFLAGS += -Wl,--allow-shlib-undefined
-    LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli
+    ifneq ($(INSTALL_LOCATION),)
+      LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli:$(INSTALL_LOCATION)/jre/lib/$(LIBARCH)/jli
+    else
+      LDFLAGS += -Wl,-rpath -Wl,\$$ORIGIN/jli
+    endif
   endif
 endif
 endif
diff -r 6cb22bfdd98b -r 575b3a2fa6c9 src/share/classes/sun/security/pkcs11/P11Cipher.java
--- a/src/share/classes/sun/security/pkcs11/P11Cipher.java	Fri Apr 18 06:40:58 2014 +0100
+++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java	Tue Jun 03 18:52:56 2014 +0100
@@ -69,7 +69,7 @@
     private static interface Padding {
         // ENC: format the specified buffer with padding bytes and return the
         // actual padding length
-        int setPaddingBytes(byte[] paddingBuffer, int padLen);
+        int setPaddingBytes(byte[] paddingBuffer, int offset, int padLen);
 
         // DEC: return the length of trailing padding bytes given the specified
         // padded data
@@ -90,8 +90,8 @@
             this.blockSize = blockSize;
         }
 
-        public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
-            Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
+        public int setPaddingBytes(byte[] paddingBuffer, int offset, int padLen) {
+            Arrays.fill(paddingBuffer, offset, offset + padLen, (byte) (padLen & 0x007f));
             return padLen;
         }
 
@@ -160,10 +160,16 @@
     // original IV, if in MODE_CBC or MODE_CTR
     private byte[] iv;
 
-    // number of bytes buffered internally by the native mechanism and padBuffer
-    // if we do the padding
+    // number of bytes buffered by the blockBuffer
     private int bytesBuffered;
 
+    // number of bytes buffered internally
+    private int bytesBufferedInt;
+
+    // bytes buffered from an incomplete block
+    private byte[] blockBuffer;
+    private int blockBufferLen;
+
     P11Cipher(Token token, String algorithm, long mechanism)
             throws PKCS11Exception, NoSuchAlgorithmException {
         super();
@@ -194,6 +200,9 @@
             // should not happen
             throw new ProviderException(nspe);
         }
+
+	if (blockSize > 0)
+	    blockBuffer = new byte[blockSize];
     }
 
     protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
@@ -403,7 +412,8 @@
                 token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
             }
         } catch (PKCS11Exception e) {
-            throw new ProviderException("Cancel failed", e);
+	    if (e.getErrorCode() != CKR_OPERATION_NOT_INITIALIZED)
+		throw new ProviderException("Cancel failed", e);
         } finally {
             reset();
         }
@@ -435,7 +445,9 @@
             throw ex;
         }
         bytesBuffered = 0;
+	bytesBufferedInt = 0;
         padBufferLen = 0;
+	blockBufferLen = 0;
         initialized = true;
     }
 
@@ -445,7 +457,7 @@
             return 0;
         }
 
-        int result = inLen + bytesBuffered;
+        int result = inLen + bytesBuffered + bytesBufferedInt;
         if (blockSize != 0) {
             // minus the number of bytes in the last incomplete block.
             result -= (result & (blockSize - 1));
@@ -459,7 +471,7 @@
             return 0;
         }
 
-        int result = inLen + bytesBuffered;
+        int result = inLen + bytesBuffered + bytesBufferedInt;
         if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
             // add the number of bytes to make the last block complete.
             result += (blockSize - (result & (blockSize - 1)));
@@ -471,7 +483,9 @@
     private void reset() {
         initialized = false;
         bytesBuffered = 0;
+	bytesBufferedInt = 0;
         padBufferLen = 0;
+	blockBufferLen = 0;
         if (session != null) {
             session = token.releaseSession(session);
         }
@@ -546,50 +560,65 @@
         }
         try {
             ensureInitialized();
-            int k = 0;
-            if (encrypt) {
-                k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
-                        0, out, outOfs, outLen);
-            } else {
-                int newPadBufferLen = 0;
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        // NSS throws up when called with data not in multiple
-                        // of blocks. Try to work around this by holding the
-                        // extra data in padBuffer.
-                        if (padBufferLen != padBuffer.length) {
-                            int bufCapacity = padBuffer.length - padBufferLen;
-                            if (inLen > bufCapacity) {
-                                bufferInputBytes(in, inOfs, bufCapacity);
-                                inOfs += bufCapacity;
-                                inLen -= bufCapacity;
-                            } else {
-                                bufferInputBytes(in, inOfs, inLen);
-                                return 0;
-                            }
-                        }
-                        k = token.p11.C_DecryptUpdate(session.id(),
-                                0, padBuffer, 0, padBufferLen,
-                                0, out, outOfs, outLen);
-                        padBufferLen = 0;
-                    }
-                    newPadBufferLen = inLen & (blockSize - 1);
-                    if (newPadBufferLen == 0) {
-                        newPadBufferLen = padBuffer.length;
-                    }
-                    inLen -= newPadBufferLen;
-                }
-                if (inLen > 0) {
-                    k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
-                            inLen, 0, out, (outOfs + k), (outLen - k));
-                }
-                // update 'padBuffer' if using our own padding impl.
-                if (paddingObj != null) {
-                    bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
-                }
-            }
-            bytesBuffered += (inLen - k);
-            return k;
+            int bufRes = 0;
+	    int inRes = 0;
+	    int newBlockBufferLen = 0;
+
+	    // NSS throws up when called with data not in multiple
+	    // of blocks. Try to work around this by holding the
+	    // extra data in blockBuffer.
+	    if (blockBufferLen != 0) {
+		if (blockBufferLen != blockBuffer.length) {
+		    int bufCapacity = blockBuffer.length - blockBufferLen;
+		    if (inLen >= bufCapacity) {
+			bufferInputBytes(in, inOfs, bufCapacity);
+			inOfs += bufCapacity;
+			inLen -= bufCapacity;
+		    } else {
+			bufferInputBytes(in, inOfs, inLen);
+			return 0;
+		    }
+		}
+		if (encrypt) {
+		    bufRes = token.p11.C_EncryptUpdate(session.id(), 0, blockBuffer, 0,
+						       blockBufferLen, 0, out, outOfs,
+						       outLen);
+		} else {
+		    bufRes = token.p11.C_DecryptUpdate(session.id(), 0, blockBuffer, 0,
+						       blockBufferLen, 0, out, outOfs,
+						       outLen);
+		}
+		bytesBufferedInt += (blockBufferLen - bufRes);
+		blockBufferLen = 0;
+		bytesBuffered = 0;
+	    }
+
+	    if (inLen == 0)
+		return bufRes;
+
+	    if (blockBuffer != null) {
+		newBlockBufferLen = inLen & (blockSize - 1);
+		if (!encrypt && paddingObj != null && newBlockBufferLen == 0)
+		    // Hold the last block in the buffer if we need to unpad
+		    newBlockBufferLen = blockBuffer.length;
+		inLen -= newBlockBufferLen;
+		bufferInputBytes(in, inOfs + inLen, newBlockBufferLen);
+	    }
+
+	    if (inLen > 0) {
+		if (encrypt) {
+                    inRes = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs,
+						      inLen, 0, out, (outOfs + bufRes),
+						      (outLen - bufRes));
+		} else {
+                    inRes = token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
+						      inLen, 0, out, (outOfs + bufRes),
+						      (outLen - bufRes));
+		}
+		bytesBufferedInt += (inLen - inRes);
+	    }
+
+            return inRes + bufRes;
         } catch (PKCS11Exception e) {
             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
                 throw (ShortBufferException)
@@ -642,70 +671,79 @@
                 }
             }
 
-            int k = 0;
-            if (encrypt) {
-                if (inAddr == 0 && inArray == null) {
-                    inArray = new byte[inLen];
-                    inBuffer.get(inArray);
-                } else {
-                    inBuffer.position(origPos + inLen);
-                }
-                k = token.p11.C_EncryptUpdate(session.id(),
-                        inAddr, inArray, inOfs, inLen,
-                        outAddr, outArray, outOfs, outLen);
-            } else {
-                int newPadBufferLen = 0;
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        // NSS throws up when called with data not in multiple
-                        // of blocks. Try to work around this by holding the
-                        // extra data in padBuffer.
-                        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;
-                            }
-                        }
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
-                                padBuffer, 0, padBufferLen, outAddr, outArray,
-                                outOfs, outLen);
-                        padBufferLen = 0;
-                    }
-                    newPadBufferLen = inLen & (blockSize - 1);
-                    if (newPadBufferLen == 0) {
-                        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);
-                    }
-                    k += token.p11.C_DecryptUpdate(session.id(), inAddr,
-                            inArray, inOfs, inLen, outAddr, outArray,
-                            (outOfs + k), (outLen - k));
-                }
-                // update 'padBuffer' if using our own padding impl.
-                if (paddingObj != null && newPadBufferLen != 0) {
-                    bufferInputBytes(inBuffer, newPadBufferLen);
-                }
-            }
-            bytesBuffered += (inLen - k);
+            int bufRes = 0;
+	    int inRes = 0;
+	    int newBlockBufferLen = 0;
+
+	    // NSS throws up when called with data not in multiple
+	    // of blocks. Try to work around this by holding the
+	    // extra data in blockBuffer.
+	    if (blockBufferLen != 0) {
+		if (blockBufferLen != blockBuffer.length) {
+		    int bufCapacity = blockBuffer.length - blockBufferLen;
+		    if (inLen >= bufCapacity) {
+			bufferInputBytes(inBuffer, bufCapacity);
+			inOfs += bufCapacity;
+			inLen -= bufCapacity;
+		    } else {
+			bufferInputBytes(inBuffer, inLen);
+			return 0;
+		    }
+		}
+		if (encrypt) {
+		    bufRes = token.p11.C_EncryptUpdate(session.id(), 0, blockBuffer, 0,
+						       blockBufferLen, outAddr, outArray, outOfs,
+						       outLen);
+		} else {
+		    bufRes = token.p11.C_DecryptUpdate(session.id(), 0, blockBuffer, 0,
+						       blockBufferLen, outAddr, outArray, outOfs,
+						       outLen);
+		}
+		bytesBufferedInt += (blockBufferLen - bufRes);
+		blockBufferLen = 0;
+		bytesBuffered = 0;
+	    }
+
+	    if (inLen == 0)
+		return bufRes;
+
+	    if (blockBuffer != null) {
+		newBlockBufferLen = inLen & (blockSize - 1);
+		if (!encrypt && paddingObj != null && newBlockBufferLen == 0)
+		    // Hold the last block in the buffer if we need to unpad
+		    newBlockBufferLen = blockBuffer.length;
+		inLen -= newBlockBufferLen;
+		bufferInputBytes(inBuffer, newBlockBufferLen);
+	    }
+
+	    if (inAddr == 0 && inArray == null) {
+		inArray = new byte[inLen];
+		inBuffer.get(inArray);
+	    } else {
+		inBuffer.position(inBuffer.position() + inLen);
+	    }
+
+	    if (inLen > 0) {
+		if (encrypt) {
+                    inRes = token.p11.C_EncryptUpdate(session.id(), inAddr, inArray, inOfs,
+						      inLen, outAddr, outArray, (outOfs + bufRes),
+						      (outLen - bufRes));
+		} else {
+                    inRes = token.p11.C_DecryptUpdate(session.id(), inAddr, inArray, inOfs,
+						      inLen, outAddr, outArray, (outOfs + bufRes),
+						      (outLen - bufRes));
+		}
+		bytesBufferedInt += (inLen - inRes);
+	    }
+
+	    int total = inRes + bufRes;
             if (!(outBuffer instanceof DirectBuffer) &&
                     !outBuffer.hasArray()) {
-                outBuffer.put(outArray, outOfs, k);
+                outBuffer.put(outArray, outOfs, total);
             } else {
-                outBuffer.position(outBuffer.position() + k);
+                outBuffer.position(outBuffer.position() + total);
             }
-            return k;
+	    return total;
         } catch (PKCS11Exception e) {
             // Reset input buffer to its original position for
             inBuffer.position(origPos);
@@ -722,45 +760,71 @@
             throws ShortBufferException, IllegalBlockSizeException,
             BadPaddingException {
         int requiredOutLen = doFinalLength(0);
+	boolean updating = false;
+	PKCS11Exception err = null;
+
         if (outLen < requiredOutLen) {
             throw new ShortBufferException();
         }
         try {
             ensureInitialized();
             int k = 0;
-            if (encrypt) {
-                if (paddingObj != null) {
-                    int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
-                            requiredOutLen - bytesBuffered);
-                    k = token.p11.C_EncryptUpdate(session.id(),
-                            0, padBuffer, 0, actualPadLen,
-                            0, out, outOfs, outLen);
-                }
+	    if (encrypt) {
+		if (blockBuffer != null) {
+		    // Do we need to pad?
+		    if (paddingObj != null) {
+			int actualPadLen = paddingObj.setPaddingBytes(blockBuffer,
+			    blockBufferLen, blockSize - blockBufferLen);
+			blockBufferLen = blockSize;
+		    }
+		    updating = true;
+		    k = token.p11.C_EncryptUpdate(session.id(),
+						  0, blockBuffer, 0, blockBufferLen,
+						  0, out, outOfs, outLen);
+		    updating = false;
+		}
                 k += token.p11.C_EncryptFinal(session.id(),
                         0, out, (outOfs + k), (outLen - k));
             } else {
+		if (blockBufferLen != 0) {
+		    if (paddingObj == null)
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
+						      blockBuffer, 0, blockBufferLen, 0,
+						      out, outOfs, outLen);
+		    else
+			k = token.p11.C_DecryptUpdate(session.id(), 0,
+						      blockBuffer, 0, blockBufferLen, 0,
+						      padBuffer, 0, padBuffer.length);
+		}
                 if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
-                                padBuffer, 0, padBufferLen, 0, padBuffer, 0,
-                                padBuffer.length);
-                    }
                     k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
                             padBuffer.length - k);
                     int actualPadLen = paddingObj.unpad(padBuffer, k);
                     k -= actualPadLen;
                     System.arraycopy(padBuffer, 0, out, outOfs, k);
                 } else {
-                    k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
-                            outLen);
+                    k += token.p11.C_DecryptFinal(session.id(), 0, out, (outOfs + k),
+						  (outLen - k));
                 }
             }
             return k;
         } catch (PKCS11Exception e) {
+	    err = e;
             handleException(e);
             throw new ProviderException("doFinal() failed", e);
         } finally {
-            reset();
+            if (err != null) {
+		if (err.getErrorCode() != CKR_BUFFER_TOO_SMALL) {
+		    if (updating)
+			// Work around NSS not cancelling the
+			// operation on an error in update
+			cancelOperation();
+		    else
+			reset();
+		}
+	    } else {
+		reset();
+	    }


More information about the distro-pkg-dev mailing list