[Cosm Logo]

Data Signing, Encryption, and Hash Functions


v3HashInit

Syntax

#include "security.h"
s32 v3HashInit( v3_HASH_TMP * tmp, u32 hash_type );

Description

Initialize the temporary structure tmp and setup to perform the data hashing.

See lib/security.* for examples of how to add a new hash algorithms. If you add an algorithm, you should also add a define similar to V3_HASH_SHA1 for users.

Predefined Hash Types

V3_HASH_CRC32
32-bits, for error checking only. CCITT Standard.
V3_HASH_MD5
128-bits, preferred for checksums.
V3_HASH_SHA1
160-bits, preferred for signing hashes.
V3_HASH_MD5SHA1
256-bits, preferred for RSA operations.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_HASH_ERROR_PARAM
The user passed a NULL pointer.
V3_HASH_ERROR_MEMORY
Memory problem.

Example

  v3_HASH_TMP work;

  v3MemSet( &work, v3u64u32( sizeof( v3_HASH_TMP ) ), 0 );

  if ( v3HashInit( &work, V3_HASH_MD5 ) != V3_PASS )
  {
    /* Failed */
    return( V3_FAIL );
  }

v3Hash

Syntax

#include "security.h"
s32 v3Hash( v3_HASH_TMP * tmp, const u8 * const data,
  u64 length );

Description

Feed length bytes of data into the work hash.

Make sure your data has been v3Save'd before using this.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_HASH_ERROR_STATE
Invalid state, wrong order.
V3_HASH_ERROR_PARAM
The user passed a NULL pointer.

Example

  ascii string[2388] = V3_TEST_TEXT_BLOCK;
  v3_HASH_TMP work;

  /* v3HashInit() ... */

  if ( v3Hash( &work, (ascii *) &string, v3u64u32(
    sizeof( string ) ) ) != V3_PASS )
  {
    /* Failed */
    return( V3_FAIL );
  }

v3HashEnd

Syntax

#include "security.h"
s32 v3HashEnd( v3_HASH * hash, v3_HASH_TMP * tmp );

Description

Take the work data and generate the final hash.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_HASH_ERROR_PARAM
The user passed a NULL pointer.
V3_HASH_ERROR_STATE
Invalid state, wrong order.

Example

  v3_HASH_TMP work;
  v3_HASH hash;

  /* v3HashInit() and v3Hash() ... */

  if ( v3HashEnd( &hash, &work ) != V3_PASS )
  {
    /* Failed */
    return( V3_FAIL );
  }

v3HashEq

Syntax

#include "security.h"
s32 v3HashEq( const v3_HASH * hashA, const v3_HASH * hashB );

Description

Check if the hashes are equal.

Return Values

1 if the hashes are equal, or 0 if they are not equal.

Errors

None.

Example

  v3_HASH hashA, hashB;

  /* Fill in the hashes ... */

  if( !v3HashEq( &hashA, &hashB ) )
  {
    /* Hashes are not equal */
  }


v3PRNG

Syntax

#include "security.h"
s32 v3PRNG( v3_PRNG * prng, void * data, u64 length,
  const void * salt, u64 salt_length );

Description

Generate length bytes of deterministic psuedo-random data. Initialization of the generator is done by feeding it salt_length bytes of salt. Any salt fed to the generator will be used before the data is generated, and is also cumulative, so it can be called repeatedly with additional salt to provide more initial randomness. Given the same salt, the same bytes will always come out.

Return Values

V3_PASS on success, or V3_FAIL on failure.

Errors

None.

Example

  v3_PRNG rnd;
  u8 bytes[32];
  v3_time mytime;

  v3MemSet( &rnd, v3u64u32( sizeof( v3_PRNG ) ), 0 );

  /* seed it */
  v3PRNG( &rnd, NULL, v3u64u32( 0 ),
    &mytime, v3u64u32( sizeof( v3_time ) ) );

  /* get some bytes */
  v3PRNG( &rnd, bytes, v3u64u32( sizeof( bytes ) ),
    NULL, v3u64u32( 0 ) );

  /* OR - do both at once */
  v3PRNG( &rnd, bytes, v3u64u32( sizeof( bytes ) ),
    &mytime, v3u64u32( sizeof( v3_time ) ) );

v3EncryptInit

Syntax

#include "security.h"
s32 v3EncryptInit( v3_BUFFER * output, v3_ENCODER_TMP * tmp,
  u32 encryption_type, u32 direction, u32 mode,
  const u8 * key, u32 key_bits, const u8 * iv );

Description

Initializes the output buffer and sets up the temporary data structure tmp needed to perform the type of encryption requested. direction must be either V3_ENCODER_ENCODE (encrypt) or V3_ENCODER_DECODE (decrypt). mode must be one of the modes listed below. All algorithms will use a 128bit block size, and so ECB and CBC modes will always output a multiple of 16 bytes. key should point to key_bits worth of key data. CBC and CFB modes need 16 bytes of iv. Those who need to add additional encryption types should see Encoder Functions as the encryption functions are actually an interface to the encoder functions.

Knowing what you're doing before using encryption functions would be a very good idea.

Do not call v3BufferCreate on output yourself - you still need to v3BufferFree it after you're done with it of course.

Predefined Encryption Types:

V3_CRYPTO_AES
AES - Advanced Encryption Standard (Rijndael), only defined if NO_CRYPTO is not.

Encryption Modes:

V3_CRYPTO_MODE_CFB
8-bit cipher-feedback, for stream data.
V3_CRYPTO_MODE_CBC
Cipher block chainging, for files.
V3_CRYPTO_MODE_ECB
Electronic codebook, for keys and random.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_ENCODER_ERROR_PARAM
Invalid parameter.
V3_ENCODER_ERROR_STATE
Invalid state or functions called in the wrong order.
V3_ENCODER_ERROR_MEMORY
Out of memory problem.
V3_ENCODER_ERROR_FATAL
Fatal algorithm error, call v3EncryptEnd().
V3_ENCODER_ERROR_MODE
Invalid mode or params sent to algorithm.

Example

  v3_BUFFER buf;
  v3_ENCODER_TMP tmp;
  v3_HASH hash;

  v3MemSet( &buf, v3u64u32( sizeof( v3_BUFFER ) ), 0 );
  v3MemSet( &tmp, v3u64u32( sizeof( v3_ENCODER_TMP ) ), 0 );

  /* ... setup hash ... and IV if you have one */

  /* Init encryption */
  if ( v3EncryptInit( &buf, &tmp, V3_CRYPTO_AES,
    V3_ENCODER_ENCODE, V3_CRYPTO_MODE_ECB, &hash, 128, NULL )
    != V3_PASS )
  {
    return( -1 );
  }

v3Encrypt

Syntax

#include "security.h"
s32 v3Encrypt( v3_BUFFER * output, v3_ENCODER_TMP * tmp,
  const void * const data, u64 length );

Description

Feed length bytes of data into the encryption routines. Any encrypted data will be placed into the output buffer but may not be put into the output buffer after every call for some algorithms. ECB and CBC modes will always output multiples of 16 bytes.

Make sure your data has been v3Save'd before using this.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_ENCODER_ERROR_PARAM
Invalid parameter.
V3_ENCODER_ERROR_STATE
Invalid state or functions called in the wrong order.
V3_ENCODER_ERROR_MEMORY
Out of memory problem.
V3_ENCODER_ERROR_FATAL
Fatal algorithm error, call v3EncryptEnd().

Example

  v3_BUFFER buf;
  v3_ENCODER_TMP tmp;
  u8 data[8] = { 0, 1, 2, 3, 3, 3, 3, 4 };
  u32 i;

  /* ... */
  
  for ( i = 0 ; i < 100 ; i++ )
  {
    if ( v3Encrypt( &buf, &tmp, data, v3u64u32( 8 ) ) != V3_PASS )
    {
      return( -2 );
    }
  }

