You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tw...@apache.org on 2025/09/11 05:17:36 UTC
(mina-sshd) 02/02: Merge branch 'master' into 3.0.0
This is an automated email from the ASF dual-hosted git repository.
twolf pushed a commit to branch dev_3.0
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit dd654d89dcf4817a7c64beb804c02f861ad63e14
Merge: bb9ac2069 362758d2d
Author: Thomas Wolf <tw...@apache.org>
AuthorDate: Wed Sep 10 22:52:53 2025 +0200
Merge branch 'master' into 3.0.0
.../security/eddsa/generic/SignatureEd25519.java | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --cc sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/SignatureEd25519.java
index 3e7e1eb1d,2eccf3a19..afbf4a076
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/SignatureEd25519.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/SignatureEd25519.java
@@@ -16,37 -16,57 +16,78 @@@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sshd.common.util.security.eddsa;
+package org.apache.sshd.common.util.security.eddsa.generic;
+ import java.security.SignatureException;
+import java.util.Map;
++import java.util.Objects;
-import net.i2p.crypto.eddsa.EdDSAEngine;
-import org.apache.sshd.common.util.security.eddsa.generic.GenericSignatureEd25519;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.signature.AbstractSignature;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.security.SecurityUtils;
/**
- * An implementation of {@link GenericSignatureEd25519} tied to the {@code net.i2p.crypto} EdDSA security provider.
+ * An ed25519 signature.
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class SignatureEd25519 extends GenericSignatureEd25519 {
+public class SignatureEd25519 extends AbstractSignature {
+ // See https://www.rfc-editor.org/rfc/rfc7748.html#section-4.1
+ // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed; little-endian
+ private static final int[] ED25519_ORDER = { //
+ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, //
+ 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 //
+ };
+
public SignatureEd25519() {
- super(EdDSAEngine.SIGNATURE_ALGORITHM);
+ super(SecurityUtils.ED25519, KeyPairProvider.SSH_ED25519);
+ }
+
+ @Override
+ public boolean verify(SessionContext session, byte[] sig) throws Exception {
+ byte[] data = sig;
+ Map.Entry<String, byte[]> encoding = extractEncodedSignature(data, KeyPairProvider.SSH_ED25519::equalsIgnoreCase);
+ if (encoding != null) {
+ String keyType = encoding.getKey();
+ ValidateUtils.checkTrue(KeyPairProvider.SSH_ED25519.equals(keyType), "Mismatched key type: %s", keyType);
+ data = encoding.getValue();
+ }
+
+ return doVerify(data);
}
+
+ @Override
+ protected boolean doVerify(byte[] data) throws SignatureException {
- // Fix CVE 2020-36843 in net.i2p.crypto.eddsa 0.3.0: check that s is in the range [0 .. L), where
- // L is the order.
- //
- // Note: Wikipedia says 0 < S < L. https://en.wikipedia.org/w/index.php?title=EdDSA&oldid=1304068429
- // RFC 8032 says 0 <= S < L. https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.7
- //
- // We stick to RFC 8032 here.
- if (data.length != 64 || !isValidFactor(data)) {
- return false;
++ java.security.Signature verifier = Objects.requireNonNull(getSignature(), "Signature not initialized");
++ if (SecurityUtils.EDDSA.equals(verifier.getProvider().getName())) {
++ // Fix CVE 2020-36843 in net.i2p.crypto.eddsa 0.3.0: check that s is in the range [0 .. L), where
++ // L is the order.
++ //
++ // Note: Wikipedia says 0 < S < L. https://en.wikipedia.org/w/index.php?title=EdDSA&oldid=1304068429
++ // RFC 8032 says 0 <= S < L. https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.7
++ //
++ // We stick to RFC 8032 here.
++ if (data.length != 64 || !isValidFactor(data)) {
++ return false;
++ }
+ }
- return super.doVerify(data);
++ return verifier.verify(data);
+ }
+
+ private static boolean isValidFactor(byte[] sig) {
+ // Must be strictly smaller than the field order (little-endian).
+ for (int i = 31; i >= 0; i--) {
+ int y = (sig[i + 32] & 0xFF) - ED25519_ORDER[i];
+ if (y != 0) {
+ return y < 0;
+ }
+ }
+ return false;
+ }
+
}