static void BuildCompact(JSON control, KeySet keys) { // Encrypted or Signed? if (control.ContainsKey("signing")) { JOSE.SignMessage sign = new JOSE.SignMessage(); JOSE.Signer signer = new JOSE.Signer(keys[0]); sign.SetContent(control["input"]["payload"].AsString()); sign.AddSigner(signer); JSON xx = control["signing"]["protected"]; foreach (string key in xx.Keys) { signer.AddProtected(key, xx[key]); } string output = sign.EncodeCompact(); Message msg = Message.DecodeFromString(output); CheckMessage(msg, keys[0], control["input"]); } else if (control.ContainsKey("encrypting_key")) { JOSE.EncryptMessage enc = new EncryptMessage(); JSON xx = control["encrypting_content"]["protected"]; foreach (string key in xx.Keys) { enc.AddProtected(key, xx[key]); } JOSE.Recipient recip = new Recipient(keys[0], control["input"]["alg"].AsString(), enc); enc.AddRecipient(recip); enc.SetContent(control["input"]["plaintext"].AsString()); string output = enc.EncodeCompact(); Message msg = Message.DecodeFromString(output); CheckMessage(msg, keys[0], control["input"]); } }
public void Verify(Key key, SignMessage msg) { string alg = FindAttr("alg", msg).AsString(); 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(1, signature, 0, signature.Length / 2); BigInteger s = new BigInteger(1, 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": { ISigner eddsa; if (key.AsString("kty") != "OKP") { throw new JOSE_Exception("Wrong Key Type"); } switch (key.AsString("crv")) { case "Ed25519": { Ed25519PublicKeyParameters privKey = new Ed25519PublicKeyParameters(key.AsBytes("X"), 0); eddsa = new Ed25519Signer(); eddsa.Init(false, privKey); 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); eddsa.BlockUpdate(toVerify, 0, toVerify.Length); if (!eddsa.VerifySignature(signature)) { throw new JOSE_Exception("Signature did not validate"); } break; } default: throw new JOSE_Exception("Unknown algorithm"); } break; } default: throw new JOSE_Exception("Unknown algorithm"); } }