v3EncryptEnd

Syntax

#include "security.h"
s32 v3EncryptEnd( v3_BUFFER * output, v3_ENCODER_TMP * tmp );

Description

Clear any temporary data and put the last of the encrypted data into the buffer. Make sure to empty and v3BufferFree the output buffer of your data after calling this function.

If this function fails, you must call it again. This second call will always succeed and clean up any mess.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_ENCODER_ERROR_PARAM
Invalid parameter.
V3_ENCODER_ERROR_STATE
Invalid state or functions called in the wrong order.
V3_ENCODER_ERROR_FATAL
Fatal algorithm error, call v3EncryptEnd().

Example

  v3_BUFFER buf;
  v3_ENCODER_TMP tmp;

  /* ... */
  
  if ( v3EncryptEnd( &buf, &tmp ) != V3_PASS )
  {
    /* v3EncryptEnd() must be called again on an error */
    v3EncryptEnd( &tmp );

    return( -3 );
  }

  /* empty out the buffer */

  /* then dont forget to free it */
  v3BufferFree( &buf );

v3PKIKeyGen

Syntax

#include "security.h"
s32 v3PKIKeyGen( v3_PKI_KEY * public_key, v3_PKI_KEY * private_key,
  u32 bits, const u8 * rnd_bits, u64 user_id, const ascii * alias,
  v3_time create, v3_time expire,
  void (*callback)( s32, s32, void * ), void * callback_param );

Description

Generate public_key and private_key with a bits bit n. Please read this entire description, as many parameters have special meanings and restrictions. Knowing what you're doing before using any PKI functions would be a very good idea.

bits must be at least 512, and a power of 2. Keys of 1024 bits are now suspected to be breakable by large organizations and governments, and 512 bit keys are breakable with a few computers in a few weeks, so 2048 is the smallest key recommended.

rnd_bits should be bits bits of random data. It is VERY important that the user take great care to make sure that these bits are truely random, and not based on any data such as the time. v3PRNG and v3Entropy are also not enough on their own.

create is the time of key creation and should always be the current time. expire is the expiration time of the keys. v3PKIEncode will not be allowed with an expired key. Most keys should have a lifetime of 1 year.

The user_id on a key has specific ranges and meanings:
0 to 2^31-1: human local ID.
2^31 to 2^32-1: machine local ID.
2^32 to 2^63-1: human global Cosm-assigned ID.
2^63 to 2^64-1: machine global Cosm-assigned ID.
When printed in hex, local IDs are 8 digits, and global ID are 16 digits. Local ID are use within each organization, often something like an employee number, or a customer number for example. Global IDs should not be used to identify people once they are in a local domain, the local ID should be used instead for privacy and security reasons. That something is using a human ID does NOT imply they are an adult that can sign contracts, nor any form of intelligence.

A key is uniquely identified by the bits, user_id, and create. This means that keys should not be generated more then once a second, this should not be a big concern. You should also never generate a key with a user_id you haven't been assigned, because it will not result in a valid key.

alias is a max 15 character ascii string that has no special meaning except to the key's owner as a tool to quickly tell keys apart. No special meaning should be given beyond that.

callback and callback_param provide information on the possibly long key generation process. They work as decribed in v3BNPrimeGen, with the added calls of callback( 3, 0, callback_param ) when the keypair test begins and callback( 4, 0, callback_param ) when the test finishes. Note that 2 primes will be generated during key creation.

The user-relevant (only) elements of v3_PKI_KEY are:

