mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8302233: HSS/LMS: keytool and jarsigner changes
Reviewed-by: mullan
This commit is contained in:
parent
7ad700596f
commit
0a60b0f99e
10 changed files with 120 additions and 118 deletions
|
@ -25,11 +25,9 @@
|
|||
|
||||
package sun.security.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.security.spec.*;
|
||||
import java.util.Arrays;
|
||||
|
@ -405,5 +403,38 @@ public final class KeyUtil {
|
|||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the hash algorithm from an HSS/LMS public key.
|
||||
*
|
||||
* @param publicKey the HSS/LMS public key
|
||||
* @return the hash algorithm
|
||||
* @throws NoSuchAlgorithmException if key is from an unknown configuration
|
||||
*/
|
||||
public static String hashAlgFromHSS(PublicKey publicKey)
|
||||
throws NoSuchAlgorithmException {
|
||||
try {
|
||||
DerValue val = new DerValue(publicKey.getEncoded());
|
||||
val.data.getDerValue();
|
||||
byte[] rawKey = new DerValue(val.data.getBitString()).getOctetString();
|
||||
// According to https://www.rfc-editor.org/rfc/rfc8554.html:
|
||||
// Section 6.1: HSS public key is u32str(L) || pub[0], where pub[0]
|
||||
// is the LMS public key for the top-level tree.
|
||||
// Section 5.3: LMS public key is u32str(type) || u32str(otstype) || I || T[1]
|
||||
// Section 8: type is the numeric identifier for an LMS specification.
|
||||
// This RFC defines 5 SHA-256 based types, value from 5 to 9.
|
||||
if (rawKey.length < 8) {
|
||||
throw new NoSuchAlgorithmException("Cannot decode public key");
|
||||
}
|
||||
int num = ((rawKey[4] & 0xff) << 24) + ((rawKey[5] & 0xff) << 16)
|
||||
+ ((rawKey[6] & 0xff) << 8) + (rawKey[7] & 0xff);
|
||||
return switch (num) {
|
||||
// RFC 8554 only supports SHA_256 hash algorithm
|
||||
case 5, 6, 7, 8, 9 -> "SHA-256";
|
||||
default -> throw new NoSuchAlgorithmException("Unknown LMS type: " + num);
|
||||
};
|
||||
} catch (IOException e) {
|
||||
throw new NoSuchAlgorithmException("Cannot decode public key", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,21 +184,20 @@ public class SignatureFileVerifier {
|
|||
/**
|
||||
* Returns the signed JAR block file extension for a key.
|
||||
*
|
||||
* Returns "DSA" for unknown algorithms. This is safe because the
|
||||
* signature verification process does not require the extension to
|
||||
* match the key algorithm as long as it is "RSA", "DSA", or "EC."
|
||||
*
|
||||
* @param key the key used to sign the JAR file
|
||||
* @return the extension
|
||||
* @see #isBlockOrSF(String)
|
||||
*/
|
||||
public static String getBlockExtension(PrivateKey key) {
|
||||
String keyAlgorithm = key.getAlgorithm().toUpperCase(Locale.ENGLISH);
|
||||
if (keyAlgorithm.equals("RSASSA-PSS")) {
|
||||
return "RSA";
|
||||
} else if (keyAlgorithm.equals("EDDSA")
|
||||
|| keyAlgorithm.equals("ED25519")
|
||||
|| keyAlgorithm.equals("ED448")) {
|
||||
return "EC";
|
||||
} else {
|
||||
return keyAlgorithm;
|
||||
}
|
||||
return switch (key.getAlgorithm().toUpperCase(Locale.ENGLISH)) {
|
||||
case "RSA", "RSASSA-PSS" -> "RSA";
|
||||
case "EC", "EDDSA", "ED25519", "ED448" -> "EC";
|
||||
default -> "DSA";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -212,12 +212,13 @@ public class SignatureUtil {
|
|||
* @param signer Signature object that tells you RSASSA-PSS params
|
||||
* @param sigalg Signature algorithm
|
||||
* @param privateKey key tells you EdDSA params
|
||||
* @param publicKey key tells you HSS/LMS hash algorithm
|
||||
* @param directsign Ed448 uses different digest algs depending on this
|
||||
* @return the digest algId
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static AlgorithmId getDigestAlgInPkcs7SignerInfo(
|
||||
Signature signer, String sigalg, PrivateKey privateKey, boolean directsign)
|
||||
Signature signer, String sigalg, PrivateKey privateKey, PublicKey publicKey, boolean directsign)
|
||||
throws NoSuchAlgorithmException {
|
||||
AlgorithmId digAlgID;
|
||||
String kAlg = privateKey.getAlgorithm();
|
||||
|
@ -243,18 +244,18 @@ public class SignatureUtil {
|
|||
default:
|
||||
throw new AssertionError("Unknown curve name: " + kAlg);
|
||||
}
|
||||
} else {
|
||||
if (sigalg.equalsIgnoreCase("RSASSA-PSS")) {
|
||||
try {
|
||||
digAlgID = AlgorithmId.get(signer.getParameters()
|
||||
.getParameterSpec(PSSParameterSpec.class)
|
||||
.getDigestAlgorithm());
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
throw new AssertionError("Should not happen", e);
|
||||
}
|
||||
} else {
|
||||
digAlgID = AlgorithmId.get(extractDigestAlgFromDwithE(sigalg));
|
||||
} else if (sigalg.equalsIgnoreCase("RSASSA-PSS")) {
|
||||
try {
|
||||
digAlgID = AlgorithmId.get(signer.getParameters()
|
||||
.getParameterSpec(PSSParameterSpec.class)
|
||||
.getDigestAlgorithm());
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
throw new AssertionError("Should not happen", e);
|
||||
}
|
||||
} else if (sigalg.equalsIgnoreCase("HSS/LMS")) {
|
||||
digAlgID = AlgorithmId.get(KeyUtil.hashAlgFromHSS(publicKey));
|
||||
} else {
|
||||
digAlgID = AlgorithmId.get(extractDigestAlgFromDwithE(sigalg));
|
||||
}
|
||||
return digAlgID;
|
||||
}
|
||||
|
@ -484,14 +485,15 @@ public class SignatureUtil {
|
|||
public static String getDefaultSigAlgForKey(PrivateKey k) {
|
||||
String kAlg = k.getAlgorithm().toUpperCase(Locale.ENGLISH);
|
||||
return switch (kAlg) {
|
||||
case "DH", "XDH", "X25519", "X448" -> null;
|
||||
case "DSA" -> "SHA256withDSA";
|
||||
case "RSA" -> ifcFfcStrength(KeyUtil.getKeySize(k)) + "withRSA";
|
||||
case "EC" -> ecStrength(KeyUtil.getKeySize(k)) + "withECDSA";
|
||||
case "EDDSA" -> k instanceof EdECPrivateKey
|
||||
? ((EdECPrivateKey) k).getParams().getName()
|
||||
: kAlg;
|
||||
case "RSASSA-PSS", "ED25519", "ED448" -> kAlg;
|
||||
default -> null;
|
||||
default -> kAlg; // All modern signature algorithms,
|
||||
// RSASSA-PSS, ED25519, ED448, HSS/LMS, etc
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue