BaseCipherSuitePlugin.SignatureAlgorithmDSA.DERDecodeSignature C# (CSharp) Method

DERDecodeSignature() private static method

private static DERDecodeSignature ( byte data ) : byte[]
data byte
return byte[]
        private static byte[] DERDecodeSignature(byte[] data)
        {
            // In DSA the signature length is always 2*20 bytes
            int sigLength = 20;

            // This is the largest we can decode, check type
            if (data.Length > 65538 || data[0] != 0x30) {
                throw new Exception("Invalid signature");
            }

            int fullConsumed;
            byte[] encoded = DERDecodeVector(data, 1, out fullConsumed);
            if (encoded[0] != 0x02)
                throw new Exception("Invalid signature");

            int rConsumed;
            byte[] R = DERDecodeVector(encoded, 1, out rConsumed);
            if (encoded[1+rConsumed] != 0x02)
                throw new Exception("Invalid signature");

            int sConsumed;
            byte[] S = DERDecodeVector(encoded, 1+rConsumed+1, out sConsumed);
            if (1+rConsumed+1+sConsumed != encoded.Length)
                throw new Exception("Invalid signature");

            // Make sure the signature is valid
            for (int i=0; i<R.Length-sigLength; i++) {
                if (R[i] != 0)
                    throw new Exception("Invalid signature");
            }
            for (int i=0; i<S.Length-sigLength; i++) {
                if (S[i] != 0)
                    throw new Exception("Invalid signature");
            }

            // Copy signature bytes to the decoded array
            byte[] ret = new byte[sigLength*2];
            Buffer.BlockCopy(R, System.Math.Max(0, R.Length-sigLength),
                             ret, System.Math.Max(0, sigLength-R.Length),
                             System.Math.Min(sigLength, R.Length));
            Buffer.BlockCopy(S, System.Math.Max(0, S.Length-sigLength),
                             ret, sigLength+System.Math.Max(0, sigLength-S.Length),
                             System.Math.Min(sigLength, S.Length));
            return ret;
        }