typedef struct
{
  u16 pkt_type;     /* == V3_PKI_PUBLIC or V3_PKI_PRIVATE */
  u16 pkt_version;
  u32 bits;
  s64 create;
  u64 user_id;
  s64 expire;
  ascii alias[16];
  ...
} v3_PKI_KEY;

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid or wrong size.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  void my_progress( s32 type, s32 count, void * param )
  {
    switch( type )
    {
      case 0:
        v3PrintA( "." );
        break;
      case 1:
        v3PrintA( "+" );
        break;
      case 2:
        v3PrintA( "\n" );
        break;
      case 3:
        v3PrintA( "[testing keypair..." );
        break;
      case 4:
        v3PrintA( "]\n" );
        break;
      default:
        break;
    }
  }

  void example( void )
  {
    const ascii alias[16];
    v3_PKI_KEY pub, pri;
    v3_time create, expire;
    u8 rnd_bits[256];

    /* set create, and expire in a year */
    v3SystemClock( &create );
    _V3_SET128( expire, 00000000, 01E13380, 00000000, 00000000 );
    expire = v3s128Add( create, expire );

    /* get user data and carefully construct rnd_bits */

    /* set alias to make a key for at work, employee id = 42 */
    v3StrCopyA( alias, (ascii *) "Salt mines 2002", v3u64u32( 16 ) );

    /* generate a key */
    v3MemSet( &pub, v3u64u32( sizeof( v3_PKI_KEY ) ), 0 );
    v3MemSet( &pri, v3u64u32( sizeof( v3_PKI_KEY ) ), 0 );
    if ( v3PKIKeyGen( &pub, &pri, 2048, rnd_bits,
      v3u64u32( 42 ), alias, create, expire, my_progress, NULL )
      != V3_PASS )
    {
      /* key generation failed */
    }

    /* save the keys, or use them as ephemeral keys */

    /* ... */
  }

v3PKIKeyLoad

Syntax

#include "security.h"
s32 v3PKIKeyLoad( v3_PKI_KEY * key, u64 * bytes_read,
  const u8 * buffer, u64 max_bytes, const v3_HASH * pass_hash );

Description

Load the key from the buffer into key, reading at most max_bytes bytes. bytes_read will be set to the number of bytes that were in the key.

Loading private keys also requires the V3_HASH_MD5SHA1 hash of the users passphrase pass_hash in order to decrypt the private data. When loading a public key pass_hash is ignored.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid or wrong size.
V3_PKI_ERROR_PASSPHRASE
Passphrase hash was incorrect.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_PKI_KEY pub, pri;
  v3_HASH pass_hash;
  u8 save_buf[4096];
  u64 len;

  /* read key from file etc. */

  /* loading a public key */
  if ( v3PKIKeyLoad( &pub, &len, save_buf,
    v3u64u32( sizeof( save_buf ) ), NULL ) != V3_PASS )
  {
    /* Load failed */
  }

  /* hash passphrase into pass_hash with V3_HASH_MD5SHA1 */

  /* loading a private key */
  if ( v3PKIKeyLoad( &pri, &len, save_buf,
    v3u64u32( sizeof( save_buf ) ), &data_hash ) != V3_PASS )
  {
    /* Load failed */
  }

  /* free keys */
  v3PKIKeyFree( &pub );
  v3PKIKeyFree( &pri );

v3PKIKeySave

Syntax

#include "security.h"
s32 v3PKIKeySave( u8 * buffer, u64 * length, const v3_PKI_KEY * key,
  const u64 max_bytes, const u8 * rnd_bytes,
  const v3_HASH * pass_hash );

Description

Save the key key into the buffer, writing at most max_bytes bytes. length will be set to the number of bytes written.

Private keys also requite 16 bytes of random data rnd_bytes, and a hash pass_hash which is the V3_HASH_MD5SHA1 hash of the users passphrase in order to encrypt the private data. When saving a public key these two parameters are ignored.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid or wrong size.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_PKI_KEY pub, pri;
  v3_HASH pass_hash;
  u8 save_buf[4096];
  u64 len;

  /* generate a keypair - if we load keys we dont need to re-save them */
  
  /* saving a public key */
  if ( v3PKIKeySave( save_buf, &len, &pub,
    v3u64u32( sizeof( save_buf ) ), NULL, NULL ) != V3_PASS )
  {
    /* Save failed */
  }

  /* write save_buf to file etc. */

  /* generate 16 random bytes for the rnd_bytes */

  /* hash passphrase into pass_hash with V3_HASH_MD5SHA1 */

  /* saving a private key */
  if ( v3PKIKeySave( save_buf, &len, &pri,
    v3u64u32( sizeof( save_buf ) ), rnd_bits, &pass_hash )
    != V3_PASS )
  {
    /* Save failed */
  }

  /* write save_buf to file etc. */

  /* free keys */
  v3PKIKeyFree( &pub );
  v3PKIKeyFree( &pri );

