Ejemplo n.º 1
0
 private void initialize() throws PKCS11Exception {
   if (session == null) {
     session = token.getOpSession();
   }
   PKCS11 p11 = token.p11;
   CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism);
   switch (mode) {
     case MODE_ENCRYPT:
       p11.C_EncryptInit(session.id(), ckMechanism, p11Key.keyID);
       break;
     case MODE_DECRYPT:
       p11.C_DecryptInit(session.id(), ckMechanism, p11Key.keyID);
       break;
     case MODE_SIGN:
       p11.C_SignInit(session.id(), ckMechanism, p11Key.keyID);
       break;
     case MODE_VERIFY:
       p11.C_VerifyRecoverInit(session.id(), ckMechanism, p11Key.keyID);
       break;
     default:
       throw new AssertionError("internal error");
   }
   bufOfs = 0;
   initialized = true;
 }
Ejemplo n.º 2
0
 private int implUpdate(byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen)
     throws ShortBufferException {
   if (outLen < updateLength(inLen)) {
     throw new ShortBufferException();
   }
   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;
   } catch (PKCS11Exception e) {
     if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
       throw (ShortBufferException) (new ShortBufferException().initCause(e));
     }
     reset();
     throw new ProviderException("update() failed", e);
   }
 }
Ejemplo n.º 3
0
 private int implDoFinal(byte[] out, int outOfs, int outLen)
     throws BadPaddingException, IllegalBlockSizeException {
   if (bufOfs > maxInputSize) {
     throw new IllegalBlockSizeException(
         "Data must not be longer " + "than " + maxInputSize + " bytes");
   }
   try {
     ensureInitialized();
     PKCS11 p11 = token.p11;
     int n;
     switch (mode) {
       case MODE_ENCRYPT:
         n = p11.C_Encrypt(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
         break;
       case MODE_DECRYPT:
         n = p11.C_Decrypt(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
         break;
       case MODE_SIGN:
         byte[] tmpBuffer = new byte[bufOfs];
         System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
         tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
         if (tmpBuffer.length > outLen) {
           throw new BadPaddingException("Output buffer too small");
         }
         System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
         n = tmpBuffer.length;
         break;
       case MODE_VERIFY:
         n = p11.C_VerifyRecover(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
         break;
       default:
         throw new ProviderException("internal error");
     }
     return n;
   } catch (PKCS11Exception e) {
     throw (BadPaddingException) new BadPaddingException("doFinal() failed").initCause(e);
   } finally {
     initialized = false;
     session = token.releaseSession(session);
   }
 }
Ejemplo n.º 4
0
 private int implDoFinal(byte[] out, int outOfs, int outLen)
     throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
   int requiredOutLen = doFinalLength(0);
   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);
       }
       k += token.p11.C_EncryptFinal(session.id(), 0, out, (outOfs + k), (outLen - k));
     } else {
       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);
       }
     }
     return k;
   } catch (PKCS11Exception e) {
     handleException(e);
     throw new ProviderException("doFinal() failed", e);
   } finally {
     reset();
   }
 }
Ejemplo n.º 5
0
 private void cancelOperation() {
   token.ensureValid();
   if (initialized == false) {
     return;
   }
   initialized = false;
   if ((session == null) || (token.explicitCancel == false)) {
     return;
   }
   if (session.hasObjects() == false) {
     session = token.killSession(session);
     return;
   }
   try {
     PKCS11 p11 = token.p11;
     int inLen = maxInputSize;
     int outLen = buffer.length;
     switch (mode) {
       case MODE_ENCRYPT:
         p11.C_Encrypt(session.id(), buffer, 0, inLen, buffer, 0, outLen);
         break;
       case MODE_DECRYPT:
         p11.C_Decrypt(session.id(), buffer, 0, inLen, buffer, 0, outLen);
         break;
       case MODE_SIGN:
         byte[] tmpBuffer = new byte[maxInputSize];
         p11.C_Sign(session.id(), tmpBuffer);
         break;
       case MODE_VERIFY:
         p11.C_VerifyRecover(session.id(), buffer, 0, inLen, buffer, 0, outLen);
         break;
       default:
         throw new ProviderException("internal error");
     }
   } catch (PKCS11Exception e) {
     // XXX ensure this always works, ignore error
   }
 }
