Example #1
0
/**
 \ingroup Core_Create
\brief Creates an pgp_pk_sesskey_t struct from keydata
\param key Keydata to use
\return pgp_pk_sesskey_t struct
\note It is the caller's responsiblity to free the returned pointer
\note Currently hard-coded to use CAST5
\note Currently hard-coded to use RSA
*/
pgp_pk_sesskey_t *
pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
{
	/*
         * Creates a random session key and encrypts it for the given key
         *
         * Encryption used is PK,
         * can be any, we're hardcoding RSA for now
         */

	const pgp_pubkey_t	*pubkey;
	pgp_pk_sesskey_t	*sesskey;
	pgp_symm_alg_t	 cipher;
	const uint8_t		*id;
	pgp_crypt_t		 cipherinfo;
	uint8_t			*unencoded_m_buf;
	uint8_t			*encoded_m_buf;
	size_t			 sz_encoded_m_buf;

	if (memcmp(key->encid, "\0\0\0\0\0\0\0\0", 8) == 0) {
		pubkey = pgp_get_pubkey(key);
		id = key->sigid;
	} else {
		pubkey = &key->enckey;
		id = key->encid;
	}
	/* allocate unencoded_m_buf here */
	(void) memset(&cipherinfo, 0x0, sizeof(cipherinfo));
	pgp_crypt_any(&cipherinfo,
		cipher = pgp_str_to_cipher((ciphername) ? ciphername : "cast5"));
	unencoded_m_buf = calloc(1, cipherinfo.keysize + 1 + 2);
	if (unencoded_m_buf == NULL) {
		(void) fprintf(stderr,
			"pgp_create_pk_sesskey: can't allocate\n");
		return NULL;
	}
	switch(pubkey->alg) {
	case PGP_PKA_RSA:
		sz_encoded_m_buf = BN_num_bytes(pubkey->key.rsa.n);
		break;
	case PGP_PKA_DSA:
	case PGP_PKA_ELGAMAL:
		sz_encoded_m_buf = BN_num_bytes(pubkey->key.elgamal.p);
		break;
	default:
		sz_encoded_m_buf = 0;
		break;
	}
	if ((encoded_m_buf = calloc(1, sz_encoded_m_buf)) == NULL) {
		(void) fprintf(stderr,
			"pgp_create_pk_sesskey: can't allocate\n");
		free(unencoded_m_buf);
		return NULL;
	}
	if ((sesskey = calloc(1, sizeof(*sesskey))) == NULL) {
		(void) fprintf(stderr,
			"pgp_create_pk_sesskey: can't allocate\n");
		free(unencoded_m_buf);
		free(encoded_m_buf);
		return NULL;
	}
	if (key->type != PGP_PTAG_CT_PUBLIC_KEY) {
		(void) fprintf(stderr,
			"pgp_create_pk_sesskey: bad type\n");
		free(unencoded_m_buf);
		free(encoded_m_buf);
		free(sesskey);
		return NULL;
	}
	sesskey->version = PGP_PKSK_V3;
	(void) memcpy(sesskey->key_id, id, sizeof(sesskey->key_id));

	if (pgp_get_debug_level(__FILE__)) {
		hexdump(stderr, "Encrypting for keyid", id, sizeof(sesskey->key_id));
	}
	switch (pubkey->alg) {
	case PGP_PKA_RSA:
	case PGP_PKA_DSA:
	case PGP_PKA_ELGAMAL:
		break;
	default:
		(void) fprintf(stderr,
			"pgp_create_pk_sesskey: bad pubkey algorithm\n");
		free(unencoded_m_buf);
		free(encoded_m_buf);
		free(sesskey);
		return NULL;
	}
	sesskey->alg = pubkey->alg;

	sesskey->symm_alg = cipher;
	pgp_random(sesskey->key, cipherinfo.keysize);

	if (pgp_get_debug_level(__FILE__)) {
		hexdump(stderr, "sesskey created", sesskey->key,
			cipherinfo.keysize + 1 + 2);
	}
	if (create_unencoded_m_buf(sesskey, &cipherinfo, &unencoded_m_buf[0]) == 0) {
		free(unencoded_m_buf);
		free(encoded_m_buf);
		free(sesskey);
		return NULL;
	}
	if (pgp_get_debug_level(__FILE__)) {
		hexdump(stderr, "uuencoded m buf", unencoded_m_buf, cipherinfo.keysize + 1 + 2);
	}
	encode_m_buf(unencoded_m_buf, cipherinfo.keysize + 1 + 2, pubkey, encoded_m_buf);

	/* and encrypt it */
	switch (key->key.pubkey.alg) {
	case PGP_PKA_RSA:
		if (!pgp_rsa_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey,
				&sesskey->params)) {
			free(unencoded_m_buf);
			free(encoded_m_buf);
			free(sesskey);
			return NULL;
		}
		break;
	case PGP_PKA_DSA:
	case PGP_PKA_ELGAMAL:
		if (!pgp_elgamal_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pubkey,
				&sesskey->params)) {
			free(unencoded_m_buf);
			free(encoded_m_buf);
			free(sesskey);
			return NULL;
		}
		break;
	default:
		/* will not get here - for lint only */
		break;
	}
	free(unencoded_m_buf);
	free(encoded_m_buf);
	return sesskey;
}
Example #2
0
/**
 \ingroup Core_Create
\brief Creates an ops_pk_session_key_t struct from keydata
\param key Keydata to use
\return ops_pk_session_key_t struct
\note It is the caller's responsiblity to free the returned pointer. Before freeing,
      the key must be cleared by calling ops_pk_session_key_free()
\note Currently hard-coded to use CAST5
\note Currently hard-coded to use RSA
*/
ops_pk_session_key_t *ops_create_pk_session_key(const ops_keydata_t *key)
    {
    /*
     * Creates a random session key and encrypts it for the given key
     *
     * Session Key is for use with a SK algo, 
     * can be any, we're hardcoding CAST5 for now
     *
     * Encryption used is PK, 
     * can be any, we're hardcoding RSA for now
     */

    const ops_public_key_t* pub_key=ops_get_public_key_from_data(key);
#define SZ_UNENCODED_M_BUF CAST_KEY_LENGTH+1+2
    unsigned char unencoded_m_buf[SZ_UNENCODED_M_BUF];

    const size_t sz_encoded_m_buf=BN_num_bytes(pub_key->key.rsa.n);
    unsigned char* encoded_m_buf = ops_mallocz(sz_encoded_m_buf);

    ops_pk_session_key_t *session_key=ops_mallocz(sizeof *session_key);

    assert(key->type == OPS_PTAG_CT_PUBLIC_KEY);
    session_key->version=OPS_PKSK_V3;
    memcpy(session_key->key_id, key->key_id, sizeof session_key->key_id);

    if (debug)
        {
        unsigned int i=0;
        fprintf(stderr,"Encrypting for RSA key id : ");
        for (i=0; i<sizeof session_key->key_id; i++)
            fprintf(stderr,"%2x ", key->key_id[i]);
        fprintf(stderr,"\n");
        }

    assert(key->key.pkey.algorithm == OPS_PKA_RSA);
    session_key->algorithm=key->key.pkey.algorithm;

    // \todo allow user to specify other algorithm
    session_key->symmetric_algorithm=OPS_SA_CAST5;
    ops_random(session_key->key, CAST_KEY_LENGTH);

    if (debug)
        {
        unsigned int i=0;
        fprintf(stderr,"CAST5 session key created (len=%d):\n ",
		CAST_KEY_LENGTH);
        for (i=0; i<CAST_KEY_LENGTH; i++)
            fprintf(stderr,"%2x ", session_key->key[i]);
        fprintf(stderr,"\n");
        }

    if (create_unencoded_m_buf(session_key, &unencoded_m_buf[0])==ops_false)
        {
        free(encoded_m_buf);
        return NULL;
        }

    if (debug)
        {
        unsigned int i=0;
        printf("unencoded m buf:\n");
        for (i=0; i<SZ_UNENCODED_M_BUF; i++)
            printf("%2x ", unencoded_m_buf[i]);
        printf("\n");
        }
    encode_m_buf(&unencoded_m_buf[0], SZ_UNENCODED_M_BUF, pub_key,
		 &encoded_m_buf[0]);
    
    // and encrypt it
    if(!ops_rsa_encrypt_mpi(encoded_m_buf, sz_encoded_m_buf, pub_key,
			    &session_key->parameters))
        {
        free (encoded_m_buf);
        return NULL;
        }

    free(encoded_m_buf);
    return session_key;
    }