v3PKIKeyFree

Syntax

#include "security.h"
void v3PKIKeyFree( v3_PKI_KEY * key );

Description

Free all internal key data, and zero the key structure.

Return Values

None.

Errors

None.

Example

  v3_PKI_KEY key;

  v3MemSet( &key, v3u64u32( sizeof( v3_PKI_KEY ) ), 0 );

  /* use the key */

  v3PKIKeyFree( &key );

v3PKISigLoad

Syntax

#include "security.h"
s32 v3PKISigLoad( v3_PKI_SIG * sig, u64 * bytes_read,
  const u8 * buffer, u64 max_bytes );

Description

Load the signature from the buffer into sig, reading at most max_bytes bytes. bytes_read will be set to the number of bytes that were in the signature.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid or wrong size.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_PKI_SIG sig;
  u8 save_buf[4096];
  u64 len;

  if ( v3PKISigLoad( &sig, &len, save_buf, v3u64u32( 4096 ) )
    != V3_PASS )
  {
    /* failure to read signature */
  }

  /* use signature for key or verification */
  
  /* free signature */
  v3PKISigFree( &sig );

v3PKISigSave

Syntax

#include "security.h"
s32 v3PKISigSave( u8 * buffer, u64 * length, const v3_PKI_SIG * sig,
  u64 max_bytes );

Description

Save the signature sig into the buffer, writing at most max_bytes bytes. length will be set to the number of bytes written.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid or wrong size.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_PKI_SIG sig;
  u8 save_buf[4096];
  u64 len;

  /* load or create signature */

  if ( v3PKISigSave( save_buf, &len, &sig, v3u64u32( 4096 ) )
    != V3_PASS )
  {
    /* failure to write signature */
  }

  /* free signature */
  v3PKISigFree( &sig );

v3PKISigFree

Syntax

#include "security.h"
void v3PKISigFree( v3_PKI_SIG * sig );

Description

Free all internal data, and zero the signature structure.

Return Values

V3_PASS on success, or an error code on failure.

Errors

None.

Example

  v3_PKI_SIG sig;

  v3MemSet( &sig, v3u64u32( sizeof( v3_PKI_SIG ) ), 0 );

  /* use the sig */

  v3PKISigFree( &sig );

v3PKIEncode

Syntax

#include "security.h"
s32 v3PKIEncode( v3_PKI_SIG * sig, const v3_HASH * hash,
  v3_time timestamp, u8 type, u8 shared, const v3_PKI_KEY * key );

Description

Use the key to encode the hash data, timestamp (in seconds), type, and shared flag into the signature sig. A signature of type V3_PKI_SIG_MESSAGE needs a public key, all other types need a private key to encode. You should always use V3_HASH_MD5SHA1 to generate the hash for signatures. Care should be taken in chosing the type and shared flag you use.

The user-relevant (only) elements of v3_PKI_SIG are:

typedef struct
{
  u16 pkt_type;     /* == V3_PKI_SIG */
  u16 pkt_version;
  u32 bits;
  s64 create;
  u64 user_id;
  s64 timestamp;
  u8 type;
  u8 shared;
  v3_BN sig;
} v3_PKI_SIG;

Signature Types

V3_PKI_SIG_MESSAGE
Sending hash data to the key owner.
V3_PKI_SIG_SIGN
Signer signs data.
V3_PKI_SIG_KNOWN
Signer untrusted but known data.
V3_PKI_SIG_WEAK
Signer weakly trusts the data.
V3_PKI_SIG_STRONG
Signer strongly trusts the data.
V3_PKI_SIG_TIMESTAMP
Signer says data existed at time only.
V3_PKI_SIG_REVOKE
Signer revokes the matching signature.

