8236512: PKCS11 Connection closed after Cipher.doFinal and NoPadding

Fri, 30 Oct 2020 07:09:00 +0000

author
valeriep
date
Fri, 30 Oct 2020 07:09:00 +0000
changeset 14229
efb922cd7ac4
parent 14228
e5da2855d413
child 14230
3191f0bcdd13

8236512: PKCS11 Connection closed after Cipher.doFinal and NoPadding
Summary: Removed killSession() calls in certain impl classes when cancelling operations
Reviewed-by: xuelei

src/share/classes/sun/security/pkcs11/P11AEADCipher.java file | annotate | diff | comparison | revisions
src/share/classes/sun/security/pkcs11/P11Cipher.java file | annotate | diff | comparison | revisions
src/share/classes/sun/security/pkcs11/P11Mac.java file | annotate | diff | comparison | revisions
src/share/classes/sun/security/pkcs11/P11PSSSignature.java file | annotate | diff | comparison | revisions
src/share/classes/sun/security/pkcs11/P11RSACipher.java file | annotate | diff | comparison | revisions
src/share/classes/sun/security/pkcs11/P11Signature.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/sun/security/pkcs11/P11AEADCipher.java	Wed Nov 06 09:45:04 2019 -0800
     1.2 +++ b/src/share/classes/sun/security/pkcs11/P11AEADCipher.java	Fri Oct 30 07:09:00 2020 +0000
     1.3 @@ -1,4 +1,5 @@
     1.4 -/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
     1.5 +/*
     1.6 + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -331,25 +332,25 @@
    1.11      }
    1.12  
    1.13      private void cancelOperation() {
    1.14 +        // cancel operation by finishing it; avoid killSession as some
    1.15 +        // hardware vendors may require re-login
    1.16 +        int bufLen = doFinalLength(0);
    1.17 +        byte[] buffer = new byte[bufLen];
    1.18 +        byte[] in = dataBuffer.toByteArray();
    1.19 +        int inLen = in.length;
    1.20          try {
    1.21 -            if (session.hasObjects() == false) {
    1.22 -                session = token.killSession(session);
    1.23 -                return;
    1.24 +            if (encrypt) {
    1.25 +                token.p11.C_Encrypt(session.id(), 0, in, 0, inLen,
    1.26 +                        0, buffer, 0, bufLen);
    1.27              } else {
    1.28 -                // cancel operation by finishing it
    1.29 -                int bufLen = doFinalLength(0);
    1.30 -                byte[] buffer = new byte[bufLen];
    1.31 -
    1.32 -                if (encrypt) {
    1.33 -                    token.p11.C_Encrypt(session.id(), 0, buffer, 0, bufLen,
    1.34 -                            0, buffer, 0, bufLen);
    1.35 -                } else {
    1.36 -                    token.p11.C_Decrypt(session.id(), 0, buffer, 0, bufLen,
    1.37 -                            0, buffer, 0, bufLen);
    1.38 -                }
    1.39 +                token.p11.C_Decrypt(session.id(), 0, in, 0, inLen,
    1.40 +                        0, buffer, 0, bufLen);
    1.41              }
    1.42          } catch (PKCS11Exception e) {
    1.43 -            throw new ProviderException("Cancel failed", e);
    1.44 +            if (encrypt) {
    1.45 +                throw new ProviderException("Cancel failed", e);
    1.46 +            }
    1.47 +            // ignore failure for decryption
    1.48          }
    1.49      }
    1.50  
    1.51 @@ -432,18 +433,21 @@
    1.52          if (!initialized) {
    1.53              return;
    1.54          }
    1.55 +        initialized = false;
    1.56 +
    1.57          try {
    1.58              if (session == null) {
    1.59                  return;
    1.60              }
    1.61 +
    1.62              if (doCancel && token.explicitCancel) {
    1.63                  cancelOperation();
    1.64              }
    1.65          } finally {
    1.66              p11Key.releaseKeyID();
    1.67              session = token.releaseSession(session);
    1.68 +            dataBuffer.reset();
    1.69          }
    1.70 -        initialized = false;
    1.71      }
    1.72  
    1.73      // see JCE spec
     2.1 --- a/src/share/classes/sun/security/pkcs11/P11Cipher.java	Wed Nov 06 09:45:04 2019 -0800
     2.2 +++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java	Fri Oct 30 07:09:00 2020 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -409,10 +409,12 @@
    2.11              return;
    2.12          }
    2.13          initialized = false;
    2.14 +
    2.15          try {
    2.16              if (session == null) {
    2.17                  return;
    2.18              }
    2.19 +
    2.20              if (doCancel && token.explicitCancel) {
    2.21                  cancelOperation();
    2.22              }
    2.23 @@ -426,22 +428,21 @@
    2.24  
    2.25      private void cancelOperation() {
    2.26          token.ensureValid();
    2.27 -        if (session.hasObjects() == false) {
    2.28 -            session = token.killSession(session);
    2.29 -            return;
    2.30 -        } else {
    2.31 -            try {
    2.32 -                // cancel operation by finishing it
    2.33 -                int bufLen = doFinalLength(0);
    2.34 -                byte[] buffer = new byte[bufLen];
    2.35 -                if (encrypt) {
    2.36 -                    token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
    2.37 -                } else {
    2.38 -                    token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
    2.39 -                }
    2.40 -            } catch (PKCS11Exception e) {
    2.41 +        // cancel operation by finishing it; avoid killSession as some
    2.42 +        // hardware vendors may require re-login
    2.43 +        try {
    2.44 +            int bufLen = doFinalLength(0);
    2.45 +            byte[] buffer = new byte[bufLen];
    2.46 +            if (encrypt) {
    2.47 +                token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
    2.48 +            } else {
    2.49 +                token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
    2.50 +            }
    2.51 +        } catch (PKCS11Exception e) {
    2.52 +            if (encrypt) {
    2.53                  throw new ProviderException("Cancel failed", e);
    2.54              }
    2.55 +            // ignore failure for decryption
    2.56          }
    2.57      }
    2.58  
     3.1 --- a/src/share/classes/sun/security/pkcs11/P11Mac.java	Wed Nov 06 09:45:04 2019 -0800
     3.2 +++ b/src/share/classes/sun/security/pkcs11/P11Mac.java	Fri Oct 30 07:09:00 2020 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -122,10 +122,12 @@
    3.11              return;
    3.12          }
    3.13          initialized = false;
    3.14 +
    3.15          try {
    3.16              if (session == null) {
    3.17                  return;
    3.18              }
    3.19 +
    3.20              if (doCancel && token.explicitCancel) {
    3.21                  cancelOperation();
    3.22              }
    3.23 @@ -137,15 +139,12 @@
    3.24  
    3.25      private void cancelOperation() {
    3.26          token.ensureValid();
    3.27 -        if (session.hasObjects() == false) {
    3.28 -            session = token.killSession(session);
    3.29 -            return;
    3.30 -        } else {
    3.31 -            try {
    3.32 -                token.p11.C_SignFinal(session.id(), 0);
    3.33 -            } catch (PKCS11Exception e) {
    3.34 -                throw new ProviderException("Cancel failed", e);
    3.35 -            }
    3.36 +        // cancel operation by finishing it; avoid killSession as some
    3.37 +        // hardware vendors may require re-login
    3.38 +        try {
    3.39 +            token.p11.C_SignFinal(session.id(), 0);
    3.40 +        } catch (PKCS11Exception e) {
    3.41 +            throw new ProviderException("Cancel failed", e);
    3.42          }
    3.43      }
    3.44  
    3.45 @@ -207,7 +206,6 @@
    3.46              ensureInitialized();
    3.47              return token.p11.C_SignFinal(session.id(), 0);
    3.48          } catch (PKCS11Exception e) {
    3.49 -            reset(true);
    3.50              throw new ProviderException("doFinal() failed", e);
    3.51          } finally {
    3.52              reset(false);
     4.1 --- a/src/share/classes/sun/security/pkcs11/P11PSSSignature.java	Wed Nov 06 09:45:04 2019 -0800
     4.2 +++ b/src/share/classes/sun/security/pkcs11/P11PSSSignature.java	Fri Oct 30 07:09:00 2020 +0000
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -223,10 +223,12 @@
    4.11              return;
    4.12          }
    4.13          initialized = false;
    4.14 +
    4.15          try {
    4.16              if (session == null) {
    4.17                  return;
    4.18              }
    4.19 +
    4.20              if (doCancel && token.explicitCancel) {
    4.21                  cancelOperation();
    4.22              }
    4.23 @@ -242,14 +244,10 @@
    4.24          token.ensureValid();
    4.25          if (DEBUG) System.out.print("Cancelling operation");
    4.26  
    4.27 -        if (session.hasObjects() == false) {
    4.28 -            if (DEBUG) System.out.println(" by killing session");
    4.29 -            session = token.killSession(session);
    4.30 -            return;
    4.31 -        }
    4.32 -        // "cancel" operation by finishing it
    4.33 -        if (mode == M_SIGN) {
    4.34 -            try {
    4.35 +        // cancel operation by finishing it; avoid killSession as some
    4.36 +        // hardware vendors may require re-login
    4.37 +        try {
    4.38 +            if (mode == M_SIGN) {
    4.39                  if (type == T_UPDATE) {
    4.40                      if (DEBUG) System.out.println(" by C_SignFinal");
    4.41                      token.p11.C_SignFinal(session.id(), 0);
    4.42 @@ -259,11 +257,7 @@
    4.43                      if (DEBUG) System.out.println(" by C_Sign");
    4.44                      token.p11.C_Sign(session.id(), digest);
    4.45                  }
    4.46 -            } catch (PKCS11Exception e) {
    4.47 -                throw new ProviderException("cancel failed", e);
    4.48 -            }
    4.49 -        } else { // M_VERIFY
    4.50 -            try {
    4.51 +            } else { // M_VERIFY
    4.52                  byte[] signature =
    4.53                      new byte[(p11Key.length() + 7) >> 3];
    4.54                  if (type == T_UPDATE) {
    4.55 @@ -275,10 +269,12 @@
    4.56                      if (DEBUG) System.out.println(" by C_Verify");
    4.57                      token.p11.C_Verify(session.id(), digest, signature);
    4.58                  }
    4.59 -            } catch (PKCS11Exception e) {
    4.60 -                // will fail since the signature is incorrect
    4.61 -                // XXX check error code
    4.62              }
    4.63 +        } catch (PKCS11Exception e) {
    4.64 +            if (mode == M_SIGN) {
    4.65 +                throw new ProviderException("cancel failed", e);
    4.66 +            }
    4.67 +            // ignore failure for verification
    4.68          }
    4.69      }
    4.70  
     5.1 --- a/src/share/classes/sun/security/pkcs11/P11RSACipher.java	Wed Nov 06 09:45:04 2019 -0800
     5.2 +++ b/src/share/classes/sun/security/pkcs11/P11RSACipher.java	Fri Oct 30 07:09:00 2020 +0000
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -246,10 +246,12 @@
    5.11              return;
    5.12          }
    5.13          initialized = false;
    5.14 +
    5.15          try {
    5.16              if (session == null) {
    5.17                  return;
    5.18              }
    5.19 +
    5.20              if (doCancel && token.explicitCancel) {
    5.21                  cancelOperation();
    5.22              }
    5.23 @@ -263,36 +265,33 @@
    5.24      // state variables such as "initialized"
    5.25      private void cancelOperation() {
    5.26          token.ensureValid();
    5.27 -        if (session.hasObjects() == false) {
    5.28 -            session = token.killSession(session);
    5.29 -            return;
    5.30 -        } else {
    5.31 -            try {
    5.32 -                PKCS11 p11 = token.p11;
    5.33 -                int inLen = maxInputSize;
    5.34 -                int outLen = buffer.length;
    5.35 -                long sessId = session.id();
    5.36 -                switch (mode) {
    5.37 -                case MODE_ENCRYPT:
    5.38 -                    p11.C_Encrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen);
    5.39 -                    break;
    5.40 -                case MODE_DECRYPT:
    5.41 -                    p11.C_Decrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen);
    5.42 -                    break;
    5.43 -                case MODE_SIGN:
    5.44 -                    byte[] tmpBuffer = new byte[maxInputSize];
    5.45 -                    p11.C_Sign(sessId, tmpBuffer);
    5.46 -                    break;
    5.47 -                case MODE_VERIFY:
    5.48 -                    p11.C_VerifyRecover(sessId, buffer, 0, inLen, buffer,
    5.49 -                            0, outLen);
    5.50 -                    break;
    5.51 -                default:
    5.52 -                    throw new ProviderException("internal error");
    5.53 -                }
    5.54 -            } catch (PKCS11Exception e) {
    5.55 -                // XXX ensure this always works, ignore error
    5.56 +        // cancel operation by finishing it; avoid killSession as some
    5.57 +        // hardware vendors may require re-login
    5.58 +        try {
    5.59 +            PKCS11 p11 = token.p11;
    5.60 +            int inLen = maxInputSize;
    5.61 +            int outLen = buffer.length;
    5.62 +            long sessId = session.id();
    5.63 +            switch (mode) {
    5.64 +            case MODE_ENCRYPT:
    5.65 +                p11.C_Encrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen);
    5.66 +                break;
    5.67 +            case MODE_DECRYPT:
    5.68 +                p11.C_Decrypt(sessId, 0, buffer, 0, inLen, 0, buffer, 0, outLen);
    5.69 +                break;
    5.70 +            case MODE_SIGN:
    5.71 +                byte[] tmpBuffer = new byte[maxInputSize];
    5.72 +                p11.C_Sign(sessId, tmpBuffer);
    5.73 +                break;
    5.74 +            case MODE_VERIFY:
    5.75 +                p11.C_VerifyRecover(sessId, buffer, 0, inLen, buffer,
    5.76 +                        0, outLen);
    5.77 +                break;
    5.78 +            default:
    5.79 +                throw new ProviderException("internal error");
    5.80              }
    5.81 +        } catch (PKCS11Exception e) {
    5.82 +            // XXX ensure this always works, ignore error
    5.83          }
    5.84      }
    5.85  
    5.86 @@ -361,6 +360,7 @@
    5.87      private int implDoFinal(byte[] out, int outOfs, int outLen)
    5.88              throws BadPaddingException, IllegalBlockSizeException {
    5.89          if (bufOfs > maxInputSize) {
    5.90 +            reset(true);
    5.91              throw new IllegalBlockSizeException("Data must not be longer "
    5.92                  + "than " + maxInputSize + " bytes");
    5.93          }
     6.1 --- a/src/share/classes/sun/security/pkcs11/P11Signature.java	Wed Nov 06 09:45:04 2019 -0800
     6.2 +++ b/src/share/classes/sun/security/pkcs11/P11Signature.java	Fri Oct 30 07:09:00 2020 +0000
     6.3 @@ -245,10 +245,12 @@
     6.4              return;
     6.5          }
     6.6          initialized = false;
     6.7 +
     6.8          try {
     6.9              if (session == null) {
    6.10                  return;
    6.11              }
    6.12 +
    6.13              if (doCancel && token.explicitCancel) {
    6.14                  cancelOperation();
    6.15              }
    6.16 @@ -259,59 +261,51 @@
    6.17      }
    6.18  
    6.19      private void cancelOperation() {
    6.20 -
    6.21          token.ensureValid();
    6.22 -        if (session.hasObjects() == false) {
    6.23 -            session = token.killSession(session);
    6.24 -            return;
    6.25 -        } else {
    6.26 -            // "cancel" operation by finishing it
    6.27 -            // XXX make sure all this always works correctly
    6.28 +        // cancel operation by finishing it; avoid killSession as some
    6.29 +        // hardware vendors may require re-login
    6.30 +        try {
    6.31              if (mode == M_SIGN) {
    6.32 -                try {
    6.33 -                    if (type == T_UPDATE) {
    6.34 -                        token.p11.C_SignFinal(session.id(), 0);
    6.35 -                    } else {
    6.36 -                        byte[] digest;
    6.37 -                        if (type == T_DIGEST) {
    6.38 -                            digest = md.digest();
    6.39 -                        } else { // T_RAW
    6.40 -                            digest = buffer;
    6.41 -                        }
    6.42 -                        token.p11.C_Sign(session.id(), digest);
    6.43 +                if (type == T_UPDATE) {
    6.44 +                    token.p11.C_SignFinal(session.id(), 0);
    6.45 +                } else {
    6.46 +                    byte[] digest;
    6.47 +                    if (type == T_DIGEST) {
    6.48 +                        digest = md.digest();
    6.49 +                    } else { // T_RAW
    6.50 +                        digest = buffer;
    6.51                      }
    6.52 -                } catch (PKCS11Exception e) {
    6.53 -                    throw new ProviderException("cancel failed", e);
    6.54 +                    token.p11.C_Sign(session.id(), digest);
    6.55                  }
    6.56              } else { // M_VERIFY
    6.57                  byte[] signature;
    6.58 -                try {
    6.59 -                    if (keyAlgorithm.equals("DSA")) {
    6.60 -                        signature = new byte[40];
    6.61 -                    } else {
    6.62 -                        signature = new byte[(p11Key.length() + 7) >> 3];
    6.63 +                if (keyAlgorithm.equals("DSA")) {
    6.64 +                    signature = new byte[40];
    6.65 +                } else {
    6.66 +                    signature = new byte[(p11Key.length() + 7) >> 3];
    6.67 +                }
    6.68 +                if (type == T_UPDATE) {
    6.69 +                    token.p11.C_VerifyFinal(session.id(), signature);
    6.70 +                } else {
    6.71 +                    byte[] digest;
    6.72 +                    if (type == T_DIGEST) {
    6.73 +                        digest = md.digest();
    6.74 +                    } else { // T_RAW
    6.75 +                        digest = buffer;
    6.76                      }
    6.77 -                    if (type == T_UPDATE) {
    6.78 -                        token.p11.C_VerifyFinal(session.id(), signature);
    6.79 -                    } else {
    6.80 -                        byte[] digest;
    6.81 -                        if (type == T_DIGEST) {
    6.82 -                            digest = md.digest();
    6.83 -                        } else { // T_RAW
    6.84 -                            digest = buffer;
    6.85 -                        }
    6.86 -                        token.p11.C_Verify(session.id(), digest, signature);
    6.87 -                    }
    6.88 -                } catch (PKCS11Exception e) {
    6.89 -                    long errorCode = e.getErrorCode();
    6.90 -                    if ((errorCode == CKR_SIGNATURE_INVALID) ||
    6.91 -                        (errorCode == CKR_SIGNATURE_LEN_RANGE)) {
    6.92 -                        // expected since signature is incorrect
    6.93 -                        return;
    6.94 -                    }
    6.95 -                    throw new ProviderException("cancel failed", e);
    6.96 +                    token.p11.C_Verify(session.id(), digest, signature);
    6.97                  }
    6.98              }
    6.99 +        } catch (PKCS11Exception e) {
   6.100 +            if (mode == M_VERIFY) {
   6.101 +                long errorCode = e.getErrorCode();
   6.102 +                if ((errorCode == CKR_SIGNATURE_INVALID) ||
   6.103 +                     (errorCode == CKR_SIGNATURE_LEN_RANGE)) {
   6.104 +                     // expected since signature is incorrect
   6.105 +                     return;
   6.106 +                }
   6.107 +            }
   6.108 +            throw new ProviderException("cancel failed", e);
   6.109          }
   6.110      }
   6.111  

mercurial