SubjectPublicKeyInfoFactory
A factory to produce Public Key Info Objects.
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.EdEC;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.X509
{
public static class SubjectPublicKeyInfoFactory
{
public unsafe static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey)
{
if (publicKey == null)
throw new ArgumentNullException("publicKey");
if (publicKey.IsPrivate)
throw new ArgumentException("Private key passed - public key expected.", "publicKey");
ElGamalPublicKeyParameters elGamalPublicKeyParameters = publicKey as ElGamalPublicKeyParameters;
if (elGamalPublicKeyParameters != null) {
ElGamalParameters parameters = elGamalPublicKeyParameters.Parameters;
ElGamalParameter parameters2 = new ElGamalParameter(parameters.P, parameters.G);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, parameters2), new DerInteger(elGamalPublicKeyParameters.Y));
}
DsaPublicKeyParameters dsaPublicKeyParameters = publicKey as DsaPublicKeyParameters;
if (dsaPublicKeyParameters != null) {
DsaParameters parameters3 = dsaPublicKeyParameters.Parameters;
DsaParameter parameters4 = new DsaParameter(parameters3.P, parameters3.Q, parameters3.G);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, parameters4), new DerInteger(dsaPublicKeyParameters.Y));
}
DHPublicKeyParameters dHPublicKeyParameters = publicKey as DHPublicKeyParameters;
if (dHPublicKeyParameters != null) {
DHParameters parameters5 = dHPublicKeyParameters.Parameters;
DHParameter parameters6 = new DHParameter(parameters5.P, parameters5.G, parameters5.L);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(dHPublicKeyParameters.AlgorithmOid, parameters6), new DerInteger(dHPublicKeyParameters.Y));
}
RsaKeyParameters rsaKeyParameters = publicKey as RsaKeyParameters;
if (rsaKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), new RsaPublicKeyStructure(rsaKeyParameters.Modulus, rsaKeyParameters.Exponent));
ECPublicKeyParameters eCPublicKeyParameters = publicKey as ECPublicKeyParameters;
if (eCPublicKeyParameters != null) {
ECPoint q = eCPublicKeyParameters.Q;
ECGost3410Parameters eCGost3410Parameters = eCPublicKeyParameters.Parameters as ECGost3410Parameters;
if (eCGost3410Parameters != null) {
int fieldElementEncodingLength = eCPublicKeyParameters.Parameters.Curve.FieldElementEncodingLength;
DerObjectIdentifier algorithm = (fieldElementEncodingLength > 32) ? RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
Gost3410PublicKeyAlgParameters parameters7 = new Gost3410PublicKeyAlgParameters(eCGost3410Parameters.PublicKeyParamSet, eCGost3410Parameters.DigestParamSet, eCGost3410Parameters.EncryptionParamSet);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(algorithm, parameters7), CreateECGost3410PublicKey(fieldElementEncodingLength, q));
}
if (eCPublicKeyParameters.AlgorithmName == "ECGOST3410") {
if (eCPublicKeyParameters.PublicKeyParamSet == null)
throw new NotImplementedException("Not a CryptoPro parameter set");
int fieldElementEncodingLength2 = eCPublicKeyParameters.Parameters.Curve.FieldElementEncodingLength;
Gost3410PublicKeyAlgParameters parameters8 = new Gost3410PublicKeyAlgParameters(eCPublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, parameters8), CreateECGost3410PublicKey(fieldElementEncodingLength2, q));
}
X962Parameters parameters9 = eCPublicKeyParameters.Parameters.ToX962Parameters();
int encodedLength = q.GetEncodedLength(false);
Span<byte> span;
if (encodedLength <= 512) {
int num = encodedLength;
span = new Span<byte>(stackalloc byte[(int)(uint)num], num);
} else
span = new byte[encodedLength];
Span<byte> span2 = span;
q.EncodeTo(false, span2);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, parameters9), span2);
}
Gost3410PublicKeyParameters gost3410PublicKeyParameters = publicKey as Gost3410PublicKeyParameters;
if (gost3410PublicKeyParameters != null) {
if (gost3410PublicKeyParameters.PublicKeyParamSet == null)
throw new NotImplementedException("Not a CryptoPro parameter set");
byte[] contents = Arrays.ReverseInPlace(gost3410PublicKeyParameters.Y.ToByteArrayUnsigned());
Gost3410PublicKeyAlgParameters parameters10 = new Gost3410PublicKeyAlgParameters(gost3410PublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x94, parameters10), new DerOctetString(contents));
}
X448PublicKeyParameters x448PublicKeyParameters = publicKey as X448PublicKeyParameters;
if (x448PublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), x448PublicKeyParameters.DataSpan);
X25519PublicKeyParameters x25519PublicKeyParameters = publicKey as X25519PublicKeyParameters;
if (x25519PublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), x25519PublicKeyParameters.DataSpan);
Ed448PublicKeyParameters ed448PublicKeyParameters = publicKey as Ed448PublicKeyParameters;
if (ed448PublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), ed448PublicKeyParameters.GetEncoded());
Ed25519PublicKeyParameters ed25519PublicKeyParameters = publicKey as Ed25519PublicKeyParameters;
if (ed25519PublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), ed25519PublicKeyParameters.GetEncoded());
MLDsaPublicKeyParameters mLDsaPublicKeyParameters = publicKey as MLDsaPublicKeyParameters;
if (mLDsaPublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(mLDsaPublicKeyParameters.Parameters.Oid), mLDsaPublicKeyParameters.GetEncoded());
MLKemPublicKeyParameters mLKemPublicKeyParameters = publicKey as MLKemPublicKeyParameters;
if (mLKemPublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(mLKemPublicKeyParameters.Parameters.Oid), mLKemPublicKeyParameters.GetEncoded());
SlhDsaPublicKeyParameters slhDsaPublicKeyParameters = publicKey as SlhDsaPublicKeyParameters;
if (slhDsaPublicKeyParameters != null)
return new SubjectPublicKeyInfo(new AlgorithmIdentifier(slhDsaPublicKeyParameters.Parameters.Oid), slhDsaPublicKeyParameters.GetEncoded());
throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(publicKey));
}
private static Asn1OctetString CreateECGost3410PublicKey(int fieldSize, ECPoint q)
{
byte[] array = new byte[fieldSize * 2];
EncodeECGost3410FieldElement(q.AffineXCoord.ToBigInteger(), array, 0, fieldSize);
EncodeECGost3410FieldElement(q.AffineYCoord.ToBigInteger(), array, fieldSize, fieldSize);
return DerOctetString.WithContents(array);
}
private static void EncodeECGost3410FieldElement(BigInteger bi, byte[] buf, int off, int len)
{
BigIntegers.AsUnsignedByteArray(bi, buf, off, len);
Array.Reverse(buf, off, len);
}
}
}