Skip to main content

cpp_expire_key.cpp

#include <memory>
#include <cstdio>
#include <teconnection.h>
#include <teexception.h>
#include <tekey.h>
#include <iostream>

// Expire a key, then remove it, and show what each does to the next decrypt.
//
// An EXPIRED key keeps its record -- its access control list is still readable -- and every
// later use of it is refused with ERR_KEY_EXPIRED (0x0406). A REMOVED key is gone from this
// key server: its next use is refused with ERR_NO_SUCH_KEY (0x0404). The caller needs the
// Encryptor role's "Expire Key" and the OWNER right on the key (the key's creator has it).

static void printCode(const char* what, uint32_t code)
{
char b[16];
snprintf(b, sizeof b, "0x%04x", (unsigned)code);
_TESTD cout << what << b << _TESTD endl;
}

// Decrypt `encrypted` under `hl`; returns 0 when it decrypted, otherwise the refusal's code.
static uint32_t tryDecrypt(PISOFT::TEKey& agent, const _TESTD string& encrypted,
const _TESTD string& hl, const _TESTD string& iv)
{
_TESTD string data = encrypted;
try {
agent.decryptData (data, hl, iv);
return 0;
} catch (PISOFT::TEException& ex) {
return ex.getServerErrorCode();
}
}

int main (int argc, char* argv[])
{
if (argc < 3) {
_TESTD cerr << "usage: " << argv[0] << " username password [server [port]]" << _TESTD endl;
return 1;
}

_TESTD string username = argv[1];
_TESTD string password = argv[2];
_TESTD string host = "localhost";
int port = 8888;
if (argc > 3) {
host = argv[3];
if (argc > 4) {
port = atoi (argv[4]);
}
}

try {
std::unique_ptr<PISOFT::TEConnection> conn =
PISOFT::TEConnection::createInstance (PISOFT::TEConnection::SecureConnection);
conn->open (host, port, username, password);

PISOFT::TEKey agent;
agent.attachConnection (conn.get());

_TESTD string data = "Test Data";
_TESTD string hl, iv;
agent.encryptData (data, hl, iv);
_TESTD string encrypted = data;
agent.decryptData (data, hl, iv);
_TESTD cout << "decrypted: " << data << _TESTD endl;

// Expire: one result per key, in request order.
_TESTD string* hlptr = &hl;
uint32_t result = PISOFT::TEKey::RESULT_UNKNOWN;
agent.expireKey (&hlptr, 1, &result);
if (result != PISOFT::TEKey::RESULT_EXPIRED) {
printCode ("Failed, expireKey answered ", result);
return 1;
}
_TESTD cout << "expired" << _TESTD endl;

uint32_t code = tryDecrypt (agent, encrypted, hl, iv);
if (code != PISOFT::TEKey::CODE_KEY_EXPIRED) {
printCode ("Failed, a decrypt under the expired key answered ", code);
return 1;
}
printCode ("decrypt refused, the key is expired: ", code);

// Remove: the key, its access control list and every cached copy are deleted.
agent.removeKey (&hlptr, 1, &result);
if (result != PISOFT::TEKey::RESULT_REMOVED) {
printCode ("Failed, removeKey answered ", result);
return 1;
}
_TESTD cout << "removed" << _TESTD endl;

code = tryDecrypt (agent, encrypted, hl, iv);
if (code != PISOFT::TEKey::CODE_NO_SUCH_KEY) {
printCode ("Failed, a decrypt under the removed key answered ", code);
return 1;
}
printCode ("decrypt refused, no such key: ", code);
agent.detachConnection ();

_TESTD cout << "Done!" << _TESTD endl;
return 0;

} catch (PISOFT::TEException& ex) {
_TESTD cout << "Failed!" << _TESTD endl;
_TESTD cerr << ex.getAllMessages() << _TESTD endl;
return 1;
}
}