OpenSshPublicKeyUtilities
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Utilities
{
public static class OpenSshPublicKeyUtilities
{
private static readonly string RSA = "ssh-rsa";
private static readonly string ECDSA = "ecdsa";
private static readonly string ED_25519 = "ssh-ed25519";
private static readonly string DSS = "ssh-dss";
public static AsymmetricKeyParameter ParsePublicKey(byte[] encoded)
{
return ParsePublicKey(new SshBuffer(encoded));
}
public static byte[] EncodePublicKey(AsymmetricKeyParameter cipherParameters)
{
if (cipherParameters == null)
throw new ArgumentNullException("cipherParameters");
if (cipherParameters.IsPrivate)
throw new ArgumentException("Not a public key", "cipherParameters");
RsaKeyParameters rsaKeyParameters = cipherParameters as RsaKeyParameters;
if (rsaKeyParameters != null) {
SshBuilder sshBuilder = new SshBuilder();
sshBuilder.WriteStringAscii(RSA);
sshBuilder.WriteMpint(rsaKeyParameters.Exponent);
sshBuilder.WriteMpint(rsaKeyParameters.Modulus);
return sshBuilder.GetBytes();
}
ECPublicKeyParameters eCPublicKeyParameters = cipherParameters as ECPublicKeyParameters;
if (eCPublicKeyParameters != null) {
string text = null;
DerObjectIdentifier publicKeyParamSet = eCPublicKeyParameters.PublicKeyParamSet;
if (publicKeyParamSet != null)
text = SshNamedCurves.GetName(publicKeyParamSet);
if (text == null)
throw new ArgumentException("unable to derive ssh curve name for EC public key");
SshBuilder sshBuilder2 = new SshBuilder();
sshBuilder2.WriteStringAscii(ECDSA + "-sha2-" + text);
sshBuilder2.WriteStringAscii(text);
sshBuilder2.WriteBlock(eCPublicKeyParameters.Q.GetEncoded(false));
return sshBuilder2.GetBytes();
}
DsaPublicKeyParameters dsaPublicKeyParameters = cipherParameters as DsaPublicKeyParameters;
if (dsaPublicKeyParameters != null) {
DsaParameters parameters = dsaPublicKeyParameters.Parameters;
SshBuilder sshBuilder3 = new SshBuilder();
sshBuilder3.WriteStringAscii(DSS);
sshBuilder3.WriteMpint(parameters.P);
sshBuilder3.WriteMpint(parameters.Q);
sshBuilder3.WriteMpint(parameters.G);
sshBuilder3.WriteMpint(dsaPublicKeyParameters.Y);
return sshBuilder3.GetBytes();
}
Ed25519PublicKeyParameters ed25519PublicKeyParameters = cipherParameters as Ed25519PublicKeyParameters;
if (ed25519PublicKeyParameters != null) {
SshBuilder sshBuilder4 = new SshBuilder();
sshBuilder4.WriteStringAscii(ED_25519);
sshBuilder4.WriteBlock(ed25519PublicKeyParameters.GetEncoded());
return sshBuilder4.GetBytes();
}
throw new ArgumentException("unable to convert " + Platform.GetTypeName(cipherParameters) + " to public key");
}
private static AsymmetricKeyParameter ParsePublicKey(SshBuffer buffer)
{
AsymmetricKeyParameter asymmetricKeyParameter = null;
string text = buffer.ReadStringAscii();
if (RSA.Equals(text)) {
BigInteger exponent = buffer.ReadMpintPositive();
BigInteger modulus = buffer.ReadMpintPositive();
asymmetricKeyParameter = new RsaKeyParameters(false, modulus, exponent);
} else if (DSS.Equals(text)) {
BigInteger p = buffer.ReadMpintPositive();
BigInteger q = buffer.ReadMpintPositive();
BigInteger g = buffer.ReadMpintPositive();
asymmetricKeyParameter = new DsaPublicKeyParameters(buffer.ReadMpintPositive(), new DsaParameters(p, q, g));
} else if (text.StartsWith(ECDSA)) {
string text2 = buffer.ReadStringAscii();
DerObjectIdentifier oid = SshNamedCurves.GetOid(text2);
X9ECParameters x9ECParameters = (oid == null) ? null : SshNamedCurves.GetByOid(oid);
if (x9ECParameters == null)
throw new InvalidOperationException("unable to find curve for " + text + " using curve name " + text2);
byte[] encoded = buffer.ReadBlock();
asymmetricKeyParameter = new ECPublicKeyParameters(x9ECParameters.Curve.DecodePoint(encoded), new ECNamedDomainParameters(oid, x9ECParameters));
} else if (ED_25519.Equals(text)) {
asymmetricKeyParameter = new Ed25519PublicKeyParameters(buffer.ReadBlock());
}
if (asymmetricKeyParameter == null)
throw new ArgumentException("unable to parse key");
if (buffer.HasRemaining())
throw new ArgumentException("decoded key has trailing data");
return asymmetricKeyParameter;
}
}
}