Crypt-OpenToken

 view release on metacpan or  search on metacpan

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

    $digest->add($fields->{iv})  if ($fields->{iv_len} > 0);
    $digest->add($fields->{key}) if ($fields->{key_len} > 0);
    $digest->add($plaintext);

    return $digest->digest;
}

sub _unpack {
    my ($self, $token_str) = @_;
    use bytes;

    my ($otk, $ver, $cipher, $hmac, $iv, $key, $payload)
        = unpack(TOKEN_PACK, $token_str);
    unless ($otk eq 'OTK') {
        croak "invalid literal identifier in OTK; '$otk'";
    }
    unless ($ver == 1) {
        croak "unsupported OTK version; '$ver'";
    }

    return {
        version     => $ver,
        cipher      => $cipher,
        hmac        => $hmac,
        iv_len      => length($iv),
        iv          => $iv,
        key_len     => length($key),
        key         => $key,
        payload_len => length($payload),
        payload     => $payload,
    };
}

sub _pack {
    my ($self, %fields) = @_;

    # truncate to specified lengths
    for (qw(iv key payload)) {
        substr($fields{$_}, $fields{ $_ . "_len" }) = '';
    }

    my $token_str = pack(TOKEN_PACK,
        'OTK', @fields{qw(version cipher hmac iv key payload)}
    );
    return $token_str;
}

# Custom Base64 decoding; OTK has some oddities in how they encode things
# using Base64.
sub _base64_decode {
    my ($self, $token_str) = @_;

    # fixup: convert trailing "*"s into "="s (OTK specific encoding)
    $token_str =~ s/(\*+)$/'=' x length($1)/e;

    # fixup: convert "_" to "/" (PingId PHP bindings encode this way)
    # fixup: convert "-" to "+" (PingId PHP bindings encode this way)
    $token_str =~ tr{_-}{/+};

    # Base64 decode it, and we're done.
    my $decoded = decode_base64($token_str);
    return $decoded;
}

# Custom Base64 encoding; OTK has some oddities in how they encode things
# using Base64.
sub _base64_encode {
    my ($self, $token_str) = @_;

    # Base64 encode the token string
    my $encoded = encode_base64($token_str, '');

    # fixup: convert "+" to "-" (PingId PHP bindings encode this way)
    # fixup: convert "/" to "_" (PingId PHP bindings encode this way)
    $encoded =~ tr{/+}{_-};

    # fixup: convert trailing "="s to "*"s (OTK specific encoding)
    $encoded =~ s/(\=+)$/'*' x length($1)/e;

    return $encoded;
}

no Moose;

1;

=for stopwords OpenTokens Socialtext PingFederate TripleDES Base64 decrypts merchantability

=head1 NAME

Crypt::OpenToken - Perl implementation of Ping Identity's "OpenToken"

=head1 SYNOPSIS

  use Crypt::OpenToken;

  my $data = {
      foo => 'bar',
      bar => 'baz',
  };

  # create an OpenToken factory based on a given shared password
  my $factory = Crypt::OpenToken->new(password => 'abc123');

  # encrypt a hash-ref of data into an OpenToken.
  my $token_str = $factory->create(
      Crypt::OpenToken::CIPHER_AES128,
      $data,
  );

  # decrypt an OpenToken, check if its valid, and get data back out
  my $token = $factory->parse($token_str);
  if ($token->is_valid) {
      $data = $token->data();
  }

=head1 DESCRIPTION

This module provides a Perl implementation of the "OpenToken" standard as
defined by Ping Identity in their IETF Draft.

=head1 METHODS



( run in 1.039 second using v1.01-cache-2.11-cpan-df04353d9ac )