AWS-SNS-Verify
view release on metacpan or search on metacpan
# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.012.
Changes
LICENSE
MANIFEST
META.yml
Makefile.PL
README
author.t/01_verify.t
author.t/unicode.t
dist.ini
lib/AWS/SNS/Verify.pm
t/01_verify.t
t/02_valid_cert_url.t
t/author-pod-coverage.t
t/author-pod-syntax.t
author.t/01_verify.t view on Meta::CPAN
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:041977924901:test:5b4ab24c-a248-4b55-84ef-7143a86f483f"
}
END
my $sns = AWS::SNS::Verify->new(body => $body, certificate_string => $cert_string);
isa_ok($sns, 'AWS::SNS::Verify');
#is($sns->certificate_string, $sns->fetch_certificate, 'loading the certificate ok');
ok $sns->verify, 'does message check out';
my $unicode = <<END;
{
"Type" : "Notification",
"MessageId" : "95841c0a-329b-5910-bcc0-4a45a34aa6c7",
"TopicArn" : "arn:aws:sns:us-east-1:041977924901:test",
"Message" : "A Test Banana:\uD83C\uDF4C",
"Timestamp" : "2019-11-20T19:10:09.894Z",
"SignatureVersion" : "1",
"Signature" : "DRcI8zgRFKXD/N679D3v9q8uYEt0HYJYUNQoGsNZ3JF6x5mmoEG2e9u+5MwwS2tkOsvwQQZg3vfM8bpiNMcvzqIruZPA4b+MRjyHOPqHEPMmIeM8VsZaqJJVSXErQp/q9xJka6JNOzIKA34TjR5WaDJjuHBgNVaftimlPvpeqKTWSQ9UPdw0wh9Fj1fDlGqr8eVs9LhhAx7EKSNgG1lNuJykf5x4fMq/3SQv30wmtQZ...
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:041977924901:test:5b4ab24c-a248-4b55-84ef-7143a86f483f"
}
END
$sns = AWS::SNS::Verify->new(body => $unicode, certificate_string => $cert_string);
ok $sns->verify, 'does unicode message check out';
note "Tampered body doesn't validate";
my $tampered_body = <<END;
{
"Type" : "Notification",
"MessageId" : "1eea0adc-aa9b-5cac-b812-5c933b245eab",
"TopicArn" : "arn:aws:sns:us-east-1:041977924901:test",
author.t/01_verify.t view on Meta::CPAN
"Timestamp" : "2019-11-20T19:09:51.151Z",
"SignatureVersion" : "1",
"Signature" : "mztEsPesQ3OGqhYh2nv1iYPZdsYPUY8bFt5AzbxnbLYwUI5r+tOeQem1slr8LydSATRN0aZfqHW5rl4FXuLLQhtkuhZ2qOony8H6kKTGGf5QXWCIPN/ge3V1hfB+GNpAd2UNg9XqLt3PKZHrlW4aLLHixCUf0Baf/6lfQhHLHyp/HcVjm0VCp1s3MSMBZaFHoQTNoBf/Ur7xUvwYH2OvQNMn854yRnlpa85VI/RABZ7...
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:041977924901:test:5b4ab24c-a248-4b55-84ef-7143a86f483f"
}
END
my $tampered_body_sns = AWS::SNS::Verify->new(body => $tampered_body, certificate_string => $cert_string);
throws_ok(
sub { $tampered_body_sns->verify },
#qr/Could not verify the SES message/,
'Ouch',
"Tampered with body doesn't valiate",
);
note "Invalid cert doesn't validate";
my $invalid_cert_sns = AWS::SNS::Verify->new(body => $body, certificate_string => "Nopes");
throws_ok(
sub { $invalid_cert_sns->verify },
qr/FATAL: invalid or unsupported RSA key format/,
"Invalid cert doesn't valiate",
);
done_testing();
author.t/unicode.t view on Meta::CPAN
"TopicArn" : "arn:aws:sns:us-east-1:041977924901:test",
"Message" : "A Test Banana:\uD83C\uDF4C",
"Timestamp" : "2019-11-20T19:10:09.894Z",
"SignatureVersion" : "1",
"Signature" : "DRcI8zgRFKXD/N679D3v9q8uYEt0HYJYUNQoGsNZ3JF6x5mmoEG2e9u+5MwwS2tkOsvwQQZg3vfM8bpiNMcvzqIruZPA4b+MRjyHOPqHEPMmIeM8VsZaqJJVSXErQp/q9xJka6JNOzIKA34TjR5WaDJjuHBgNVaftimlPvpeqKTWSQ9UPdw0wh9Fj1fDlGqr8eVs9LhhAx7EKSNgG1lNuJykf5x4fMq/3SQv30wmtQZ...
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-6aad65c2f9911b05cd53efda11f913f9.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:041977924901:test:5b4ab24c-a248-4b55-84ef-7143a86f483f"
}
END
my $sns = AWS::SNS::Verify->new(body => $unicode, certificate_string => $cert_string);
ok $sns->verify, 'does unicode message check out';
done_testing();
lib/AWS/SNS/Verify.pm view on Meta::CPAN
}
}
return join("\n", @parts)."\n";
}
sub decode_signature {
my $self = shift;
return decode_base64($self->message->{Signature});
}
sub verify {
my $self = shift;
my $pk = $self->certificate;
unless ($pk->verify_message($self->decode_signature, $self->generate_signature_string, 'SHA1', 'v1.5')) {
ouch 'Bad SNS Signature', 'Could not verify the SNS message from its signature.', $self;
}
return 1;
}
# See also:
# https://github.com/aws/aws-php-sns-message-validator/blob/master/src/MessageValidator.php#L22
sub valid_cert_url {
my $self = shift;
my ($url_string) = @_;
$url_string ||= '';
lib/AWS/SNS/Verify.pm view on Meta::CPAN
AWS::SNS::Verify - Verifies authenticity of SNS messages.
=head1 VERSION
version 0.0105
=head1 SYNOPSIS
my $body = request->body; # example fetch raw body from Dancer
my $sns = AWS::SNS::Verify->new(body => $body);
if ($sns->verify) {
return $sns->message;
}
=head1 DESCRIPTION
This module will parse a message from Amazon Simple Notification Service and validate its signature. This way you know the message came from AWS and not some third-party. More info here: L<http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.ve...
=head1 METHODS
=head2 new
Constructor.
=over
=item body
lib/AWS/SNS/Verify.pm view on Meta::CPAN
If you wish to use a cached version, then pass it in.
=item validate_signing_cert_url (default: true)
If you're using a fake SNS server in your local test environment, the SigningCertURL won't be an AWS endpoint. If so, set validate_signing_cert_url to 0.
Don't ever do this in any kind of Production environment.
=back
=head2 verify
Returns a 1 on success, or die with an L<Ouch> on a failure.
=head2 message
Returns a hash reference of the decoded L<body> that was passed in to the constructor.
=head2 certificate_string
If you want to cache the certificate in a local cache, then get it using this method.
lib/AWS/SNS/Verify.pm view on Meta::CPAN
You should never need to call this, it decodes the base64 signature.
=head2 fetch_certificate
You should never need to call this, it fetches the signing certificate.
=head2 generate_signature_string
You should never need to call this, it generates the signature string required to verify the request.
=head2 valid_cert_url
You should never need to call this, it checks the validity of the certificate signing URL per L<https://github.com/aws/aws-php-sns-message-validator/blob/master/src/MessageValidator.php#L22>
=head1 REQUIREMENTS
Requires Perl 5.12 or higher and these modules:
=over
t/01_verify.t view on Meta::CPAN
}
}
END
my $sns = AWS::SNS::Verify->new(body => $body, certificate_string => $cert_string);
isa_ok($sns, 'AWS::SNS::Verify');
#is($sns->certificate_string, $sns->fetch_certificate, 'loading the certificate ok');
ok $sns->verify, 'does message check out';
note "Tampered body doesn't validate";
my $tampered_body = <<END;
{
"Type" : "Notification",
"MessageId" : "a890c547-5d98-55e2-971d-8826fff56413",
"TopicArn" : "arn:aws:sns:us-east-1:041977924901:foo",
t/01_verify.t view on Meta::CPAN
"MessageAttributes" : {
"AWS.SNS.MOBILE.MPNS.Type" : {"Type":"String","Value":"token"},
"AWS.SNS.MOBILE.WNS.Type" : {"Type":"String","Value":"wns/badge"},
"AWS.SNS.MOBILE.MPNS.NotificationClass" : {"Type":"String","Value":"realtime"}
}
}
END
my $tampered_body_sns = AWS::SNS::Verify->new(body => $tampered_body, certificate_string => $cert_string);
throws_ok(
sub { $tampered_body_sns->verify },
qr/Could not verify the SNS message/,
"Tampered with body doesn't validate",
);
note "Invalid cert doesn't validate";
my $invalid_cert_sns = AWS::SNS::Verify->new(body => $body, certificate_string => "Nopes");
throws_ok(
sub { $invalid_cert_sns->verify },
qr/FATAL: invalid or unsupported RSA key format/,
"Invalid cert doesn't valiate",
);
done_testing();
( run in 0.566 second using v1.01-cache-2.11-cpan-5467b0d2c73 )