Esempio n. 1
0
        public override PasetoSecurityToken Verify(PasetoToken token, IEnumerable <SecurityKey> signingKeys)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }
            if (signingKeys == null || !signingKeys.Any())
            {
                throw new ArgumentNullException(nameof(signingKeys));
            }

            var keys = signingKeys.OfType <EdDsaSecurityKey>().ToList();

            if (!keys.Any())
            {
                throw new SecurityTokenInvalidSigningKeyException($"PASETO v2 requires key of type {typeof(EdDsaSecurityKey)}");
            }

            if (token.Version != PasetoConstants.Versions.V2)
            {
                throw new ArgumentException("Invalid PASETO version");
            }
            if (token.Purpose != PasetoConstants.Purposes.Public)
            {
                throw new ArgumentException("Invalid PASETO purpose");
            }

            // decode payload
            var payload = Base64UrlEncoder.DecodeBytes(token.EncodedPayload);

            if (payload.Length < 64)
            {
                throw new SecurityTokenInvalidSignatureException("Payload does not contain signature");
            }

            // extract signature from payload (rightmost 64 bytes)
            var signature = new byte[64];

            Buffer.BlockCopy(payload, payload.Length - 64, signature, 0, 64);

            // decode payload JSON
            var message = new byte[payload.Length - 64];

            Buffer.BlockCopy(payload, 0, message, 0, payload.Length - 64);
            token.SetPayload(Encoding.UTF8.GetString(message));

            // pack
            var signedMessage = PreAuthEncode(new[]
            {
                Encoding.UTF8.GetBytes(PublicHeader),
                message,
                Base64UrlEncoder.DecodeBytes(token.EncodedFooter ?? string.Empty)
            });

            // verify signature using valid keys
            foreach (var publicKey in keys)
            {
                var signer = new Ed25519Signer();
                signer.Init(false, publicKey.KeyParameters);
                signer.BlockUpdate(signedMessage, 0, signedMessage.Length);

                var isValidSignature = signer.VerifySignature(signature);
                if (isValidSignature)
                {
                    return(new PasetoSecurityToken(token));
                }
            }

            throw new SecurityTokenInvalidSignatureException("Invalid PASETO signature");
        }
Esempio n. 2
0
        public override PasetoSecurityToken Verify(PasetoToken token, IEnumerable <SecurityKey> signingKeys)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }
            if (signingKeys == null || !signingKeys.Any())
            {
                throw new ArgumentNullException(nameof(signingKeys));
            }

            var keys = signingKeys.OfType <RsaSecurityKey>().ToList();

            if (!keys.Any())
            {
                throw new SecurityTokenInvalidSigningKeyException($"PASETO v1 requires key of type {typeof(RsaSecurityKey)}");
            }

            if (token.Version != PasetoConstants.Versions.V1)
            {
                throw new ArgumentException("Invalid PASETO version");
            }
            if (token.Purpose != PasetoConstants.Purposes.Public)
            {
                throw new ArgumentException("Invalid PASETO purpose");
            }

            // decode payload
            var payload = Base64UrlEncoder.DecodeBytes(token.EncodedPayload);

            if (payload.Length < 256)
            {
                throw new SecurityTokenInvalidSignatureException("Payload does not contain signature");
            }

            // extract signature from payload (rightmost 64 bytes)
            var signature = new byte[256];

            Buffer.BlockCopy(payload, payload.Length - 256, signature, 0, 256);

            // decode payload JSON
            var message = new byte[payload.Length - 256];

            Buffer.BlockCopy(payload, 0, message, 0, payload.Length - 256);
            token.SetPayload(Encoding.UTF8.GetString(message));

            // pack
            var signedMessage = PreAuthEncode(new[]
            {
                Encoding.UTF8.GetBytes(PublicHeader),
                message,
                Base64UrlEncoder.DecodeBytes(token.EncodedFooter ?? string.Empty)
            });

            // verify signature using valid keys
            foreach (var publicKey in keys)
            {
                try
                {
                    var isValidSignature = publicKey.Rsa.VerifyData(signedMessage, signature, HashAlgorithmName.SHA384, RSASignaturePadding.Pss);
                    if (isValidSignature)
                    {
                        return(new PasetoSecurityToken(token));
                    }
                }
                catch (Exception)
                {
                    // ignored
                }
            }

            throw new SecurityTokenInvalidSignatureException("Invalid PASETO signature");
        }