Пример #1
0
 private AlgorithmIdentifier getSignatureAlgoId(final String signerConf) throws SignerException {
   CmpUtf8Pairs keyValues = new CmpUtf8Pairs(signerConf);
   String algoS = keyValues.getValue("algo");
   if (algoS == null) {
     throw new SignerException("algo is not specified");
   }
   try {
     return AlgorithmUtil.getSignatureAlgoId(algoS);
   } catch (NoSuchAlgorithmException e) {
     throw new SignerException(e.getMessage(), e);
   }
 }
Пример #2
0
  /*
   * sigAlgoControl will be considered only if hashAlgo is not set
   *
   */
  private ConcurrentContentSigner doCreateSigner(
      String type,
      final String conf,
      final String hashAlgo,
      final SignatureAlgoControl sigAlgoControl,
      final X509Certificate[] certificateChain)
      throws SignerException {
    if (signerTypeMapping.containsKey(type)) {
      type = signerTypeMapping.get(type);
    }

    if ("PKCS11".equalsIgnoreCase(type)
        || "PKCS12".equalsIgnoreCase(type)
        || "JKS".equalsIgnoreCase(type)) {
      CmpUtf8Pairs keyValues = new CmpUtf8Pairs(conf);

      String s = keyValues.getValue("parallelism");
      int parallelism = defaultParallelism;
      if (s != null) {
        try {
          parallelism = Integer.parseInt(s);
        } catch (NumberFormatException e) {
          throw new SignerException("invalid parallelism " + s);
        }

        if (parallelism < 1) {
          throw new SignerException("invalid parallelism " + s);
        }
      }

      if ("PKCS11".equalsIgnoreCase(type)) {
        String pkcs11Module = keyValues.getValue("module");
        if (pkcs11Module == null) {
          pkcs11Module = DEFAULT_P11MODULE_NAME;
        }

        s = keyValues.getValue("slot");
        Integer slotIndex = (s == null) ? null : Integer.parseInt(s);

        s = keyValues.getValue("slot-id");
        Long slotId = (s == null) ? null : Long.parseLong(s);

        if ((slotIndex == null && slotId == null) || (slotIndex != null && slotId != null)) {
          throw new SignerException("exactly one of slot (index) and slot-id must be specified");
        }
        P11SlotIdentifier slot = new P11SlotIdentifier(slotIndex, slotId);

        String keyLabel = keyValues.getValue("key-label");
        s = keyValues.getValue("key-id");
        byte[] keyId = null;
        if (s != null) {
          keyId = Hex.decode(s);
        }

        if ((keyId == null && keyLabel == null) || (keyId != null && keyLabel != null)) {
          throw new SignerException("exactly one of key-id and key-label must be specified");
        }

        P11KeyIdentifier keyIdentifier;
        if (keyId != null) {
          keyIdentifier = new P11KeyIdentifier(keyId);
        } else {
          keyIdentifier = new P11KeyIdentifier(keyLabel);
        }

        P11CryptService p11CryptService = getP11CryptService(pkcs11Module);
        P11ContentSignerBuilder signerBuilder =
            new P11ContentSignerBuilder(p11CryptService, slot, keyIdentifier, certificateChain);

        try {
          AlgorithmIdentifier signatureAlgId;
          if (hashAlgo == null) {
            signatureAlgId = getSignatureAlgoId(conf);
          } else {
            PublicKey pubKey;
            try {
              pubKey = getPkcs11PublicKey(pkcs11Module, slot, keyIdentifier);
            } catch (InvalidKeyException e) {
              throw new SignerException("invalid key: " + e.getMessage(), e);
            }

            signatureAlgId = AlgorithmUtil.getSignatureAlgoId(pubKey, hashAlgo, sigAlgoControl);
          }
          return signerBuilder.createSigner(signatureAlgId, parallelism);
        } catch (OperatorCreationException | NoSuchPaddingException | NoSuchAlgorithmException e) {
          throw new SignerException(e.getMessage(), e);
        }

      } else {
        String passwordHint = keyValues.getValue("password");
        char[] password;
        if (passwordHint == null) {
          password = null;
        } else {
          if (passwordResolver == null) {
            password = passwordHint.toCharArray();
          } else {
            try {
              password = passwordResolver.resolvePassword(passwordHint);
            } catch (PasswordResolverException e) {
              throw new SignerException("could not resolve password. Message: " + e.getMessage());
            }
          }
        }

        s = keyValues.getValue("keystore");
        String keyLabel = keyValues.getValue("key-label");

        InputStream keystoreStream;
        if (StringUtil.startsWithIgnoreCase(s, "base64:")) {
          keystoreStream = new ByteArrayInputStream(Base64.decode(s.substring("base64:".length())));
        } else if (StringUtil.startsWithIgnoreCase(s, "file:")) {
          String fn = s.substring("file:".length());
          try {
            keystoreStream = new FileInputStream(IoUtil.expandFilepath(fn));
          } catch (FileNotFoundException e) {
            throw new SignerException("file not found: " + fn);
          }
        } else {
          throw new SignerException("unknown keystore content format");
        }

        SoftTokenContentSignerBuilder signerBuilder =
            new SoftTokenContentSignerBuilder(
                type, keystoreStream, password, keyLabel, password, certificateChain);

        try {
          AlgorithmIdentifier signatureAlgId;
          if (hashAlgo == null) {
            signatureAlgId = getSignatureAlgoId(conf);
          } else {
            PublicKey pubKey = signerBuilder.getCert().getPublicKey();
            signatureAlgId = AlgorithmUtil.getSignatureAlgoId(pubKey, hashAlgo, sigAlgoControl);
          }

          return signerBuilder.createSigner(signatureAlgId, parallelism);
        } catch (OperatorCreationException | NoSuchPaddingException | NoSuchAlgorithmException e) {
          throw new SignerException(e.getMessage());
        }
      }
    } else if (StringUtil.startsWithIgnoreCase(type, "java:")) {
      if (hashAlgo == null) {
        ConcurrentContentSigner contentSigner;
        String classname = type.substring("java:".length());
        try {
          Class<?> clazz = Class.forName(classname);
          contentSigner = (ConcurrentContentSigner) clazz.newInstance();
        } catch (Exception e) {
          throw new SignerException(e.getMessage(), e);
        }
        contentSigner.initialize(conf, passwordResolver);

        if (certificateChain != null) {
          contentSigner.setCertificateChain(certificateChain);
        }

        return contentSigner;
      } else {
        throw new SignerException("unknwon type: " + type);
      }
    } else {
      throw new SignerException("unknwon type: " + type);
    }
  }
