Moved generic PGP parsing functions to pgp_utils.[ch]
This commit is contained in:
@@ -6,6 +6,7 @@ AM_CFLAGS = -rdynamic
|
||||
plugin_LTLIBRARIES = libstrongswan-pgp.la
|
||||
|
||||
libstrongswan_pgp_la_SOURCES = pgp_plugin.h pgp_plugin.c \
|
||||
pgp_utils.h pgp_utils.c \
|
||||
pgp_encoder.h pgp_encoder.c \
|
||||
pgp_builder.h pgp_builder.c
|
||||
|
||||
|
||||
@@ -15,141 +15,12 @@
|
||||
*/
|
||||
|
||||
#include "pgp_builder.h"
|
||||
#include "pgp_utils.h"
|
||||
|
||||
#include <enum.h>
|
||||
#include <debug.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
|
||||
typedef enum pgp_pubkey_alg_t pgp_pubkey_alg_t;
|
||||
typedef enum pgp_sym_alg_t pgp_sym_alg_t;
|
||||
|
||||
/**
|
||||
* OpenPGP public key algorithms as defined in section 9.1 of RFC 4880
|
||||
*/
|
||||
enum pgp_pubkey_alg_t {
|
||||
PGP_PUBKEY_ALG_RSA = 1,
|
||||
PGP_PUBKEY_ALG_RSA_ENC_ONLY = 2,
|
||||
PGP_PUBKEY_ALG_RSA_SIGN_ONLY = 3,
|
||||
PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY = 16,
|
||||
PGP_PUBKEY_ALG_DSA = 17,
|
||||
PGP_PUBKEY_ALG_ECC = 18,
|
||||
PGP_PUBKEY_ALG_ECDSA = 19,
|
||||
PGP_PUBKEY_ALG_ELGAMAL = 20,
|
||||
PGP_PUBKEY_ALG_DIFFIE_HELLMAN = 21,
|
||||
};
|
||||
|
||||
/**
|
||||
* OpenPGP symmetric key algorithms as defined in section 9.2 of RFC 4880
|
||||
*/
|
||||
enum pgp_sym_alg_t {
|
||||
PGP_SYM_ALG_PLAIN = 0,
|
||||
PGP_SYM_ALG_IDEA = 1,
|
||||
PGP_SYM_ALG_3DES = 2,
|
||||
PGP_SYM_ALG_CAST5 = 3,
|
||||
PGP_SYM_ALG_BLOWFISH = 4,
|
||||
PGP_SYM_ALG_SAFER = 5,
|
||||
PGP_SYM_ALG_DES = 6,
|
||||
PGP_SYM_ALG_AES_128 = 7,
|
||||
PGP_SYM_ALG_AES_192 = 8,
|
||||
PGP_SYM_ALG_AES_256 = 9,
|
||||
PGP_SYM_ALG_TWOFISH = 10
|
||||
};
|
||||
|
||||
ENUM_BEGIN(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_RSA, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
|
||||
"RSA",
|
||||
"RSA_ENC_ONLY",
|
||||
"RSA_SIGN_ONLY"
|
||||
);
|
||||
ENUM_NEXT(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY, PGP_PUBKEY_ALG_DIFFIE_HELLMAN, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
|
||||
"ELGAMAL_ENC_ONLY",
|
||||
"DSA",
|
||||
"ECC",
|
||||
"ECDSA",
|
||||
"ELGAMAL",
|
||||
"DIFFIE_HELLMAN"
|
||||
);
|
||||
ENUM_END(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_DIFFIE_HELLMAN);
|
||||
|
||||
ENUM(pgp_sym_alg_names, PGP_SYM_ALG_PLAIN, PGP_SYM_ALG_TWOFISH,
|
||||
"PLAINTEXT",
|
||||
"IDEA",
|
||||
"3DES",
|
||||
"CAST5",
|
||||
"BLOWFISH",
|
||||
"SAFER",
|
||||
"DES",
|
||||
"AES_128",
|
||||
"AES_192",
|
||||
"AES_256",
|
||||
"TWOFISH"
|
||||
);
|
||||
|
||||
/**
|
||||
* Read a PGP scalar of bytes length, advance blob
|
||||
*/
|
||||
static bool read_scalar(chunk_t *blob, size_t bytes, u_int32_t *scalar)
|
||||
{
|
||||
u_int32_t res = 0;
|
||||
|
||||
if (bytes > blob->len)
|
||||
{
|
||||
DBG1("PGP data too short to read %d byte scalar", bytes);
|
||||
return FALSE;
|
||||
}
|
||||
while (bytes-- > 0)
|
||||
{
|
||||
res = 256 * res + blob->ptr[0];
|
||||
*blob = chunk_skip(*blob, 1);
|
||||
}
|
||||
*scalar = res;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read length of an PGP old packet length encoding
|
||||
*/
|
||||
static bool old_packet_length(chunk_t *blob, u_int32_t *length)
|
||||
{
|
||||
/* bits 0 and 1 define the packet length type */
|
||||
u_char type;
|
||||
|
||||
if (!blob->len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
type = 0x03 & blob->ptr[0];
|
||||
*blob = chunk_skip(*blob, 1);
|
||||
|
||||
if (type > 2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return read_scalar(blob, type == 0 ? 1 : type * 2, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a PGP MPI, advance blob
|
||||
*/
|
||||
static bool read_mpi(chunk_t *blob, chunk_t *mpi)
|
||||
{
|
||||
u_int32_t bits, bytes;
|
||||
|
||||
if (!read_scalar(blob, 2, &bits))
|
||||
{
|
||||
DBG1("PGP data too short to read MPI length");
|
||||
return FALSE;
|
||||
}
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > blob->len)
|
||||
{
|
||||
DBG1("PGP data too short to read %d byte MPI", bytes);
|
||||
return FALSE;
|
||||
}
|
||||
*mpi = chunk_create(blob->ptr, bytes);
|
||||
*blob = chunk_skip(*blob, bytes);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a generic public key from a PGP packet
|
||||
*/
|
||||
@@ -158,7 +29,7 @@ static public_key_t *parse_public_key(chunk_t blob)
|
||||
u_int32_t alg;
|
||||
public_key_t *key;
|
||||
|
||||
if (!read_scalar(&blob, 1, &alg))
|
||||
if (!pgp_read_scalar(&blob, 1, &alg))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -187,7 +58,7 @@ static public_key_t *parse_rsa_public_key(chunk_t blob)
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (!read_mpi(&blob, &mpi[i]))
|
||||
if (!pgp_read_mpi(&blob, &mpi[i]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -208,12 +79,12 @@ static private_key_t *parse_rsa_private_key(chunk_t blob)
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (!read_mpi(&blob, &mpi[i]))
|
||||
if (!pgp_read_mpi(&blob, &mpi[i]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!read_scalar(&blob, 1, &s2k))
|
||||
if (!pgp_read_scalar(&blob, 1, &s2k))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -230,7 +101,7 @@ static private_key_t *parse_rsa_private_key(chunk_t blob)
|
||||
|
||||
for (i = 2; i < 6; i++)
|
||||
{
|
||||
if (!read_mpi(&blob, &mpi[i]))
|
||||
if (!pgp_read_mpi(&blob, &mpi[i]))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -270,56 +141,37 @@ static bool decrypt_not_allowed(private_key_t *this,
|
||||
static private_key_t *parse_private_key(chunk_t blob)
|
||||
{
|
||||
chunk_t packet;
|
||||
u_char tag, type;
|
||||
u_int32_t len, version, created, days, alg;
|
||||
pgp_packet_tag_t tag;
|
||||
u_int32_t version, created, days, alg;
|
||||
private_key_t *key;
|
||||
|
||||
tag = blob.ptr[0];
|
||||
|
||||
/* bit 7 must be set */
|
||||
if (!(tag & 0x80))
|
||||
{
|
||||
DBG1("invalid packet tag");
|
||||
return NULL;
|
||||
}
|
||||
/* bit 6 set defines new packet format */
|
||||
if (tag & 0x40)
|
||||
{
|
||||
DBG1("new PGP packet format not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = (tag & 0x3C) >> 2;
|
||||
if (!old_packet_length(&blob, &len) || len > blob.len)
|
||||
{
|
||||
DBG1("invalid packet length");
|
||||
return NULL;
|
||||
}
|
||||
packet.len = len;
|
||||
packet.ptr = blob.ptr;
|
||||
blob = chunk_skip(blob, len);
|
||||
|
||||
if (!read_scalar(&packet, 1, &version))
|
||||
if (!pgp_read_packet(&blob, &packet, &tag))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (version < 3 || version > 4)
|
||||
if (!pgp_read_scalar(&packet, 1, &version))
|
||||
{
|
||||
DBG1("OpenPGP packet version V%d not supported", version);
|
||||
return NULL;
|
||||
return FALSE;
|
||||
}
|
||||
if (!read_scalar(&packet, 4, &created))
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
if (!pgp_read_scalar(&packet, 2, &days))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
DBG1("PGP packet version V%d not supported", version);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pgp_read_scalar(&packet, 4, &created))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (version == 3)
|
||||
{
|
||||
if (!read_scalar(&packet, 2, &days))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!read_scalar(&packet, 1, &alg))
|
||||
if (!pgp_read_scalar(&packet, 1, &alg))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pgp_utils.h"
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
ENUM_BEGIN(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_RSA, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
|
||||
"RSA",
|
||||
"RSA_ENC_ONLY",
|
||||
"RSA_SIGN_ONLY"
|
||||
);
|
||||
ENUM_NEXT(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY, PGP_PUBKEY_ALG_DIFFIE_HELLMAN, PGP_PUBKEY_ALG_RSA_SIGN_ONLY,
|
||||
"ELGAMAL_ENC_ONLY",
|
||||
"DSA",
|
||||
"ECC",
|
||||
"ECDSA",
|
||||
"ELGAMAL",
|
||||
"DIFFIE_HELLMAN"
|
||||
);
|
||||
ENUM_END(pgp_pubkey_alg_names, PGP_PUBKEY_ALG_DIFFIE_HELLMAN);
|
||||
|
||||
ENUM(pgp_sym_alg_names, PGP_SYM_ALG_PLAIN, PGP_SYM_ALG_TWOFISH,
|
||||
"PLAINTEXT",
|
||||
"IDEA",
|
||||
"3DES",
|
||||
"CAST5",
|
||||
"BLOWFISH",
|
||||
"SAFER",
|
||||
"DES",
|
||||
"AES_128",
|
||||
"AES_192",
|
||||
"AES_256",
|
||||
"TWOFISH"
|
||||
);
|
||||
|
||||
ENUM_BEGIN(pgp_packet_tag_names, PGP_PKT_RESERVED, PGP_PKT_PUBLIC_SUBKEY,
|
||||
"Reserved",
|
||||
"Public-Key Encrypted Session Key Packet",
|
||||
"Signature Packet",
|
||||
"Symmetric-Key Encrypted Session Key Packet",
|
||||
"One-Pass Signature Packet",
|
||||
"Secret Key Packet",
|
||||
"Public Key Packet",
|
||||
"Secret Subkey Packet",
|
||||
"Compressed Data Packet",
|
||||
"Symmetrically Encrypted Data Packet",
|
||||
"Marker Packet",
|
||||
"Literal Data Packet",
|
||||
"Trust Packet",
|
||||
"User ID Packet",
|
||||
"Public Subkey Packet"
|
||||
);
|
||||
ENUM_NEXT(pgp_packet_tag_names, PGP_PKT_USER_ATTRIBUTE, PGP_PKT_MOD_DETECT_CODE, PGP_PKT_PUBLIC_SUBKEY,
|
||||
"User Attribute Packet",
|
||||
"Sym. Encrypted and Integrity Protected Data Packet",
|
||||
"Modification Detection Code Packet"
|
||||
);
|
||||
ENUM_END(pgp_packet_tag_names, PGP_PKT_MOD_DETECT_CODE);
|
||||
|
||||
/**
|
||||
* Read a PGP scalar of bytes length, advance blob
|
||||
*/
|
||||
bool pgp_read_scalar(chunk_t *blob, size_t bytes, u_int32_t *scalar)
|
||||
{
|
||||
u_int32_t res = 0;
|
||||
|
||||
if (bytes > blob->len)
|
||||
{
|
||||
DBG1("PGP data too short to read %d byte scalar", bytes);
|
||||
return FALSE;
|
||||
}
|
||||
while (bytes-- > 0)
|
||||
{
|
||||
res = 256 * res + blob->ptr[0];
|
||||
*blob = chunk_skip(*blob, 1);
|
||||
}
|
||||
*scalar = res;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a PGP MPI, advance blob
|
||||
*/
|
||||
bool pgp_read_mpi(chunk_t *blob, chunk_t *mpi)
|
||||
{
|
||||
u_int32_t bits, bytes;
|
||||
|
||||
if (!pgp_read_scalar(blob, 2, &bits))
|
||||
{
|
||||
DBG1("PGP data too short to read MPI length");
|
||||
return FALSE;
|
||||
}
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > blob->len)
|
||||
{
|
||||
DBG1("PGP data too short to read %d byte MPI", bytes);
|
||||
return FALSE;
|
||||
}
|
||||
*mpi = chunk_create(blob->ptr, bytes);
|
||||
*blob = chunk_skip(*blob, bytes);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read length of an PGP old packet length encoding
|
||||
*/
|
||||
static bool pgp_old_packet_length(chunk_t *blob, u_int32_t *length)
|
||||
{
|
||||
/* bits 0 and 1 define the packet length type */
|
||||
u_char type;
|
||||
|
||||
if (!blob->len)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
type = 0x03 & blob->ptr[0];
|
||||
*blob = chunk_skip(*blob, 1);
|
||||
|
||||
if (type > 2)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return pgp_read_scalar(blob, type == 0 ? 1 : type * 2, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag)
|
||||
{
|
||||
u_int32_t len;
|
||||
u_char t;
|
||||
|
||||
if (!blob->len)
|
||||
{
|
||||
DBG1("missing input");
|
||||
return FALSE;
|
||||
}
|
||||
t = blob->ptr[0];
|
||||
|
||||
/* bit 7 must be set */
|
||||
if (!(t & 0x80))
|
||||
{
|
||||
DBG1("invalid packet tag");
|
||||
return FALSE;
|
||||
}
|
||||
/* bit 6 set defines new packet format */
|
||||
if (t & 0x40)
|
||||
{
|
||||
DBG1("new PGP packet format not supported");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
t = (t & 0x3C) >> 2;
|
||||
if (!pgp_old_packet_length(blob, &len) || len > blob->len)
|
||||
{
|
||||
DBG1("invalid packet length");
|
||||
return FALSE;
|
||||
}
|
||||
*data = chunk_create(blob->ptr, len);
|
||||
*blob = chunk_skip(*blob, len);
|
||||
*tag = t;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pgp_utils pgp_utils
|
||||
* @{ @ingroup pgp
|
||||
*/
|
||||
|
||||
#ifndef PGP_UTILS_H_
|
||||
#define PGP_UTILS_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef enum pgp_pubkey_alg_t pgp_pubkey_alg_t;
|
||||
typedef enum pgp_sym_alg_t pgp_sym_alg_t;
|
||||
typedef enum pgp_packet_tag_t pgp_packet_tag_t;
|
||||
|
||||
/**
|
||||
* OpenPGP public key algorithms as defined in section 9.1 of RFC 4880
|
||||
*/
|
||||
enum pgp_pubkey_alg_t {
|
||||
PGP_PUBKEY_ALG_RSA = 1,
|
||||
PGP_PUBKEY_ALG_RSA_ENC_ONLY = 2,
|
||||
PGP_PUBKEY_ALG_RSA_SIGN_ONLY = 3,
|
||||
PGP_PUBKEY_ALG_ELGAMAL_ENC_ONLY = 16,
|
||||
PGP_PUBKEY_ALG_DSA = 17,
|
||||
PGP_PUBKEY_ALG_ECC = 18,
|
||||
PGP_PUBKEY_ALG_ECDSA = 19,
|
||||
PGP_PUBKEY_ALG_ELGAMAL = 20,
|
||||
PGP_PUBKEY_ALG_DIFFIE_HELLMAN = 21,
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names of pgp_pubkey_alg_t
|
||||
*/
|
||||
extern enum_name_t *pgp_pubkey_alg_names;
|
||||
|
||||
/**
|
||||
* OpenPGP symmetric key algorithms as defined in section 9.2 of RFC 4880
|
||||
*/
|
||||
enum pgp_sym_alg_t {
|
||||
PGP_SYM_ALG_PLAIN = 0,
|
||||
PGP_SYM_ALG_IDEA = 1,
|
||||
PGP_SYM_ALG_3DES = 2,
|
||||
PGP_SYM_ALG_CAST5 = 3,
|
||||
PGP_SYM_ALG_BLOWFISH = 4,
|
||||
PGP_SYM_ALG_SAFER = 5,
|
||||
PGP_SYM_ALG_DES = 6,
|
||||
PGP_SYM_ALG_AES_128 = 7,
|
||||
PGP_SYM_ALG_AES_192 = 8,
|
||||
PGP_SYM_ALG_AES_256 = 9,
|
||||
PGP_SYM_ALG_TWOFISH = 10
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names of pgp_sym_alg_t
|
||||
*/
|
||||
extern enum_name_t *pgp_sym_alg_names;
|
||||
|
||||
/**
|
||||
* OpenPGP packet tags as defined in section 4.3 of RFC 4880
|
||||
*/
|
||||
enum pgp_packet_tag_t {
|
||||
PGP_PKT_RESERVED = 0,
|
||||
PGP_PKT_PUBKEY_ENC_SESSION_KEY = 1,
|
||||
PGP_PKT_SIGNATURE = 2,
|
||||
PGP_PKT_SYMKEY_ENC_SESSION_KEY = 3,
|
||||
PGP_PKT_ONE_PASS_SIGNATURE_PKT = 4,
|
||||
PGP_PKT_SECRET_KEY = 5,
|
||||
PGP_PKT_PUBLIC_KEY = 6,
|
||||
PGP_PKT_SECRET_SUBKEY = 7,
|
||||
PGP_PKT_COMPRESSED_DATA = 8,
|
||||
PGP_PKT_SYMKEY_ENC_DATA = 9,
|
||||
PGP_PKT_MARKER = 10,
|
||||
PGP_PKT_LITERAL_DATA = 11,
|
||||
PGP_PKT_TRUST = 12,
|
||||
PGP_PKT_USER_ID = 13,
|
||||
PGP_PKT_PUBLIC_SUBKEY = 14,
|
||||
PGP_PKT_USER_ATTRIBUTE = 17,
|
||||
PGP_PKT_SYM_ENC_INT_PROT_DATA = 18,
|
||||
PGP_PKT_MOD_DETECT_CODE = 19
|
||||
};
|
||||
|
||||
/**
|
||||
* Enum names of pgp_packet_tag_t
|
||||
*/
|
||||
extern enum_name_t *pgp_packet_tag_names;
|
||||
|
||||
/**
|
||||
* Parse a PGP encoded MPI.
|
||||
*
|
||||
* @param blob blob to read from, gets advanced
|
||||
* @param mpi parsed MPI value
|
||||
* @return TRUE if MPI parsed successfully
|
||||
*/
|
||||
bool pgp_read_mpi(chunk_t *blob, chunk_t *mpi);
|
||||
|
||||
/**
|
||||
* Parse a PGP encoded Scalar.
|
||||
*
|
||||
* @param blob blob to read from, gets advanced
|
||||
* @param bytes number of bytes the scalar uses for encoding
|
||||
* @param scalar resultin scalar
|
||||
* @return TRUE if scalar parsed successfully
|
||||
*/
|
||||
bool pgp_read_scalar(chunk_t *blob, size_t bytes, u_int32_t *scalar);
|
||||
|
||||
/**
|
||||
* Parse a PGP packet.
|
||||
*
|
||||
* @param blob blob to read from, gets advanced
|
||||
* @param data contained packet data
|
||||
* @param tag tag of the parsed PGP packet
|
||||
* @return TRUE if packet parsed successfully
|
||||
*/
|
||||
bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag);
|
||||
|
||||
#endif /* PGP_UTILS_ @}*/
|
||||
Reference in New Issue
Block a user