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); } }
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"); } } }
@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; }
/* * 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); } }
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); } } }