Пример #3
0
  private static void validateSigner(
      final ConcurrentContentSigner signer,
      final X509Certificate[] certificateChain,
      final String signerType,
      final String signerConf)
      throws SignerException {
    X509Certificate cert = signer.getCertificate();
    if (certificateChain == null) {
      return;
    }

    String signatureAlgoName;
    try {
      signatureAlgoName = AlgorithmUtil.getSignatureAlgoName(signer.getAlgorithmIdentifier());
    } catch (NoSuchAlgorithmException e) {
      throw new SignerException(e.getMessage(), e);
    }

    ContentSigner csigner;
    try {
      csigner = signer.borrowContentSigner();
    } catch (NoIdleSignerException e) {
      throw new SignerException(e.getMessage(), e);
    }

    try {
      byte[] dummyContent = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
      Signature verifier = Signature.getInstance(signatureAlgoName, "BC");

      OutputStream signatureStream = csigner.getOutputStream();
      signatureStream.write(dummyContent);
      byte[] signatureValue = csigner.getSignature();

      verifier.initVerify(cert.getPublicKey());
      verifier.update(dummyContent);
      boolean valid = verifier.verify(signatureValue);
      if (valid == false) {
        String subject = X509Util.getRFC4519Name(cert.getSubjectX500Principal());

        StringBuilder sb = new StringBuilder();
        sb.append("key and certificate not match. ");
        sb.append("key type='").append(signerType).append("'; ");

        CmpUtf8Pairs keyValues = new CmpUtf8Pairs(signerConf);
        String pwd = keyValues.getValue("password");
        if (pwd != null) {
          keyValues.putUtf8Pair("password", "****");
        }
        keyValues.putUtf8Pair("algo", signatureAlgoName);
        sb.append("conf='").append(keyValues.getEncoded()).append("', ");
        sb.append("certificate subject='").append(subject).append("'");

        throw new SignerException(sb.toString());
      }
    } catch (IOException
        | NoSuchAlgorithmException
        | InvalidKeyException
        | SignatureException
        | NoSuchProviderException e) {
      throw new SignerException(e.getMessage(), e);
    } finally {
      if (csigner != null) {
        signer.returnContentSigner(csigner);
      }
    }
  }