frostfs-sdk-csharp/src/FrostFS.SDK.ClientV2/RequestSigner.cs
Ivan Pchelintsev 0d83541d82 [#1] Optimize imports
Signed-off-by: Ivan Pchelintsev <i.pchelintsev@yadro.com>
2024-05-22 14:29:20 +03:00

97 lines
3.7 KiB
C#

using System.Security.Cryptography;
using FrostFS.Refs;
using FrostFS.SDK.Cryptography;
using FrostFS.Session;
using Google.Protobuf;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
namespace FrostFS.SDK.ClientV2
{
public static class RequestSigner
{
public const int RFC6979SignatureSize = 64;
public static byte[] SignRFC6979(this ECDsa key, byte[] data)
{
var digest = new Sha256Digest();
var secp256r1 = SecNamedCurves.GetByName("secp256r1");
var ec_parameters = new ECDomainParameters(secp256r1.Curve, secp256r1.G, secp256r1.N);
var private_key = new ECPrivateKeyParameters(new BigInteger(1, key.PrivateKey()), ec_parameters);
var signer = new ECDsaSigner(new HMacDsaKCalculator(digest));
var hash = new byte[digest.GetDigestSize()];
digest.BlockUpdate(data, 0, data.Length);
digest.DoFinal(hash, 0);
signer.Init(true, private_key);
var rs = signer.GenerateSignature(hash);
var signature = new byte[RFC6979SignatureSize];
var rbytes = rs[0].ToByteArrayUnsigned();
var sbytes = rs[1].ToByteArrayUnsigned();
var index = RFC6979SignatureSize / 2 - rbytes.Length;
rbytes.CopyTo(signature, index);
index = RFC6979SignatureSize - sbytes.Length;
sbytes.CopyTo(signature, index);
return signature;
}
public static SignatureRFC6979 SignRFC6979(this ECDsa key, IMessage message)
{
return new SignatureRFC6979
{
Key = ByteString.CopyFrom(key.PublicKey()),
Sign = ByteString.CopyFrom(key.SignRFC6979(message.ToByteArray())),
};
}
public static SignatureRFC6979 SignRFC6979(this ECDsa key, ByteString data)
{
return new SignatureRFC6979
{
Key = ByteString.CopyFrom(key.PublicKey()),
Sign = ByteString.CopyFrom(key.SignRFC6979(data.ToByteArray())),
};
}
public static byte[] SignData(this ECDsa key, byte[] data)
{
var hash = new byte[65];
hash[0] = 0x04;
key
.SignHash(SHA512.Create().ComputeHash(data))
.CopyTo(hash, 1);
return hash;
}
public static Signature SignMessagePart(this ECDsa key, IMessage? data)
{
var data2sign = data is null ? Array.Empty<byte>() : data.ToByteArray();
var sig = new Signature
{
Key = ByteString.CopyFrom(key.PublicKey()),
Sign = ByteString.CopyFrom(key.SignData(data2sign)),
};
return sig;
}
public static void Sign(this IVerificableMessage message, ECDsa key)
{
var meta = message.GetMetaHeader();
IVerificationHeader verify = message switch
{
IRequest => new RequestVerificationHeader(),
IResponse => new ResponseVerificationHeader(),
_ => throw new InvalidOperationException("Unsopported message type")
};
var verifyOrigin = message.GetVerificationHeader();
if (verifyOrigin is null)
verify.BodySignature = key.SignMessagePart(message.GetBody());
verify.MetaSignature = key.SignMessagePart(meta);
verify.OriginSignature = key.SignMessagePart(verifyOrigin);
verify.SetOrigin(verifyOrigin);
message.SetVerificationHeader(verify);
}
}
}