Shared Flags

V3_PKI_SHARED_NO
Signatere is valid to signer only.
V3_PKI_SHARED_YES
Signatere is valid to any reader.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_EXPIRED
Key is expired.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_HASH data_hash, sig_hash;
  v3_PKI_KEY pri;
  v3_PKI_SIG sig;
  v3_time sig_time;
  u8 sig_type;
  u8 share;

  /* hash the data into data_hash (use V3_HASH_MD5SHA1) */

  /* load private key into pub with v3PKIKeyLoad() */

  /* get the current time */
  v3SystemClock( &time_now );

  /* Sign the hash */
  if ( v3PKIEncode( &sig, &data_hash, time_now,
    V3_PKI_SIG_SIGN, V3_PKI_SHARED_YES, &pri ) != V3_PASS )
  {
    /* Encoding failed */
  }

  /* save the signature with v3PKISigSave() */

  /* free the key and sig */
  v3PKIKeyFree( &key );
  v3PKISigFree( &sig );

v3PKIDecode

Syntax

#include "security.h"
s32 v3PKIDecode( v3_HASH * hash, v3_time * timestamp, u8 * type,
  u8 * shared, const v3_PKI_SIG * sig, const v3_PKI_KEY * key );

Description

Extract the hash, timestamp, type, and shared flag from the signature sig using the key. A V3_PASS from this function does NOT mean the signature is valid, only that it was decoded correctly. A signature of type V3_PKI_SIG_MESSAGE needs a private key, all other types need a public key to decode.

It is important to understand that the undecoded parameters of a signature (sig.timestamp, sig.type, sig.shared) are MEANINGLESS, because they can be trivially modified by an attacker. Only use the decoded values.

Signature Types

V3_PKI_SIG_MESSAGE
Sending hash data to the key owner.
V3_PKI_SIG_SIGN
Signer signs data.
V3_PKI_SIG_KNOWN
Signer untrusted but known data.
V3_PKI_SIG_WEAK
Signer weakly trusts the data.
V3_PKI_SIG_STRONG
Signer strongly trusts the data.
V3_PKI_SIG_TIMESTAMP
Signer says data existed at time only.
V3_PKI_SIG_REVOKE
Signer revokes the matching signature.

Shared Flags

V3_PKI_SHARED_NO
Signatere is valid to signer only.
V3_PKI_SHARED_YES
Signatere is valid to any reader.

Return Values

V3_PASS on success, or an error code on failure.

Errors

V3_PKI_ERROR_PARAM
Invalid parameter.
V3_PKI_ERROR_MEMORY
Internal error, usually memory.
V3_PKI_ERROR_FORMAT
Key or signature is invalid.
V3_PKI_ERROR_NO_CRYPTO
Compiled with -DNO_CRYPTO.

Example

  v3_HASH data_hash, sig_hash;
  v3_PKI_KEY pub;
  v3_PKI_SIG sig;
  v3_time sig_time;
  u8 sig_type;
  u8 share;

  /* hash the data into data_hash (use V3_HASH_MD5SHA1) */

  /* load public key into pub with v3PKIKeyLoad() */

  /* load the signature into sig with v3PKISigLoad() */

  if ( v3PKIDecode( &sig_hash, &sig_time, &sig_type, &share,
    &sig, &pub ) != V3_PASS )
  {
    /* decode failed */
  }

  /* now verify the signature */
  if ( !v3HashEq( &data_hash, &sig_hash ) )
  {
    /* Signature was not for the data we hashed */
  }

  /*
    sig_time, sig_type, and share are now what
    the signer set them to, and effect what it means.
  */

  v3PKIKeyFree( &key );
  v3PKISigFree( &sig );

© Copyright Mithral Communications & Design Inc. 1995-2003. All rights reserved. Mithral® and Cosm® are trademarks of Mithral Communications & Design Inc.
Document last modified: May 22, 2003