예제 #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
  public BiometricInfoOption(final BiometricInfo jaxb) throws NoSuchAlgorithmException {
    ParamChecker.assertNotNull("jaxb", jaxb);
    this.sourceDataUriOccurrence = jaxb.getIncludeSourceDataUri();
    this.hashAlgorithms = XmlX509CertprofileUtil.toOIDSet(jaxb.getHashAlgorithm());

    for (ASN1ObjectIdentifier m : hashAlgorithms) {
      AlgorithmUtil.getHashOutputSizeInOctets(m);
    }

    this.predefinedTypes = new HashSet<>();
    this.idTypes = new HashSet<>();
    for (BiometricTypeType m : jaxb.getType()) {
      if (m.getPredefined() != null) {
        predefinedTypes.add(m.getPredefined().getValue());
      } else if (m.getOid() != null) {
        idTypes.add(new ASN1ObjectIdentifier(m.getOid().getValue()));
      } else {
        throw new RuntimeException("should not reach here, invalid biometricType");
      }
    }
  }
예제 #3
0
  @Override
  protected Object _doExecute() throws Exception {
    P10RequestGenerator p10Gen = new P10RequestGenerator();

    hashAlgo = hashAlgo.trim().toUpperCase();
    if (hashAlgo.indexOf('-') != -1) {
      hashAlgo = hashAlgo.replaceAll("-", "");
    }

    if (needExtensionTypes == null) {
      needExtensionTypes = new LinkedList<>();
    }

    // SubjectAltNames
    List<Extension> extensions = new LinkedList<>();
    if (isNotEmpty(subjectAltNames)) {
      extensions.add(P10RequestGenerator.createExtensionSubjectAltName(subjectAltNames, false));
      needExtensionTypes.add(Extension.subjectAlternativeName.getId());
    }

    // SubjectInfoAccess
    if (isNotEmpty(subjectInfoAccesses)) {
      extensions.add(
          P10RequestGenerator.createExtensionSubjectInfoAccess(subjectInfoAccesses, false));
      needExtensionTypes.add(Extension.subjectInfoAccess.getId());
    }

    // Keyusage
    if (isNotEmpty(keyusages)) {
      Set<KeyUsage> usages = new HashSet<>();
      for (String usage : keyusages) {
        usages.add(KeyUsage.getKeyUsage(usage));
      }
      org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
      ASN1ObjectIdentifier extType = Extension.keyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // ExtendedKeyusage
    if (isNotEmpty(extkeyusages)) {
      Set<ASN1ObjectIdentifier> oids =
          new HashSet<>(SecurityUtil.textToASN1ObjectIdentifers(extkeyusages));
      ExtendedKeyUsage extValue = X509Util.createExtendedUsage(oids);
      ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // QcEuLimitValue
    if (isNotEmpty(qcEuLimits)) {
      ASN1EncodableVector v = new ASN1EncodableVector();
      for (String m : qcEuLimits) {
        StringTokenizer st = new StringTokenizer(m, ":");
        try {
          String currencyS = st.nextToken();
          String amountS = st.nextToken();
          String exponentS = st.nextToken();

          Iso4217CurrencyCode currency;
          try {
            int intValue = Integer.parseInt(currencyS);
            currency = new Iso4217CurrencyCode(intValue);
          } catch (NumberFormatException e) {
            currency = new Iso4217CurrencyCode(currencyS);
          }

          int amount = Integer.parseInt(amountS);
          int exponent = Integer.parseInt(exponentS);

          MonetaryValue monterayValue = new MonetaryValue(currency, amount, exponent);
          QCStatement statment =
              new QCStatement(ObjectIdentifiers.id_etsi_qcs_QcLimitValue, monterayValue);
          v.add(statment);
        } catch (Exception e) {
          throw new Exception("invalid qc-eu-limit '" + m + "'");
        }
      }

      ASN1ObjectIdentifier extType = Extension.qCStatements;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // biometricInfo
    if (biometricType != null && biometricHashAlgo != null && biometricFile != null) {
      TypeOfBiometricData _biometricType;
      if (StringUtil.isNumber(biometricType)) {
        _biometricType = new TypeOfBiometricData(Integer.parseInt(biometricType));
      } else {
        _biometricType = new TypeOfBiometricData(new ASN1ObjectIdentifier(biometricType));
      }

      ASN1ObjectIdentifier _biometricHashAlgo = AlgorithmUtil.getHashAlg(biometricHashAlgo);
      byte[] biometricBytes = IoUtil.read(biometricFile);
      MessageDigest md = MessageDigest.getInstance(_biometricHashAlgo.getId());
      md.reset();
      byte[] _biometricDataHash = md.digest(biometricBytes);

      DERIA5String _sourceDataUri = null;
      if (biometricUri != null) {
        _sourceDataUri = new DERIA5String(biometricUri);
      }
      BiometricData biometricData =
          new BiometricData(
              _biometricType,
              new AlgorithmIdentifier(_biometricHashAlgo),
              new DEROctetString(_biometricDataHash),
              _sourceDataUri);

      ASN1EncodableVector v = new ASN1EncodableVector();
      v.add(biometricData);

      ASN1ObjectIdentifier extType = Extension.biometricInfo;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    } else if (biometricType == null && biometricHashAlgo == null && biometricFile == null) {
      // Do nothing
    } else {
      throw new Exception(
          "either all of biometric triples (type, hash algo, file)"
              + " must be set or none of them should be set");
    }

    if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
      ExtensionExistence ee =
          new ExtensionExistence(
              SecurityUtil.textToASN1ObjectIdentifers(needExtensionTypes),
              SecurityUtil.textToASN1ObjectIdentifers(wantExtensionTypes));
      extensions.add(
          new Extension(
              ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions,
              false,
              ee.toASN1Primitive().getEncoded()));
    }

    ConcurrentContentSigner identifiedSigner =
        getSigner(hashAlgo, new SignatureAlgoControl(rsaMgf1, dsaPlain));
    Certificate cert = Certificate.getInstance(identifiedSigner.getCertificate().getEncoded());

    X500Name subjectDN;
    if (subject != null) {
      subjectDN = getSubject(subject);
    } else {
      subjectDN = cert.getSubject();
    }

    SubjectPublicKeyInfo subjectPublicKeyInfo = cert.getSubjectPublicKeyInfo();

    ContentSigner signer = identifiedSigner.borrowContentSigner();

    PKCS10CertificationRequest p10Req;
    try {
      p10Req = p10Gen.generateRequest(signer, subjectPublicKeyInfo, subjectDN, extensions);
    } finally {
      identifiedSigner.returnContentSigner(signer);
    }

    File file = new File(outputFilename);
    saveVerbose("saved PKCS#10 request to file", file, p10Req.getEncoded());
    return null;
  }
예제 #4
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);
    }
  }
예제 #5
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);
      }
    }
  }