Example #1
0
 @Override
 public Long readUserIdFromToken(String token) {
   Long id = null;
   try {
     Map<String, Object> parsed = verifier.verify(token);
     Object objectId = parsed.get("id");
     if (objectId instanceof Integer) {
       id = Long.valueOf((Integer) objectId);
     } else if (objectId instanceof Long) {
       id = (Long) objectId;
     } else if (objectId instanceof String) {
       id = Long.valueOf((String) objectId);
     }
   } catch (NoSuchAlgorithmException e) {
     e.printStackTrace();
   } catch (InvalidKeyException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   } catch (SignatureException e) {
     e.printStackTrace();
   } catch (JWTVerifyException e) {
     e.printStackTrace();
   } catch (Exception e) {
     e.printStackTrace();
   }
   return id;
 }
  public void checkServerTrusted(X509Certificate[] chain, String authType)
      throws CertificateException {
    calledCheckServerTrusted = true;
    if (!authType.equals("RSA") && !authType.equals("DHE_RSA"))
      throw new CertificateException("Only RSA and DHE_RSA supported, not " + authType);

    if (chain.length != 3) throw new CertificateException("Need three certificates");

    X509Certificate cert0 = chain[0];
    X509Certificate cert1 = chain[1];
    X509Certificate cert2 = chain[2];
    int failedCert = 0;
    try {
      // NOTE: cert0 is a self-signed key used only for SSL
      failedCert = 0;
      cert0.verify(cert0.getPublicKey());
      // NOTE: cert1 is the SSL key signed by the server's Martus key
      failedCert = 1;
      cert1.verify(cert2.getPublicKey());
      // NOTE: cert2 is a self-signed key of and by the server's Martus key
      failedCert = 2;
      cert2.verify(cert2.getPublicKey());
      failedCert = -1;

      PublicKey tryPublicKey = expectedPublicKey;
      if (tryPublicKey == null) {
        if (expectedPublicCode == null) throw new CertificateException("No key or code is trusted");
        String certPublicKeyString = SimpleX509TrustManager.getKeyString(cert2.getPublicKey());
        String certPublicCode = MartusCrypto.computePublicCode(certPublicKeyString);
        if (expectedPublicCode.equals(certPublicCode)) {
          tryPublicKey = cert2.getPublicKey();
        }
      }

      if (tryPublicKey == null) throw new CertificateException("Key is not trusted");
      cert1.verify(tryPublicKey);
      String keyString = SimpleX509TrustManager.getKeyString(tryPublicKey);
      setExpectedPublicKey(keyString);
    } catch (SignatureException e) {
      MartusLogger.logException(e);
      MartusLogger.log("Failed cert: " + failedCert);
      String key0 = SimpleX509TrustManager.getKeyString(cert0.getPublicKey());
      String key1 = SimpleX509TrustManager.getKeyString(cert1.getPublicKey());
      String key2 = SimpleX509TrustManager.getKeyString(cert2.getPublicKey());
      MartusLogger.log("Cert0 public: " + key0);
      if (!key0.equals(key1)) MartusLogger.log("Cert1 public: " + key1);
      MartusLogger.log("Cert2 public: " + key2);
      MartusLogger.log("Cert2 public code: " + MartusCrypto.formatAccountIdForLog(key2));
      String expectedKeyString = SimpleX509TrustManager.getKeyString(expectedPublicKey);
      MartusLogger.log(
          "Expected public code: " + MartusCrypto.formatAccountIdForLog(expectedKeyString));

      throw new CertificateException(e.toString());
    } catch (Exception e) {
      // Tests will cause this to fire
      MartusLogger.logException(e);
      throw new CertificateException(e.toString());
    }
  }
Example #3
0
  @Override
  public Response createResponse() {
    // todo fix this with JSON etc.
    String plainText = getPlainText();
    try {
      signedText_ = Signature.calculateRFC2104HMAC(plainText, key_);
    } catch (SignatureException e) {
      e.printStackTrace();
    }

    return this;
  }
Example #4
0
 public byte[] getSender() {
   try {
     if (sendAddress == null) {
       ECKey key = ECKey.signatureToKey(getRawHash(), getSignature().toBase64());
       sendAddress = key.getAddress();
     }
     return sendAddress;
   } catch (SignatureException e) {
     logger.error(e.getMessage(), e);
   }
   return null;
 }
