/** * Parse a secret key from one of the GPG S expression keys. * * @return a secret key object. */ public static PGPSecretKey parseSecretKeyFromSExpr( InputStream inputStream, PBEProtectionRemoverFactory keyProtectionRemoverFactory, KeyFingerPrintCalculator fingerPrintCalculator) throws IOException, PGPException { SXprUtils.skipOpenParenthesis(inputStream); String type; type = SXprUtils.readString(inputStream, inputStream.read()); if (type.equals("protected-private-key")) { SXprUtils.skipOpenParenthesis(inputStream); String curveName; String keyType = SXprUtils.readString(inputStream, inputStream.read()); if (keyType.equals("ecc")) { SXprUtils.skipOpenParenthesis(inputStream); String curveID = SXprUtils.readString(inputStream, inputStream.read()); curveName = SXprUtils.readString(inputStream, inputStream.read()); if (curveName.startsWith("NIST ")) { curveName = curveName.substring("NIST ".length()); } SXprUtils.skipCloseParenthesis(inputStream); } else { throw new PGPException("no curve details found"); } byte[] qVal; SXprUtils.skipOpenParenthesis(inputStream); type = SXprUtils.readString(inputStream, inputStream.read()); if (type.equals("q")) { qVal = SXprUtils.readBytes(inputStream, inputStream.read()); } else { throw new PGPException("no q value found"); } PublicKeyPacket pubPacket = new PublicKeyPacket( PublicKeyAlgorithmTags.ECDSA, new Date(), new ECDSAPublicBCPGKey(ECNamedCurveTable.getOID(curveName), new BigInteger(1, qVal))); SXprUtils.skipCloseParenthesis(inputStream); byte[] dValue = getDValue(inputStream, keyProtectionRemoverFactory, curveName); // TODO: check SHA-1 hash. return new PGPSecretKey( new SecretKeyPacket( pubPacket, SymmetricKeyAlgorithmTags.NULL, null, null, new ECSecretBCPGKey(new BigInteger(1, dValue)).getEncoded()), new PGPPublicKey(pubPacket, fingerPrintCalculator)); } throw new PGPException("unknown key type found"); }
private static void addNamedCurves_jdk18on() { final Class<?>[] Param_CurveDB_add = new Class[] { String.class, String.class, int.class, String.class, String.class, String.class, String.class, String.class, String.class, int.class, Pattern.class }; final Class<?>[] Param_getCurve = new Class[] {String.class}; Method method_add = getMethod(class_CurveDB, "add", Param_CurveDB_add); if (method_add == null) { return; } Method method_getCurve = getMethod(class_CurveDB, "lookup", Param_getCurve); if (method_getCurve == null) { return; } Field field_oidMap = getField(class_CurveDB, "oidMap"); if (field_oidMap == null) { return; } Field field_specCollection = getField(class_CurveDB, "specCollection"); if (field_specCollection == null) { return; } Set<String> processedCurveOids = new HashSet<>(); Map<String, String> addedCurves = new HashMap<>(); Enumeration<?> curveNames = ECNamedCurveTable.getNames(); while (curveNames.hasMoreElements()) { String curveName = (String) curveNames.nextElement(); ASN1ObjectIdentifier curveId = getCurveId(curveName); if (curveId == null) { LOG.debug("cound not find curve OID for curve {}, ignore it", curveName); continue; } String curveDesc = "named curve " + curveName + " (" + curveId + ")"; if (processedCurveOids.contains(curveId.getId())) { LOG.debug("{} is already processed, ignore it", curveDesc); continue; } processedCurveOids.add(curveId.getId()); if (curve_isRegistered(method_getCurve, curveId)) { LOG.info("{} is already registered, ignore it", curveDesc); continue; } X9ECParameters params = ECNamedCurveTable.getByOID(curveId); ECCurve curve = params.getCurve(); if (curve instanceof ECCurve.Fp || curve instanceof ECCurve.F2m) { CurveData c = new CurveData(params); boolean added = CurveDB_add( method_add, curveName, curveId.getId(), c.type, c.sfield, c.a, c.b, c.x, c.y, c.n, c.h); if (added) { LOG.debug("added {}", curveDesc); addedCurves.put(curveName, curveId.getId()); } else { LOG.warn("could not add {}", curveDesc); } } else { LOG.info("unknown curve type {}", curve.getClass().getName()); } } try { Map<?, ?> oidMap = (Map<?, ?>) field_oidMap.get(null); Collection<?> namedCurves = Collections.unmodifiableCollection(oidMap.values()); field_specCollection.set(null, namedCurves); } catch (IllegalArgumentException | IllegalAccessException | ClassCastException e) { final String message = "could not update change the value of field CurveDB.specCollection."; if (LOG.isWarnEnabled()) { LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); } logAddedCurves(addedCurves); }
/** * Create a public key from the passed in SubjectPublicKeyInfo * * @param keyInfo the SubjectPublicKeyInfo containing the key data * @return the appropriate key parameter * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) throws IOException { AlgorithmIdentifier algId = keyInfo.getAlgorithm(); if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption) || algId.getAlgorithm().equals(X509ObjectIdentifiers.id_ea_rsa)) { RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey()); return new RSAKeyParameters(false, pubKey.getModulus(), pubKey.getPublicExponent()); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.dhpublicnumber)) { DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey()); BigInteger y = dhPublicKey.getY().getValue(); DHDomainParameters dhParams = DHDomainParameters.getInstance(algId.getParameters()); BigInteger p = dhParams.getP().getValue(); BigInteger g = dhParams.getG().getValue(); BigInteger q = dhParams.getQ().getValue(); BigInteger j = null; if (dhParams.getJ() != null) { j = dhParams.getJ().getValue(); } DHValidationParameters validation = null; DHValidationParms dhValidationParms = dhParams.getValidationParms(); if (dhValidationParms != null) { byte[] seed = dhValidationParms.getSeed().getBytes(); BigInteger pgenCounter = dhValidationParms.getPgenCounter().getValue(); // TODO Check pgenCounter size? validation = new DHValidationParameters(seed, pgenCounter.intValue()); } return new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)); } else if (algId.getAlgorithm().equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); ASN1Integer derY = (ASN1Integer) keyInfo.parsePublicKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); DHParameters dhParams = new DHParameters(params.getP(), params.getG(), null, l); return new DHPublicKeyParameters(derY.getValue(), dhParams); } // BEGIN android-removed // else if (algId.getAlgorithm().equals(OIWObjectIdentifiers.elGamalAlgorithm)) // { // ElGamalParameter params = new ElGamalParameter((ASN1Sequence)algId.getParameters()); // ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); // // return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters( // params.getP(), params.getG())); // } // END android-removed else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_dsa) || algId.getAlgorithm().equals(OIWObjectIdentifiers.dsaWithSHA1)) { ASN1Integer derY = (ASN1Integer) keyInfo.parsePublicKey(); ASN1Encodable de = algId.getParameters(); DSAParameters parameters = null; if (de != null) { DSAParameter params = DSAParameter.getInstance(de.toASN1Primitive()); parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); } return new DSAPublicKeyParameters(derY.getValue(), parameters); } else if (algId.getAlgorithm().equals(X9ObjectIdentifiers.id_ecPublicKey)) { X962Parameters params = X962Parameters.getInstance(algId.getParameters()); X9ECParameters x9; if (params.isNamedCurve()) { ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) params.getParameters(); x9 = ECNamedCurveTable.getByOID(oid); } else { x9 = X9ECParameters.getInstance(params.getParameters()); } ASN1OctetString key = new DEROctetString(keyInfo.getPublicKeyData().getBytes()); X9ECPoint derQ = new X9ECPoint(x9.getCurve(), key); // TODO We lose any named parameters here ECDomainParameters dParams = new ECDomainParameters(x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); return new ECPublicKeyParameters(derQ.getPoint(), dParams); } else { throw new RuntimeException("algorithm identifier in key not recognised"); } }
private static void addNamedCurves_jdk17() { final Class<?>[] Param_NamedCurve_add = new Class[] { String.class, String.class, int.class, String.class, String.class, String.class, String.class, String.class, String.class, int.class }; final Class<?>[] Param_getCurve = new Class[] {String.class}; Method method_add = getMethod(class_NamedCurve, "add", Param_NamedCurve_add); if (method_add == null) { return; } Method method_getCurve = getMethod(class_NamedCurve, "getECParameterSpec", Param_getCurve); if (method_getCurve == null) { return; } Field field_SPLIT_PATTERN = getField(class_NamedCurve, "SPLIT_PATTERN"); if (field_SPLIT_PATTERN == null) { return; } try { field_SPLIT_PATTERN.set(null, SPLIT_PATTERN); } catch (IllegalArgumentException | IllegalAccessException e) { final String message = "could not set Field SPLIT_PATTERN"; if (LOG.isWarnEnabled()) { LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); return; } Set<String> processedCurveOids = new HashSet<>(); Map<String, String> addedCurves = new HashMap<>(); Enumeration<?> curveNames = ECNamedCurveTable.getNames(); while (curveNames.hasMoreElements()) { String curveName = (String) curveNames.nextElement(); ASN1ObjectIdentifier curveId = getCurveId(curveName); if (curveId == null) { LOG.info("cound not find curve OID for curve {}, ignore it", curveName); continue; } String curveDesc = "named curve " + curveName + " (" + curveId + ")"; if (processedCurveOids.contains(curveId.getId())) { LOG.debug("{} is already processed, ignore it", curveDesc); continue; } processedCurveOids.add(curveId.getId()); if (curve_isRegistered(method_getCurve, curveId)) { LOG.debug("{} is already registered, ignore it", curveDesc); continue; } X9ECParameters params = ECNamedCurveTable.getByOID(curveId); ECCurve curve = params.getCurve(); if (curve instanceof ECCurve.Fp || curve instanceof ECCurve.F2m) { CurveData c = new CurveData(params); boolean added = NamedCurve_add( method_add, curveName, curveId.getId(), c.type, c.sfield, c.a, c.b, c.x, c.y, c.n, c.h); if (added) { LOG.debug("added {}", curveDesc); addedCurves.put(curveName, curveId.getId()); } else { LOG.warn("could not add {}", curveDesc); } } else { LOG.info("unknown curve type {}", curve.getClass().getName()); } } try { field_SPLIT_PATTERN.set(null, null); } catch (IllegalArgumentException | IllegalAccessException e) { final String message = "could not set Field SPLIT_PATTERN"; if (LOG.isWarnEnabled()) { LOG.warn(LogUtil.buildExceptionLogFormat(message), e.getClass().getName(), e.getMessage()); } LOG.debug(message, e); return; } logAddedCurves(addedCurves); }