Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -350,6 +350,13 @@ private void cancelOperation() {
0, buffer, 0, bufLen);
}
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
}
if (encrypt) {
throw new ProviderException("Cancel failed", e);
}
Expand Down Expand Up @@ -616,6 +623,12 @@ private int implDoFinal(byte[] in, int inOfs, int inLen,
}
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);
Expand Down Expand Up @@ -702,6 +715,12 @@ private int implDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -439,6 +439,13 @@ private void cancelOperation() {
token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
}
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
}
if (encrypt) {
throw new ProviderException("Cancel failed", e);
}
Expand Down Expand Up @@ -628,7 +635,11 @@ private int implUpdate(byte[] in, int inOfs, int inLen,
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
reset(false);
// 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);
}
}
Expand Down Expand Up @@ -746,7 +757,11 @@ private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
reset(false);
// 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);
}
}
Expand All @@ -770,9 +785,14 @@ private int implDoFinal(byte[] out, int outOfs, int outLen)
0, padBuffer, 0, actualPadLen,
0, out, outOfs, outLen);
}
// 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;
Comment on lines +788 to +793
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@valeriepeng I made a code change here so I'd like you to have a final look and validate. I'm just aligning the 'P11Cipher::implDoFinal(byte[]..' function to 'P11Cipher::implDoFinal(ByteBuffer..'. The rationale is that 'doFalse = false' can be placed before the C_EncryptFinal call because any error on it does not require a cancel (it already cancels the operation)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, aligning them is better.

k += token.p11.C_EncryptFinal(session.id(),
0, out, (outOfs + k), (outLen - k));
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
Expand All @@ -784,22 +804,26 @@ private int implDoFinal(byte[] out, int outOfs, int outLen)
padBuffer, 0, padBufferLen, 0, padBuffer, 0,
padBuffer.length);
}
// 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;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment that for line 793 of P11Cipher

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, looks good.

k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
padBuffer.length - k);
doCancel = false;

int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
System.arraycopy(padBuffer, 0, out, outOfs, k);
} else {
doCancel = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment than for line 793 of P11Cipher

k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
outLen);
doCancel = false;
}
}
return k;
} catch (PKCS11Exception e) {
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
Expand Down Expand Up @@ -845,9 +869,14 @@ private int implDoFinal(ByteBuffer outBuffer)
0, padBuffer, 0, actualPadLen,
outAddr, outArray, outOfs, outLen);
}
// 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));
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
Expand All @@ -861,18 +890,23 @@ private int implDoFinal(ByteBuffer outBuffer)
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);
doCancel = false;

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);
doCancel = false;
}
}
if ((!encrypt && paddingObj != null) ||
Expand All @@ -884,7 +918,6 @@ private int implDoFinal(ByteBuffer outBuffer)
}
return k;
} catch (PKCS11Exception e) {
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -151,6 +151,13 @@ private void cancelOperation() {
try {
token.p11.C_SignFinal(session.id(), 0);
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
}
throw new ProviderException("Cancel failed", e);
}
}
Expand Down Expand Up @@ -213,6 +220,12 @@ protected byte[] engineDoFinal() {
ensureInitialized();
return token.p11.C_SignFinal(session.id(), 0);
} catch (PKCS11Exception e) {
// As per the PKCS#11 standard, C_SignFinal may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are handled at OpenJDK's libj2pkcs11 native
// library. Thus, P11Mac::reset can be called with a 'false'
// doCancel argument from here.
throw new ProviderException("doFinal() failed", e);
} finally {
reset(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -298,6 +298,13 @@ private void cancelOperation() {
}
}
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
}
if (mode == M_SIGN) {
throw new ProviderException("cancel failed", e);
}
Expand Down Expand Up @@ -662,6 +669,11 @@ protected byte[] engineSign() throws SignatureException {
doCancel = false;
return signature;
} catch (PKCS11Exception pe) {
// As per the PKCS#11 standard, C_Sign and C_SignFinal may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are handled at OpenJDK's libj2pkcs11 native
// library. Thus, doCancel can safely be 'false' here.
doCancel = false;
throw new ProviderException(pe);
} catch (ProviderException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -314,6 +314,13 @@ private void cancelOperation() {
}
}
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
}
if (mode == M_VERIFY) {
long errorCode = e.getErrorCode();
if ((errorCode == CKR_SIGNATURE_INVALID) ||
Expand Down Expand Up @@ -654,6 +661,11 @@ protected byte[] engineSign() throws SignatureException {
}
}
} catch (PKCS11Exception pe) {
// As per the PKCS#11 standard, C_Sign and C_SignFinal may only
// keep the operation active on CKR_BUFFER_TOO_SMALL errors or
// successful calls to determine the output length. However,
// these cases are handled at OpenJDK's libj2pkcs11 native
// library. Thus, doCancel can safely be 'false' here.
doCancel = false;
throw new ProviderException(pe);
} catch (SignatureException | ProviderException e) {
Expand Down
Loading