mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
- A separate enum members take with lots of code duplication
This commit is contained in:
@@ -119,8 +119,8 @@ public enum KeyType {
|
||||
|
||||
},
|
||||
|
||||
/** SSH identifier for ECDSA keys */
|
||||
ECDSA("ecdsa-sha2-nistp256") {
|
||||
/** SSH identifier for ECDSA-256 keys */
|
||||
ECDSA256("ecdsa-sha2-nistp256") {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
@@ -149,7 +149,7 @@ public enum KeyType {
|
||||
);
|
||||
}
|
||||
|
||||
if (!NISTP_CURVE.equals(curveName)) {
|
||||
if (!NISTP_CURVE_256.equals(curveName)) {
|
||||
throw new GeneralSecurityException(String.format("Unknown curve %s", curveName));
|
||||
}
|
||||
|
||||
@@ -175,13 +175,79 @@ public enum KeyType {
|
||||
final ECPublicKey ecdsa = (ECPublicKey) pk;
|
||||
byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve());
|
||||
|
||||
buf.putString(NISTP_CURVE)
|
||||
buf.putString(NISTP_CURVE_256)
|
||||
.putBytes(encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return ("ECDSA".equals(key.getAlgorithm()));
|
||||
return ("ECDSA".equals(key.getAlgorithm()) && ((ECPublicKey) key).getParams().getCurve().getField().getFieldSize() == 256);
|
||||
}
|
||||
},
|
||||
|
||||
/** SSH identifier for ECDSA-384 keys */
|
||||
ECDSA384("ecdsa-sha2-nistp384") {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
if (!SecurityUtils.isBouncyCastleRegistered()) {
|
||||
throw new GeneralSecurityException("BouncyCastle is required to read a key of type " + sType);
|
||||
}
|
||||
try {
|
||||
// final String algo = buf.readString(); it has been already read
|
||||
final String curveName = buf.readString();
|
||||
final int keyLen = buf.readUInt32AsInt();
|
||||
final byte x04 = buf.readByte(); // it must be 0x04, but don't think we need that check
|
||||
final byte[] x = new byte[(keyLen - 1) / 2];
|
||||
final byte[] y = new byte[(keyLen - 1) / 2];
|
||||
buf.readRawBytes(x);
|
||||
buf.readRawBytes(y);
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug(String.format("Key algo: %s, Key curve: %s, Key Len: %s, 0x04: %s\nx: %s\ny: %s",
|
||||
sType,
|
||||
curveName,
|
||||
keyLen,
|
||||
x04,
|
||||
Arrays.toString(x),
|
||||
Arrays.toString(y))
|
||||
);
|
||||
}
|
||||
|
||||
if (!NISTP_CURVE_384.equals(curveName)) {
|
||||
throw new GeneralSecurityException(String.format("Unknown curve %s", curveName));
|
||||
}
|
||||
|
||||
BigInteger bigX = new BigInteger(1, x);
|
||||
BigInteger bigY = new BigInteger(1, y);
|
||||
|
||||
X9ECParameters ecParams = NISTNamedCurves.getByName("p-384");
|
||||
ECPoint pPublicPoint = ecParams.getCurve().createPoint(bigX, bigY);
|
||||
ECParameterSpec spec = new ECParameterSpec(ecParams.getCurve(),
|
||||
ecParams.getG(), ecParams.getN());
|
||||
ECPublicKeySpec publicSpec = new ECPublicKeySpec(pPublicPoint, spec);
|
||||
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA");
|
||||
return keyFactory.generatePublic(publicSpec);
|
||||
} catch (Exception ex) {
|
||||
throw new GeneralSecurityException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
final ECPublicKey ecdsa = (ECPublicKey) pk;
|
||||
byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve());
|
||||
|
||||
buf.putString(NISTP_CURVE_384)
|
||||
.putBytes(encoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return ("ECDSA".equals(key.getAlgorithm()) && ((ECPublicKey) key).getParams().getCurve().getField().getFieldSize() == 384);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -285,7 +351,8 @@ public enum KeyType {
|
||||
};
|
||||
|
||||
|
||||
private static final String NISTP_CURVE = "nistp256";
|
||||
private static final String NISTP_CURVE_256 = "nistp256";
|
||||
private static final String NISTP_CURVE_384 = "nistp384";
|
||||
|
||||
protected final String sType;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public class SignatureECDSA
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return KeyType.ECDSA.toString();
|
||||
return KeyType.ECDSA256.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
137
src/main/java/net/schmizz/sshj/signature/SignatureECDSA384.java
Normal file
137
src/main/java/net/schmizz/sshj/signature/SignatureECDSA384.java
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C)2009 - SSHJ Contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.schmizz.sshj.signature;
|
||||
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
import net.schmizz.sshj.common.KeyType;
|
||||
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.SignatureException;
|
||||
|
||||
/** ECDSA {@link Signature} */
|
||||
public class SignatureECDSA384
|
||||
extends AbstractSignature {
|
||||
|
||||
/** A named factory for ECDSA signature */
|
||||
public static class Factory
|
||||
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||
|
||||
@Override
|
||||
public Signature create() {
|
||||
return new SignatureECDSA384();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return KeyType.ECDSA384.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public SignatureECDSA384() {
|
||||
super("SHA384withECDSA");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode(byte[] sig) {
|
||||
int rIndex = 3;
|
||||
int rLen = sig[rIndex++] & 0xff;
|
||||
byte[] r = new byte[rLen];
|
||||
System.arraycopy(sig, rIndex, r, 0, r.length);
|
||||
|
||||
int sIndex = rIndex + rLen + 1;
|
||||
int sLen = sig[sIndex++] & 0xff;
|
||||
byte[] s = new byte[sLen];
|
||||
System.arraycopy(sig, sIndex, s, 0, s.length);
|
||||
|
||||
System.arraycopy(sig, 4, r, 0, rLen);
|
||||
System.arraycopy(sig, 6 + rLen, s, 0, sLen);
|
||||
|
||||
Buffer buf = new Buffer.PlainBuffer();
|
||||
buf.putMPInt(new BigInteger(r));
|
||||
buf.putMPInt(new BigInteger(s));
|
||||
|
||||
return buf.getCompactData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(byte[] sig) {
|
||||
byte[] r;
|
||||
byte[] s;
|
||||
try {
|
||||
Buffer sigbuf = new Buffer.PlainBuffer(sig);
|
||||
final String algo = new String(sigbuf.readBytes());
|
||||
if (!"ecdsa-sha2-nistp384".equals(algo)) {
|
||||
throw new SSHRuntimeException(String.format("Signature :: ecdsa-sha2-nistp384 expected, got %s", algo));
|
||||
}
|
||||
final int rsLen = sigbuf.readUInt32AsInt();
|
||||
if (sigbuf.available() != rsLen) {
|
||||
throw new SSHRuntimeException("Invalid key length");
|
||||
}
|
||||
r = sigbuf.readBytes();
|
||||
s = sigbuf.readBytes();
|
||||
} catch (Exception e) {
|
||||
throw new SSHRuntimeException(e);
|
||||
}
|
||||
|
||||
int rLen = r.length;
|
||||
int sLen = s.length;
|
||||
|
||||
/* We can't have the high bit set, so add an extra zero at the beginning if so. */
|
||||
if ((r[0] & 0x80) != 0) {
|
||||
rLen++;
|
||||
}
|
||||
if ((s[0] & 0x80) != 0) {
|
||||
sLen++;
|
||||
}
|
||||
|
||||
/* Calculate total output length */
|
||||
int length = 6 + rLen + sLen;
|
||||
byte[] asn1 = new byte[length];
|
||||
|
||||
/* ASN.1 SEQUENCE tag */
|
||||
asn1[0] = (byte) 0x30;
|
||||
|
||||
/* Size of SEQUENCE */
|
||||
asn1[1] = (byte) (4 + rLen + sLen);
|
||||
|
||||
/* ASN.1 INTEGER tag */
|
||||
asn1[2] = (byte) 0x02;
|
||||
|
||||
/* "r" INTEGER length */
|
||||
asn1[3] = (byte) rLen;
|
||||
|
||||
/* Copy in the "r" INTEGER */
|
||||
System.arraycopy(r, 0, asn1, 4, rLen);
|
||||
|
||||
/* ASN.1 INTEGER tag */
|
||||
asn1[rLen + 4] = (byte) 0x02;
|
||||
|
||||
/* "s" INTEGER length */
|
||||
asn1[rLen + 5] = (byte) sLen;
|
||||
|
||||
/* Copy in the "s" INTEGER */
|
||||
System.arraycopy(s, 0, asn1, (6 + rLen), sLen);
|
||||
|
||||
|
||||
try {
|
||||
return signature.verify(asn1);
|
||||
} catch (SignatureException e) {
|
||||
throw new SSHRuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user