public void Verify(Key key, SignMessage msg) { string alg = FindAttr("alg", msg).AsString(); COSE.EdDSA eddsa; IDigest digest; IDigest digest2; switch (alg) { case "RS256": case "ES256": case "PS256": case "HS256": digest = new Sha256Digest(); digest2 = new Sha256Digest(); break; case "RS384": case "ES384": case "PS384": case "HS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "RS512": case "ES512": case "PS512": case "HS512": digest = new Sha512Digest(); digest2 = new Sha512Digest(); break; case "EdDSA": digest = null; digest2 = null; break; default: throw new JOSE_Exception("Unknown signature algorithm"); } switch (alg) { case "RS256": case "RS384": case "RS512": { if (key.AsString("kty") != "RSA") { throw new JOSE_Exception("Wrong Key"); } RsaDigestSigner signer = new RsaDigestSigner(digest); RsaKeyParameters pub = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e")); signer.Init(false, pub); signer.BlockUpdate(protectedB64, 0, protectedB64.Length); signer.BlockUpdate(rgbDot, 0, 1); signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length); if (!signer.VerifySignature(signature)) { throw new JOSE_Exception("Message failed to verify"); } } break; case "PS256": case "PS384": case "PS512": { PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize()); RsaKeyParameters pub = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e")); signer.Init(false, pub); signer.BlockUpdate(protectedB64, 0, protectedB64.Length); signer.BlockUpdate(rgbDot, 0, 1); signer.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length); if (!signer.VerifySignature(signature)) { throw new JOSE_Exception("Message failed to verify"); } } break; case "ES256": case "ES384": case "ES512": { if (key.AsString("kty") != "EC") { throw new JOSE_Exception("Wrong Key Type"); } X9ECParameters p = NistNamedCurves.GetByName(key.AsString("crv")); ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); ECPoint point = p.Curve.CreatePoint(key.AsBigInteger("x" ), key.AsBigInteger("y")); ECPublicKeyParameters pubKey = new ECPublicKeyParameters(point, parameters); ECDsaSigner ecdsa = new ECDsaSigner(); ecdsa.Init(false, pubKey); digest.BlockUpdate(protectedB64, 0, protectedB64.Length); digest.BlockUpdate(rgbDot, 0, rgbDot.Length); digest.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length); byte[] o1 = new byte[digest.GetDigestSize()]; digest.DoFinal(o1, 0); BigInteger r = new BigInteger(signature, 0, signature.Length / 2); BigInteger s = new BigInteger(signature, signature.Length / 2, signature.Length / 2); if (!ecdsa.VerifySignature(o1, r, s)) { throw new JOSE_Exception("Signature did not validate"); } } break; case "HS256": case "HS384": case "HS512": { HMac hmac = new HMac(digest); KeyParameter K = new KeyParameter(Message.base64urldecode(key.AsString("k"))); hmac.Init(K); hmac.BlockUpdate(protectedB64, 0, protectedB64.Length); hmac.BlockUpdate(rgbDot, 0, rgbDot.Length); hmac.BlockUpdate(msg.payloadB64, 0, msg.payloadB64.Length); byte[] resBuf = new byte[hmac.GetMacSize()]; hmac.DoFinal(resBuf, 0); bool fVerify = true; for (int i = 0; i < resBuf.Length; i++) { if (resBuf[i] != signature[i]) { fVerify = false; } } if (!fVerify) { throw new JOSE_Exception("Signature did not validte"); } } break; case "EdDSA": if (key.AsString("kty") != "OKP") { throw new JOSE_Exception("Wrong Key Type"); } switch (key.AsString("crv")) { case "Ed25519": eddsa = new COSE.EdDSA25517(); break; default: throw new JOSE_Exception("Unknown OKP curve"); } COSE.EdDSAPoint eddsaPoint = eddsa.DecodePoint(key.AsBytes("x")); byte[] toVerify = new byte[protectedB64.Length + rgbDot.Length + msg.payloadB64.Length]; Array.Copy(protectedB64, 0, toVerify, 0, protectedB64.Length); Array.Copy(rgbDot, 0, toVerify, protectedB64.Length, rgbDot.Length); Array.Copy(msg.payloadB64, 0, toVerify, protectedB64.Length + rgbDot.Length, msg.payloadB64.Length); if (!eddsa.Verify(key.AsBytes("x"), toVerify, signature)) { throw new JOSE_Exception("Signature did not validate"); } break; default: throw new JOSE_Exception("Unknown algorithm"); } }
private byte[] Sign(byte[] bytesToBeSigned) { string alg = null; // Get the set algorithm or infer one try { alg = FindAttribute("alg").AsString(); } catch (Exception) { ; } if (alg == null) { switch (keyToSign.AsString("kty")) { case "RSA": alg = "PS256"; break; case "EC": switch (keyToSign.AsString("crv")) { case "P-256": alg = "ES256"; break; case "P-384": alg = "ES384"; break; case "P-521": alg = "ES512"; break; default: throw new JOSE_Exception("Unknown curve"); } break; default: throw new JOSE_Exception("Unknown or unsupported key type " + keyToSign.AsString("kty")); } objUnprotected.Add("alg", alg); } IDigest digest; IDigest digest2; switch (alg) { case "RS256": case "ES256": case "PS256": case "HS256": digest = new Sha256Digest(); digest2 = new Sha256Digest(); break; case "RS384": case "ES384": case "PS384": case "HS384": digest = new Sha384Digest(); digest2 = new Sha384Digest(); break; case "RS512": case "ES512": case "PS512": case "HS512": digest = new Sha512Digest(); digest2 = new Sha512Digest(); break; case "EdDSA": digest = null; digest2 = null; break; default: throw new JOSE_Exception("Unknown signature algorithm"); } switch (alg) { case "RS256": case "RS384": case "RS512": { RsaDigestSigner signer = new RsaDigestSigner(digest); RsaKeyParameters prv = new RsaPrivateCrtKeyParameters(ConvertBigNum(keyToSign.AsBytes("n")), ConvertBigNum(keyToSign.AsBytes("e")), ConvertBigNum(keyToSign.AsBytes("d")), ConvertBigNum(keyToSign.AsBytes("p")), ConvertBigNum(keyToSign.AsBytes("q")), ConvertBigNum(keyToSign.AsBytes("dp")), ConvertBigNum(keyToSign.AsBytes("dq")), ConvertBigNum(keyToSign.AsBytes("qi"))); signer.Init(true, prv); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.GenerateSignature()); } case "PS256": case "PS384": case "PS512": { PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize()); RsaKeyParameters prv = new RsaPrivateCrtKeyParameters(ConvertBigNum(keyToSign.AsBytes("n")), ConvertBigNum(keyToSign.AsBytes("e")), ConvertBigNum(keyToSign.AsBytes("d")), ConvertBigNum(keyToSign.AsBytes("p")), ConvertBigNum(keyToSign.AsBytes("q")), ConvertBigNum(keyToSign.AsBytes("dp")), ConvertBigNum(keyToSign.AsBytes("dq")), ConvertBigNum(keyToSign.AsBytes("qi"))); ParametersWithRandom rnd = new ParametersWithRandom(prv, Message.s_PRNG); signer.Init(true, rnd); signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); return(signer.GenerateSignature()); } case "ES256": case "ES384": case "ES512": { X9ECParameters p = NistNamedCurves.GetByName(keyToSign.AsString("crv")); ECDomainParameters parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters("ECDSA", ConvertBigNum(keyToSign.AsBytes("d")), parameters); ParametersWithRandom param = new ParametersWithRandom(privKey, Message.s_PRNG); ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest())); ecdsa.Init(true, param); BigInteger[] sig = ecdsa.GenerateSignature(bytesToBeSigned); byte[] r = sig[0].ToByteArray(); byte[] s = sig[1].ToByteArray(); byte[] sigs = new byte[r.Length + s.Length]; Array.Copy(r, sigs, r.Length); Array.Copy(s, 0, sigs, r.Length, s.Length); return(sigs); } case "HS256": case "HS384": case "HS512": { HMac hmac = new HMac(digest); KeyParameter key = new KeyParameter(keyToSign.AsBytes("k")); byte[] resBuf = new byte[hmac.GetMacSize()]; hmac.Init(key); hmac.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length); hmac.DoFinal(resBuf, 0); return(resBuf); } case "EdDSA": { switch (keyToSign.AsString("crv")) { case "Ed25519": COSE.EdDSA25517 x = new COSE.EdDSA25517(); return(x.Sign(keyToSign.AsBytes("x"), keyToSign.AsBytes("d"), bytesToBeSigned)); } } break; } return(null); }