Apache2-Authen-OdinAuth

 view release on metacpan or  search on metacpan

lib/Crypt/OdinAuth.pm  view on Meta::CPAN

package Crypt::OdinAuth;

use 5.006;
use strict;
use warnings;

=head1 NAME

Crypt::OdinAuth - Cryptographic calculations for the OdinAuth SSO system

=head1 VERSION

Version 0.2.1

=cut

our $VERSION = '0.2.1';

use Digest;
use Digest::HMAC;
use Digest::SHA256;
use MIME::Base64 qw(encode_base64url decode_base64url);

use constant OLD_COOKIE => 24*60*60; # cookie older than 24h is discarded

=head1 SYNOPSIS

This module exports functions for calculating and verifying signed
cookies for OdinAuth SSO Apache handler.

    use Crypt::OdinAuth;

    Crypt::OdinAuth::hmac_for('secret', 'login_name', 'role1,role2,role3', 1337357387, 'netcat')
    #=> '349b7135f43bd4c0111564960e7d9d583dde0c5c'

    Crypt::OdinAuth::cookie_for('secret', 'login_name', 'role1,role2,role3', 'netcat')
    #=> 'login_name-role1,role2,role3-1337357638-7ec415a6816c8e9dab7b788e1262769ef80af7d8'

=head1 SUBROUTINES

=head2 hmac_for(secret, user, roles, timestamp, user_agent)

=cut
sub hmac_for ($$$$$) {
    my ( $secret, $user, $roles, $ts, $ua ) = @_;
    my $hmac = Digest::HMAC->new($secret, Digest->new("SHA-256"));

    $hmac->add(join(',',
                    encode_base64url($user),
                    encode_base64url($roles),
                    $ts,
                    encode_base64url($ua)));
    return $hmac->hexdigest;
}

=head2 cookie_for(secret, user, roles, user_agent)

=cut

sub cookie_for {
    my ( $secret, $user, $roles, $ua, $ts ) = @_;
    $ts = time() unless defined($ts);

    my $hmac = hmac_for($secret, $user, $roles, $ts, $ua);
    return join(',',
                encode_base64url($user),
                encode_base64url($roles),
                $ts,
                $hmac);
}

=head2 check_cookie(secret, cookie, user_agent)

=cut

sub check_cookie ($$$) {
    my ( $secret, $cookie, $ua ) = @_;

    $cookie =~ /^\s*([a-zA-Z0-9_-]+),([a-zA-Z0-9_-]+),(\d+),([0-9a-f]+)\s*$/
      or die "Wrong cookie format\n";

    my $user = decode_base64url($1);
    my $roles = decode_base64url($2);
    my $ts = $3;
    my $hmac = $4;

    # Use double hmac to prevent timing attacks
    # http://codahale.com/a-lesson-in-timing-attacks/



( run in 0.548 second using v1.01-cache-2.11-cpan-13bb782fe5a )