Example #5
0
  /**
   * Endorse the proof
   *
   * @param aStampContext current context
   * @param aProof proof
   * @return endorsed proof
   * @throws NoSuchAlgorithmException
   * @throws BadPaddingException
   * @throws IllegalBlockSizeException
   * @throws NoSuchPaddingException
   * @throws InvalidKeyException
   */
  private static byte[] endorseP(WitnessContext aStampContext, byte aProof[]) {

    // Sign on the proof first
    byte[] sig = {};
    try {
      sig = CryptoUtil.signDSA(aStampContext.getPriDSASelf(), aProof);
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (SignatureException e) {
      e.printStackTrace();
    }

    // Include own ID in EP
    byte[] wID = aStampContext.getPubDSASelf().getEncoded();

    ArrayList<byte[]> array = new ArrayList<byte[]>();
    array.add(wID);
    array.add(aProof);
    array.add(sig);

    byte[] epContent = MessageUtil.compileMessages(array);

    // Encrypt epContent with an AES key first
    SecretKey aesKey = null;
    byte[] epEncrypted = {};
    byte[] keyEncrypted = {};
    try {
      aesKey = CryptoUtil.generateAESKey(128);
      epEncrypted = CryptoUtil.encryptAES(aesKey, epContent);
      keyEncrypted = CryptoUtil.encryptRSA(aStampContext.getPubRSACA(), aesKey.getEncoded());
    } catch (NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
      e.printStackTrace();
    } catch (BadPaddingException e) {
      e.printStackTrace();
    }

    ArrayList<byte[]> arrayOut = new ArrayList<byte[]>();
    arrayOut.add(epEncrypted);
    arrayOut.add(keyEncrypted);

    return MessageUtil.compileMessages(arrayOut);
  }
  public static X509IdentityToken createX509IdentityToken(
      EndpointDescription ep,
      byte[] serverNonce,
      Cert certificate,
      PrivateKey key,
      SignatureData signatureData)
      throws ServiceResultException {
    if (signatureData == null)
      throw new NullPointerException("signatureData must be defined (will be filled in)");
    UserTokenPolicy policy = ep.findUserTokenPolicy(UserTokenType.Certificate);
    if (policy == null)
      throw new ServiceResultException(
          StatusCodes.Bad_IdentityTokenRejected, "Certificate UserTokenType is not supported");

    X509IdentityToken token = new X509IdentityToken(policy.getPolicyId(), certificate.getEncoded());

    String securityPolicyUri = policy.getSecurityPolicyUri();
    if (securityPolicyUri == null) securityPolicyUri = ep.getSecurityPolicyUri();
    SecurityPolicy securityPolicy = SecurityPolicy.getSecurityPolicy(securityPolicyUri);
    Cert serverCert = new Cert(ep.getServerCertificate());
    if ((securityPolicy != null) && (serverCert != null))
      try {
        // Create a Signature object and initialize it with the private
        // key
        Signature signature =
            Signature.getInstance(
                securityPolicy.getAsymmetricSignatureAlgorithm().getTransformation());
        signature.initSign(key);

        signature.update(serverCert.getEncoded());
        signature.update(serverNonce);

        signatureData.setSignature(signature.sign());
        signatureData.setAlgorithm(securityPolicy.getAsymmetricSignatureAlgorithm().getUri());

      } catch (NoSuchAlgorithmException e) {
        throw new ServiceResultException(
            StatusCodes.Bad_SecurityChecksFailed, "Signature generation failed: " + e.getMessage());
      } catch (InvalidKeyException e) {
        // Server certificate does not have encrypt usage
        throw new ServiceResultException(
            StatusCodes.Bad_CertificateInvalid,
            "Server certificate in endpoint is invalid: " + e.getMessage());
      } catch (SignatureException e) {
        throw new ServiceResultException(
            StatusCodes.Bad_SecurityChecksFailed, "Signature generation failed: " + e.getMessage());
      }
    return token;
  }
 /**
  * Verify that signature is ok or not.
  *
  * @param key
  * @param buffer
  * @param signature
  * @return
  */
 public boolean verifySignature(byte[] buffer, byte[] signature) {
   try {
     Signature sig = Signature.getInstance("SHA1WithRSA");
     sig.initVerify(keyPair.getPublic());
     sig.update(buffer, 0, buffer.length);
     return sig.verify(signature);
   } catch (SignatureException e) {
     e.printStackTrace();
   } catch (InvalidKeyException e) {
     e.printStackTrace();
   } catch (NoSuchAlgorithmException e) {
     e.printStackTrace();
   }
   return false;
 }
 private byte[] doSign() {
   KeyPair keys = loadAllKeysFromKeystore();
   Signature sig = null;
   byte[] sigByte = null;
   PrivateKey privKey = keys.getPrivate();
   try {
     sig = Signature.getInstance("SHA1WithRSA");
     sig.initSign(privKey);
     sig.update(this.document, 0, this.document.length);
     sigByte = sig.sign();
   } catch (SignatureException e) {
     e.printStackTrace();
   } catch (InvalidKeyException e) {
     e.printStackTrace();
   } catch (NoSuchAlgorithmException e) {
     e.printStackTrace();
   }
   return sigByte;
 }
 @Override
 public MetadataObject resolve(X509Certificate attestationCertificate) {
   String issuer = attestationCertificate.getIssuerDN().getName();
   for (X509Certificate cert : certs.get(issuer)) {
     try {
       attestationCertificate.verify(cert.getPublicKey());
       return metadata.get(cert);
     } catch (CertificateException e) {
       e.printStackTrace();
     } catch (NoSuchAlgorithmException e) {
       e.printStackTrace();
     } catch (InvalidKeyException e) {
       e.printStackTrace();
     } catch (NoSuchProviderException e) {
       e.printStackTrace();
     } catch (SignatureException e) {
       e.printStackTrace();
     }
   }
   return null;
 }
  /**
   * @param aSecretCertificate
   * @param currentDate
   * @param appId
   * @return
   */
  private static boolean isValidCertificate(
      String aSecretCertificate, String currentDate, String appId) {
    boolean isValid = false;
    String hMacString;
    try {
      // load the privatekey for the appId
      // TODO load the private for this appid
      String privateKey = "kljlkdfldsflds";
      String data = currentDate + appId;
      hMacString = calculateRFC2104HMAC(privateKey, data);
      if (aSecretCertificate.equals(hMacString)) ;
      isValid = true;
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (SignatureException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }

    return isValid;
  }
  /**
   * Method that verifies an incoming signature and returns the response as application/xml.
   *
   * @param signatureVerificationRequest the request which is converted to a {@link
   *     SignatureVerificationRequest} from xml
   * @return the {@link SignatureVerificationResponse} as application/xml
   */
  @POST
  @Path("/verifySignature")
  @Consumes("application/xml")
  @Produces("application/xml")
  public SignatureVerificationResponse verifySignature(
      SignatureVerificationRequest signatureVerificationRequest) {

    SignatureVerificationResponse response = new SignatureVerificationResponse();
    response.setCertificateInfos(new CertificateInfos());

    boolean verified = false;
    String message = null;

    try {

      SignatureFormat format = signatureVerificationRequest.getSignatureFormat();
      if (SignatureFormat.XMLDIGSIG.equals(format)) {
        try {
          SignatureData signatureData =
              getFromXmlDigSigSignature(signatureVerificationRequest, response);

          verified = super.verifySignature(signatureData);
        } catch (SignatureException e) {
          e.printStackTrace();
          message = e.getMessage();
        }
      } else if (SignatureFormat.CMS.equals(format)) {
        SignatureData signData = getFromCmsSignature(signatureVerificationRequest, response);

        try {
          // Verify
          verified = super.verifySignature(signData);
        } catch (SignatureException e) {
          e.printStackTrace();
          message = e.getMessage();
        }
      }

      response.setStatus(verified ? SignatureStatus.SUCCESS : SignatureStatus.FAILURE);
      if (message != null) {
        response.setMessage(message);
      }

    } catch (IOException ex) {
      throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
    } catch (MarshalException ex) {
      throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
    } catch (ParserConfigurationException ex) {
      throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
    } catch (SAXException ex) {
      throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
    } catch (CMSException ex) {
      throw new WebApplicationException(ex, Response.Status.INTERNAL_SERVER_ERROR);
    }

    return response;
  }
Example #12
0
  @Override
  public boolean verifySignature(Object message, byte[] signatureToVerify) {
    //        return true;

    try {
      Signature newSig = Signature.getInstance(CryptoUtil.ALGORITHM, CryptoUtil.PROVIDER);
      newSig.initVerify(publicKey);
      byte[] byteRep = CryptoUtil.convertToJsonByteArray(message);
      newSig.update(byteRep);
      newSig.verify(signatureToVerify);

    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (NoSuchProviderException e) {
      e.printStackTrace();
    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (SignatureException e) {
      e.printStackTrace();
      return false;
    }

    return true;
  }
  public Boolean verifySignature(byte[] originalData, byte[] signedData) {
    boolean verified = false;

    try {
      Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
      sig.initVerify(getPublicKey());
      sig.update(originalData, 0, originalData.length);
      verified = sig.verify(signedData);
    } catch (SignatureException ex) {
      ex.printStackTrace();
      Logger.getLogger(SignatureVerifier.class.getName()).log(Level.SEVERE, null);
    } catch (InvalidKeyException ex) {
      ex.printStackTrace();
      Logger.getLogger(SignatureVerifier.class.getName()).log(Level.SEVERE, null);
    } catch (NoSuchAlgorithmException ex) {
      ex.printStackTrace();
      Logger.getLogger(SignatureVerifier.class.getName()).log(Level.SEVERE, null);
    } catch (NoSuchProviderException ex) {
      ex.printStackTrace();
      Logger.getLogger(SignatureVerifier.class.getName()).log(Level.SEVERE, null);
    }

    return verified;
  }
Example #14
0
  @Test
  public void test() throws SymmetricKeyDecryptionException, SymmetricKeyEncryptionException {
    // Precondition:
    // Owner has pw-protected MasterKeystore containig MKey_sig and MKey_enc
    // Owner hat lesser protected DeviceKeystore containing at least one
    // DeviceKey DevKey_1_enc

    // Create Empty SharePartList
    assertNotNull(volume);

    // ShareMetaData shareMetaData = volume.createShareMetaData(alias,
    // mKey_sig_pub, mKey_sig, deviceAlias, devKey1_enc);
    ShareMetaData shareMetaData = null;
    try {
      shareMetaData =
          new ShareMetaData(
              new JDBCHelperNonRevokeable("jdbc:sqlite:" + dbName + File.separator), mKey_sig_pub);
    } catch (Exception e) {
      e.printStackTrace();
      fail(e.getMessage());
    }
    try {
      Field smdField = Volume.class.getDeclaredField("shareMetaData");
      smdField.setAccessible(true);
      smdField.set(volume, shareMetaData);
    } catch (Exception e) {
      fail(e.getMessage());
    }
    assertNotNull(shareMetaData);

    SharePartList spl = shareMetaData.initSharePartList();
    assertEquals("SharePartList is not empty, although it should be", 0, spl.size());
    // Sign SharePartList
    try {
      spl.sign(mKey_sig);
      assertTrue(CryptCore.verifySignature(spl, spl.getSignature(), mKey_sig_pub));
    } catch (SignatureException e2) {
      fail(e2.getMessage());
    }

    spl.add(mKey_sig_pub, alias);
    assertEquals("SharePartList is not empty, although it should be", 1, spl.size());
    try {
      spl.sign(mKey_sig);
      assertTrue(CryptCore.verifySignature(spl, spl.getSignature(), mKey_sig_pub));
    } catch (SignatureException e2) {
      fail(e2.getMessage());
    }

    // get DevKeys for the Devices that the owner wants to enable for this
    // Volume
    // Put keys in dkList
    dkList.put(deviceAlias, devKey1_enc);
    assertEquals("DeviceKeyList should have 1 element", 1, dkList.size());

    // Create and sign devicelist
    DeviceList dl = shareMetaData.createDeviceList(mKey_sig_pub, dkList);
    assertEquals(
        "ShareMetaData should have 1 DeviceList",
        1,
        shareMetaData.getDeviceLists().values().size());

    // Create symmetric ShareKey
    SecretKey sk = CryptCore.generateSymmetricKey();
    assertNotNull(sk);

    // Encrypt sk for all deviceLists
    Collection<DeviceList> deviceLists = shareMetaData.getDeviceLists().values();
    Collection<PublicKey> pubKeys = new LinkedList<PublicKey>();
    for (DeviceList devList : deviceLists) {
      pubKeys.addAll(devList.getPublicKeys());
    }
    assertEquals(1, pubKeys.size());
    // fetch ShareKeyDB
    ShareKeyDB db = shareMetaData.getShareKeys();
    assertNotNull(db);
    // add Encrypted Keys to db
    try {
      db.add(sk, pubKeys);
    } catch (SymmetricKeyEncryptionException e1) {
      fail(e1.getMessage());
    }
    assertEquals(1, db.size());
    try {
      db.sign(mKey_sig, alias);
    } catch (SignatureException e1) {
      fail(e1.getMessage());
    }

    // Encrypt skOb for all deviceLists
    shareMetaData.addObfuscationKey(devKey1_enc, null, null);

    System.out.println("Making ShareMetaData persistent...");

    try {
      dl.sign(mKey_sig, shareMetaData.shareKeys, shareMetaData.obfuscationKeys);
      assertTrue(
          SignatureHelper.verify(
              dl.getSignature(),
              mKey_sig_pub,
              dl,
              shareMetaData.shareKeys.get(dl.getPublicKeys()),
              shareMetaData.obfuscationKeys.get(dl.getPublicKeys())));

    } catch (SignatureException
        | InvalidKeyException
        | NoSuchAlgorithmException
        | SerializationException e2) {
      fail(e2.getMessage());
    }

    // make sharemetadata persistent
    try {
      shareMetaData.persist();
      shareMetaData.persist(dl);
    } catch (Exception e) {
      fail(e.getMessage());
    }

    System.out.println("Loading Volume...");

    // load volume with sharemetadata
    try {
      Volume loadedVol = new Volume(dbName);
      ShareMetaData loadedSMD = loadedVol.loadShareMetaData(mKey_sig_pub);

      assertArrayEquals(shareMetaData.getSignature(), loadedSMD.getSignature());

      System.out.println("DONE");
    } catch (Exception e) {
      e.printStackTrace(System.err);
      fail(e.getMessage());
    }
  }
        @Override
        public void onClick(View view) {

          Utils.Log("Send clicked");

          // If the message field is not empty
          if (!messageText.getText().toString().isEmpty()) {

            final Message message = new Message();
            message.setSender(username);
            message.setRecipient(conversation.getUsername());

            // If DHKE was completed and a key exists
            if (!dbManager.getAESKey(conversation.getUsername()).isEmpty()) {
              String signature = "";
              String key = dbManager.getAESKey(conversation.getUsername());
              byte[] iv = Crypto.GenerateRandomIV();
              final String plainText = messageText.getText().toString();
              final String cipherText = Crypto.AESencrypt(key, plainText, iv);
              final String base64IV = Base64.encodeToString(iv, Base64.NO_WRAP);

              try {
                PrivateKey RSAKeySign =
                    Crypto.RSAStringToPrivateKey(dbManager.getRSAKeySignaturePrivate());

                signature =
                    Base64.encodeToString(
                        Crypto.RSASign(Base64.decode(cipherText, Base64.NO_WRAP), RSAKeySign),
                        Base64.NO_WRAP);

              } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
              } catch (InvalidKeySpecException e) {
                e.printStackTrace();
              } catch (NoSuchProviderException e) {
                e.printStackTrace();
              } catch (InvalidKeyException e) {
                e.printStackTrace();
              } catch (SignatureException e) {
                e.printStackTrace();
              }

              message.setMessage(cipherText);
              message.setIv(base64IV);
              message.setSignature(signature);

              new HttpHandler() {
                @Override
                public HttpUriRequest getHttpRequestMethod() {
                  HttpPost httpPost = new HttpPost(Utils.SERVER_SEND_MESSAGE);

                  List<NameValuePair> nameValuePairs = new ArrayList<>();
                  nameValuePairs.add(new BasicNameValuePair("sender", message.getSender()));
                  nameValuePairs.add(new BasicNameValuePair("recipient", message.getRecipient()));
                  nameValuePairs.add(new BasicNameValuePair("message", message.getMessage()));
                  nameValuePairs.add(new BasicNameValuePair("iv", message.getIv()));
                  nameValuePairs.add(new BasicNameValuePair("signature", message.getSignature()));

                  try {
                    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                  } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                  }

                  return httpPost;
                }

                @Override
                public void onResponse(String result) {
                  Utils.Log("HttpResult: " + result);

                  if (conversation.isEncrypted().equals("true")) {
                    message.setMessage(
                        Crypto.AESencrypt(
                            conversationPass,
                            plainText,
                            Base64.decode(message.getIv(), Base64.NO_WRAP)));
                    message.setEncrypted(true);

                    dbManager.addMessage(message);

                    message.setEncrypted(false);
                    message.setMessage(plainText);

                    messages.add(message);
                    adapter.notifyDataSetChanged();

                  } else {
                    message.setMessage(plainText);
                    message.setEncrypted(false);

                    dbManager.addMessage(message);

                    messages.add(message);
                    adapter.notifyDataSetChanged();
                  }

                  messageList.setSelection(messages.size() + 1);
                }
              }.execute();

              messageText.setText("");

            }

            // DHKE was not complete yet, store messages unencrypted temporarily
            // and then encrypt and send them once the exchange is complete
            else {
              message.setEncrypted(false);
              message.setMessage(messageText.getText().toString());
              message.setIv(Base64.encodeToString(Crypto.GenerateRandomIV(), Base64.NO_WRAP));

              dbManager.addMessage(message);

              messages.add(message);
              adapter.notifyDataSetChanged();

              messageList.setSelection(adapter.getCount() - 1);
              messageText.setText("");
            }
          }
        }
Example #16
0
  /**
   * Performs test signatures for the specified keys or for all if "all" specified.
   *
   * @param keyStore Loaded keystore to read keys from
   * @param alias Alias of key to test or "all" to test all
   * @param authCode Key password (if used, ie for JKS only)
   * @param signatureProvider Provider for creating the signature
   * @return The results for each key found
   * @throws CryptoTokenOfflineException In case the key could not be used
   */
  public static Collection<KeyTestResult> testKey(
      KeyStore keyStore, String alias, char[] authCode, String signatureProvider)
      throws CryptoTokenOfflineException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("testKey for alias: " + alias);
    }

    final Collection<KeyTestResult> result = new LinkedList<KeyTestResult>();

    try {
      final Enumeration<String> e = keyStore.aliases();
      while (e.hasMoreElements()) {
        final String keyAlias = e.nextElement();
        if (alias.equalsIgnoreCase(ICryptoToken.ALL_KEYS) || alias.equals(keyAlias)) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("checking keyAlias: " + keyAlias);
          }

          if (keyStore.isKeyEntry(keyAlias)) {
            String status;
            String publicKeyHash = null;
            boolean success = false;
            try {
              final PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, authCode);
              final Certificate entryCert = keyStore.getCertificate(keyAlias);
              if (entryCert != null) {
                final PublicKey publicKey = entryCert.getPublicKey();
                publicKeyHash = createKeyHash(publicKey);
                testSignAndVerify(privateKey, publicKey, signatureProvider);
                success = true;
                status = "";
              } else {
                status = "Not testing keys with alias " + keyAlias + ". No certificate exists.";
              }
            } catch (ClassCastException ce) {
              status = "Not testing keys with alias " + keyAlias + ". Not a private key.";
            } catch (InvalidKeyException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            } catch (KeyStoreException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            } catch (NoSuchAlgorithmException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            } catch (NoSuchProviderException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            } catch (SignatureException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            } catch (UnrecoverableKeyException ex) {
              LOG.error("Error testing key: " + keyAlias, ex);
              status = ex.getMessage();
            }
            result.add(new KeyTestResult(keyAlias, success, status, publicKeyHash));
          }
        }
      }
    } catch (KeyStoreException ex) {
      throw new CryptoTokenOfflineException(ex);
    }

    if (LOG.isDebugEnabled()) {
      LOG.debug("<testKey");
    }
    return result;
  }
  /** @deprecated */
  private boolean doVerify(PublicKey key, Provider sigProvider)
      throws CMSException, NoSuchAlgorithmException {
    String digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(this.getDigestAlgOID());
    String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
    String signatureName = digestName + "with" + encName;
    Signature sig = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, sigProvider);
    MessageDigest digest = CMSSignedHelper.INSTANCE.getDigestInstance(digestName, sigProvider);

    // TODO [BJA-109] Note: PSSParameterSpec requires JDK1.4+
    /*
            try
            {
                DERObjectIdentifier sigAlgOID = encryptionAlgorithm.getObjectId();
                DEREncodable sigParams = this.encryptionAlgorithm.getParameters();
                if (sigAlgOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
                {
                    // RFC 4056
                    // When the id-RSASSA-PSS algorithm identifier is used for a signature,
                    // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
                    if (sigParams == null)
                    {
                        throw new CMSException(
                            "RSASSA-PSS signature must specify algorithm parameters");
                    }

                    AlgorithmParameters params = AlgorithmParameters.getInstance(
                        sigAlgOID.getId(), sig.getProvider().getName());
                    params.init(sigParams.getDERObject().getEncoded(), "ASN.1");

                    PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
                    sig.setParameter(spec);
                }
                else
                {
                    // TODO Are there other signature algorithms that provide parameters?
                    if (sigParams != null)
                    {
                        throw new CMSException("unrecognised signature parameters provided");
                    }
                }
            }
            catch (IOException e)
            {
                throw new CMSException("error encoding signature parameters.", e);
            }
            catch (InvalidAlgorithmParameterException e)
            {
                throw new CMSException("error setting signature parameters.", e);
            }
            catch (InvalidParameterSpecException e)
            {
                throw new CMSException("error processing signature parameters.", e);
            }
    */

    try {
      if (digestCalculator != null) {
        resultDigest = digestCalculator.getDigest();
      } else {
        if (content != null) {
          content.write(new DigOutputStream(digest));
        } else if (signedAttributeSet == null) {
          // TODO Get rid of this exception and just treat content==null as empty not missing?
          throw new CMSException("data not encapsulated in signature - use detached constructor.");
        }

        resultDigest = digest.digest();
      }
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    }

    // RFC 3852 11.1 Check the content-type attribute is correct
    {
      DERObject validContentType =
          getSingleValuedSignedAttribute(CMSAttributes.contentType, "content-type");
      if (validContentType == null) {
        if (!isCounterSignature && signedAttributeSet != null) {
          throw new CMSException(
              "The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
        }
      } else {
        if (isCounterSignature) {
          throw new CMSException(
              "[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
        }

        if (!(validContentType instanceof DERObjectIdentifier)) {
          throw new CMSException(
              "content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
        }

        DERObjectIdentifier signedContentType = (DERObjectIdentifier) validContentType;

        if (!signedContentType.equals(contentType)) {
          throw new CMSException("content-type attribute value does not match eContentType");
        }
      }
    }

    // RFC 3852 11.2 Check the message-digest attribute is correct
    {
      DERObject validMessageDigest =
          getSingleValuedSignedAttribute(CMSAttributes.messageDigest, "message-digest");
      if (validMessageDigest == null) {
        if (signedAttributeSet != null) {
          throw new CMSException(
              "the message-digest signed attribute type MUST be present when there are any signed attributes present");
        }
      } else {
        if (!(validMessageDigest instanceof ASN1OctetString)) {
          throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
        }

        ASN1OctetString signedMessageDigest = (ASN1OctetString) validMessageDigest;

        if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) {
          throw new CMSSignerDigestMismatchException(
              "message-digest attribute value does not match calculated value");
        }
      }
    }

    // RFC 3852 11.4 Validate countersignature attribute(s)
    {
      AttributeTable signedAttrTable = this.getSignedAttributes();
      if (signedAttrTable != null
          && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) {
        throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
      }

      AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
      if (unsignedAttrTable != null) {
        ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
        for (int i = 0; i < csAttrs.size(); ++i) {
          Attribute csAttr = (Attribute) csAttrs.get(i);
          if (csAttr.getAttrValues().size() < 1) {
            throw new CMSException(
                "A countersignature attribute MUST contain at least one AttributeValue");
          }

          // Note: We don't recursively validate the countersignature value
        }
      }
    }

    try {
      sig.initVerify(key);

      if (signedAttributeSet == null) {
        if (digestCalculator != null) {
          // need to decrypt signature and check message bytes
          return verifyDigest(resultDigest, key, this.getSignature(), sigProvider);
        } else if (content != null) {
          // TODO Use raw signature of the hash value instead
          content.write(new SigOutputStream(sig));
        }
      } else {
        sig.update(this.getEncodedSignedAttributes());
      }

      return sig.verify(this.getSignature());
    } catch (InvalidKeyException e) {
      throw new CMSException("key not appropriate to signature in message.", e);
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    } catch (SignatureException e) {
      throw new CMSException("invalid signature format in message: " + e.getMessage(), e);
    }
  }
  /**
   * Extract credentials from the request.
   *
   * @param req
   * @return credentials associated with the request.
   */
  public Credentials getCredentials(HttpServletRequest req, HttpServletResponse response) {
    if (testing) {
      calls.add(new Object[] {"getCredentials", req, response});
      return new SimpleCredentials("testing", "testing".toCharArray());
    }
    Credentials cred = null;
    String userId = null;
    String sakaiTrustedHeader = req.getHeader("x-sakai-token");
    if (trustedTokenEnabled
        && sakaiTrustedHeader != null
        && sakaiTrustedHeader.trim().length() > 0) {
      String host = req.getRemoteAddr();
      if (!safeHostAddrSet.contains(host)) {
        LOG.warn("Ignoring Trusted Token request from {} ", host);
      } else {
        // we have a HMAC based token, we should see if it is valid against the key we
        // have
        // and if so create some credentials.
        String[] parts = sakaiTrustedHeader.split(";");
        if (parts.length == 3) {
          try {
            String hash = parts[0];
            String user = parts[1];
            String timestamp = parts[2];
            String hmac = Signature.calculateRFC2104HMAC(user + ";" + timestamp, sharedSecret);
            if (hmac.equals(hash)) {
              // the user is Ok, we will trust it.
              userId = user;
              cred = createCredentials(userId, TrustedTokenTypes.TRUSTED_TOKEN);
            } else {
              LOG.debug("HMAC Match Failed {} != {} ", hmac, hash);
            }
          } catch (SignatureException e) {
            LOG.warn(
                "Failed to validate server token : {} {} ", sakaiTrustedHeader, e.getMessage());
          }
        } else {
          LOG.warn(
              "Illegal number of elements in trusted server token:{} {}  ",
              sakaiTrustedHeader,
              parts.length);
        }
      }
    }
    if (userId == null) {
      if (usingSession) {
        HttpSession session = req.getSession(false);
        if (session != null) {
          Credentials testCredentials =
              (Credentials) session.getAttribute(SA_AUTHENTICATION_CREDENTIALS);
          if (testCredentials instanceof SimpleCredentials) {
            SimpleCredentials sc = (SimpleCredentials) testCredentials;
            Object o = sc.getAttribute(CA_AUTHENTICATION_USER);
            if (o instanceof TrustedUser) {
              TrustedUser tu = (TrustedUser) o;
              if (tu.getUser() != null) {
                userId = tu.getUser();
                cred = testCredentials;
              }
            }
          }
        } else {
          cred = null;
        }
      } else {
        Cookie[] cookies = req.getCookies();
        if (cookies != null) {
          for (Cookie c : cookies) {
            if (trustedAuthCookieName.equals(c.getName())) {
              if (secureCookie && !c.getSecure()) {
                continue;
              }
              String cookieValue = c.getValue();
              String[] decodedToken = decodeCookie(c.getValue());
              if (decodedToken != null) {
                userId = decodedToken[0];
                String tokenType = decodedToken[1];
                TokenTrustValidator ttv = registeredTypes.get(tokenType);
                if (ttv == null || ttv.isTrusted(req)) {
                  LOG.debug("Token is valid and decoded to {} ", userId);
                  cred = createCredentials(userId, tokenType);
                  refreshToken(response, c.getValue(), userId, tokenType);
                  break;
                } else {
                  LOG.debug("Cookie cant be trusted for this request {} ", cookieValue);
                }
              } else {
                LOG.debug("Invalid Cookie {} ", cookieValue);
                clearCookie(response);
              }
            }
          }
        }
      }
    }
    if (userId != null) {
      LOG.debug("Trusted Authentication for {} with credentials {}  ", userId, cred);
    }

    return cred;
  }