Crypt::OTR - Off-The-Record encryption library for secure instant messaging applications


    use Crypt::OTR;
    # call near the beginning of your program

    # create OTR object, set up callbacks
    my $otr = new Crypt::OTR(
        account_name     => "alice",            # name of account associated with this keypair
        protocol_name    => "my_protocol_name", # e.g. 'AIM'
        max_message_size => 1024,               # how much to fragment
    $otr->set_callback('inject' => \&otr_inject);
    $otr->set_callback('otr_message' => \&otr_system_message);
    $otr->set_callback('verified' => \&otr_verified);
    $otr->set_callback('unverified' => \&otr_unverified);

    # create a context for user "bob"
    $otr->establish("bob");  # calls otr_inject($account_name, $protocol, $dest_account, $message)

    # send a message to bob
    my $plaintext = "hello, bob! this is a message from alice";
    if (my $ciphertext = $otr->encrypt("bob", $plaintext)) {
        $my_app->send_message_to_user("bob", $ciphertext);
    } else {
        warn "Your message was not sent - no encrypted conversation is established\n";

    # called from bob's end
    if (my $plaintext = $otr->decrypt("alice", $ciphertext)) {
        print "alice: $plaintext\n";
    } else {
        warn "We received an encrypted message from alice but were unable to decrypt it\n";

    # done with chats

    # called when OTR is ready to send a message after massaging it.
    # this method should actually transmit $message to $dest_account
    sub otr_inject {
        my ($self, $account_name, $protocol, $dest_account, $message) = @_;
        $my_app->send_message_to_user($dest_account, $message);

    # called to display an OTR control message for a particular user or protocol
    sub otr_system_message {
        my ($self, $account_name, $protocol, $other_user, $otr_message) = @_;
        warn "OTR says: $otr_message\n";
        return 1;

    # called when a verified conversation is established with $from_account
    sub verified {
        my ($self, $from_account) = @_;
        print "Started verified conversation with $from_account\n";

    # called when an unverified conversation is established with $from_account
    sub unverified {
        my ($self, $from_account) = @_;
        print "Started unverified conversation with $from_account\n";


Perl wrapper around libotr - see

This module is experimental and unfinished, not yet recommended for production or important systems.


No namespace pollution will be tolerated.



This method sets up OTR and should be called early at the start of your application, before using any OTR facilities. It is probably unwise to call this more than once.


This method sets up an OTR context for an account on a protocol (e.g. "lindenstacker" on OSCAR (AIM))


 'account_name'     => name of the account in your application

 'protocol'         => string identifying your application

 'max_message_size' => how many bytes messages should be fragmented into

 'config_dir'       => where to store keys and fingerprints, defaults to $ENV{HOME}/.otr
set_callback($event, \&callback)

Set a callback to be called when various events happen:

  inject: Called when establishing a connection, or sending a
  fragmented message. This should send your message over whatever
  communication channel your application is using.

  otr_message: Called when OTR wants to display a notification to the
  user. Return 1 if the message has been displayed, return 0 if you
  want OTR to display the message inline.

  verified: A conncetion has been established and the other party's
  key fingerprint has been verified

  unverified: A connection has been established but the key
  fingerprint has not been verified

  disconnect: Connection has been disconnected

  system_message: OTR has a system message to display to the user

  error: Error message to display

  warning: Warning message to display

  info: Informative message to display

  new_fingerprint: Received a new fingerprint for a user

  smp_request: Identity verification challenge request

Attemps to begin an OTR-encrypted conversation with $user_name. This will call the inject callback with a message containing an OTR connection attempt.

encrypt($user_name, $plaintext)

Encrypts $plaintext for $user_name. Returns undef unless an encrypted message has been generated, in which case it returns that.

decrypt($user_name, $ciphertext)

Decrypt a message from $user_name, returns plaintext if successful, otherwise undef

In list context, returns ($plaintext, $should_discard). If $should_discard is set, you should ignore the message entirely as it is an internal OTR protocol message or message fragment.

start_smp($user_name, $secret, $question)

Start the Socialist Millionaires' Protocol over the current connection, using the given initial secret, and optionally a question to pass to the buddy (not supported).

continue_smp($user_name, $secret)

Continue the Socialist Millionaires' Protocol over the current connection, using the given initial secret


Abort the SMP protocol. Used when malformed or unexpected messages are received.


Ends an encrypted conversation, no new messages from $user_name will be able to be decrypted



- More documentation (always)

- More tests (always)

- Find leaking scalars


Patrick Tierney, <> Mischa Spiegelmock, <>

This module is unfinished, not very tested, and incomplete. Would you like to help make it better? Send an email to one of the authors, we'd love to get more people involved


  Copyright (C) 2010 by Patrick Tierney, Mischa Spiegelmock

    This program is free software: you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see