Ejemplo n.º 6
0
 private void cancelOperation() {
   if (initialized == false) {
     return;
   }
   initialized = false;
   if ((session == null) || (token.explicitCancel == false)) {
     return;
   }
   // cancel operation by finishing it
   int bufLen = doFinalLength(0);
   byte[] buffer = new byte[bufLen];
   try {
     if (encrypt) {
       token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
     } else {
       token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
     }
   } catch (PKCS11Exception e) {
     throw new ProviderException("Cancel failed", e);
   } finally {
     reset();
   }
 }
Ejemplo n.º 7
0
  private void initialize() throws PKCS11Exception {
    if (session == null) {
      session = token.getOpSession();
    }
    CK_MECHANISM mechParams =
        (blockMode == MODE_CTR
            ? new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv))
            : new CK_MECHANISM(mechanism, iv));

    try {
      if (encrypt) {
        token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);
      } else {
        token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID);
      }
    } catch (PKCS11Exception ex) {
      // release session when initialization failed
      session = token.releaseSession(session);
      throw ex;
    }
    bytesBuffered = 0;
    padBufferLen = 0;
    initialized = true;
  }
Ejemplo n.º 8
0
 // see JCE spec
 protected byte[] engineWrap(Key key) throws InvalidKeyException, IllegalBlockSizeException {
   String keyAlg = key.getAlgorithm();
   P11Key sKey = null;
   try {
     // The conversion may fail, e.g. trying to wrap an AES key on
     // a token that does not support AES, or when the key size is
     // not within the range supported by the token.
     sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
   } catch (InvalidKeyException ike) {
     byte[] toBeWrappedKey = key.getEncoded();
     if (toBeWrappedKey == null) {
       throw new InvalidKeyException("wrap() failed, no encoding available", ike);
     }
     // Directly encrypt the key encoding when key conversion failed
     implInit(Cipher.ENCRYPT_MODE, p11Key);
     implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
     try {
       return doFinal();
     } catch (BadPaddingException bpe) {
       // should not occur
       throw new InvalidKeyException("wrap() failed", bpe);
     } finally {
       // Restore original mode
       implInit(Cipher.WRAP_MODE, p11Key);
     }
   }
   Session s = null;
   try {
     s = token.getOpSession();
     return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism), p11Key.keyID, sKey.keyID);
   } catch (PKCS11Exception e) {
     throw new InvalidKeyException("wrap() failed", e);
   } finally {
     token.releaseSession(s);
   }
 }
Ejemplo n.º 9
0
  private int implDoFinal(ByteBuffer outBuffer)
      throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
    int outLen = outBuffer.remaining();
    int requiredOutLen = doFinalLength(0);
    if (outLen < requiredOutLen) {
      throw new ShortBufferException();
    }

    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();
        } else {
          outArray = new byte[outLen];
        }
      }

      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, outAddr, outArray, outOfs, outLen);
        }
        k += token.p11.C_EncryptFinal(session.id(), outAddr, outArray, (outOfs + k), (outLen - k));
      } else {
        if (paddingObj != null) {
          if (padBufferLen != 0) {
            k =
                token.p11.C_DecryptUpdate(
                    session.id(), 0, padBuffer, 0, padBufferLen, 0, padBuffer, 0, padBuffer.length);
            padBufferLen = 0;
          }
          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 {
          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();
    }
  }
Ejemplo n.º 10
0
  private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer) throws ShortBufferException {
    int inLen = inBuffer.remaining();
    if (inLen <= 0) {
      return 0;
    }

    int outLen = outBuffer.remaining();
    if (outLen < updateLength(inLen)) {
      throw new ShortBufferException();
    }
    int origPos = inBuffer.position();
    try {
      ensureInitialized();

      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];
        }
      }

      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);
      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.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
        throw (ShortBufferException) (new ShortBufferException().initCause(e));
      }
      reset();
      throw new ProviderException("update() failed", e);
    }
  }