public bool Validate(OneKey signerKey) { CBORObject alg; // Get the set algorithm or infer one byte[] bytesToBeSigned = toBeSigned(); alg = FindAttribute(HeaderKeys.Algorithm); if (alg == null) { throw new CoseException("No algorithm specified"); } IDigest digest = null; IDigest digest2 = null; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "ES384": case "PS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "HSS-LMS": break; default: throw new CoseException("Unknown signature algorithm"); } } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.RSA_PSS_256: digest = new Sha256Digest(); digest2 = new Sha256Digest(); break; case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.RSA_PSS_384: digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case AlgorithmValuesInt.ECDSA_512: case AlgorithmValuesInt.RSA_PSS_512: digest = new Sha512Digest(); digest2 = new Sha512Digest(); break; case AlgorithmValuesInt.EdDSA: break; default: throw new CoseException("Unknown signature algorithm"); } } else { throw new CoseException("Algorthm incorrectly encoded"); } if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "HSS-LMS": return(HashSig.Validate(bytesToBeSigned, signerKey[CoseKeyParameterKeys.Lms_Public].GetByteString(), _rgbSignature)); default: throw new CoseException("Unknown Algorithm"); } } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.RSA_PSS_256: case AlgorithmValuesInt.RSA_PSS_384: case AlgorithmValuesInt.RSA_PSS_512: { PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength()); RsaKeyParameters prv = new RsaPrivateCrtKeyParameters(signerKey.AsBigInteger(CoseKeyParameterKeys.RSA_n), signerKey.AsBigInteger(CoseKeyParameterKeys.RSA_e), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv)); ParametersWithRandom param = new ParametersWithRandom(prv, GetPRNG()); signer.Init(false, param); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.VerifySignature(_rgbSignature)); } case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.ECDSA_512: { digest.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); byte[] digestedMessage = new byte[digest.GetDigestSize()]; digest.DoFinal(digestedMessage, 0); X9ECParameters p = signerKey.GetCurve(); ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); ECPoint point = signerKey.GetPoint(); ECPublicKeyParameters param = new ECPublicKeyParameters(point, parameters); ECDsaSigner ecdsa = new ECDsaSigner(); ecdsa.Init(false, param); BigInteger r = new BigInteger(1, _rgbSignature, 0, _rgbSignature.Length / 2); BigInteger s = new BigInteger(1, _rgbSignature, _rgbSignature.Length / 2, _rgbSignature.Length / 2); return(ecdsa.VerifySignature(digestedMessage, r, s)); } #if true case AlgorithmValuesInt.EdDSA: { ISigner eddsa; if (signerKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519)) { Ed25519PublicKeyParameters privKey = new Ed25519PublicKeyParameters(signerKey[CoseKeyParameterKeys.OKP_X].GetByteString(), 0); eddsa = new Ed25519Signer(); eddsa.Init(false, privKey); } else if (signerKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448)) { Ed448PublicKeyParameters privKey = new Ed448PublicKeyParameters(signerKey[CoseKeyParameterKeys.OKP_X].GetByteString(), 0); eddsa = new Ed448Signer(new byte[0]); eddsa.Init(false, privKey); } else { throw new CoseException("Unrecognized curve"); } eddsa.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(eddsa.VerifySignature(_rgbSignature)); } #endif default: throw new CoseException("Unknown Algorithm"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }
private byte[] _Sign(byte[] bytesToBeSigned) { CBORObject alg; // Get the set algorithm or infer one if (rgbContent == null) { throw new CoseException("No Content Specified"); } alg = FindAttribute(HeaderKeys.Algorithm); if (alg == null) { if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.Integer) { switch ((GeneralValuesInt)_keyToSign[CoseKeyKeys.KeyType].AsInt32()) { case GeneralValuesInt.KeyType_RSA: alg = AlgorithmValues.RSA_PSS_256; break; case GeneralValuesInt.KeyType_EC2: if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer) { switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32()) { case GeneralValuesInt.P256: alg = AlgorithmValues.ECDSA_256; break; case GeneralValuesInt.P521: alg = AlgorithmValues.ECDSA_512; break; default: throw new CoseException("Unknown curve"); } } else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString) { switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString()) { case "P-384": alg = CBORObject.FromObject("ES384"); break; default: throw new CoseException("Unknown curve"); } } else { throw new CoseException("Curve is incorrectly encoded"); } break; case GeneralValuesInt.KeyType_OKP: if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Integer) { switch ((GeneralValuesInt)_keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32()) { case GeneralValuesInt.Ed25519: alg = AlgorithmValues.EdDSA; break; case GeneralValuesInt.Ed448: alg = AlgorithmValues.EdDSA; break; default: throw new CoseException("Unknown curve"); } } else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString) { switch (_keyToSign[CoseKeyParameterKeys.EC_Curve].AsString()) { default: throw new CoseException("Unknown curve"); } } else { throw new CoseException("Curve is incorrectly encoded"); } break; default: throw new CoseException("Unknown or unsupported key type " + _keyToSign.AsString("kty")); } } else if (_keyToSign[CoseKeyKeys.KeyType].Type == CBORType.TextString) { throw new CoseException("Unknown or unsupported key type " + _keyToSign[CoseKeyKeys.KeyType].AsString()); } else { throw new CoseException("Key type is not correctly encoded"); } UnprotectedMap.Add(HeaderKeys.Algorithm, alg); } IDigest digest = null; IDigest digest2 = null; if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "ES384": case "PS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "HSS-LMS": break; default: throw new CoseException("Unknown Algorithm Specified"); } } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.RSA_PSS_256: digest = new Sha256Digest(); digest2 = new Sha256Digest(); break; case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.RSA_PSS_384: digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case AlgorithmValuesInt.ECDSA_512: case AlgorithmValuesInt.RSA_PSS_512: digest = new Sha512Digest(); digest2 = new Sha512Digest(); break; case AlgorithmValuesInt.EdDSA: break; default: throw new CoseException("Unknown Algorithm Specified"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } if (alg.Type == CBORType.TextString) { switch (alg.AsString()) { case "HSS-LMS": HashSig sig = new HashSig(_keyToSign[CoseKeyParameterKeys.Lms_Private].AsString()); byte[] signBytes = sig.Sign(bytesToBeSigned); _keyToSign.Replace(CoseKeyParameterKeys.Lms_Private, CBORObject.FromObject(sig.PrivateKey)); return(signBytes); default: throw new CoseException("Unknown Algorithm Specified"); } } else if (alg.Type == CBORType.Integer) { switch ((AlgorithmValuesInt)alg.AsInt32()) { case AlgorithmValuesInt.RSA_PSS_256: case AlgorithmValuesInt.RSA_PSS_384: case AlgorithmValuesInt.RSA_PSS_512: { PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength()); RsaKeyParameters prv = new RsaPrivateCrtKeyParameters( _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), _keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv)); ParametersWithRandom param = new ParametersWithRandom(prv, GetPRNG()); signer.Init(true, param); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.GenerateSignature()); } case AlgorithmValuesInt.ECDSA_256: case AlgorithmValuesInt.ECDSA_384: case AlgorithmValuesInt.ECDSA_512: { CBORObject privateKeyD = _keyToSign[CoseKeyParameterKeys.EC_D]; if (privateKeyD == null) { throw new CoseException("Private key required to sign"); } SecureRandom random = GetPRNG(); digest.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); byte[] digestedMessage = new byte[digest.GetDigestSize()]; digest.DoFinal(digestedMessage, 0); X9ECParameters p = _keyToSign.GetCurve(); ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters("ECDSA", ConvertBigNum(privateKeyD), parameters); ParametersWithRandom param = new ParametersWithRandom(privKey, random); ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest())); ecdsa.Init(true, param); BigInteger[] sig = ecdsa.GenerateSignature(digestedMessage); byte[] r = sig[0].ToByteArrayUnsigned(); byte[] s = sig[1].ToByteArrayUnsigned(); int cbR = (p.Curve.FieldSize + 7) / 8; byte[] sigs = new byte[cbR * 2]; Array.Copy(r, 0, sigs, cbR - r.Length, r.Length); Array.Copy(s, 0, sigs, cbR + cbR - s.Length, s.Length); return(sigs); } #if true case AlgorithmValuesInt.EdDSA: { ISigner eddsa; if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519)) { Ed25519PrivateKeyParameters privKey = new Ed25519PrivateKeyParameters(_keyToSign[CoseKeyParameterKeys.OKP_D].GetByteString(), 0); eddsa = new Ed25519Signer(); eddsa.Init(true, privKey); } else if (_keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448)) { Ed448PrivateKeyParameters privKey = new Ed448PrivateKeyParameters(_keyToSign[CoseKeyParameterKeys.OKP_D].GetByteString(), 0); eddsa = new Ed448Signer(new byte[0]); eddsa.Init(true, privKey); } else { throw new CoseException("Unrecognized curve"); } eddsa.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(eddsa.GenerateSignature()); } #endif default: throw new CoseException("Unknown Algorithm Specified"); } } else { throw new CoseException("Algorithm incorrectly encoded"); } }