diff options
author | Nvinside <Nvinside@eced67a3-f377-a0ae-92ae-d6de1850b05a> | 2010-09-28 21:16:09 +0000 |
---|---|---|
committer | Nvinside <Nvinside@eced67a3-f377-a0ae-92ae-d6de1850b05a> | 2010-09-28 21:16:09 +0000 |
commit | 13988df650ab3b6f4909161d1f7cedac4f393a0f (patch) | |
tree | 1b63cef77b260d21b61bf4a7c8ebf717e99284c5 /libotr-3.2.0/src | |
parent | c797e6fa50865060670b9d1b8db497a1f2335b77 (diff) |
This is part 2 of 4, this also fixes some x64 errors, warnings and allow you to build a full debug unicode
huuuuuge tipo fixes
warning fixed (not all but many for this time)
Prepare for a gpg-error change
Support of ia32 AES instructions
gpg error change
Msvc compiler fixes
Allow transient-key for ecdsa (würg-grund :D )
spelling fixes
added new trigger events
add a entropy gatherer for W32CE and some other stuff
gcc fixes
boooooooooooooost performance of SHA-512 and SHA-256 ...
unfortunately that is all ;( ..... some work i'll be add maybe later this week
git-svn-id: http://mirotr.googlecode.com/svn/trunk@38 eced67a3-f377-a0ae-92ae-d6de1850b05a
Diffstat (limited to 'libotr-3.2.0/src')
-rw-r--r-- | libotr-3.2.0/src/auth.c | 2034 | ||||
-rw-r--r-- | libotr-3.2.0/src/auth.h | 66 | ||||
-rw-r--r-- | libotr-3.2.0/src/context.c | 332 | ||||
-rw-r--r-- | libotr-3.2.0/src/message.c | 1420 | ||||
-rw-r--r-- | libotr-3.2.0/src/privkey.c | 688 |
5 files changed, 2270 insertions, 2270 deletions
diff --git a/libotr-3.2.0/src/auth.c b/libotr-3.2.0/src/auth.c index a6752c3..de69645 100644 --- a/libotr-3.2.0/src/auth.c +++ b/libotr-3.2.0/src/auth.c @@ -33,27 +33,27 @@ */ void otrl_auth_new(OtrlAuthInfo *auth) { - auth->authstate = OTRL_AUTHSTATE_NONE; - otrl_dh_keypair_init(&(auth->our_dh)); - auth->our_keyid = 0; - auth->encgx = NULL; - auth->encgx_len = 0; - memset(auth->r, 0, 16); - memset(auth->hashgx, 0, 32); - auth->their_pub = NULL; - auth->their_keyid = 0; - auth->enc_c = NULL; - auth->enc_cp = NULL; - auth->mac_m1 = NULL; - auth->mac_m1p = NULL; - auth->mac_m2 = NULL; - auth->mac_m2p = NULL; - memset(auth->their_fingerprint, 0, 20); - auth->initiated = 0; - auth->protocol_version = 0; - memset(auth->secure_session_id, 0, 20); - auth->secure_session_id_len = 0; - auth->lastauthmsg = NULL; + auth->authstate = OTRL_AUTHSTATE_NONE; + otrl_dh_keypair_init(&(auth->our_dh)); + auth->our_keyid = 0; + auth->encgx = NULL; + auth->encgx_len = 0; + memset(auth->r, 0, 16); + memset(auth->hashgx, 0, 32); + auth->their_pub = NULL; + auth->their_keyid = 0; + auth->enc_c = NULL; + auth->enc_cp = NULL; + auth->mac_m1 = NULL; + auth->mac_m1p = NULL; + auth->mac_m2 = NULL; + auth->mac_m2p = NULL; + memset(auth->their_fingerprint, 0, 20); + auth->initiated = 0; + auth->protocol_version = 0; + memset(auth->secure_session_id, 0, 20); + auth->secure_session_id_len = 0; + auth->lastauthmsg = NULL; } /* @@ -61,36 +61,36 @@ void otrl_auth_new(OtrlAuthInfo *auth) */ void otrl_auth_clear(OtrlAuthInfo *auth) { - auth->authstate = OTRL_AUTHSTATE_NONE; - otrl_dh_keypair_free(&(auth->our_dh)); - auth->our_keyid = 0; - free(auth->encgx); - auth->encgx = NULL; - auth->encgx_len = 0; - memset(auth->r, 0, 16); - memset(auth->hashgx, 0, 32); - gcry_mpi_release(auth->their_pub); - auth->their_pub = NULL; - auth->their_keyid = 0; - gcry_cipher_close(auth->enc_c); - gcry_cipher_close(auth->enc_cp); - gcry_md_close(auth->mac_m1); - gcry_md_close(auth->mac_m1p); - gcry_md_close(auth->mac_m2); - gcry_md_close(auth->mac_m2p); - auth->enc_c = NULL; - auth->enc_cp = NULL; - auth->mac_m1 = NULL; - auth->mac_m1p = NULL; - auth->mac_m2 = NULL; - auth->mac_m2p = NULL; - memset(auth->their_fingerprint, 0, 20); - auth->initiated = 0; - auth->protocol_version = 0; - memset(auth->secure_session_id, 0, 20); - auth->secure_session_id_len = 0; - free(auth->lastauthmsg); - auth->lastauthmsg = NULL; + auth->authstate = OTRL_AUTHSTATE_NONE; + otrl_dh_keypair_free(&(auth->our_dh)); + auth->our_keyid = 0; + free(auth->encgx); + auth->encgx = NULL; + auth->encgx_len = 0; + memset(auth->r, 0, 16); + memset(auth->hashgx, 0, 32); + gcry_mpi_release(auth->their_pub); + auth->their_pub = NULL; + auth->their_keyid = 0; + gcry_cipher_close(auth->enc_c); + gcry_cipher_close(auth->enc_cp); + gcry_md_close(auth->mac_m1); + gcry_md_close(auth->mac_m1p); + gcry_md_close(auth->mac_m2); + gcry_md_close(auth->mac_m2p); + auth->enc_c = NULL; + auth->enc_cp = NULL; + auth->mac_m1 = NULL; + auth->mac_m1p = NULL; + auth->mac_m2 = NULL; + auth->mac_m2p = NULL; + memset(auth->their_fingerprint, 0, 20); + auth->initiated = 0; + auth->protocol_version = 0; + memset(auth->secure_session_id, 0, 20); + auth->secure_session_id_len = 0; + free(auth->lastauthmsg); + auth->lastauthmsg = NULL; } /* @@ -100,96 +100,96 @@ void otrl_auth_clear(OtrlAuthInfo *auth) */ gcry_error_t otrl_auth_start_v2(OtrlAuthInfo *auth) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - size_t npub; - gcry_cipher_hd_t enc = NULL; - unsigned char ctr[16]; - unsigned char *buf, *bufp; - size_t buflen, lenp; - - /* Clear out this OtrlAuthInfo and start over */ - otrl_auth_clear(auth); - auth->initiated = 1; - - otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); - auth->our_keyid = 1; - - /* Pick an encryption key */ - gcry_randomize(auth->r, 16, GCRY_STRONG_RANDOM); - - /* Allocate space for the encrypted g^x */ - gcry_mpi_print(format, NULL, 0, &npub, auth->our_dh.pub); - auth->encgx = malloc(4+npub); - if (auth->encgx == NULL) goto memerr; - auth->encgx_len = 4+npub; - bufp = auth->encgx; - lenp = auth->encgx_len; - write_mpi(auth->our_dh.pub, npub, "g^x"); - assert(lenp == 0); - - /* Hash g^x */ - gcry_md_hash_buffer(GCRY_MD_SHA256, auth->hashgx, auth->encgx, - auth->encgx_len); - - /* Encrypt g^x using the key r */ - err = gcry_cipher_open(&enc, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, - GCRY_CIPHER_SECURE); - if (err) goto err; - - err = gcry_cipher_setkey(enc, auth->r, 16); - if (err) goto err; - - memset(ctr, 0, 16); - err = gcry_cipher_setctr(enc, ctr, 16); - if (err) goto err; - - err = gcry_cipher_encrypt(enc, auth->encgx, auth->encgx_len, NULL, 0); - if (err) goto err; - - gcry_cipher_close(enc); - enc = NULL; - - /* Now serialize the message */ - lenp = 3 + 4 + auth->encgx_len + 4 + 32; - bufp = malloc(lenp); - if (bufp == NULL) goto memerr; - buf = bufp; - buflen = lenp; - - memmove(bufp, "\x00\x02\x02", 3); /* header */ - debug_data("Header", bufp, 3); - bufp += 3; lenp -= 3; - - /* Encrypted g^x */ - write_int(auth->encgx_len); - debug_int("Enc gx len", bufp-4); - memmove(bufp, auth->encgx, auth->encgx_len); - debug_data("Enc gx", bufp, auth->encgx_len); - bufp += auth->encgx_len; lenp -= auth->encgx_len; - - /* Hashed g^x */ - write_int(32); - debug_int("hashgx len", bufp-4); - memmove(bufp, auth->hashgx, 32); - debug_data("hashgx", bufp, 32); - bufp += 32; lenp -= 32; - - assert(lenp == 0); - - auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); - free(buf); - if (auth->lastauthmsg == NULL) goto memerr; - auth->authstate = OTRL_AUTHSTATE_AWAITING_DHKEY; - - return err; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + size_t npub; + gcry_cipher_hd_t enc = NULL; + unsigned char ctr[16]; + unsigned char *buf, *bufp; + size_t buflen, lenp; + + /* Clear out this OtrlAuthInfo and start over */ + otrl_auth_clear(auth); + auth->initiated = 1; + + otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); + auth->our_keyid = 1; + + /* Pick an encryption key */ + gcry_randomize(auth->r, 16, GCRY_STRONG_RANDOM); + + /* Allocate space for the encrypted g^x */ + gcry_mpi_print(format, NULL, 0, &npub, auth->our_dh.pub); + auth->encgx = malloc(4+npub); + if (auth->encgx == NULL) goto memerr; + auth->encgx_len = 4+npub; + bufp = auth->encgx; + lenp = auth->encgx_len; + write_mpi(auth->our_dh.pub, npub, "g^x"); + assert(lenp == 0); + + /* Hash g^x */ + gcry_md_hash_buffer(GCRY_MD_SHA256, auth->hashgx, auth->encgx, + auth->encgx_len); + + /* Encrypt g^x using the key r */ + err = gcry_cipher_open(&enc, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, + GCRY_CIPHER_SECURE); + if (err) goto err; + + err = gcry_cipher_setkey(enc, auth->r, 16); + if (err) goto err; + + memset(ctr, 0, 16); + err = gcry_cipher_setctr(enc, ctr, 16); + if (err) goto err; + + err = gcry_cipher_encrypt(enc, auth->encgx, auth->encgx_len, NULL, 0); + if (err) goto err; + + gcry_cipher_close(enc); + enc = NULL; + + /* Now serialize the message */ + lenp = 3 + 4 + auth->encgx_len + 4 + 32; + bufp = malloc(lenp); + if (bufp == NULL) goto memerr; + buf = bufp; + buflen = lenp; + + memmove(bufp, "\x00\x02\x02", 3); /* header */ + debug_data("Header", bufp, 3); + bufp += 3; lenp -= 3; + + /* Encrypted g^x */ + write_int(auth->encgx_len); + debug_int("Enc gx len", bufp-4); + memmove(bufp, auth->encgx, auth->encgx_len); + debug_data("Enc gx", bufp, auth->encgx_len); + bufp += auth->encgx_len; lenp -= auth->encgx_len; + + /* Hashed g^x */ + write_int(32); + debug_int("hashgx len", bufp-4); + memmove(bufp, auth->hashgx, 32); + debug_data("hashgx", bufp, 32); + bufp += 32; lenp -= 32; + + assert(lenp == 0); + + auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); + free(buf); + if (auth->lastauthmsg == NULL) goto memerr; + auth->authstate = OTRL_AUTHSTATE_AWAITING_DHKEY; + + return err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - otrl_auth_clear(auth); - gcry_cipher_close(enc); - return err; + otrl_auth_clear(auth); + gcry_cipher_close(enc); + return err; } /* @@ -198,38 +198,38 @@ err: */ static gcry_error_t create_key_message(OtrlAuthInfo *auth) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - unsigned char *buf, *bufp; - size_t buflen, lenp; - size_t npub; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + unsigned char *buf, *bufp; + size_t buflen, lenp; + size_t npub; - gcry_mpi_print(format, NULL, 0, &npub, auth->our_dh.pub); - buflen = 3 + 4 + npub; - buf = malloc(buflen); - if (buf == NULL) goto memerr; - bufp = buf; - lenp = buflen; + gcry_mpi_print(format, NULL, 0, &npub, auth->our_dh.pub); + buflen = 3 + 4 + npub; + buf = malloc(buflen); + if (buf == NULL) goto memerr; + bufp = buf; + lenp = buflen; - memmove(bufp, "\x00\x02\x0a", 3); /* header */ - debug_data("Header", bufp, 3); - bufp += 3; lenp -= 3; + memmove(bufp, "\x00\x02\x0a", 3); /* header */ + debug_data("Header", bufp, 3); + bufp += 3; lenp -= 3; - /* g^y */ - write_mpi(auth->our_dh.pub, npub, "g^y"); + /* g^y */ + write_mpi(auth->our_dh.pub, npub, "g^y"); - assert(lenp == 0); + assert(lenp == 0); - free(auth->lastauthmsg); - auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); - free(buf); - if (auth->lastauthmsg == NULL) goto memerr; + free(auth->lastauthmsg); + auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); + free(buf); + if (auth->lastauthmsg == NULL) goto memerr; - return err; + return err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); - return err; + err = gcry_error(GPG_ERR_ENOMEM); + return err; } /* @@ -240,73 +240,73 @@ memerr: gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, const char *commitmsg) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp = NULL, *encbuf = NULL; - unsigned char hashbuf[32]; - size_t buflen, lenp, enclen, hashlen; - int res; - - res = otrl_base64_otr_decode(commitmsg, &buf, &buflen); - if (res == -1) goto memerr; - if (res == -2) goto invval; - - bufp = buf; - lenp = buflen; - - /* Header */ - require_len(3); - if (memcmp(bufp, "\x00\x02\x02", 3)) goto invval; - bufp += 3; lenp -= 3; - - /* Encrypted g^x */ - read_int(enclen); - require_len(enclen); - encbuf = malloc(enclen); - if (encbuf == NULL && enclen > 0) goto memerr; - memmove(encbuf, bufp, enclen); - bufp += enclen; lenp -= enclen; - - /* Hashed g^x */ - read_int(hashlen); - if (hashlen != 32) goto invval; - require_len(32); - memmove(hashbuf, bufp, 32); - bufp += 32; lenp -= 32; - - if (lenp != 0) goto invval; - free(buf); - buf = NULL; - - switch(auth->authstate) { + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp = NULL, *encbuf = NULL; + unsigned char hashbuf[32]; + size_t buflen, lenp, enclen, hashlen; + int res; + + res = otrl_base64_otr_decode(commitmsg, &buf, &buflen); + if (res == -1) goto memerr; + if (res == -2) goto invval; + + bufp = buf; + lenp = buflen; + + /* Header */ + require_len(3); + if (memcmp(bufp, "\x00\x02\x02", 3)) goto invval; + bufp += 3; lenp -= 3; + + /* Encrypted g^x */ + read_int(enclen); + require_len(enclen); + encbuf = malloc(enclen); + if (encbuf == NULL && enclen > 0) goto memerr; + memmove(encbuf, bufp, enclen); + bufp += enclen; lenp -= enclen; + + /* Hashed g^x */ + read_int(hashlen); + if (hashlen != 32) goto invval; + require_len(32); + memmove(hashbuf, bufp, 32); + bufp += 32; lenp -= 32; + + if (lenp != 0) goto invval; + free(buf); + buf = NULL; + + switch(auth->authstate) { case OTRL_AUTHSTATE_NONE: case OTRL_AUTHSTATE_AWAITING_SIG: case OTRL_AUTHSTATE_V1_SETUP: - /* Store the incoming information */ - otrl_auth_clear(auth); - otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); - auth->our_keyid = 1; - auth->encgx = encbuf; - encbuf = NULL; - auth->encgx_len = enclen; - memmove(auth->hashgx, hashbuf, 32); + /* Store the incoming information */ + otrl_auth_clear(auth); + otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); + auth->our_keyid = 1; + auth->encgx = encbuf; + encbuf = NULL; + auth->encgx_len = enclen; + memmove(auth->hashgx, hashbuf, 32); - /* Create a D-H Key Message */ - err = create_key_message(auth); - if (err) goto err; - auth->authstate = OTRL_AUTHSTATE_AWAITING_REVEALSIG; + /* Create a D-H Key Message */ + err = create_key_message(auth); + if (err) goto err; + auth->authstate = OTRL_AUTHSTATE_AWAITING_REVEALSIG; - break; + break; case OTRL_AUTHSTATE_AWAITING_DHKEY: - /* We sent a D-H Commit Message, and we also received one - * back. Compare the hashgx values to see which one wins. */ - if (memcmp(auth->hashgx, hashbuf, 32) > 0) { + /* We sent a D-H Commit Message, and we also received one + * back. Compare the hashgx values to see which one wins. */ + if (memcmp(auth->hashgx, hashbuf, 32) > 0) { /* Ours wins. Ignore the message we received, and just * resend the same D-H Commit message again. */ free(encbuf); encbuf = NULL; - } else { + } else { /* Ours loses. Use the incoming parameters instead. */ otrl_auth_clear(auth); otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); @@ -320,30 +320,30 @@ gcry_error_t otrl_auth_handle_commit(OtrlAuthInfo *auth, err = create_key_message(auth); if (err) goto err; auth->authstate = OTRL_AUTHSTATE_AWAITING_REVEALSIG; - } - break; + } + break; case OTRL_AUTHSTATE_AWAITING_REVEALSIG: - /* Use the incoming parameters, but just retransmit the old - * D-H Key Message. */ - free(auth->encgx); - auth->encgx = encbuf; - encbuf = NULL; - auth->encgx_len = enclen; - memmove(auth->hashgx, hashbuf, 32); - break; - } - - return err; + /* Use the incoming parameters, but just retransmit the old + * D-H Key Message. */ + free(auth->encgx); + auth->encgx = encbuf; + encbuf = NULL; + auth->encgx_len = enclen; + memmove(auth->hashgx, hashbuf, 32); + break; + } + + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(encbuf); - return err; + free(buf); + free(encbuf); + return err; } /* @@ -358,92 +358,92 @@ static gcry_error_t calculate_pubkey_auth(unsigned char **authbufp, gcry_mpi_t our_dh_pub, gcry_mpi_t their_dh_pub, OtrlPrivKey *privkey, unsigned int keyid) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - size_t ourpublen, theirpublen, totallen, lenp; - unsigned char *buf = NULL, *bufp = NULL; - unsigned char macbuf[32]; - unsigned char *sigbuf = NULL; - size_t siglen; - - /* How big are the DH public keys? */ - gcry_mpi_print(format, NULL, 0, &ourpublen, our_dh_pub); - gcry_mpi_print(format, NULL, 0, &theirpublen, their_dh_pub); - - /* How big is the total structure to be MAC'd? */ - totallen = 4 + ourpublen + 4 + theirpublen + 2 + privkey->pubkey_datalen + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + size_t ourpublen, theirpublen, totallen, lenp; + unsigned char *buf = NULL, *bufp = NULL; + unsigned char macbuf[32]; + unsigned char *sigbuf = NULL; + size_t siglen; + + /* How big are the DH public keys? */ + gcry_mpi_print(format, NULL, 0, &ourpublen, our_dh_pub); + gcry_mpi_print(format, NULL, 0, &theirpublen, their_dh_pub); + + /* How big is the total structure to be MAC'd? */ + totallen = 4 + ourpublen + 4 + theirpublen + 2 + privkey->pubkey_datalen + 4; - buf = malloc(totallen); - if (buf == NULL) goto memerr; - - bufp = buf; - lenp = totallen; - - /* Write the data to be MAC'd */ - write_mpi(our_dh_pub, ourpublen, "Our DH pubkey"); - write_mpi(their_dh_pub, theirpublen, "Their DH pubkey"); - bufp[0] = ((privkey->pubkey_type) >> 16) & 0xff; - bufp[1] = (privkey->pubkey_type) & 0xff; - bufp += 2; lenp -= 2; - memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); - debug_data("Pubkey", bufp, privkey->pubkey_datalen); - bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; - write_int(keyid); - debug_int("Keyid", bufp-4); - - assert(lenp == 0); - - /* Do the MAC */ - gcry_md_reset(mackey); - gcry_md_write(mackey, buf, totallen); - memmove(macbuf, gcry_md_read(mackey, GCRY_MD_SHA256), 32); - - free(buf); - buf = NULL; - - /* Sign the MAC */ - err = otrl_privkey_sign(&sigbuf, &siglen, privkey, macbuf, 32); - if (err) goto err; - - /* Calculate the total size of the structure to be encrypted */ - totallen = 2 + privkey->pubkey_datalen + 4 + siglen; - buf = malloc(totallen); - if (buf == NULL) goto memerr; - bufp = buf; - lenp = totallen; - - /* Write the data to be encrypted */ - bufp[0] = ((privkey->pubkey_type) >> 16) & 0xff; - bufp[1] = (privkey->pubkey_type) & 0xff; - bufp += 2; lenp -= 2; - memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); - debug_data("Pubkey", bufp, privkey->pubkey_datalen); - bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; - write_int(keyid); - debug_int("Keyid", bufp-4); - memmove(bufp, sigbuf, siglen); - debug_data("Signature", bufp, siglen); - bufp += siglen; lenp -= siglen; - free(sigbuf); - sigbuf = NULL; - - assert(lenp == 0); - - /* Now do the encryption */ - err = gcry_cipher_encrypt(enckey, buf, totallen, NULL, 0); - if (err) goto err; - - *authbufp = buf; - buf = NULL; - *authlenp = totallen; - - return err; + buf = malloc(totallen); + if (buf == NULL) goto memerr; + + bufp = buf; + lenp = totallen; + + /* Write the data to be MAC'd */ + write_mpi(our_dh_pub, ourpublen, "Our DH pubkey"); + write_mpi(their_dh_pub, theirpublen, "Their DH pubkey"); + bufp[0] = ((privkey->pubkey_type) >> 8) & 0xff; + bufp[1] = (privkey->pubkey_type) & 0xff; + bufp += 2; lenp -= 2; + memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); + debug_data("Pubkey", bufp, privkey->pubkey_datalen); + bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; + write_int(keyid); + debug_int("Keyid", bufp-4); + + assert(lenp == 0); + + /* Do the MAC */ + gcry_md_reset(mackey); + gcry_md_write(mackey, buf, totallen); + memmove(macbuf, gcry_md_read(mackey, GCRY_MD_SHA256), 32); + + free(buf); + buf = NULL; + + /* Sign the MAC */ + err = otrl_privkey_sign(&sigbuf, &siglen, privkey, macbuf, 32); + if (err) goto err; + + /* Calculate the total size of the structure to be encrypted */ + totallen = 2 + privkey->pubkey_datalen + 4 + siglen; + buf = malloc(totallen); + if (buf == NULL) goto memerr; + bufp = buf; + lenp = totallen; + + /* Write the data to be encrypted */ + bufp[0] = ((privkey->pubkey_type) >> 8) & 0xff; + bufp[1] = (privkey->pubkey_type) & 0xff; + bufp += 2; lenp -= 2; + memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); + debug_data("Pubkey", bufp, privkey->pubkey_datalen); + bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; + write_int(keyid); + debug_int("Keyid", bufp-4); + memmove(bufp, sigbuf, siglen); + debug_data("Signature", bufp, siglen); + bufp += siglen; lenp -= siglen; + free(sigbuf); + sigbuf = NULL; + + assert(lenp == 0); + + /* Now do the encryption */ + err = gcry_cipher_encrypt(enckey, buf, totallen, NULL, 0); + if (err) goto err; + + *authbufp = buf; + buf = NULL; + *authlenp = totallen; + + return err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(sigbuf); - return err; + free(buf); + free(sigbuf); + return err; } /* @@ -458,107 +458,107 @@ static gcry_error_t check_pubkey_auth(unsigned char fingerprintbufp[20], gcry_md_hd_t mackey, gcry_cipher_hd_t enckey, gcry_mpi_t our_dh_pub, gcry_mpi_t their_dh_pub) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - size_t ourpublen, theirpublen, totallen, lenp; - unsigned char *buf = NULL, *bufp = NULL; - unsigned char macbuf[32]; - unsigned short pubkey_type; - gcry_mpi_t p,q,g,y; - gcry_sexp_t pubs = NULL; - unsigned int received_keyid; - unsigned char *fingerprintstart, *fingerprintend, *sigbuf; - size_t siglen; - - /* Start by decrypting it */ - err = gcry_cipher_decrypt(enckey, authbuf, authlen, NULL, 0); - if (err) goto err; - - bufp = authbuf; - lenp = authlen; - - /* Get the public key and calculate its fingerprint */ - require_len(2); - pubkey_type = (bufp[0] << 8) + bufp[1]; - bufp += 2; lenp -= 2; - if (pubkey_type != OTRL_PUBKEY_TYPE_DSA) goto invval; - fingerprintstart = bufp; - read_mpi(p); - read_mpi(q); - read_mpi(g); - read_mpi(y); - fingerprintend = bufp; - gcry_md_hash_buffer(GCRY_MD_SHA1, fingerprintbufp, - fingerprintstart, fingerprintend-fingerprintstart); - gcry_sexp_build(&pubs, NULL, + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + size_t ourpublen, theirpublen, totallen, lenp; + unsigned char *buf = NULL, *bufp = NULL; + unsigned char macbuf[32]; + unsigned short pubkey_type; + gcry_mpi_t p,q,g,y; + gcry_sexp_t pubs = NULL; + unsigned int received_keyid; + unsigned char *fingerprintstart, *fingerprintend, *sigbuf; + size_t siglen; + + /* Start by decrypting it */ + err = gcry_cipher_decrypt(enckey, authbuf, authlen, NULL, 0); + if (err) goto err; + + bufp = authbuf; + lenp = authlen; + + /* Get the public key and calculate its fingerprint */ + require_len(2); + pubkey_type = (bufp[0] << 8) + bufp[1]; + bufp += 2; lenp -= 2; + if (pubkey_type != OTRL_PUBKEY_TYPE_DSA) goto invval; + fingerprintstart = bufp; + read_mpi(p); + read_mpi(q); + read_mpi(g); + read_mpi(y); + fingerprintend = bufp; + gcry_md_hash_buffer(GCRY_MD_SHA1, fingerprintbufp, + fingerprintstart, fingerprintend-fingerprintstart); + gcry_sexp_build(&pubs, NULL, "(public-key (dsa (p %m)(q %m)(g %m)(y %m)))", p, q, g, y); - gcry_mpi_release(p); - gcry_mpi_release(q); - gcry_mpi_release(g); - gcry_mpi_release(y); + gcry_mpi_release(p); + gcry_mpi_release(q); + gcry_mpi_release(g); + gcry_mpi_release(y); - /* Get the keyid */ - read_int(received_keyid); - if (received_keyid == 0) goto invval; + /* Get the keyid */ + read_int(received_keyid); + if (received_keyid == 0) goto invval; - /* Get the signature */ - sigbuf = bufp; - siglen = lenp; + /* Get the signature */ + sigbuf = bufp; + siglen = lenp; - /* How big are the DH public keys? */ - gcry_mpi_print(format, NULL, 0, &ourpublen, our_dh_pub); - gcry_mpi_print(format, NULL, 0, &theirpublen, their_dh_pub); + /* How big are the DH public keys? */ + gcry_mpi_print(format, NULL, 0, &ourpublen, our_dh_pub); + gcry_mpi_print(format, NULL, 0, &theirpublen, their_dh_pub); - /* Now calculate the message to be MAC'd. */ - totallen = 4 + ourpublen + 4 + theirpublen + 2 + + /* Now calculate the message to be MAC'd. */ + totallen = 4 + ourpublen + 4 + theirpublen + 2 + (fingerprintend - fingerprintstart) + 4; - buf = malloc(totallen); - if (buf == NULL) goto memerr; - - bufp = buf; - lenp = totallen; - - write_mpi(their_dh_pub, theirpublen, "Their DH pubkey"); - write_mpi(our_dh_pub, ourpublen, "Our DH pubkey"); - bufp[0] = (pubkey_type >> 16) & 0xff; - bufp[1] = pubkey_type & 0xff; - bufp += 2; lenp -= 2; - memmove(bufp, fingerprintstart, fingerprintend - fingerprintstart); - debug_data("Pubkey", bufp, fingerprintend - fingerprintstart); - bufp += fingerprintend - fingerprintstart; - lenp -= fingerprintend - fingerprintstart; - write_int(received_keyid); - debug_int("Keyid", bufp-4); - - assert(lenp == 0); - - /* Do the MAC */ - gcry_md_reset(mackey); - gcry_md_write(mackey, buf, totallen); - memmove(macbuf, gcry_md_read(mackey, GCRY_MD_SHA256), 32); - - free(buf); - buf = NULL; - - /* Verify the signature on the MAC */ - err = otrl_privkey_verify(sigbuf, siglen, pubkey_type, pubs, macbuf, 32); - if (err) goto err; - gcry_sexp_release(pubs); - pubs = NULL; - - /* Everything checked out */ - *keyidp = received_keyid; - - return err; + buf = malloc(totallen); + if (buf == NULL) goto memerr; + + bufp = buf; + lenp = totallen; + + write_mpi(their_dh_pub, theirpublen, "Their DH pubkey"); + write_mpi(our_dh_pub, ourpublen, "Our DH pubkey"); + bufp[0] = (pubkey_type >> 8) & 0xff; + bufp[1] = pubkey_type & 0xff; + bufp += 2; lenp -= 2; + memmove(bufp, fingerprintstart, fingerprintend - fingerprintstart); + debug_data("Pubkey", bufp, fingerprintend - fingerprintstart); + bufp += fingerprintend - fingerprintstart; + lenp -= fingerprintend - fingerprintstart; + write_int(received_keyid); + debug_int("Keyid", bufp-4); + + assert(lenp == 0); + + /* Do the MAC */ + gcry_md_reset(mackey); + gcry_md_write(mackey, buf, totallen); + memmove(macbuf, gcry_md_read(mackey, GCRY_MD_SHA256), 32); + + free(buf); + buf = NULL; + + /* Verify the signature on the MAC */ + err = otrl_privkey_verify(sigbuf, siglen, pubkey_type, pubs, macbuf, 32); + if (err) goto err; + gcry_sexp_release(pubs); + pubs = NULL; + + /* Everything checked out */ + *keyidp = received_keyid; + + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - gcry_sexp_release(pubs); - return err; + free(buf); + gcry_sexp_release(pubs); + return err; } /* @@ -569,67 +569,67 @@ err: static gcry_error_t create_revealsig_message(OtrlAuthInfo *auth, OtrlPrivKey *privkey) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp, *startmac; - size_t buflen, lenp; - - unsigned char *authbuf = NULL; - size_t authlen; - - /* Get the encrypted authenticator */ - err = calculate_pubkey_auth(&authbuf, &authlen, auth->mac_m1, auth->enc_c, - auth->our_dh.pub, auth->their_pub, privkey, auth->our_keyid); - if (err) goto err; - - buflen = 3 + 4 + 16 + 4 + authlen + 20; - buf = malloc(buflen); - if (buf == NULL) goto memerr; - - bufp = buf; - lenp = buflen; - - memmove(bufp, "\x00\x02\x11", 3); /* header */ - debug_data("Header", bufp, 3); - bufp += 3; lenp -= 3; - - /* r */ - write_int(16); - memmove(bufp, auth->r, 16); - debug_data("r", bufp, 16); - bufp += 16; lenp -= 16; - - /* Encrypted authenticator */ - startmac = bufp; - write_int(authlen); - memmove(bufp, authbuf, authlen); - debug_data("auth", bufp, authlen); - bufp += authlen; lenp -= authlen; - free(authbuf); - authbuf = NULL; - - /* MAC it, but only take the first 20 bytes */ - gcry_md_reset(auth->mac_m2); - gcry_md_write(auth->mac_m2, startmac, bufp - startmac); - memmove(bufp, gcry_md_read(auth->mac_m2, GCRY_MD_SHA256), 20); - debug_data("MAC", bufp, 20); - bufp += 20; lenp -= 20; - - assert(lenp == 0); - - free(auth->lastauthmsg); - auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); - if (auth->lastauthmsg == NULL) goto memerr; - free(buf); - buf = NULL; - - return err; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp, *startmac; + size_t buflen, lenp; + + unsigned char *authbuf = NULL; + size_t authlen; + + /* Get the encrypted authenticator */ + err = calculate_pubkey_auth(&authbuf, &authlen, auth->mac_m1, auth->enc_c, + auth->our_dh.pub, auth->their_pub, privkey, auth->our_keyid); + if (err) goto err; + + buflen = 3 + 4 + 16 + 4 + authlen + 20; + buf = malloc(buflen); + if (buf == NULL) goto memerr; + + bufp = buf; + lenp = buflen; + + memmove(bufp, "\x00\x02\x11", 3); /* header */ + debug_data("Header", bufp, 3); + bufp += 3; lenp -= 3; + + /* r */ + write_int(16); + memmove(bufp, auth->r, 16); + debug_data("r", bufp, 16); + bufp += 16; lenp -= 16; + + /* Encrypted authenticator */ + startmac = bufp; + write_int(authlen); + memmove(bufp, authbuf, authlen); + debug_data("auth", bufp, authlen); + bufp += authlen; lenp -= authlen; + free(authbuf); + authbuf = NULL; + + /* MAC it, but only take the first 20 bytes */ + gcry_md_reset(auth->mac_m2); + gcry_md_write(auth->mac_m2, startmac, bufp - startmac); + memmove(bufp, gcry_md_read(auth->mac_m2, GCRY_MD_SHA256), 20); + debug_data("MAC", bufp, 20); + bufp += 20; lenp -= 20; + + assert(lenp == 0); + + free(auth->lastauthmsg); + auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); + if (auth->lastauthmsg == NULL) goto memerr; + free(buf); + buf = NULL; + + return err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(authbuf); - return err; + free(buf); + free(authbuf); + return err; } /* @@ -640,62 +640,62 @@ err: static gcry_error_t create_signature_message(OtrlAuthInfo *auth, OtrlPrivKey *privkey) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp, *startmac; - size_t buflen, lenp; - - unsigned char *authbuf = NULL; - size_t authlen; - - /* Get the encrypted authenticator */ - err = calculate_pubkey_auth(&authbuf, &authlen, auth->mac_m1p, - auth->enc_cp, auth->our_dh.pub, auth->their_pub, privkey, - auth->our_keyid); - if (err) goto err; - - buflen = 3 + 4 + authlen + 20; - buf = malloc(buflen); - if (buf == NULL) goto memerr; - - bufp = buf; - lenp = buflen; - - memmove(bufp, "\x00\x02\x12", 3); /* header */ - debug_data("Header", bufp, 3); - bufp += 3; lenp -= 3; - - /* Encrypted authenticator */ - startmac = bufp; - write_int(authlen); - memmove(bufp, authbuf, authlen); - debug_data("auth", bufp, authlen); - bufp += authlen; lenp -= authlen; - free(authbuf); - authbuf = NULL; - - /* MAC it, but only take the first 20 bytes */ - gcry_md_reset(auth->mac_m2p); - gcry_md_write(auth->mac_m2p, startmac, bufp - startmac); - memmove(bufp, gcry_md_read(auth->mac_m2p, GCRY_MD_SHA256), 20); - debug_data("MAC", bufp, 20); - bufp += 20; lenp -= 20; - - assert(lenp == 0); - - free(auth->lastauthmsg); - auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); - if (auth->lastauthmsg == NULL) goto memerr; - free(buf); - buf = NULL; - - return err; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp, *startmac; + size_t buflen, lenp; + + unsigned char *authbuf = NULL; + size_t authlen; + + /* Get the encrypted authenticator */ + err = calculate_pubkey_auth(&authbuf, &authlen, auth->mac_m1p, + auth->enc_cp, auth->our_dh.pub, auth->their_pub, privkey, + auth->our_keyid); + if (err) goto err; + + buflen = 3 + 4 + authlen + 20; + buf = malloc(buflen); + if (buf == NULL) goto memerr; + + bufp = buf; + lenp = buflen; + + memmove(bufp, "\x00\x02\x12", 3); /* header */ + debug_data("Header", bufp, 3); + bufp += 3; lenp -= 3; + + /* Encrypted authenticator */ + startmac = bufp; + write_int(authlen); + memmove(bufp, authbuf, authlen); + debug_data("auth", bufp, authlen); + bufp += authlen; lenp -= authlen; + free(authbuf); + authbuf = NULL; + + /* MAC it, but only take the first 20 bytes */ + gcry_md_reset(auth->mac_m2p); + gcry_md_write(auth->mac_m2p, startmac, bufp - startmac); + memmove(bufp, gcry_md_read(auth->mac_m2p, GCRY_MD_SHA256), 20); + debug_data("MAC", bufp, 20); + bufp += 20; lenp -= 20; + + assert(lenp == 0); + + free(auth->lastauthmsg); + auth->lastauthmsg = otrl_base64_otr_encode(buf, buflen); + if (auth->lastauthmsg == NULL) goto memerr; + free(buf); + buf = NULL; + + return err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(authbuf); - return err; + free(buf); + free(authbuf); + return err; } /* @@ -706,85 +706,85 @@ err: gcry_error_t otrl_auth_handle_key(OtrlAuthInfo *auth, const char *keymsg, int *havemsgp, OtrlPrivKey *privkey) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp = NULL; - size_t buflen, lenp; - gcry_mpi_t incoming_pub = NULL; - int res; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp = NULL; + size_t buflen, lenp; + gcry_mpi_t incoming_pub = NULL; + int res; - *havemsgp = 0; + *havemsgp = 0; - res = otrl_base64_otr_decode(keymsg, &buf, &buflen); - if (res == -1) goto memerr; - if (res == -2) goto invval; + res = otrl_base64_otr_decode(keymsg, &buf, &buflen); + if (res == -1) goto memerr; + if (res == -2) goto invval; - bufp = buf; - lenp = buflen; + bufp = buf; + lenp = buflen; - /* Header */ - if (memcmp(bufp, "\x00\x02\x0a", 3)) goto invval; - bufp += 3; lenp -= 3; + /* Header */ + if (memcmp(bufp, "\x00\x02\x0a", 3)) goto invval; + bufp += 3; lenp -= 3; - /* g^y */ - read_mpi(incoming_pub); + /* g^y */ + read_mpi(incoming_pub); - if (lenp != 0) goto invval; - free(buf); - buf = NULL; + if (lenp != 0) goto invval; + free(buf); + buf = NULL; - switch(auth->authstate) { + switch(auth->authstate) { case OTRL_AUTHSTATE_AWAITING_DHKEY: - /* Store the incoming public key */ - gcry_mpi_release(auth->their_pub); - auth->their_pub = incoming_pub; - incoming_pub = NULL; - - /* Compute the encryption and MAC keys */ - err = otrl_dh_compute_v2_auth_keys(&(auth->our_dh), - auth->their_pub, auth->secure_session_id, - &(auth->secure_session_id_len), - &(auth->enc_c), &(auth->enc_cp), - &(auth->mac_m1), &(auth->mac_m1p), - &(auth->mac_m2), &(auth->mac_m2p)); - if (err) goto err; - - /* Create the Reveal Signature Message */ - err = create_revealsig_message(auth, privkey); - if (err) goto err; - *havemsgp = 1; - auth->authstate = OTRL_AUTHSTATE_AWAITING_SIG; - - break; + /* Store the incoming public key */ + gcry_mpi_release(auth->their_pub); + auth->their_pub = incoming_pub; + incoming_pub = NULL; + + /* Compute the encryption and MAC keys */ + err = otrl_dh_compute_v2_auth_keys(&(auth->our_dh), + auth->their_pub, auth->secure_session_id, + &(auth->secure_session_id_len), + &(auth->enc_c), &(auth->enc_cp), + &(auth->mac_m1), &(auth->mac_m1p), + &(auth->mac_m2), &(auth->mac_m2p)); + if (err) goto err; + + /* Create the Reveal Signature Message */ + err = create_revealsig_message(auth, privkey); + if (err) goto err; + *havemsgp = 1; + auth->authstate = OTRL_AUTHSTATE_AWAITING_SIG; + + break; case OTRL_AUTHSTATE_AWAITING_SIG: - if (gcry_mpi_cmp(incoming_pub, auth->their_pub) == 0) { + if (gcry_mpi_cmp(incoming_pub, auth->their_pub) == 0) { /* Retransmit the Reveal Signature Message */ *havemsgp = 1; - } else { + } else { /* Ignore this message */ *havemsgp = 0; - } - break; + } + break; case OTRL_AUTHSTATE_NONE: case OTRL_AUTHSTATE_AWAITING_REVEALSIG: case OTRL_AUTHSTATE_V1_SETUP: - /* Ignore this message */ - *havemsgp = 0; - break; - } + /* Ignore this message */ + *havemsgp = 0; + break; + } - gcry_mpi_release(incoming_pub); - return err; + gcry_mpi_release(incoming_pub); + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - gcry_mpi_release(incoming_pub); - return err; + free(buf); + gcry_mpi_release(incoming_pub); + return err; } /* @@ -799,162 +799,162 @@ gcry_error_t otrl_auth_handle_revealsig(OtrlAuthInfo *auth, gcry_error_t (*auth_succeeded)(const OtrlAuthInfo *auth, void *asdata), void *asdata) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp = NULL, *gxbuf = NULL; - unsigned char *authstart, *authend, *macstart; - size_t buflen, lenp, rlen, authlen; - gcry_cipher_hd_t enc = NULL; - gcry_mpi_t incoming_pub = NULL; - unsigned char ctr[16], hashbuf[32]; - int res; - - *havemsgp = 0; - - res = otrl_base64_otr_decode(revealmsg, &buf, &buflen); - if (res == -1) goto memerr; - if (res == -2) goto invval; - - bufp = buf; - lenp = buflen; - - /* Header */ - if (memcmp(bufp, "\x00\x02\x11", 3)) goto invval; - bufp += 3; lenp -= 3; - - /* r */ - read_int(rlen); - if (rlen != 16) goto invval; - require_len(rlen); - memmove(auth->r, bufp, rlen); - bufp += rlen; lenp -= rlen; - - /* auth */ - authstart = bufp; - read_int(authlen); - require_len(authlen); - bufp += authlen; lenp -= authlen; - authend = bufp; - - /* MAC */ - require_len(20); - macstart = bufp; - bufp += 20; lenp -= 20; - - if (lenp != 0) goto invval; - - switch(auth->authstate) { + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp = NULL, *gxbuf = NULL; + unsigned char *authstart, *authend, *macstart; + size_t buflen, lenp, rlen, authlen; + gcry_cipher_hd_t enc = NULL; + gcry_mpi_t incoming_pub = NULL; + unsigned char ctr[16], hashbuf[32]; + int res; + + *havemsgp = 0; + + res = otrl_base64_otr_decode(revealmsg, &buf, &buflen); + if (res == -1) goto memerr; + if (res == -2) goto invval; + + bufp = buf; + lenp = buflen; + + /* Header */ + if (memcmp(bufp, "\x00\x02\x11", 3)) goto invval; + bufp += 3; lenp -= 3; + + /* r */ + read_int(rlen); + if (rlen != 16) goto invval; + require_len(rlen); + memmove(auth->r, bufp, rlen); + bufp += rlen; lenp -= rlen; + + /* auth */ + authstart = bufp; + read_int(authlen); + require_len(authlen); + bufp += authlen; lenp -= authlen; + authend = bufp; + + /* MAC */ + require_len(20); + macstart = bufp; + bufp += 20; lenp -= 20; + + if (lenp != 0) goto invval; + + switch(auth->authstate) { case OTRL_AUTHSTATE_AWAITING_REVEALSIG: - gxbuf = malloc(auth->encgx_len); - if (auth->encgx_len && gxbuf == NULL) goto memerr; - - /* Use r to decrypt the value of g^x we received earlier */ - err = gcry_cipher_open(&enc, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, - GCRY_CIPHER_SECURE); - if (err) goto err; - - err = gcry_cipher_setkey(enc, auth->r, 16); - if (err) goto err; - - memset(ctr, 0, 16); - err = gcry_cipher_setctr(enc, ctr, 16); - if (err) goto err; - - err = gcry_cipher_decrypt(enc, gxbuf, auth->encgx_len, - auth->encgx, auth->encgx_len); - if (err) goto err; - - gcry_cipher_close(enc); - enc = NULL; - - /* Check the hash */ - gcry_md_hash_buffer(GCRY_MD_SHA256, hashbuf, gxbuf, - auth->encgx_len); - if (memcmp(hashbuf, auth->hashgx, 32)) goto decfail; - - /* Extract g^x */ - bufp = gxbuf; - lenp = auth->encgx_len; - - read_mpi(incoming_pub); - free(gxbuf); - gxbuf = NULL; - - if (lenp != 0) goto invval; - - gcry_mpi_release(auth->their_pub); - auth->their_pub = incoming_pub; - incoming_pub = NULL; - - /* Compute the encryption and MAC keys */ - err = otrl_dh_compute_v2_auth_keys(&(auth->our_dh), - auth->their_pub, auth->secure_session_id, - &(auth->secure_session_id_len), - &(auth->enc_c), &(auth->enc_cp), - &(auth->mac_m1), &(auth->mac_m1p), - &(auth->mac_m2), &(auth->mac_m2p)); - if (err) goto err; - - /* Check the MAC */ - gcry_md_reset(auth->mac_m2); - gcry_md_write(auth->mac_m2, authstart, authend - authstart); - if (memcmp(macstart, + gxbuf = malloc(auth->encgx_len); + if (auth->encgx_len && gxbuf == NULL) goto memerr; + + /* Use r to decrypt the value of g^x we received earlier */ + err = gcry_cipher_open(&enc, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, + GCRY_CIPHER_SECURE); + if (err) goto err; + + err = gcry_cipher_setkey(enc, auth->r, 16); + if (err) goto err; + + memset(ctr, 0, 16); + err = gcry_cipher_setctr(enc, ctr, 16); + if (err) goto err; + + err = gcry_cipher_decrypt(enc, gxbuf, auth->encgx_len, + auth->encgx, auth->encgx_len); + if (err) goto err; + + gcry_cipher_close(enc); + enc = NULL; + + /* Check the hash */ + gcry_md_hash_buffer(GCRY_MD_SHA256, hashbuf, gxbuf, + auth->encgx_len); + if (memcmp(hashbuf, auth->hashgx, 32)) goto decfail; + + /* Extract g^x */ + bufp = gxbuf; + lenp = auth->encgx_len; + + read_mpi(incoming_pub); + free(gxbuf); + gxbuf = NULL; + + if (lenp != 0) goto invval; + + gcry_mpi_release(auth->their_pub); + auth->their_pub = incoming_pub; + incoming_pub = NULL; + + /* Compute the encryption and MAC keys */ + err = otrl_dh_compute_v2_auth_keys(&(auth->our_dh), + auth->their_pub, auth->secure_session_id, + &(auth->secure_session_id_len), + &(auth->enc_c), &(auth->enc_cp), + &(auth->mac_m1), &(auth->mac_m1p), + &(auth->mac_m2), &(auth->mac_m2p)); + if (err) goto err; + + /* Check the MAC */ + gcry_md_reset(auth->mac_m2); + gcry_md_write(auth->mac_m2, authstart, authend - authstart); + if (memcmp(macstart, gcry_md_read(auth->mac_m2, GCRY_MD_SHA256), 20)) goto invval; - /* Check the auth */ - err = check_pubkey_auth(auth->their_fingerprint, - &(auth->their_keyid), authstart + 4, - authend - authstart - 4, auth->mac_m1, auth->enc_c, - auth->our_dh.pub, auth->their_pub); - if (err) goto err; - - authstart = NULL; - authend = NULL; - macstart = NULL; - free(buf); - buf = NULL; - - /* Create the Signature Message */ - err = create_signature_message(auth, privkey); - if (err) goto err; - - /* No error? Then we've completed our end of the - * authentication. */ - auth->protocol_version = 2; - auth->session_id_half = OTRL_SESSIONID_SECOND_HALF_BOLD; - if (auth_succeeded) err = auth_succeeded(auth, asdata); - *havemsgp = 1; - auth->our_keyid = 0; - auth->authstate = OTRL_AUTHSTATE_NONE; - - break; + /* Check the auth */ + err = check_pubkey_auth(auth->their_fingerprint, + &(auth->their_keyid), authstart + 4, + authend - authstart - 4, auth->mac_m1, auth->enc_c, + auth->our_dh.pub, auth->their_pub); + if (err) goto err; + + authstart = NULL; + authend = NULL; + macstart = NULL; + free(buf); + buf = NULL; + + /* Create the Signature Message */ + err = create_signature_message(auth, privkey); + if (err) goto err; + + /* No error? Then we've completed our end of the + * authentication. */ + auth->protocol_version = 2; + auth->session_id_half = OTRL_SESSIONID_SECOND_HALF_BOLD; + if (auth_succeeded) err = auth_succeeded(auth, asdata); + *havemsgp = 1; + auth->our_keyid = 0; + auth->authstate = OTRL_AUTHSTATE_NONE; + + break; case OTRL_AUTHSTATE_NONE: case OTRL_AUTHSTATE_AWAITING_DHKEY: case OTRL_AUTHSTATE_AWAITING_SIG: case OTRL_AUTHSTATE_V1_SETUP: - /* Ignore this message */ - *havemsgp = 0; - free(buf); - buf = NULL; - break; - } + /* Ignore this message */ + *havemsgp = 0; + free(buf); + buf = NULL; + break; + } - return err; + return err; decfail: - err = gcry_error(GPG_ERR_NO_ERROR); - goto err; + err = gcry_error(GPG_ERR_NO_ERROR); + goto err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(gxbuf); - gcry_cipher_close(enc); - gcry_mpi_release(incoming_pub); - return err; + free(buf); + free(gxbuf); + gcry_cipher_close(enc); + gcry_mpi_release(incoming_pub); + return err; } /* @@ -968,92 +968,92 @@ gcry_error_t otrl_auth_handle_signature(OtrlAuthInfo *auth, gcry_error_t (*auth_succeeded)(const OtrlAuthInfo *auth, void *asdata), void *asdata) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp = NULL; - unsigned char *authstart, *authend, *macstart; - size_t buflen, lenp, authlen; - int res; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp = NULL; + unsigned char *authstart, *authend, *macstart; + size_t buflen, lenp, authlen; + int res; - *havemsgp = 0; + *havemsgp = 0; - res = otrl_base64_otr_decode(sigmsg, &buf, &buflen); - if (res == -1) goto memerr; - if (res == -2) goto invval; + res = otrl_base64_otr_decode(sigmsg, &buf, &buflen); + if (res == -1) goto memerr; + if (res == -2) goto invval; - bufp = buf; - lenp = buflen; + bufp = buf; + lenp = buflen; - /* Header */ - if (memcmp(bufp, "\x00\x02\x12", 3)) goto invval; - bufp += 3; lenp -= 3; + /* Header */ + if (memcmp(bufp, "\x00\x02\x12", 3)) goto invval; + bufp += 3; lenp -= 3; - /* auth */ - authstart = bufp; - read_int(authlen); - require_len(authlen); - bufp += authlen; lenp -= authlen; - authend = bufp; + /* auth */ + authstart = bufp; + read_int(authlen); + require_len(authlen); + bufp += authlen; lenp -= authlen; + authend = bufp; - /* MAC */ - require_len(20); - macstart = bufp; - bufp += 20; lenp -= 20; + /* MAC */ + require_len(20); + macstart = bufp; + bufp += 20; lenp -= 20; - if (lenp != 0) goto invval; + if (lenp != 0) goto invval; - switch(auth->authstate) { + switch(auth->authstate) { case OTRL_AUTHSTATE_AWAITING_SIG: - /* Check the MAC */ - gcry_md_reset(auth->mac_m2p); - gcry_md_write(auth->mac_m2p, authstart, authend - authstart); - if (memcmp(macstart, + /* Check the MAC */ + gcry_md_reset(auth->mac_m2p); + gcry_md_write(auth->mac_m2p, authstart, authend - authstart); + if (memcmp(macstart, gcry_md_read(auth->mac_m2p, GCRY_MD_SHA256), 20)) goto invval; - /* Check the auth */ - err = check_pubkey_auth(auth->their_fingerprint, - &(auth->their_keyid), authstart + 4, - authend - authstart - 4, auth->mac_m1p, auth->enc_cp, - auth->our_dh.pub, auth->their_pub); - if (err) goto err; - - authstart = NULL; - authend = NULL; - macstart = NULL; - free(buf); - buf = NULL; - - /* No error? Then we've completed our end of the - * authentication. */ - auth->protocol_version = 2; - auth->session_id_half = OTRL_SESSIONID_FIRST_HALF_BOLD; - if (auth_succeeded) err = auth_succeeded(auth, asdata); - free(auth->lastauthmsg); - auth->lastauthmsg = NULL; - *havemsgp = 1; - auth->our_keyid = 0; - auth->authstate = OTRL_AUTHSTATE_NONE; - - break; + /* Check the auth */ + err = check_pubkey_auth(auth->their_fingerprint, + &(auth->their_keyid), authstart + 4, + authend - authstart - 4, auth->mac_m1p, auth->enc_cp, + auth->our_dh.pub, auth->their_pub); + if (err) goto err; + + authstart = NULL; + authend = NULL; + macstart = NULL; + free(buf); + buf = NULL; + + /* No error? Then we've completed our end of the + * authentication. */ + auth->protocol_version = 2; + auth->session_id_half = OTRL_SESSIONID_FIRST_HALF_BOLD; + if (auth_succeeded) err = auth_succeeded(auth, asdata); + free(auth->lastauthmsg); + auth->lastauthmsg = NULL; + *havemsgp = 1; + auth->our_keyid = 0; + auth->authstate = OTRL_AUTHSTATE_NONE; + + break; case OTRL_AUTHSTATE_NONE: case OTRL_AUTHSTATE_AWAITING_DHKEY: case OTRL_AUTHSTATE_AWAITING_REVEALSIG: case OTRL_AUTHSTATE_V1_SETUP: - /* Ignore this message */ - *havemsgp = 0; - break; - } + /* Ignore this message */ + *havemsgp = 0; + break; + } - return err; + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - return err; + free(buf); + return err; } /* Version 1 routines, for compatibility */ @@ -1066,75 +1066,75 @@ err: static gcry_error_t create_v1_key_exchange_message(OtrlAuthInfo *auth, unsigned char reply, OtrlPrivKey *privkey) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - unsigned char *buf = NULL, *bufp = NULL, *sigbuf = NULL; - size_t lenp, ourpublen, totallen, siglen; - unsigned char hashbuf[20]; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + unsigned char *buf = NULL, *bufp = NULL, *sigbuf = NULL; + size_t lenp, ourpublen, totallen, siglen; + unsigned char hashbuf[20]; - if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA) { + if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA) { return gpg_error(GPG_ERR_INV_VALUE); - } + } - /* How big is the DH public key? */ - gcry_mpi_print(format, NULL, 0, &ourpublen, auth->our_dh.pub); + /* How big is the DH public key? */ + gcry_mpi_print(format, NULL, 0, &ourpublen, auth->our_dh.pub); - totallen = 3 + 1 + privkey->pubkey_datalen + 4 + 4 + ourpublen + 40; - buf = malloc(totallen); - if (buf == NULL) goto memerr; + totallen = 3 + 1 + privkey->pubkey_datalen + 4 + 4 + ourpublen + 40; + buf = malloc(totallen); + if (buf == NULL) goto memerr; - bufp = buf; - lenp = totallen; + bufp = buf; + lenp = totallen; - memmove(bufp, "\x00\x01\x0a", 3); /* header */ - debug_data("Header", bufp, 3); - bufp += 3; lenp -= 3; + memmove(bufp, "\x00\x01\x0a", 3); /* header */ + debug_data("Header", bufp, 3); + bufp += 3; lenp -= 3; - bufp[0] = reply; - debug_data("Reply", bufp, 1); - bufp += 1; lenp -= 1; + bufp[0] = reply; + debug_data("Reply", bufp, 1); + bufp += 1; lenp -= 1; - memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); - debug_data("Pubkey", bufp, privkey->pubkey_datalen); - bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; + memmove(bufp, privkey->pubkey_data, privkey->pubkey_datalen); + debug_data("Pubkey", bufp, privkey->pubkey_datalen); + bufp += privkey->pubkey_datalen; lenp -= privkey->pubkey_datalen; - write_int(auth->our_keyid); - debug_int("Keyid", bufp-4); + write_int(auth->our_keyid); + debug_int("Keyid", bufp-4); - write_mpi(auth->our_dh.pub, ourpublen, "D-H y"); + write_mpi(auth->our_dh.pub, ourpublen, "D-H y"); - /* Hash all the data written so far, and sign the hash */ - gcry_md_hash_buffer(GCRY_MD_SHA1, hashbuf, buf, bufp - buf); + /* Hash all the data written so far, and sign the hash */ + gcry_md_hash_buffer(GCRY_MD_SHA1, hashbuf, buf, bufp - buf); - err = otrl_privkey_sign(&sigbuf, &siglen, privkey, hashbuf, 20); - if (err) goto err; + err = otrl_privkey_sign(&sigbuf, &siglen, privkey, hashbuf, 20); + if (err) goto err; - if (siglen != 40) goto invval; - memmove(bufp, sigbuf, 40); - debug_data("Signature", bufp, 40); - bufp += 40; lenp -= 40; - free(sigbuf); - sigbuf = NULL; + if (siglen != 40) goto invval; + memmove(bufp, sigbuf, 40); + debug_data("Signature", bufp, 40); + bufp += 40; lenp -= 40; + free(sigbuf); + sigbuf = NULL; - assert(lenp == 0); + assert(lenp == 0); - free(auth->lastauthmsg); - auth->lastauthmsg = otrl_base64_otr_encode(buf, totallen); - if (auth->lastauthmsg == NULL) goto memerr; - free(buf); - buf = NULL; + free(auth->lastauthmsg); + auth->lastauthmsg = otrl_base64_otr_encode(buf, totallen); + if (auth->lastauthmsg == NULL) goto memerr; + free(buf); + buf = NULL; - return err; + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - free(sigbuf); - return err; + free(buf); + free(sigbuf); + return err; } /* @@ -1147,27 +1147,27 @@ err: gcry_error_t otrl_auth_start_v1(OtrlAuthInfo *auth, DH_keypair *our_dh, unsigned int our_keyid, OtrlPrivKey *privkey) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - /* Clear out this OtrlAuthInfo and start over */ - otrl_auth_clear(auth); - auth->initiated = 1; + /* Clear out this OtrlAuthInfo and start over */ + otrl_auth_clear(auth); + auth->initiated = 1; - /* Import the given DH keypair, or else create a fresh one */ - if (our_dh) { + /* Import the given DH keypair, or else create a fresh one */ + if (our_dh) { otrl_dh_keypair_copy(&(auth->our_dh), our_dh); auth->our_keyid = our_keyid; - } else { + } else { otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); auth->our_keyid = 1; - } + } - err = create_v1_key_exchange_message(auth, 0, privkey); - if (!err) { + err = create_v1_key_exchange_message(auth, 0, privkey); + if (!err) { auth->authstate = OTRL_AUTHSTATE_V1_SETUP; - } + } - return err; + return err; } /* @@ -1184,133 +1184,133 @@ gcry_error_t otrl_auth_handle_v1_key_exchange(OtrlAuthInfo *auth, gcry_error_t (*auth_succeeded)(const OtrlAuthInfo *auth, void *asdata), void *asdata) { - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - unsigned char *buf = NULL, *bufp = NULL; - unsigned char *fingerprintstart, *fingerprintend; - unsigned char fingerprintbuf[20], hashbuf[20]; - gcry_mpi_t p, q, g, y, received_pub = NULL; - gcry_sexp_t pubs = NULL; - size_t buflen, lenp; - unsigned char received_reply; - unsigned int received_keyid; - int res; - - *havemsgp = 0; - - res = otrl_base64_otr_decode(keyexchmsg, &buf, &buflen); - if (res == -1) goto memerr; - if (res == -2) goto invval; - - bufp = buf; - lenp = buflen; - - /* Header */ - require_len(3); - if (memcmp(bufp, "\x00\x01\x0a", 3)) goto invval; - bufp += 3; lenp -= 3; - - /* Reply */ - require_len(1); - received_reply = bufp[0]; - bufp += 1; lenp -= 1; - - /* Public Key */ - fingerprintstart = bufp; - read_mpi(p); - read_mpi(q); - read_mpi(g); - read_mpi(y); - fingerprintend = bufp; - gcry_md_hash_buffer(GCRY_MD_SHA1, fingerprintbuf, - fingerprintstart, fingerprintend-fingerprintstart); - gcry_sexp_build(&pubs, NULL, + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + unsigned char *buf = NULL, *bufp = NULL; + unsigned char *fingerprintstart, *fingerprintend; + unsigned char fingerprintbuf[20], hashbuf[20]; + gcry_mpi_t p, q, g, y, received_pub = NULL; + gcry_sexp_t pubs = NULL; + size_t buflen, lenp; + unsigned char received_reply; + unsigned int received_keyid; + int res; + + *havemsgp = 0; + + res = otrl_base64_otr_decode(keyexchmsg, &buf, &buflen); + if (res == -1) goto memerr; + if (res == -2) goto invval; + + bufp = buf; + lenp = buflen; + + /* Header */ + require_len(3); + if (memcmp(bufp, "\x00\x01\x0a", 3)) goto invval; + bufp += 3; lenp -= 3; + + /* Reply */ + require_len(1); + received_reply = bufp[0]; + bufp += 1; lenp -= 1; + + /* Public Key */ + fingerprintstart = bufp; + read_mpi(p); + read_mpi(q); + read_mpi(g); + read_mpi(y); + fingerprintend = bufp; + gcry_md_hash_buffer(GCRY_MD_SHA1, fingerprintbuf, + fingerprintstart, fingerprintend-fingerprintstart); + gcry_sexp_build(&pubs, NULL, "(public-key (dsa (p %m)(q %m)(g %m)(y %m)))", p, q, g, y); - gcry_mpi_release(p); - gcry_mpi_release(q); - gcry_mpi_release(g); - gcry_mpi_release(y); - - /* keyid */ - read_int(received_keyid); - if (received_keyid == 0) goto invval; - - /* D-H pubkey */ - read_mpi(received_pub); - - /* Verify the signature */ - if (lenp != 40) goto invval; - gcry_md_hash_buffer(GCRY_MD_SHA1, hashbuf, buf, bufp - buf); - err = otrl_privkey_verify(bufp, lenp, OTRL_PUBKEY_TYPE_DSA, - pubs, hashbuf, 20); - if (err) goto err; - gcry_sexp_release(pubs); - pubs = NULL; - free(buf); - buf = NULL; - - if (auth->authstate != OTRL_AUTHSTATE_V1_SETUP && received_reply == 0x01) { + gcry_mpi_release(p); + gcry_mpi_release(q); + gcry_mpi_release(g); + gcry_mpi_release(y); + + /* keyid */ + read_int(received_keyid); + if (received_keyid == 0) goto invval; + + /* D-H pubkey */ + read_mpi(received_pub); + + /* Verify the signature */ + if (lenp != 40) goto invval; + gcry_md_hash_buffer(GCRY_MD_SHA1, hashbuf, buf, bufp - buf); + err = otrl_privkey_verify(bufp, lenp, OTRL_PUBKEY_TYPE_DSA, + pubs, hashbuf, 20); + if (err) goto err; + gcry_sexp_release(pubs); + pubs = NULL; + free(buf); + buf = NULL; + + if (auth->authstate != OTRL_AUTHSTATE_V1_SETUP && received_reply == 0x01) { /* They're replying to something we never sent. We must be * logged in more than once; ignore the message. */ err = gpg_error(GPG_ERR_NO_ERROR); goto err; - } + } - if (auth->authstate != OTRL_AUTHSTATE_V1_SETUP) { + if (auth->authstate != OTRL_AUTHSTATE_V1_SETUP) { /* Clear the auth and start over */ otrl_auth_clear(auth); - } + } - /* Everything checked out */ - auth->their_keyid = received_keyid; - gcry_mpi_release(auth->their_pub); - auth->their_pub = received_pub; - received_pub = NULL; - memmove(auth->their_fingerprint, fingerprintbuf, 20); + /* Everything checked out */ + auth->their_keyid = received_keyid; + gcry_mpi_release(auth->their_pub); + auth->their_pub = received_pub; + received_pub = NULL; + memmove(auth->their_fingerprint, fingerprintbuf, 20); - if (received_reply == 0x01) { + if (received_reply == 0x01) { /* Don't send a reply to this. */ *havemsgp = 0; - } else { + } else { /* Import the given DH keypair, or else create a fresh one */ if (our_dh) { - otrl_dh_keypair_copy(&(auth->our_dh), our_dh); - auth->our_keyid = our_keyid; + otrl_dh_keypair_copy(&(auth->our_dh), our_dh); + auth->our_keyid = our_keyid; } else if (auth->our_keyid == 0) { - otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); - auth->our_keyid = 1; + otrl_dh_gen_keypair(DH1536_GROUP_ID, &(auth->our_dh)); + auth->our_keyid = 1; } /* Reply with our own Key Exchange Message */ err = create_v1_key_exchange_message(auth, 1, privkey); if (err) goto err; *havemsgp = 1; - } + } - /* Compute the session id */ - err = otrl_dh_compute_v1_session_id(&(auth->our_dh), - auth->their_pub, auth->secure_session_id, - &(auth->secure_session_id_len), - &(auth->session_id_half)); - if (err) goto err; + /* Compute the session id */ + err = otrl_dh_compute_v1_session_id(&(auth->our_dh), + auth->their_pub, auth->secure_session_id, + &(auth->secure_session_id_len), + &(auth->session_id_half)); + if (err) goto err; - /* We've completed our end of the authentication */ - auth->protocol_version = 1; - if (auth_succeeded) err = auth_succeeded(auth, asdata); - auth->our_keyid = 0; - auth->authstate = OTRL_AUTHSTATE_NONE; + /* We've completed our end of the authentication */ + auth->protocol_version = 1; + if (auth_succeeded) err = auth_succeeded(auth, asdata); + auth->our_keyid = 0; + auth->authstate = OTRL_AUTHSTATE_NONE; - return err; + return err; invval: - err = gcry_error(GPG_ERR_INV_VALUE); - goto err; + err = gcry_error(GPG_ERR_INV_VALUE); + goto err; memerr: - err = gcry_error(GPG_ERR_ENOMEM); + err = gcry_error(GPG_ERR_ENOMEM); err: - free(buf); - gcry_sexp_release(pubs); - gcry_mpi_release(received_pub); - return err; + free(buf); + gcry_sexp_release(pubs); + gcry_mpi_release(received_pub); + return err; } #ifdef OTRL_TESTING_AUTH @@ -1321,93 +1321,93 @@ err: static gcry_error_t starting(const OtrlAuthInfo *auth, void *asdata) { - char *name = asdata; + char *name = asdata; - fprintf(stderr, "\nStarting ENCRYPTED mode for %s (v%d).\n", name, auth->protocol_version); + fprintf(stderr, "\nStarting ENCRYPTED mode for %s (v%d).\n", name, auth->protocol_version); - fprintf(stderr, "\nour_dh (%d):", auth->our_keyid); - gcry_mpi_dump(auth->our_dh.pub); - fprintf(stderr, "\ntheir_pub (%d):", auth->their_keyid); - gcry_mpi_dump(auth->their_pub); + fprintf(stderr, "\nour_dh (%d):", auth->our_keyid); + gcry_mpi_dump(auth->our_dh.pub); + fprintf(stderr, "\ntheir_pub (%d):", auth->their_keyid); + gcry_mpi_dump(auth->their_pub); - debug_data("\nTheir fingerprint", auth->their_fingerprint, 20); - debug_data("\nSecure session id", auth->secure_session_id, - auth->secure_session_id_len); - fprintf(stderr, "Sessionid half: %d\n\n", auth->session_id_half); + debug_data("\nTheir fingerprint", auth->their_fingerprint, 20); + debug_data("\nSecure session id", auth->secure_session_id, + auth->secure_session_id_len); + fprintf(stderr, "Sessionid half: %d\n\n", auth->session_id_half); - return gpg_error(GPG_ERR_NO_ERROR); + return gpg_error(GPG_ERR_NO_ERROR); } int main(int argc, char **argv) { - OtrlAuthInfo alice, bob; - gcry_error_t err; - int havemsg; - OtrlUserState us; - OtrlPrivKey *alicepriv, *bobpriv; - - otrl_mem_init(); - otrl_dh_init(); - otrl_auth_new(&alice); - otrl_auth_new(&bob); - - us = otrl_userstate_create(); - otrl_privkey_read(us, "/home/iang/.gaim/otr.private_key"); - alicepriv = otrl_privkey_find(us, "oneeyedian", "prpl-oscar"); - bobpriv = otrl_privkey_find(us, "otr4ian", "prpl-oscar"); - - printf("\n\n ***** V2 *****\n\n"); - - err = otrl_auth_start_v2(&bob, NULL, 0); - CHECK_ERR - printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); - err = otrl_auth_handle_commit(&alice, bob.lastauthmsg, NULL, 0); - CHECK_ERR - printf("\nAlice: %d\n%s\n\n", strlen(alice.lastauthmsg), alice.lastauthmsg); - err = otrl_auth_handle_key(&bob, alice.lastauthmsg, &havemsg, bobpriv); - CHECK_ERR - if (havemsg) { + OtrlAuthInfo alice, bob; + gcry_error_t err; + int havemsg; + OtrlUserState us; + OtrlPrivKey *alicepriv, *bobpriv; + + otrl_mem_init(); + otrl_dh_init(); + otrl_auth_new(&alice); + otrl_auth_new(&bob); + + us = otrl_userstate_create(); + otrl_privkey_read(us, "/home/iang/.gaim/otr.private_key"); + alicepriv = otrl_privkey_find(us, "oneeyedian", "prpl-oscar"); + bobpriv = otrl_privkey_find(us, "otr4ian", "prpl-oscar"); + + printf("\n\n ***** V2 *****\n\n"); + + err = otrl_auth_start_v2(&bob, NULL, 0); + CHECK_ERR printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); - } else { + err = otrl_auth_handle_commit(&alice, bob.lastauthmsg, NULL, 0); + CHECK_ERR + printf("\nAlice: %d\n%s\n\n", strlen(alice.lastauthmsg), alice.lastauthmsg); + err = otrl_auth_handle_key(&bob, alice.lastauthmsg, &havemsg, bobpriv); + CHECK_ERR + if (havemsg) { + printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); + } else { printf("\nIGNORE\n\n"); - } - err = otrl_auth_handle_revealsig(&alice, bob.lastauthmsg, &havemsg, - alicepriv, starting, "Alice"); - CHECK_ERR - if (havemsg) { + } + err = otrl_auth_handle_revealsig(&alice, bob.lastauthmsg, &havemsg, + alicepriv, starting, "Alice"); + CHECK_ERR + if (havemsg) { printf("\nAlice: %d\n%s\n\n", strlen(alice.lastauthmsg), alice.lastauthmsg); - } else { + } else { printf("\nIGNORE\n\n"); - } - err = otrl_auth_handle_signature(&bob, alice.lastauthmsg, &havemsg, - starting, "Bob"); - CHECK_ERR - - printf("\n\n ***** V1 *****\n\n"); - - err = otrl_auth_start_v1(&bob, NULL, 0, bobpriv); - CHECK_ERR - printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); - err = otrl_auth_handle_v1_key_exchange(&alice, bob.lastauthmsg, - &havemsg, alicepriv, NULL, 0, starting, "Alice"); - CHECK_ERR - if (havemsg) { + } + err = otrl_auth_handle_signature(&bob, alice.lastauthmsg, &havemsg, + starting, "Bob"); + CHECK_ERR + + printf("\n\n ***** V1 *****\n\n"); + + err = otrl_auth_start_v1(&bob, NULL, 0, bobpriv); + CHECK_ERR + printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); + err = otrl_auth_handle_v1_key_exchange(&alice, bob.lastauthmsg, + &havemsg, alicepriv, NULL, 0, starting, "Alice"); + CHECK_ERR + if (havemsg) { printf("\nAlice: %d\n%s\n\n", strlen(alice.lastauthmsg), alice.lastauthmsg); - } else { + } else { printf("\nIGNORE\n\n"); - } - err = otrl_auth_handle_v1_key_exchange(&bob, alice.lastauthmsg, - &havemsg, bobpriv, NULL, 0, starting, "Bob"); - CHECK_ERR - if (havemsg) { + } + err = otrl_auth_handle_v1_key_exchange(&bob, alice.lastauthmsg, + &havemsg, bobpriv, NULL, 0, starting, "Bob"); + CHECK_ERR + if (havemsg) { printf("\nBob: %d\n%s\n\n", strlen(bob.lastauthmsg), bob.lastauthmsg); - } else { + } else { printf("\nIGNORE\n\n"); - } + } - otrl_userstate_free(us); - otrl_auth_clear(&alice); - otrl_auth_clear(&bob); - return 0; + otrl_userstate_free(us); + otrl_auth_clear(&alice); + otrl_auth_clear(&bob); + return 0; } #endif diff --git a/libotr-3.2.0/src/auth.h b/libotr-3.2.0/src/auth.h index 6de75dd..ac9c668 100644 --- a/libotr-3.2.0/src/auth.h +++ b/libotr-3.2.0/src/auth.h @@ -24,52 +24,52 @@ #include "dh.h" typedef enum { - OTRL_AUTHSTATE_NONE, - OTRL_AUTHSTATE_AWAITING_DHKEY, - OTRL_AUTHSTATE_AWAITING_REVEALSIG, - OTRL_AUTHSTATE_AWAITING_SIG, - OTRL_AUTHSTATE_V1_SETUP + OTRL_AUTHSTATE_NONE, + OTRL_AUTHSTATE_AWAITING_DHKEY, + OTRL_AUTHSTATE_AWAITING_REVEALSIG, + OTRL_AUTHSTATE_AWAITING_SIG, + OTRL_AUTHSTATE_V1_SETUP } OtrlAuthState; typedef struct { - OtrlAuthState authstate; /* Our state */ + OtrlAuthState authstate; /* Our state */ - DH_keypair our_dh; /* Our D-H key */ - unsigned int our_keyid; /* ...and its keyid */ + DH_keypair our_dh; /* Our D-H key */ + unsigned int our_keyid; /* ...and its keyid */ - unsigned char *encgx; /* The encrypted value of g^x */ - size_t encgx_len; /* ...and its length */ - unsigned char r[16]; /* The encryption key */ + unsigned char *encgx; /* The encrypted value of g^x */ + size_t encgx_len; /* ...and its length */ + unsigned char r[16]; /* The encryption key */ - unsigned char hashgx[32]; /* SHA256(g^x) */ + unsigned char hashgx[32]; /* SHA256(g^x) */ - gcry_mpi_t their_pub; /* Their D-H public key */ - unsigned int their_keyid; /* ...and its keyid */ + gcry_mpi_t their_pub; /* Their D-H public key */ + unsigned int their_keyid; /* ...and its keyid */ - gcry_cipher_hd_t enc_c, enc_cp; /* c and c' encryption keys */ - gcry_md_hd_t mac_m1, mac_m1p; /* m1 and m1' MAC keys */ - gcry_md_hd_t mac_m2, mac_m2p; /* m2 and m2' MAC keys */ + gcry_cipher_hd_t enc_c, enc_cp; /* c and c' encryption keys */ + gcry_md_hd_t mac_m1, mac_m1p; /* m1 and m1' MAC keys */ + gcry_md_hd_t mac_m2, mac_m2p; /* m2 and m2' MAC keys */ - unsigned char their_fingerprint[20]; /* The fingerprint of their - long-term signing key */ + unsigned char their_fingerprint[20]; /* The fingerprint of their + long-term signing key */ - int initiated; /* Did we initiate this - authentication? */ + int initiated; /* Did we initiate this + authentication? */ - unsigned int protocol_version; /* The protocol version number - used to authenticate. */ + unsigned int protocol_version; /* The protocol version number + used to authenticate. */ - unsigned char secure_session_id[20]; /* The secure session id */ - size_t secure_session_id_len; /* And its actual length, - which may be either 20 (for - v1) or 8 (for v2) */ - OtrlSessionIdHalf session_id_half; /* Which half of the session - id gets shown in bold */ + unsigned char secure_session_id[20]; /* The secure session id */ + size_t secure_session_id_len; /* And its actual length, + which may be either 20 (for + v1) or 8 (for v2) */ + OtrlSessionIdHalf session_id_half; /* Which half of the session + id gets shown in bold */ - char *lastauthmsg; /* The last auth message - (base-64 encoded) we sent, - in case we need to - retransmit it. */ + char *lastauthmsg; /* The last auth message + (base-64 encoded) we sent, + in case we need to + retransmit it. */ } OtrlAuthInfo; #include "privkey-t.h" diff --git a/libotr-3.2.0/src/context.c b/libotr-3.2.0/src/context.c index e1601ec..8807b89 100644 --- a/libotr-3.2.0/src/context.c +++ b/libotr-3.2.0/src/context.c @@ -31,60 +31,60 @@ static ConnContext * new_context(const char * user, const char * accountname, const char * protocol) { - ConnContext * context; - OtrlSMState *smstate; - context = malloc(sizeof(*context)); - assert(context != NULL); - context->username = strdup(user); - context->accountname = strdup(accountname); - context->protocol = strdup(protocol); - context->fragment = NULL; - context->fragment_len = 0; - context->fragment_n = 0; - context->fragment_k = 0; - context->msgstate = OTRL_MSGSTATE_PLAINTEXT; - otrl_auth_new(&(context->auth)); + ConnContext * context; + OtrlSMState *smstate; + context = malloc(sizeof(*context)); + assert(context != NULL); + context->username = _strdup(user); + context->accountname = _strdup(accountname); + context->protocol = _strdup(protocol); + context->fragment = NULL; + context->fragment_len = 0; + context->fragment_n = 0; + context->fragment_k = 0; + context->msgstate = OTRL_MSGSTATE_PLAINTEXT; + otrl_auth_new(&(context->auth)); - smstate = malloc(sizeof(OtrlSMState)); - assert(smstate != NULL); - otrl_sm_state_new(smstate); - context->smstate = smstate; + smstate = malloc(sizeof(OtrlSMState)); + assert(smstate != NULL); + otrl_sm_state_new(smstate); + context->smstate = smstate; - context->fingerprint_root.fingerprint = NULL; - context->fingerprint_root.context = context; - context->fingerprint_root.next = NULL; - context->fingerprint_root.tous = NULL; - context->active_fingerprint = NULL; - context->their_keyid = 0; - context->their_y = NULL; - context->their_old_y = NULL; - context->our_keyid = 0; - context->our_dh_key.groupid = 0; - context->our_dh_key.priv = NULL; - context->our_dh_key.pub = NULL; - context->our_old_dh_key.groupid = 0; - context->our_old_dh_key.priv = NULL; - context->our_old_dh_key.pub = NULL; - otrl_dh_session_blank(&(context->sesskeys[0][0])); - otrl_dh_session_blank(&(context->sesskeys[0][1])); - otrl_dh_session_blank(&(context->sesskeys[1][0])); - otrl_dh_session_blank(&(context->sesskeys[1][1])); - memset(context->sessionid, 0, 20); - context->sessionid_len = 0; - context->protocol_version = 0; - context->numsavedkeys = 0; - context->preshared_secret = NULL; - context->preshared_secret_len = 0; - context->saved_mac_keys = NULL; - context->generation = 0; - context->lastsent = 0; - context->lastmessage = NULL; - context->may_retransmit = 0; - context->otr_offer = OFFER_NOT; - context->app_data = NULL; - context->app_data_free = NULL; - context->next = NULL; - return context; + context->fingerprint_root.fingerprint = NULL; + context->fingerprint_root.context = context; + context->fingerprint_root.next = NULL; + context->fingerprint_root.tous = NULL; + context->active_fingerprint = NULL; + context->their_keyid = 0; + context->their_y = NULL; + context->their_old_y = NULL; + context->our_keyid = 0; + context->our_dh_key.groupid = 0; + context->our_dh_key.priv = NULL; + context->our_dh_key.pub = NULL; + context->our_old_dh_key.groupid = 0; + context->our_old_dh_key.priv = NULL; + context->our_old_dh_key.pub = NULL; + otrl_dh_session_blank(&(context->sesskeys[0][0])); + otrl_dh_session_blank(&(context->sesskeys[0][1])); + otrl_dh_session_blank(&(context->sesskeys[1][0])); + otrl_dh_session_blank(&(context->sesskeys[1][1])); + memset(context->sessionid, 0, 20); + context->sessionid_len = 0; + context->protocol_version = 0; + context->numsavedkeys = 0; + context->preshared_secret = NULL; + context->preshared_secret_len = 0; + context->saved_mac_keys = NULL; + context->generation = 0; + context->lastsent = 0; + context->lastmessage = NULL; + context->may_retransmit = 0; + context->otr_offer = OFFER_NOT; + context->app_data = NULL; + context->app_data_free = NULL; + context->next = NULL; + return context; } ConnContext * otrl_context_new(const char * user, const char * accountname, @@ -103,40 +103,40 @@ ConnContext * otrl_context_find(OtrlUserState us, const char *user, int *addedp, void (*add_app_data)(void *data, ConnContext *context), void *data) { - ConnContext ** curp; - int usercmp = 1, acctcmp = 1, protocmp = 1; - if (addedp) *addedp = 0; - if (!user || !accountname || !protocol) return NULL; - for (curp = &(us->context_root); *curp; curp = &((*curp)->next)) { - if ((usercmp = strcmp((*curp)->username, user)) > 0 || + ConnContext ** curp; + int usercmp = 1, acctcmp = 1, protocmp = 1; + if (addedp) *addedp = 0; + if (!user || !accountname || !protocol) return NULL; + for (curp = &(us->context_root); *curp; curp = &((*curp)->next)) { + if ((usercmp = strcmp((*curp)->username, user)) > 0 || (usercmp == 0 && (acctcmp = strcmp((*curp)->accountname, accountname)) > 0) || (usercmp == 0 && acctcmp == 0 && (protocmp = strcmp((*curp)->protocol, protocol)) >= 0)) - /* We're at the right place in the list. We've either found - * it, or gone too far. */ - break; - } - if (usercmp == 0 && acctcmp == 0 && protocmp == 0) { + /* We're at the right place in the list. We've either found + * it, or gone too far. */ + break; + } + if (usercmp == 0 && acctcmp == 0 && protocmp == 0) { /* Found it! */ return *curp; - } - if (add_if_missing) { + } + if (add_if_missing) { ConnContext *newctx; if (addedp) *addedp = 1; newctx = new_context(user, accountname, protocol); newctx->next = *curp; if (*curp) { - (*curp)->tous = &(newctx->next); + (*curp)->tous = &(newctx->next); } *curp = newctx; newctx->tous = curp; if (add_app_data) { - add_app_data(data, *curp); + add_app_data(data, *curp); } return *curp; - } - return NULL; + } + return NULL; } /* Find a fingerprint in a given context, perhaps adding it if not @@ -144,14 +144,14 @@ ConnContext * otrl_context_find(OtrlUserState us, const char *user, Fingerprint *otrl_context_find_fingerprint(ConnContext *context, unsigned char fingerprint[20], int add_if_missing, int *addedp) { - Fingerprint *f = context->fingerprint_root.next; - if (addedp) *addedp = 0; - while(f) { + Fingerprint *f = context->fingerprint_root.next; + if (addedp) *addedp = 0; + while(f) { if (!memcmp(f->fingerprint, fingerprint, 20)) return f; f = f->next; - } - /* Didn't find it. */ - if (add_if_missing) { + } + /* Didn't find it. */ + if (add_if_missing) { if (addedp) *addedp = 1; f = malloc(sizeof(*f)); assert(f != NULL); @@ -162,22 +162,22 @@ Fingerprint *otrl_context_find_fingerprint(ConnContext *context, f->trust = NULL; f->next = context->fingerprint_root.next; if (f->next) { - f->next->tous = &(f->next); + f->next->tous = &(f->next); } context->fingerprint_root.next = f; f->tous = &(context->fingerprint_root.next); return f; - } - return NULL; + } + return NULL; } /* Set the trust level for a given fingerprint */ void otrl_context_set_trust(Fingerprint *fprint, const char *trust) { - if (fprint == NULL) return; + if (fprint == NULL) return; - free(fprint->trust); - fprint->trust = trust ? strdup(trust) : NULL; + free(fprint->trust); + fprint->trust = trust ? _strdup(trust) : NULL; } /* Set the preshared secret for a given fingerprint. Note that this @@ -186,65 +186,65 @@ void otrl_context_set_trust(Fingerprint *fprint, const char *trust) void otrl_context_set_preshared_secret(ConnContext *context, const unsigned char *secret, size_t secret_len) { - free(context->preshared_secret); - context->preshared_secret = NULL; - context->preshared_secret_len = 0; + free(context->preshared_secret); + context->preshared_secret = NULL; + context->preshared_secret_len = 0; - if (secret_len) { + if (secret_len) { context->preshared_secret = malloc(secret_len); if (context->preshared_secret) { - memmove(context->preshared_secret, secret, secret_len); - context->preshared_secret_len = secret_len; + memmove(context->preshared_secret, secret, secret_len); + context->preshared_secret_len = secret_len; + } } - } } /* Force a context into the OTRL_MSGSTATE_FINISHED state. */ void otrl_context_force_finished(ConnContext *context) { - context->msgstate = OTRL_MSGSTATE_FINISHED; - otrl_auth_clear(&(context->auth)); - free(context->fragment); - context->fragment = NULL; - context->fragment_len = 0; - context->fragment_n = 0; - context->fragment_k = 0; - context->active_fingerprint = NULL; - context->their_keyid = 0; - gcry_mpi_release(context->their_y); - context->their_y = NULL; - gcry_mpi_release(context->their_old_y); - context->their_old_y = NULL; - context->our_keyid = 0; - otrl_dh_keypair_free(&(context->our_dh_key)); - otrl_dh_keypair_free(&(context->our_old_dh_key)); - otrl_dh_session_free(&(context->sesskeys[0][0])); - otrl_dh_session_free(&(context->sesskeys[0][1])); - otrl_dh_session_free(&(context->sesskeys[1][0])); - otrl_dh_session_free(&(context->sesskeys[1][1])); - memset(context->sessionid, 0, 20); - context->sessionid_len = 0; - free(context->preshared_secret); - context->preshared_secret = NULL; - context->preshared_secret_len = 0; - context->protocol_version = 0; - context->numsavedkeys = 0; - free(context->saved_mac_keys); - context->saved_mac_keys = NULL; - gcry_free(context->lastmessage); - context->lastmessage = NULL; - context->may_retransmit = 0; - otrl_sm_state_free(context->smstate); + context->msgstate = OTRL_MSGSTATE_FINISHED; + otrl_auth_clear(&(context->auth)); + free(context->fragment); + context->fragment = NULL; + context->fragment_len = 0; + context->fragment_n = 0; + context->fragment_k = 0; + context->active_fingerprint = NULL; + context->their_keyid = 0; + gcry_mpi_release(context->their_y); + context->their_y = NULL; + gcry_mpi_release(context->their_old_y); + context->their_old_y = NULL; + context->our_keyid = 0; + otrl_dh_keypair_free(&(context->our_dh_key)); + otrl_dh_keypair_free(&(context->our_old_dh_key)); + otrl_dh_session_free(&(context->sesskeys[0][0])); + otrl_dh_session_free(&(context->sesskeys[0][1])); + otrl_dh_session_free(&(context->sesskeys[1][0])); + otrl_dh_session_free(&(context->sesskeys[1][1])); + memset(context->sessionid, 0, 20); + context->sessionid_len = 0; + free(context->preshared_secret); + context->preshared_secret = NULL; + context->preshared_secret_len = 0; + context->protocol_version = 0; + context->numsavedkeys = 0; + free(context->saved_mac_keys); + context->saved_mac_keys = NULL; + gcry_free(context->lastmessage); + context->lastmessage = NULL; + context->may_retransmit = 0; + otrl_sm_state_free(context->smstate); } /* Force a context into the OTRL_MSGSTATE_PLAINTEXT state. */ void otrl_context_force_plaintext(ConnContext *context) { - /* First clean up everything we'd need to do for the FINISHED state */ - otrl_context_force_finished(context); + /* First clean up everything we'd need to do for the FINISHED state */ + otrl_context_force_finished(context); - /* And just set the state properly */ - context->msgstate = OTRL_MSGSTATE_PLAINTEXT; + /* And just set the state properly */ + context->msgstate = OTRL_MSGSTATE_PLAINTEXT; } /* Forget a fingerprint (so long as it's not the active one. If it's a @@ -255,76 +255,76 @@ void otrl_context_force_plaintext(ConnContext *context) void otrl_context_forget_fingerprint(Fingerprint *fprint, int and_maybe_context) { - ConnContext *context = fprint->context; - if (fprint == &(context->fingerprint_root)) { + ConnContext *context = fprint->context; + if (fprint == &(context->fingerprint_root)) { if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT && and_maybe_context) { - otrl_context_forget(context); + otrl_context_forget(context); } - } else { + } else { if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT || context->active_fingerprint != fprint) { - free(fprint->fingerprint); - free(fprint->trust); - *(fprint->tous) = fprint->next; - if (fprint->next) { + free(fprint->fingerprint); + free(fprint->trust); + *(fprint->tous) = fprint->next; + if (fprint->next) { fprint->next->tous = fprint->tous; - } - free(fprint); - if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT && - context->fingerprint_root.next == NULL && - and_maybe_context) { + } + free(fprint); + if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT && + context->fingerprint_root.next == NULL && + and_maybe_context) { /* We just deleted the only fingerprint. Forget the * whole thing. */ otrl_context_forget(context); - } + } + } } - } } /* Forget a whole context, so long as it's PLAINTEXT. */ void otrl_context_forget(ConnContext *context) { - if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT) return; + if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT) return; - /* Just to be safe, force to plaintext. This also frees any - * extraneous data lying around. */ - otrl_context_force_plaintext(context); + /* Just to be safe, force to plaintext. This also frees any + * extraneous data lying around. */ + otrl_context_force_plaintext(context); - /* First free all the Fingerprints */ - while(context->fingerprint_root.next) { + /* First free all the Fingerprints */ + while(context->fingerprint_root.next) { otrl_context_forget_fingerprint(context->fingerprint_root.next, 0); - } - /* Now free all the dynamic info here */ - free(context->username); - free(context->accountname); - free(context->protocol); - free(context->smstate); - context->username = NULL; - context->accountname = NULL; - context->protocol = NULL; - context->smstate = NULL; + } + /* Now free all the dynamic info here */ + free(context->username); + free(context->accountname); + free(context->protocol); + free(context->smstate); + context->username = NULL; + context->accountname = NULL; + context->protocol = NULL; + context->smstate = NULL; - /* Free the application data, if it exists */ - if (context->app_data && context->app_data_free) { + /* Free the application data, if it exists */ + if (context->app_data && context->app_data_free) { (context->app_data_free)(context->app_data); context->app_data = NULL; - } + } - /* Fix the list linkages */ - *(context->tous) = context->next; - if (context->next) { + /* Fix the list linkages */ + *(context->tous) = context->next; + if (context->next) { context->next->tous = context->tous; - } + } - free(context); + free(context); } /* Forget all the contexts in a given OtrlUserState. */ void otrl_context_forget_all(OtrlUserState us) { - while (us->context_root) { + while (us->context_root) { otrl_context_force_plaintext(us->context_root); otrl_context_forget(us->context_root); - } + } } diff --git a/libotr-3.2.0/src/message.c b/libotr-3.2.0/src/message.c index 704bb5c..06c3347 100644 --- a/libotr-3.2.0/src/message.c +++ b/libotr-3.2.0/src/message.c @@ -45,7 +45,7 @@ extern unsigned int otrl_api_version; /* Deallocate a message allocated by other otrl_message_* routines. */ void otrl_message_free(char *message) { - free(message); + free(message); } /* Handle a message about to be sent to the network. It is safe to pass @@ -76,62 +76,62 @@ gcry_error_t otrl_message_sending(OtrlUserState us, void (*add_appdata)(void *data, ConnContext *context), void *data) { - struct context * context; - char * msgtosend; - gcry_error_t err; - OtrlPolicy policy = OTRL_POLICY_DEFAULT; - int context_added = 0; + struct context * context; + char * msgtosend; + gcry_error_t err; + OtrlPolicy policy = OTRL_POLICY_DEFAULT; + int context_added = 0; - *messagep = NULL; + *messagep = NULL; - if (!accountname || !protocol || !recipient || !message || !messagep) - return gcry_error(GPG_ERR_NO_ERROR); + if (!accountname || !protocol || !recipient || !message || !messagep) + return gcry_error(GPG_ERR_NO_ERROR); - /* See if we have a fingerprint for this user */ - context = otrl_context_find(us, recipient, accountname, protocol, - 1, &context_added, add_appdata, data); + /* See if we have a fingerprint for this user */ + context = otrl_context_find(us, recipient, accountname, protocol, + 1, &context_added, add_appdata, data); - /* Update the context list if we added one */ - if (context_added && ops->update_context_list) { + /* Update the context list if we added one */ + if (context_added && ops->update_context_list) { ops->update_context_list(opdata); - } + } - /* Check the policy */ - if (ops->policy) { + /* Check the policy */ + if (ops->policy) { policy = ops->policy(opdata, context); - } + } - /* Should we go on at all? */ - if ((policy & OTRL_POLICY_VERSION_MASK) == 0) { - return gcry_error(GPG_ERR_NO_ERROR); - } + /* Should we go on at all? */ + if ((policy & OTRL_POLICY_VERSION_MASK) == 0) { + return gcry_error(GPG_ERR_NO_ERROR); + } - /* If this is an OTR Query message, don't encrypt it. */ - if (otrl_proto_message_type(message) == OTRL_MSGTYPE_QUERY) { + /* If this is an OTR Query message, don't encrypt it. */ + if (otrl_proto_message_type(message) == OTRL_MSGTYPE_QUERY) { /* Replace the "?OTR?" with a custom message */ char *bettermsg = otrl_proto_default_query_msg(accountname, policy); if (bettermsg) { - *messagep = bettermsg; + *messagep = bettermsg; } return gcry_error(GPG_ERR_NO_ERROR); - } + } - /* What is the current message disposition? */ - switch(context->msgstate) { + /* What is the current message disposition? */ + switch(context->msgstate) { case OTRL_MSGSTATE_PLAINTEXT: - if ((policy & OTRL_POLICY_REQUIRE_ENCRYPTION)) { + if ((policy & OTRL_POLICY_REQUIRE_ENCRYPTION)) { /* We're trying to send an unencrypted message with a policy * that disallows that. Don't do that, but try to start * up OTR instead. */ if ((!(ops->display_otr_message) || ops->display_otr_message(opdata, accountname, - protocol, recipient, "Attempting to start a " - "private conversation...")) && ops->notify) { - const char *format = "You attempted to send an " + protocol, recipient, "Attempting to start a " + "private conversation...")) && ops->notify) { + const char *format = "You attempted to send an " "unencrypted message to %s"; - char *primary = malloc(strlen(format) + - strlen(recipient) - 1); - if (primary) { + char *primary = malloc(strlen(format) + + strlen(recipient) - 1); + if (primary) { sprintf(primary, format, recipient); ops->notify(opdata, OTRL_NOTIFY_WARNING, accountname, protocol, recipient, "OTR Policy Violation", @@ -142,108 +142,108 @@ gcry_error_t otrl_message_sending(OtrlUserState us, "retransmitted when the private conversation " "starts."); free(primary); - } + } } context->lastmessage = gcry_malloc_secure(strlen(message) + 1); if (context->lastmessage) { - char *bettermsg = otrl_proto_default_query_msg(accountname, - policy); - strcpy(context->lastmessage, message); - context->lastsent = time(NULL); - context->may_retransmit = 2; - if (bettermsg) { + char *bettermsg = otrl_proto_default_query_msg(accountname, + policy); + strcpy(context->lastmessage, message); + context->lastsent = time(NULL); + context->may_retransmit = 2; + if (bettermsg) { *messagep = bettermsg; - } else { + } else { return gcry_error(GPG_ERR_ENOMEM); - } + } } - } else { + } else { if ((policy & OTRL_POLICY_SEND_WHITESPACE_TAG) && context->otr_offer != OFFER_REJECTED) { - /* See if this user can speak OTR. Append the - * OTR_MESSAGE_TAG to the plaintext message, and see - * if he responds. */ - size_t msglen = strlen(message); - size_t basetaglen = strlen(OTRL_MESSAGE_TAG_BASE); - size_t v1taglen = (policy & OTRL_POLICY_ALLOW_V1) ? + /* See if this user can speak OTR. Append the + * OTR_MESSAGE_TAG to the plaintext message, and see + * if he responds. */ + size_t msglen = strlen(message); + size_t basetaglen = strlen(OTRL_MESSAGE_TAG_BASE); + size_t v1taglen = (policy & OTRL_POLICY_ALLOW_V1) ? strlen(OTRL_MESSAGE_TAG_V1) : 0; - size_t v2taglen = (policy & OTRL_POLICY_ALLOW_V2) ? + size_t v2taglen = (policy & OTRL_POLICY_ALLOW_V2) ? strlen(OTRL_MESSAGE_TAG_V2) : 0; - char *taggedmsg = malloc(msglen + basetaglen + v1taglen - +v2taglen + 1); - if (taggedmsg) { + char *taggedmsg = malloc(msglen + basetaglen + v1taglen + +v2taglen + 1); + if (taggedmsg) { strcpy(taggedmsg, message); strcpy(taggedmsg + msglen, OTRL_MESSAGE_TAG_BASE); if (v1taglen) { - strcpy(taggedmsg + msglen + basetaglen, - OTRL_MESSAGE_TAG_V1); + strcpy(taggedmsg + msglen + basetaglen, + OTRL_MESSAGE_TAG_V1); } if (v2taglen) { - strcpy(taggedmsg + msglen + basetaglen + v1taglen, - OTRL_MESSAGE_TAG_V2); + strcpy(taggedmsg + msglen + basetaglen + v1taglen, + OTRL_MESSAGE_TAG_V2); } *messagep = taggedmsg; if (context) { - context->otr_offer = OFFER_SENT; + context->otr_offer = OFFER_SENT; } - } + } + } } - } - break; + break; case OTRL_MSGSTATE_ENCRYPTED: - /* Create the new, encrypted message */ - err = otrl_proto_create_data(&msgtosend, context, message, tlvs, - 0); - if (!err) { + /* Create the new, encrypted message */ + err = otrl_proto_create_data(&msgtosend, context, message, tlvs, + 0); + if (!err) { context->lastsent = time(NULL); *messagep = msgtosend; - } else { + } else { /* Uh, oh. Whatever we do, *don't* send the message in the * clear. */ - *messagep = strdup("?OTR Error: Error occurred encrypting " + *messagep = _strdup("?OTR Error: Error occurred encrypting " "message"); if ((!(ops->display_otr_message) || ops->display_otr_message(opdata, accountname, - protocol, recipient, "An error occurred when " - "encrypting your message. The message was not " - "sent.")) && ops->notify) { - ops->notify(opdata, OTRL_NOTIFY_ERROR, - accountname, protocol, recipient, - "Error encrypting message", - "An error occurred when encrypting your message", - "The message was not sent."); + protocol, recipient, "An error occurred when " + "encrypting your message. The message was not " + "sent.")) && ops->notify) { + ops->notify(opdata, OTRL_NOTIFY_ERROR, + accountname, protocol, recipient, + "Error encrypting message", + "An error occurred when encrypting your message", + "The message was not sent."); } if (!(*messagep)) { - return gcry_error(GPG_ERR_ENOMEM); + return gcry_error(GPG_ERR_ENOMEM); + } } - } - break; + break; case OTRL_MSGSTATE_FINISHED: - *messagep = strdup(""); - if ((!(ops->display_otr_message) || - ops->display_otr_message(opdata, accountname, + *messagep = _strdup(""); + if ((!(ops->display_otr_message) || + ops->display_otr_message(opdata, accountname, protocol, recipient, "Your message was not sent. " "Either end your private conversation, or restart " "it.")) && ops->notify) { const char *fmt = "%s has already closed his/her private " - "connection to you"; + "connection to you"; char *primary = malloc(strlen(fmt) + strlen(recipient) - 1); if (primary) { - sprintf(primary, fmt, recipient); - ops->notify(opdata, OTRL_NOTIFY_ERROR, - accountname, protocol, recipient, - "Private connection closed", primary, - "Your message was not sent. Either close your " - "private connection to him, or refresh it."); + sprintf(primary, fmt, recipient); + ops->notify(opdata, OTRL_NOTIFY_ERROR, + accountname, protocol, recipient, + "Private connection closed", primary, + "Your message was not sent. Either close your " + "private connection to him, or refresh it."); } - } - if (!(*messagep)) { + } + if (!(*messagep)) { return gcry_error(GPG_ERR_ENOMEM); - } - break; - } + } + break; + } - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } /* If err == 0, send the last auth message for the given context to the @@ -252,76 +252,76 @@ gcry_error_t otrl_message_sending(OtrlUserState us, static gcry_error_t send_or_error_auth(const OtrlMessageAppOps *ops, void *opdata, gcry_error_t err, ConnContext *context) { - if (!err) { + if (!err) { const char *msg = context->auth.lastauthmsg; if (msg && *msg) { - otrl_message_fragment_and_send(ops, opdata, context, msg, OTRL_FRAGMENT_SEND_ALL, NULL); - /*if (ops->inject_message) { + otrl_message_fragment_and_send(ops, opdata, context, msg, OTRL_FRAGMENT_SEND_ALL, NULL); + /*if (ops->inject_message) { ops->inject_message(opdata, context->accountname, context->protocol, context->username, msg); - }*/ + }*/ } - } else { + } else { const char *buf_format = "Error setting up private conversation: %s"; const char *strerr; char *buf; switch(gcry_err_code(err)) { - case GPG_ERR_INV_VALUE: + case GPG_ERR_INV_VALUE: strerr = "Malformed message received"; break; - default: + default: strerr = gcry_strerror(err); break; } buf = malloc(strlen(buf_format) + strlen(strerr) - 1); if (buf) { - sprintf(buf, buf_format, strerr); + sprintf(buf, buf_format, strerr); } if ((!(ops->display_otr_message) || ops->display_otr_message(opdata, context->accountname, - context->protocol, context->username, buf)) + context->protocol, context->username, buf)) && ops->notify) { - ops->notify(opdata, OTRL_NOTIFY_ERROR, context->accountname, - context->protocol, context->username, "OTR error", - buf, NULL); + ops->notify(opdata, OTRL_NOTIFY_ERROR, context->accountname, + context->protocol, context->username, "OTR error", + buf, NULL); } free(buf); - } - return err; + } + return err; } typedef struct { - int gone_encrypted; - OtrlUserState us; - const OtrlMessageAppOps *ops; - void *opdata; - ConnContext *context; - int ignore_message; - char **messagep; + int gone_encrypted; + OtrlUserState us; + const OtrlMessageAppOps *ops; + void *opdata; + ConnContext *context; + int ignore_message; + char **messagep; } EncrData; static gcry_error_t go_encrypted(const OtrlAuthInfo *auth, void *asdata) { - EncrData *edata = asdata; - gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); - Fingerprint *found_print = NULL; - int fprint_added = 0; - OtrlMessageState oldstate = edata->context->msgstate; - Fingerprint *oldprint = edata->context->active_fingerprint; - - /* See if we're talking to ourselves */ - if (!gcry_mpi_cmp(auth->their_pub, auth->our_dh.pub)) { + EncrData *edata = asdata; + gcry_error_t err = gcry_error(GPG_ERR_NO_ERROR); + Fingerprint *found_print = NULL; + int fprint_added = 0; + OtrlMessageState oldstate = edata->context->msgstate; + Fingerprint *oldprint = edata->context->active_fingerprint; + + /* See if we're talking to ourselves */ + if (!gcry_mpi_cmp(auth->their_pub, auth->our_dh.pub)) { /* Yes, we are. */ if ((!(edata->ops->display_otr_message) || edata->ops->display_otr_message(edata->opdata, - edata->context->accountname, edata->context->protocol, - edata->context->username, - "We are receiving our own OTR messages. " - "You are either trying to talk to yourself, " - "or someone is reflecting your messages back " - "at you.")) && edata->ops->notify) { - edata->ops->notify(edata->opdata, OTRL_NOTIFY_ERROR, + edata->context->accountname, edata->context->protocol, + edata->context->username, + "We are receiving our own OTR messages. " + "You are either trying to talk to yourself, " + "or someone is reflecting your messages back " + "at you.")) && edata->ops->notify) { + edata->ops->notify(edata->opdata, OTRL_NOTIFY_ERROR, edata->context->accountname, edata->context->protocol, edata->context->username, "OTR Error", "We are receiving our own OTR messages.", @@ -331,70 +331,70 @@ static gcry_error_t go_encrypted(const OtrlAuthInfo *auth, void *asdata) } edata->ignore_message = 1; return gcry_error(GPG_ERR_NO_ERROR); - } + } - found_print = otrl_context_find_fingerprint(edata->context, - edata->context->auth.their_fingerprint, 1, &fprint_added); + found_print = otrl_context_find_fingerprint(edata->context, + edata->context->auth.their_fingerprint, 1, &fprint_added); - if (fprint_added) { + if (fprint_added) { /* Inform the user of the new fingerprint */ if (edata->ops->new_fingerprint) { - edata->ops->new_fingerprint(edata->opdata, edata->us, - edata->context->accountname, edata->context->protocol, - edata->context->username, - edata->context->auth.their_fingerprint); + edata->ops->new_fingerprint(edata->opdata, edata->us, + edata->context->accountname, edata->context->protocol, + edata->context->username, + edata->context->auth.their_fingerprint); } /* Arrange that the new fingerprint be written to disk */ if (edata->ops->write_fingerprints) { - edata->ops->write_fingerprints(edata->opdata); + edata->ops->write_fingerprints(edata->opdata); + } } - } - /* Is this a new session or just a refresh of an existing one? */ - if (edata->context->msgstate == OTRL_MSGSTATE_ENCRYPTED && - oldprint == found_print && - edata->context->our_keyid - 1 == edata->context->auth.our_keyid && - !gcry_mpi_cmp(edata->context->our_old_dh_key.pub, + /* Is this a new session or just a refresh of an existing one? */ + if (edata->context->msgstate == OTRL_MSGSTATE_ENCRYPTED && + oldprint == found_print && + edata->context->our_keyid - 1 == edata->context->auth.our_keyid && + !gcry_mpi_cmp(edata->context->our_old_dh_key.pub, edata->context->auth.our_dh.pub) && - ((edata->context->their_keyid > 0 && - edata->context->their_keyid == - edata->context->auth.their_keyid && - !gcry_mpi_cmp(edata->context->their_y, + ((edata->context->their_keyid > 0 && + edata->context->their_keyid == + edata->context->auth.their_keyid && + !gcry_mpi_cmp(edata->context->their_y, edata->context->auth.their_pub)) || - (edata->context->their_keyid > 1 && - edata->context->their_keyid - 1 == - edata->context->auth.their_keyid && - edata->context->their_old_y != NULL && - !gcry_mpi_cmp(edata->context->their_old_y, + (edata->context->their_keyid > 1 && + edata->context->their_keyid - 1 == + edata->context->auth.their_keyid && + edata->context->their_old_y != NULL && + !gcry_mpi_cmp(edata->context->their_old_y, edata->context->auth.their_pub)))) { /* This is just a refresh of the existing session. */ if (edata->ops->still_secure) { - edata->ops->still_secure(edata->opdata, edata->context, - edata->context->auth.initiated); + edata->ops->still_secure(edata->opdata, edata->context, + edata->context->auth.initiated); } edata->ignore_message = 1; return gcry_error(GPG_ERR_NO_ERROR); - } + } - /* Copy the information from the auth into the context */ - memmove(edata->context->sessionid, - edata->context->auth.secure_session_id, 20); - edata->context->sessionid_len = + /* Copy the information from the auth into the context */ + memmove(edata->context->sessionid, + edata->context->auth.secure_session_id, 20); + edata->context->sessionid_len = edata->context->auth.secure_session_id_len; - edata->context->sessionid_half = + edata->context->sessionid_half = edata->context->auth.session_id_half; - edata->context->protocol_version = + edata->context->protocol_version = edata->context->auth.protocol_version; - edata->context->their_keyid = edata->context->auth.their_keyid; - gcry_mpi_release(edata->context->their_y); - gcry_mpi_release(edata->context->their_old_y); - edata->context->their_y = gcry_mpi_copy(edata->context->auth.their_pub); - edata->context->their_old_y = NULL; + edata->context->their_keyid = edata->context->auth.their_keyid; + gcry_mpi_release(edata->context->their_y); + gcry_mpi_release(edata->context->their_old_y); + edata->context->their_y = gcry_mpi_copy(edata->context->auth.their_pub); + edata->context->their_old_y = NULL; - if (edata->context->our_keyid - 1 != edata->context->auth.our_keyid || + if (edata->context->our_keyid - 1 != edata->context->auth.our_keyid || gcry_mpi_cmp(edata->context->our_old_dh_key.pub, - edata->context->auth.our_dh.pub)) { + edata->context->auth.our_dh.pub)) { otrl_dh_keypair_free(&(edata->context->our_dh_key)); otrl_dh_keypair_free(&(edata->context->our_old_dh_key)); otrl_dh_keypair_copy(&(edata->context->our_old_dh_key), @@ -402,53 +402,53 @@ static gcry_error_t go_encrypted(const OtrlAuthInfo *auth, void *asdata) otrl_dh_gen_keypair(edata->context->our_old_dh_key.groupid, &(edata->context->our_dh_key)); edata->context->our_keyid = edata->context->auth.our_keyid + 1; - } + } - /* Create the session keys from the DH keys */ - otrl_dh_session_free(&(edata->context->sesskeys[0][0])); - err = otrl_dh_session(&(edata->context->sesskeys[0][0]), + /* Create the session keys from the DH keys */ + otrl_dh_session_free(&(edata->context->sesskeys[0][0])); + err = otrl_dh_session(&(edata->context->sesskeys[0][0]), &(edata->context->our_dh_key), edata->context->their_y); - if (err) return err; - otrl_dh_session_free(&(edata->context->sesskeys[1][0])); - err = otrl_dh_session(&(edata->context->sesskeys[1][0]), + if (err) return err; + otrl_dh_session_free(&(edata->context->sesskeys[1][0])); + err = otrl_dh_session(&(edata->context->sesskeys[1][0]), &(edata->context->our_old_dh_key), edata->context->their_y); - if (err) return err; + if (err) return err; - edata->context->generation++; - edata->context->active_fingerprint = found_print; - edata->context->msgstate = OTRL_MSGSTATE_ENCRYPTED; + edata->context->generation++; + edata->context->active_fingerprint = found_print; + edata->context->msgstate = OTRL_MSGSTATE_ENCRYPTED; - if (edata->ops->update_context_list) { + if (edata->ops->update_context_list) { edata->ops->update_context_list(edata->opdata); - } - if (oldstate == OTRL_MSGSTATE_ENCRYPTED && oldprint == found_print) { + } + if (oldstate == OTRL_MSGSTATE_ENCRYPTED && oldprint == found_print) { if (edata->ops->still_secure) { - edata->ops->still_secure(edata->opdata, edata->context, - edata->context->auth.initiated); + edata->ops->still_secure(edata->opdata, edata->context, + edata->context->auth.initiated); } - } else { + } else { if (edata->ops->gone_secure) { - edata->ops->gone_secure(edata->opdata, edata->context); + edata->ops->gone_secure(edata->opdata, edata->context); + } } - } - edata->gone_encrypted = 1; + edata->gone_encrypted = 1; - return gpg_error(GPG_ERR_NO_ERROR); + return gpg_error(GPG_ERR_NO_ERROR); } static void maybe_resend(EncrData *edata) { - gcry_error_t err; - time_t now; + gcry_error_t err; + time_t now; - if (!edata->gone_encrypted) return; + if (!edata->gone_encrypted) return; - /* See if there's a message we sent recently that should be resent. */ - now = time(NULL); - if (edata->context->lastmessage != NULL && - edata->context->may_retransmit && - edata->context->lastsent >= (now - RESEND_INTERVAL)) { + /* See if there's a message we sent recently that should be resent. */ + now = time(NULL); + if (edata->context->lastmessage != NULL && + edata->context->may_retransmit && + edata->context->lastsent >= (now - RESEND_INTERVAL)) { char *resendmsg; int resending = (edata->context->may_retransmit == 1); @@ -456,143 +456,143 @@ static void maybe_resend(EncrData *edata) err = otrl_proto_create_data(&resendmsg, edata->context, edata->context->lastmessage, NULL, 0); if (!err) { - const char *format = "<b>The last message " + const char *format = "<b>The last message " "to %s was resent.</b>"; - char *buf; + char *buf; - /* Resend the message */ - otrl_message_fragment_and_send(edata->ops, edata->opdata, edata->context, resendmsg, OTRL_FRAGMENT_SEND_ALL, NULL); - free(resendmsg); - edata->context->lastsent = now; + /* Resend the message */ + otrl_message_fragment_and_send(edata->ops, edata->opdata, edata->context, resendmsg, OTRL_FRAGMENT_SEND_ALL, NULL); + free(resendmsg); + edata->context->lastsent = now; - if (!resending) { + if (!resending) { /* We're actually just sending it * for the first time. */ edata->ignore_message = 1; - } else { + } else { /* Let the user know we resent it */ buf = malloc(strlen(format) + strlen(edata->context->username) - 1); if (buf) { - sprintf(buf, format, edata->context->username); - if (edata->ops->display_otr_message) { + sprintf(buf, format, edata->context->username); + if (edata->ops->display_otr_message) { if (!edata->ops->display_otr_message( - edata->opdata, edata->context->accountname, - edata->context->protocol, - edata->context->username, buf)) { - edata->ignore_message = 1; + edata->opdata, edata->context->accountname, + edata->context->protocol, + edata->context->username, buf)) { + edata->ignore_message = 1; } - } - if (edata->ignore_message != 1) { + } + if (edata->ignore_message != 1) { *(edata->messagep) = buf; edata->ignore_message = 0; - } else { + } else { free(buf); - } + } } - } + } + } } - } } /* Set the trust level based on the result of the SMP */ static void set_smp_trust(const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, int trusted) { - otrl_context_set_trust(context->active_fingerprint, trusted ? "smp" : ""); + otrl_context_set_trust(context->active_fingerprint, trusted ? "smp" : ""); - /* Write the new info to disk, redraw the ui, and redraw the - * OTR buttons. */ - if (ops->write_fingerprints) { + /* Write the new info to disk, redraw the ui, and redraw the + * OTR buttons. */ + if (ops->write_fingerprints) { ops->write_fingerprints(opdata); - } + } } static void init_respond_smp(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, const char *question, const unsigned char *secret, size_t secretlen, int initiating) { - unsigned char *smpmsg = NULL; - int smpmsglen; - unsigned char combined_secret[SM_DIGEST_SIZE]; - gcry_error_t err; - unsigned char our_fp[20]; - unsigned char *combined_buf; - size_t combined_buf_len; - OtrlTLV *sendtlv; - char *sendsmp = NULL; - - if (!context || context->msgstate != OTRL_MSGSTATE_ENCRYPTED) return; - - /* - * Construct the combined secret as a SHA256 hash of: - * Version byte (0x01), Initiator fingerprint (20 bytes), - * responder fingerprint (20 bytes), secure session id, input secret - */ - otrl_privkey_fingerprint_raw(us, our_fp, context->accountname, - context->protocol); - - combined_buf_len = 41 + context->sessionid_len + secretlen; - combined_buf = malloc(combined_buf_len); - combined_buf[0] = 0x01; - if (initiating) { + unsigned char *smpmsg = NULL; + int smpmsglen; + unsigned char combined_secret[SM_DIGEST_SIZE]; + gcry_error_t err; + unsigned char our_fp[20]; + unsigned char *combined_buf; + size_t combined_buf_len; + OtrlTLV *sendtlv; + char *sendsmp = NULL; + + if (!context || context->msgstate != OTRL_MSGSTATE_ENCRYPTED) return; + + /* + * Construct the combined secret as a SHA256 hash of: + * Version byte (0x01), Initiator fingerprint (20 bytes), + * responder fingerprint (20 bytes), secure session id, input secret + */ + otrl_privkey_fingerprint_raw(us, our_fp, context->accountname, + context->protocol); + + combined_buf_len = 41 + context->sessionid_len + secretlen; + combined_buf = malloc(combined_buf_len); + combined_buf[0] = 0x01; + if (initiating) { memmove(combined_buf + 1, our_fp, 20); memmove(combined_buf + 21, context->active_fingerprint->fingerprint, 20); - } else { + } else { memmove(combined_buf + 1, context->active_fingerprint->fingerprint, 20); memmove(combined_buf + 21, our_fp, 20); - } - memmove(combined_buf + 41, context->sessionid, - context->sessionid_len); - memmove(combined_buf + 41 + context->sessionid_len, - secret, secretlen); - gcry_md_hash_buffer(SM_HASH_ALGORITHM, combined_secret, combined_buf, - combined_buf_len); - free(combined_buf); - - if (initiating) { + } + memmove(combined_buf + 41, context->sessionid, + context->sessionid_len); + memmove(combined_buf + 41 + context->sessionid_len, + secret, secretlen); + gcry_md_hash_buffer(SM_HASH_ALGORITHM, combined_secret, combined_buf, + combined_buf_len); + free(combined_buf); + + if (initiating) { otrl_sm_step1(context->smstate, combined_secret, SM_DIGEST_SIZE, &smpmsg, &smpmsglen); - } else { + } else { otrl_sm_step2b(context->smstate, combined_secret, SM_DIGEST_SIZE, &smpmsg, &smpmsglen); - } + } - /* If we've got a question, attach it to the smpmsg */ - if (question != NULL) { + /* If we've got a question, attach it to the smpmsg */ + if (question != NULL) { size_t qlen = strlen(question); unsigned char *qsmpmsg = malloc(qlen + 1 + smpmsglen); if (!qsmpmsg) { - free(smpmsg); - return; + free(smpmsg); + return; } strcpy((char *)qsmpmsg, question); memmove(qsmpmsg + qlen + 1, smpmsg, smpmsglen); free(smpmsg); smpmsg = qsmpmsg; smpmsglen += qlen + 1; - } - - /* Send msg with next smp msg content */ - sendtlv = otrl_tlv_new(initiating ? - (question != NULL ? OTRL_TLV_SMP1Q : OTRL_TLV_SMP1) - : OTRL_TLV_SMP2, - smpmsglen, smpmsg); - err = otrl_proto_create_data(&sendsmp, context, "", sendtlv, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { - /* Send it, and set the next expected message to the + } + + /* Send msg with next smp msg content */ + sendtlv = otrl_tlv_new(initiating ? + (question != NULL ? OTRL_TLV_SMP1Q : OTRL_TLV_SMP1) + : OTRL_TLV_SMP2, + smpmsglen, smpmsg); + err = otrl_proto_create_data(&sendsmp, context, "", sendtlv, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { + /* Send it, and set the next expected message to the * logical response */ - err = otrl_message_fragment_and_send(ops, opdata, context, + err = otrl_message_fragment_and_send(ops, opdata, context, sendsmp, OTRL_FRAGMENT_SEND_ALL, NULL); - context->smstate->nextExpected = - initiating ? OTRL_SMP_EXPECT2 : OTRL_SMP_EXPECT3; - } - free(sendsmp); - otrl_tlv_free(sendtlv); - free(smpmsg); + context->smstate->nextExpected = + initiating ? OTRL_SMP_EXPECT2 : OTRL_SMP_EXPECT3; + } + free(sendsmp); + otrl_tlv_free(sendtlv); + free(smpmsg); } /* Initiate the Socialist Millionaires' Protocol */ @@ -600,7 +600,7 @@ void otrl_message_initiate_smp(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, const unsigned char *secret, size_t secretlen) { - init_respond_smp(us, ops, opdata, context, NULL, secret, secretlen, 1); + init_respond_smp(us, ops, opdata, context, NULL, secret, secretlen, 1); } /* Initiate the Socialist Millionaires' Protocol and send a prompt @@ -609,7 +609,7 @@ void otrl_message_initiate_smp_q(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, const char *question, const unsigned char *secret, size_t secretlen) { - init_respond_smp(us, ops, opdata, context, question, secret, secretlen, 1); + init_respond_smp(us, ops, opdata, context, question, secret, secretlen, 1); } /* Respond to a buddy initiating the Socialist Millionaires' Protocol */ @@ -617,7 +617,7 @@ void otrl_message_respond_smp(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, const unsigned char *secret, size_t secretlen) { - init_respond_smp(us, ops, opdata, context, NULL, secret, secretlen, 0); + init_respond_smp(us, ops, opdata, context, NULL, secret, secretlen, 0); } /* Abort the SMP. Called when an unexpected SMP message breaks the @@ -625,23 +625,23 @@ void otrl_message_respond_smp(OtrlUserState us, const OtrlMessageAppOps *ops, void otrl_message_abort_smp(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, ConnContext *context) { - OtrlTLV *sendtlv = otrl_tlv_new(OTRL_TLV_SMP_ABORT, 0, - (const unsigned char *)""); - char *sendsmp = NULL; - gcry_error_t err; - - context->smstate->nextExpected = OTRL_SMP_EXPECT1; - - err = otrl_proto_create_data(&sendsmp, - context, "", sendtlv, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { + OtrlTLV *sendtlv = otrl_tlv_new(OTRL_TLV_SMP_ABORT, 0, + (const unsigned char *)""); + char *sendsmp = NULL; + gcry_error_t err; + + context->smstate->nextExpected = OTRL_SMP_EXPECT1; + + err = otrl_proto_create_data(&sendsmp, + context, "", sendtlv, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { /* Send the abort signal so our buddy knows we've stopped */ err = otrl_message_fragment_and_send(ops, opdata, context, sendsmp, OTRL_FRAGMENT_SEND_ALL, NULL); - } - free(sendsmp); - otrl_tlv_free(sendtlv); + } + free(sendsmp); + otrl_tlv_free(sendtlv); } /* Handle a message just received from the network. It is safe to pass @@ -675,79 +675,79 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, void (*add_appdata)(void *data, ConnContext *context), void *data) { - ConnContext *context; - OtrlMessageType msgtype; - int context_added = 0; - OtrlMessageState msgstate; - OtrlPolicy policy = OTRL_POLICY_DEFAULT; - int fragment_assembled = 0; - char *unfragmessage = NULL; - EncrData edata; - - if (!accountname || !protocol || !sender || !message || !newmessagep) - return 0; - - *newmessagep = NULL; - if (tlvsp) *tlvsp = NULL; - - /* Find our context and state with this correspondent */ - context = otrl_context_find(us, sender, accountname, - protocol, 1, &context_added, add_appdata, data); - - /* Update the context list if we added one */ - if (context_added && ops->update_context_list) { + ConnContext *context; + OtrlMessageType msgtype; + int context_added = 0; + OtrlMessageState msgstate; + OtrlPolicy policy = OTRL_POLICY_DEFAULT; + int fragment_assembled = 0; + char *unfragmessage = NULL; + EncrData edata; + + if (!accountname || !protocol || !sender || !message || !newmessagep) + return 0; + + *newmessagep = NULL; + if (tlvsp) *tlvsp = NULL; + + /* Find our context and state with this correspondent */ + context = otrl_context_find(us, sender, accountname, + protocol, 1, &context_added, add_appdata, data); + + /* Update the context list if we added one */ + if (context_added && ops->update_context_list) { ops->update_context_list(opdata); - } + } - /* Check the policy */ - if (ops->policy) { + /* Check the policy */ + if (ops->policy) { policy = ops->policy(opdata, context); - } + } - /* Should we go on at all? */ - if ((policy & OTRL_POLICY_VERSION_MASK) == 0) { - return 0; - } + /* Should we go on at all? */ + if ((policy & OTRL_POLICY_VERSION_MASK) == 0) { + return 0; + } - /* See if we have a fragment */ - switch(otrl_proto_fragment_accumulate(&unfragmessage, context, message)) { + /* See if we have a fragment */ + switch(otrl_proto_fragment_accumulate(&unfragmessage, context, message)) { case OTRL_FRAGMENT_UNFRAGMENTED: - /* Do nothing */ - break; + /* Do nothing */ + break; case OTRL_FRAGMENT_INCOMPLETE: - /* We've accumulated this fragment, but we don't have a - * complete message yet */ - return 1; + /* We've accumulated this fragment, but we don't have a + * complete message yet */ + return 1; case OTRL_FRAGMENT_COMPLETE: - /* We've got a new complete message, in unfragmessage. */ - fragment_assembled = 1; - message = unfragmessage; - break; - } - - /* What type of message is it? Note that this just checks the - * header; it's not necessarily a _valid_ message of this type. */ - msgtype = otrl_proto_message_type(message); - msgstate = context->msgstate; - - /* See if they responded to our OTR offer */ - if ((policy & OTRL_POLICY_SEND_WHITESPACE_TAG)) { + /* We've got a new complete message, in unfragmessage. */ + fragment_assembled = 1; + message = unfragmessage; + break; + } + + /* What type of message is it? Note that this just checks the + * header; it's not necessarily a _valid_ message of this type. */ + msgtype = otrl_proto_message_type(message); + msgstate = context->msgstate; + + /* See if they responded to our OTR offer */ + if ((policy & OTRL_POLICY_SEND_WHITESPACE_TAG)) { if (msgtype != OTRL_MSGTYPE_NOTOTR) { - context->otr_offer = OFFER_ACCEPTED; + context->otr_offer = OFFER_ACCEPTED; } else if (context->otr_offer == OFFER_SENT) { - context->otr_offer = OFFER_REJECTED; + context->otr_offer = OFFER_REJECTED; + } } - } - edata.gone_encrypted = 0; - edata.us = us; - edata.context = context; - edata.ops = ops; - edata.opdata = opdata; - edata.ignore_message = -1; - edata.messagep = newmessagep; + edata.gone_encrypted = 0; + edata.us = us; + edata.context = context; + edata.ops = ops; + edata.opdata = opdata; + edata.ignore_message = -1; + edata.messagep = newmessagep; - switch(msgtype) { + switch(msgtype) { unsigned int bestversion; const char *startwhite, *endwhite; DH_keypair *our_dh; @@ -756,165 +756,165 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, gcry_error_t err; int haveauthmsg; case OTRL_MSGTYPE_QUERY: - /* See if we should use an existing DH keypair, or generate - * a fresh one. */ - if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { + /* See if we should use an existing DH keypair, or generate + * a fresh one. */ + if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { our_dh = &(context->our_old_dh_key); our_keyid = context->our_keyid - 1; - } else { + } else { our_dh = NULL; our_keyid = 0; - } + } - /* Find the best version of OTR that we both speak */ - switch(otrl_proto_query_bestversion(message, policy)) { + /* Find the best version of OTR that we both speak */ + switch(otrl_proto_query_bestversion(message, policy)) { case 2: - err = otrl_auth_start_v2(&(context->auth)); - send_or_error_auth(ops, opdata, err, context); - break; + err = otrl_auth_start_v2(&(context->auth)); + send_or_error_auth(ops, opdata, err, context); + break; case 1: - /* Get our private key */ - privkey = otrl_privkey_find(us, context->accountname, - context->protocol); - if (privkey == NULL) { + /* Get our private key */ + privkey = otrl_privkey_find(us, context->accountname, + context->protocol); + if (privkey == NULL) { /* We've got no private key! */ if (ops->create_privkey) { - ops->create_privkey(opdata, context->accountname, - context->protocol); - privkey = otrl_privkey_find(us, - context->accountname, context->protocol); + ops->create_privkey(opdata, context->accountname, + context->protocol); + privkey = otrl_privkey_find(us, + context->accountname, context->protocol); + } } - } - if (privkey) { + if (privkey) { err = otrl_auth_start_v1(&(context->auth), our_dh, our_keyid, privkey); send_or_error_auth(ops, opdata, err, context); - } - break; + } + break; default: - /* Just ignore this message */ - break; - } - /* Don't display the Query message to the user. */ - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + /* Just ignore this message */ + break; + } + /* Don't display the Query message to the user. */ + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_DH_COMMIT: - if ((policy & OTRL_POLICY_ALLOW_V2)) { + if ((policy & OTRL_POLICY_ALLOW_V2)) { err = otrl_auth_handle_commit(&(context->auth), message); send_or_error_auth(ops, opdata, err, context); - } + } - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_DH_KEY: - if ((policy & OTRL_POLICY_ALLOW_V2)) { + if ((policy & OTRL_POLICY_ALLOW_V2)) { /* Get our private key */ privkey = otrl_privkey_find(us, context->accountname, context->protocol); if (privkey == NULL) { - /* We've got no private key! */ - if (ops->create_privkey) { + /* We've got no private key! */ + if (ops->create_privkey) { ops->create_privkey(opdata, context->accountname, context->protocol); privkey = otrl_privkey_find(us, context->accountname, context->protocol); - } + } } if (privkey) { - err = otrl_auth_handle_key(&(context->auth), message, - &haveauthmsg, privkey); - if (err || haveauthmsg) { + err = otrl_auth_handle_key(&(context->auth), message, + &haveauthmsg, privkey); + if (err || haveauthmsg) { send_or_error_auth(ops, opdata, err, context); - } + } + } } - } - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_REVEALSIG: - if ((policy & OTRL_POLICY_ALLOW_V2)) { + if ((policy & OTRL_POLICY_ALLOW_V2)) { /* Get our private key */ privkey = otrl_privkey_find(us, context->accountname, context->protocol); if (privkey == NULL) { - /* We've got no private key! */ - if (ops->create_privkey) { + /* We've got no private key! */ + if (ops->create_privkey) { ops->create_privkey(opdata, context->accountname, context->protocol); privkey = otrl_privkey_find(us, context->accountname, context->protocol); - } + } } if (privkey) { - err = otrl_auth_handle_revealsig(&(context->auth), - message, &haveauthmsg, privkey, go_encrypted, - &edata); - if (err || haveauthmsg) { + err = otrl_auth_handle_revealsig(&(context->auth), + message, &haveauthmsg, privkey, go_encrypted, + &edata); + if (err || haveauthmsg) { send_or_error_auth(ops, opdata, err, context); maybe_resend(&edata); - } + } + } } - } - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_SIGNATURE: - if ((policy & OTRL_POLICY_ALLOW_V2)) { + if ((policy & OTRL_POLICY_ALLOW_V2)) { err = otrl_auth_handle_signature(&(context->auth), message, &haveauthmsg, go_encrypted, &edata); if (err || haveauthmsg) { - send_or_error_auth(ops, opdata, err, context); - maybe_resend(&edata); + send_or_error_auth(ops, opdata, err, context); + maybe_resend(&edata); + } } - } - - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_V1_KEYEXCH: - if ((policy & OTRL_POLICY_ALLOW_V1)) { + if ((policy & OTRL_POLICY_ALLOW_V1)) { /* See if we should use an existing DH keypair, or generate * a fresh one. */ if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { - our_dh = &(context->our_old_dh_key); - our_keyid = context->our_keyid - 1; + our_dh = &(context->our_old_dh_key); + our_keyid = context->our_keyid - 1; } else { - our_dh = NULL; - our_keyid = 0; + our_dh = NULL; + our_keyid = 0; } /* Get our private key */ privkey = otrl_privkey_find(us, context->accountname, context->protocol); if (privkey == NULL) { - /* We've got no private key! */ - if (ops->create_privkey) { + /* We've got no private key! */ + if (ops->create_privkey) { ops->create_privkey(opdata, context->accountname, context->protocol); privkey = otrl_privkey_find(us, context->accountname, context->protocol); - } + } } if (privkey) { - err = otrl_auth_handle_v1_key_exchange(&(context->auth), - message, &haveauthmsg, privkey, our_dh, our_keyid, - go_encrypted, &edata); - if (err || haveauthmsg) { + err = otrl_auth_handle_v1_key_exchange(&(context->auth), + message, &haveauthmsg, privkey, our_dh, our_keyid, + go_encrypted, &edata); + if (err || haveauthmsg) { send_or_error_auth(ops, opdata, err, context); maybe_resend(&edata); - } + } + } } - } - - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; + + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; case OTRL_MSGTYPE_DATA: - switch(context->msgstate) { + switch(context->msgstate) { gcry_error_t err; OtrlTLV *tlvs, *tlv; char *plaintext; @@ -926,114 +926,114 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, case OTRL_MSGSTATE_PLAINTEXT: case OTRL_MSGSTATE_FINISHED: - /* See if we're supposed to ignore this message in - * the event it's unreadable. */ - err = otrl_proto_data_read_flags(message, &flags); - if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) { + /* See if we're supposed to ignore this message in + * the event it's unreadable. */ + err = otrl_proto_data_read_flags(message, &flags); + if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) { edata.ignore_message = 1; break; - } + } - /* Don't use g_strdup_printf here, because someone - * (not us) is going to free() the *newmessagep pointer, - * not g_free() it. */ - format = "<b>The encrypted message received from %s is " + /* Don't use g_strdup_printf here, because someone + * (not us) is going to free() the *newmessagep pointer, + * not g_free() it. */ + format = "<b>The encrypted message received from %s is " "unreadable, as you are not currently communicating " "privately.</b>"; - buf = malloc(strlen(format) + strlen(context->username) - - 1); /* Remove "%s", add username + '\0' */ - if (buf) { + buf = malloc(strlen(format) + strlen(context->username) + - 1); /* Remove "%s", add username + '\0' */ + if (buf) { sprintf(buf, format, context->username); if (ops->display_otr_message) { - if (!ops->display_otr_message(opdata, accountname, + if (!ops->display_otr_message(opdata, accountname, protocol, sender, buf)) { edata.ignore_message = 1; - } + } } if (edata.ignore_message != 1) { - *newmessagep = buf; - edata.ignore_message = 0; + *newmessagep = buf; + edata.ignore_message = 0; } else { - free(buf); + free(buf); + } } - } - format = "?OTR Error: You sent encrypted " - "data to %s, who wasn't expecting it."; - if (otrl_api_version >= 0x00030100 && - ops->account_name) { + format = "?OTR Error: You sent encrypted " + "data to %s, who wasn't expecting it."; + if (otrl_api_version >= 0x00030100 && + ops->account_name) { displayaccountname = ops->account_name(opdata, context->accountname, protocol); - } else { + } else { displayaccountname = NULL; - } - buf = malloc(strlen(format) + strlen(displayaccountname ? + } + buf = malloc(strlen(format) + strlen(displayaccountname ? displayaccountname : context->accountname) - - 1); - if (buf) { + - 1); + if (buf) { sprintf(buf, format, displayaccountname ? displayaccountname : context->accountname); if (ops->inject_message) { - ops->inject_message(opdata, accountname, protocol, - sender, buf); + ops->inject_message(opdata, accountname, protocol, + sender, buf); } free(buf); - } - if (displayaccountname && otrl_api_version >= 0x00030100 && - ops->account_name_free) { + } + if (displayaccountname && otrl_api_version >= 0x00030100 && + ops->account_name_free) { ops->account_name_free(opdata, displayaccountname); - } + } - break; + break; case OTRL_MSGSTATE_ENCRYPTED: - err = otrl_proto_accept_data(&plaintext, &tlvs, context, - message, &flags); - if (err) { + err = otrl_proto_accept_data(&plaintext, &tlvs, context, + message, &flags); + if (err) { int is_conflict = - (gpg_err_code(err) == GPG_ERR_CONFLICT); + (gpg_err_code(err) == GPG_ERR_CONFLICT); if ((flags & OTRL_MSGFLAGS_IGNORE_UNREADABLE)) { - edata.ignore_message = 1; - break; + edata.ignore_message = 1; + break; } format = is_conflict ? "We received an unreadable " - "encrypted message from %s." : - "We received a malformed data message from %s."; + "encrypted message from %s." : + "We received a malformed data message from %s."; buf = malloc(strlen(format) + strlen(sender) - 1); if (buf) { - sprintf(buf, format, sender); - if ((!(ops->display_otr_message) || - ops->display_otr_message(opdata, + sprintf(buf, format, sender); + if ((!(ops->display_otr_message) || + ops->display_otr_message(opdata, accountname, protocol, sender, buf)) && ops->notify) { ops->notify(opdata, OTRL_NOTIFY_ERROR, accountname, protocol, sender, "OTR Error", buf, NULL); - } - free(buf); + } + free(buf); } if (ops->inject_message) { - ops->inject_message(opdata, accountname, protocol, - sender, is_conflict ? "?OTR Error: " - "You transmitted an unreadable " - "encrypted message." : - "?OTR Error: You transmitted " - "a malformed data message"); + ops->inject_message(opdata, accountname, protocol, + sender, is_conflict ? "?OTR Error: " + "You transmitted an unreadable " + "encrypted message." : + "?OTR Error: You transmitted " + "a malformed data message"); } edata.ignore_message = 1; break; - } + } - /* If the other side told us he's disconnected his - * private connection, make a note of that so we - * don't try sending anything else to him. */ - if (otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED)) { + /* If the other side told us he's disconnected his + * private connection, make a note of that so we + * don't try sending anything else to him. */ + if (otrl_tlv_find(tlvs, OTRL_TLV_DISCONNECTED)) { otrl_context_force_finished(context); - } + } - /* If TLVs contain SMP data, process it */ - nextMsg = context->smstate->nextExpected; - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); - if (tlv && nextMsg == OTRL_SMP_EXPECT1) { + /* If TLVs contain SMP data, process it */ + nextMsg = context->smstate->nextExpected; + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1Q); + if (tlv && nextMsg == OTRL_SMP_EXPECT1) { /* We can only do the verification half now. * We must wait for the secret to be entered * to continue. */ @@ -1042,17 +1042,17 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, size_t qlen = qend ? (qend - question + 1) : tlv->len; otrl_sm_step2a(context->smstate, tlv->data + qlen, tlv->len - qlen, 1); - } - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); - if (tlv && nextMsg == OTRL_SMP_EXPECT1) { + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP1); + if (tlv && nextMsg == OTRL_SMP_EXPECT1) { /* We can only do the verification half now. * We must wait for the secret to be entered * to continue. */ otrl_sm_step2a(context->smstate, tlv->data, tlv->len, 0); - } - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2); - if (tlv && nextMsg == OTRL_SMP_EXPECT2) { + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP2); + if (tlv && nextMsg == OTRL_SMP_EXPECT2) { unsigned char* nextmsg; int nextmsglen; OtrlTLV *sendtlv; @@ -1062,24 +1062,24 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, if (context->smstate->sm_prog_state != OTRL_SMP_PROG_CHEATED) { - /* Send msg with next smp msg content */ - sendtlv = otrl_tlv_new(OTRL_TLV_SMP3, nextmsglen, - nextmsg); - err = otrl_proto_create_data(&sendsmp, - context, "", sendtlv, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { + /* Send msg with next smp msg content */ + sendtlv = otrl_tlv_new(OTRL_TLV_SMP3, nextmsglen, + nextmsg); + err = otrl_proto_create_data(&sendsmp, + context, "", sendtlv, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { err = otrl_message_fragment_and_send(ops, opdata, context, sendsmp, OTRL_FRAGMENT_SEND_ALL, NULL); - } - free(sendsmp); - otrl_tlv_free(sendtlv); + } + free(sendsmp); + otrl_tlv_free(sendtlv); } free(nextmsg); - } - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3); - if (tlv && nextMsg == OTRL_SMP_EXPECT3) { + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP3); + if (tlv && nextMsg == OTRL_SMP_EXPECT3) { unsigned char* nextmsg; int nextmsglen; OtrlTLV *sendtlv; @@ -1088,71 +1088,71 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, tlv->len, &nextmsg, &nextmsglen); /* Set trust level based on result */ if (context->smstate->received_question == 0) { - set_smp_trust(ops, opdata, context, - (err == gcry_error(GPG_ERR_NO_ERROR))); + set_smp_trust(ops, opdata, context, + (err == gcry_error(GPG_ERR_NO_ERROR))); } if (context->smstate->sm_prog_state != OTRL_SMP_PROG_CHEATED) { - /* Send msg with next smp msg content */ - sendtlv = otrl_tlv_new(OTRL_TLV_SMP4, nextmsglen, - nextmsg); - err = otrl_proto_create_data(&sendsmp, - context, "", sendtlv, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { + /* Send msg with next smp msg content */ + sendtlv = otrl_tlv_new(OTRL_TLV_SMP4, nextmsglen, + nextmsg); + err = otrl_proto_create_data(&sendsmp, + context, "", sendtlv, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { err = otrl_message_fragment_and_send(ops, opdata, context, sendsmp, OTRL_FRAGMENT_SEND_ALL, NULL); - } - free(sendsmp); - otrl_tlv_free(sendtlv); + } + free(sendsmp); + otrl_tlv_free(sendtlv); } free(nextmsg); - } - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4); - if (tlv && nextMsg == OTRL_SMP_EXPECT4) { + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP4); + if (tlv && nextMsg == OTRL_SMP_EXPECT4) { err = otrl_sm_step5(context->smstate, tlv->data, tlv->len); /* Set trust level based on result */ set_smp_trust(ops, opdata, context, (err == gcry_error(GPG_ERR_NO_ERROR))); - } - tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); - if (tlv) { + } + tlv = otrl_tlv_find(tlvs, OTRL_TLV_SMP_ABORT); + if (tlv) { context->smstate->nextExpected = OTRL_SMP_EXPECT1; - } - if (plaintext[0] == '\0') { + } + if (plaintext[0] == '\0') { /* If it's a heartbeat (an empty message), don't * display it to the user, but log a debug message. */ format = "Heartbeat received from %s.\n"; buf = malloc(strlen(format) + strlen(sender) - 1); if (buf) { - sprintf(buf, format, sender); - if (ops->log_message) { + sprintf(buf, format, sender); + if (ops->log_message) { ops->log_message(opdata, buf); - } - free(buf); + } + free(buf); } edata.ignore_message = 1; - } else if (edata.ignore_message == 0 && - context->their_keyid > 0) { + } else if (edata.ignore_message == 0 && + context->their_keyid > 0) { /* If it's *not* a heartbeat, and we haven't * sent anything in a while, also send a * heartbeat. */ time_t now = time(NULL); if (context->lastsent < (now - HEARTBEAT_INTERVAL)) { - char *heartbeat; + char *heartbeat; - /* Create the heartbeat message */ - err = otrl_proto_create_data(&heartbeat, - context, "", NULL, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { + /* Create the heartbeat message */ + err = otrl_proto_create_data(&heartbeat, + context, "", NULL, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { /* Send it, and log a debug message */ if (ops->inject_message) { - ops->inject_message(opdata, accountname, - protocol, sender, heartbeat); + ops->inject_message(opdata, accountname, + protocol, sender, heartbeat); } free(heartbeat); @@ -1163,122 +1163,122 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, buf = malloc(strlen(format) + strlen(sender) - 1); if (buf) { - sprintf(buf, format, sender); - if (ops->log_message) { + sprintf(buf, format, sender); + if (ops->log_message) { ops->log_message(opdata, buf); - } - free(buf); + } + free(buf); + } } - } } - } + } - /* Return the TLVs even if ignore_message == 1 so - * that we can attach TLVs to heartbeats. */ - if (tlvsp) { + /* Return the TLVs even if ignore_message == 1 so + * that we can attach TLVs to heartbeats. */ + if (tlvsp) { *tlvsp = tlvs; - } else { + } else { otrl_tlv_free(tlvs); - } + } - if (edata.ignore_message != 1) { + if (edata.ignore_message != 1) { *newmessagep = plaintext; edata.ignore_message = 0; - } else { + } else { free(plaintext); - } - break; - } - break; + } + break; + } + break; case OTRL_MSGTYPE_ERROR: - if ((policy & OTRL_POLICY_ERROR_START_AKE)) { + if ((policy & OTRL_POLICY_ERROR_START_AKE)) { char *msgtosend = otrl_proto_default_query_msg( context->accountname, policy); if (msgtosend && ops->inject_message) { - ops->inject_message(opdata, context->accountname, - context->protocol, context->username, - msgtosend); + ops->inject_message(opdata, context->accountname, + context->protocol, context->username, + msgtosend); } free(msgtosend); - } + } - if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { + if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED) { /* Mark the last message we sent as eligible for * retransmission */ context->may_retransmit = 1; - } + } - /* In any event, display the error message, with the - * display_otr_message callback, if possible */ - if (ops->display_otr_message) { + /* In any event, display the error message, with the + * display_otr_message callback, if possible */ + if (ops->display_otr_message) { const char *otrerror = strstr(message, "?OTR Error:"); if (otrerror) { - /* Skip the leading '?' */ - ++otrerror; + /* Skip the leading '?' */ + ++otrerror; } else { - otrerror = message; + otrerror = message; } if (!ops->display_otr_message(opdata, accountname, protocol, - sender, otrerror)) { - edata.ignore_message = 1; + sender, otrerror)) { + edata.ignore_message = 1; + } } - } - break; + break; case OTRL_MSGTYPE_TAGGEDPLAINTEXT: - /* Strip the tag from the message */ - bestversion = otrl_proto_whitespace_bestversion(message, - &startwhite, &endwhite, policy); - if (startwhite && endwhite) { + /* Strip the tag from the message */ + bestversion = otrl_proto_whitespace_bestversion(message, + &startwhite, &endwhite, policy); + if (startwhite && endwhite) { size_t restlen = strlen(endwhite); - char *strippedmsg = strdup(message); + char *strippedmsg = _strdup(message); if (strippedmsg) { - memmove(strippedmsg + (startwhite - message), - strippedmsg + (endwhite - message), restlen+1); - *newmessagep = strippedmsg; - edata.ignore_message = 0; + memmove(strippedmsg + (startwhite - message), + strippedmsg + (endwhite - message), restlen+1); + *newmessagep = strippedmsg; + edata.ignore_message = 0; + } } - } - if (bestversion && context->msgstate != OTRL_MSGSTATE_ENCRYPTED - && (policy & OTRL_POLICY_WHITESPACE_START_AKE)) { + if (bestversion && context->msgstate != OTRL_MSGSTATE_ENCRYPTED + && (policy & OTRL_POLICY_WHITESPACE_START_AKE)) { switch(bestversion) { - case 2: + case 2: err = otrl_auth_start_v2(&(context->auth)); send_or_error_auth(ops, opdata, err, context); break; - case 1: + case 1: /* Get our private key */ privkey = otrl_privkey_find(us, context->accountname, context->protocol); if (privkey == NULL) { - /* We've got no private key! */ - if (ops->create_privkey) { + /* We've got no private key! */ + if (ops->create_privkey) { ops->create_privkey(opdata, context->accountname, context->protocol); privkey = otrl_privkey_find(us, context->accountname, context->protocol); - } + } } if (privkey) { - err = otrl_auth_start_v1(&(context->auth), NULL, 0, - privkey); - send_or_error_auth(ops, opdata, err, context); + err = otrl_auth_start_v1(&(context->auth), NULL, 0, + privkey); + send_or_error_auth(ops, opdata, err, context); } break; - default: + default: /* Don't start the AKE */ break; } - } + } - /* FALLTHROUGH */ + /* FALLTHROUGH */ case OTRL_MSGTYPE_NOTOTR: - if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT || - (policy & OTRL_POLICY_REQUIRE_ENCRYPTION)) { + if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT || + (policy & OTRL_POLICY_REQUIRE_ENCRYPTION)) { /* Not fine. Let the user know. */ /* Don't use g_strdup_printf here, because someone @@ -1286,56 +1286,56 @@ int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops, * not g_free() it. */ const char *plainmsg = (*newmessagep) ? *newmessagep : message; const char *format = "<b>The following message received " - "from %s was <i>not</i> encrypted: [</b>%s<b>]</b>"; + "from %s was <i>not</i> encrypted: [</b>%s<b>]</b>"; char *buf = malloc(strlen(format) + strlen(context->username) + strlen(plainmsg) - 3); /* Remove "%s%s", add username + message + '\0' */ if (buf) { - sprintf(buf, format, context->username, plainmsg); - if (ops->display_otr_message) { + sprintf(buf, format, context->username, plainmsg); + if (ops->display_otr_message) { if (!ops->display_otr_message(opdata, accountname, - protocol, sender, buf)) { - free(*newmessagep); - *newmessagep = NULL; - edata.ignore_message = 1; + protocol, sender, buf)) { + free(*newmessagep); + *newmessagep = NULL; + edata.ignore_message = 1; + } } - } - if (edata.ignore_message != 1) { + if (edata.ignore_message != 1) { free(*newmessagep); *newmessagep = buf; edata.ignore_message = 0; - } else { + } else { free(buf); - } + } } - } - break; + } + break; case OTRL_MSGTYPE_UNKNOWN: - /* We received an OTR message we didn't recognize. Ignore - * it, but make a log entry. */ - if (ops->log_message) { + /* We received an OTR message we didn't recognize. Ignore + * it, but make a log entry. */ + if (ops->log_message) { const char *format = "Unrecognized OTR message received " - "from %s.\n"; + "from %s.\n"; char *buf = malloc(strlen(format) + strlen(sender) - 1); if (buf) { - sprintf(buf, format, sender); - ops->log_message(opdata, buf); - free(buf); + sprintf(buf, format, sender); + ops->log_message(opdata, buf); + free(buf); + } } - } - if (edata.ignore_message == -1) edata.ignore_message = 1; - break; - } - - /* If we reassembled a fragmented message, we need to free the - * allocated memory now. */ - if (fragment_assembled) { + if (edata.ignore_message == -1) edata.ignore_message = 1; + break; + } + + /* If we reassembled a fragmented message, we need to free the + * allocated memory now. */ + if (fragment_assembled) { free(unfragmessage); - } + } - if (edata.ignore_message == -1) edata.ignore_message = 0; - return edata.ignore_message; + if (edata.ignore_message == -1) edata.ignore_message = 0; + return edata.ignore_message; } /* Send a message to the network, fragmenting first if necessary. @@ -1345,67 +1345,67 @@ gcry_error_t otrl_message_fragment_and_send(const OtrlMessageAppOps *ops, void *opdata, ConnContext *context, const char *message, OtrlFragmentPolicy fragPolicy, char **returnFragment) { - int mms = 0; - if (message && ops->inject_message) { - int msglen; + int mms = 0; + if (message && ops->inject_message) { + int msglen; - if (otrl_api_version >= 0x030100 && ops->max_message_size) { - mms = ops->max_message_size(opdata, context); - } - msglen = strlen(message); + if (otrl_api_version >= 0x030100 && ops->max_message_size) { + mms = ops->max_message_size(opdata, context); + } + msglen = strlen(message); /* Don't incur overhead of fragmentation unless necessary */ - if(mms != 0 && msglen > mms) { - char **fragments; - gcry_error_t err; - int i; - int fragment_count = ((msglen - 1) / (mms -19)) + 1; + if(mms != 0 && msglen > mms) { + char **fragments; + gcry_error_t err; + int i; + int fragment_count = ((msglen - 1) / (mms -19)) + 1; /* like ceil(msglen/(mms - 19)) */ - err = otrl_proto_fragment_create(mms, fragment_count, &fragments, - message); - if (err) { + err = otrl_proto_fragment_create(mms, fragment_count, &fragments, + message); + if (err) { return err; - } - - /* Determine which fragments to send and which to return - * based on given Fragment Policy. If the first fragment - * should be returned instead of sent, store it. */ - if (fragPolicy == OTRL_FRAGMENT_SEND_ALL_BUT_FIRST) { - *returnFragment = strdup(fragments[0]); - } else { + } + + /* Determine which fragments to send and which to return + * based on given Fragment Policy. If the first fragment + * should be returned instead of sent, store it. */ + if (fragPolicy == OTRL_FRAGMENT_SEND_ALL_BUT_FIRST) { + *returnFragment = _strdup(fragments[0]); + } else { ops->inject_message(opdata, context->accountname, context->protocol, context->username, fragments[0]); - } - for (i=1; i<fragment_count-1; i++) { + } + for (i=1; i<fragment_count-1; i++) { ops->inject_message(opdata, context->accountname, context->protocol, context->username, fragments[i]); - } - /* If the last fragment should be stored instead of sent, - * store it */ - if (fragPolicy == OTRL_FRAGMENT_SEND_ALL_BUT_LAST) { - *returnFragment = strdup(fragments[fragment_count-1]); - } else { + } + /* If the last fragment should be stored instead of sent, + * store it */ + if (fragPolicy == OTRL_FRAGMENT_SEND_ALL_BUT_LAST) { + *returnFragment = _strdup(fragments[fragment_count-1]); + } else { ops->inject_message(opdata, context->accountname, context->protocol, context->username, fragments[fragment_count-1]); - } - /* Now free all fragment memory */ - otrl_proto_fragment_free(&fragments, fragment_count); + } + /* Now free all fragment memory */ + otrl_proto_fragment_free(&fragments, fragment_count); } else { - /* No fragmentation necessary */ - if (fragPolicy == OTRL_FRAGMENT_SEND_ALL) { - ops->inject_message(opdata, context->accountname, - context->protocol, context->username, message); - } else { + /* No fragmentation necessary */ + if (fragPolicy == OTRL_FRAGMENT_SEND_ALL) { + ops->inject_message(opdata, context->accountname, + context->protocol, context->username, message); + } else { /* Copy and return the entire given message. */ int l = strlen(message) + 1; *returnFragment = malloc(sizeof(char)*l); strcpy(*returnFragment, message); - } + } + } } - } - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } /* Put a connection into the PLAINTEXT state, first sending the @@ -1415,32 +1415,32 @@ void otrl_message_disconnect(OtrlUserState us, const OtrlMessageAppOps *ops, void *opdata, const char *accountname, const char *protocol, const char *username) { - ConnContext *context = otrl_context_find(us, username, accountname, - protocol, 0, NULL, NULL, NULL); + ConnContext *context = otrl_context_find(us, username, accountname, + protocol, 0, NULL, NULL, NULL); - if (!context) return; + if (!context) return; - if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED && - context->their_keyid > 0 && - ops->is_logged_in && - ops->is_logged_in(opdata, accountname, protocol, username) == 1) { + if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED && + context->their_keyid > 0 && + ops->is_logged_in && + ops->is_logged_in(opdata, accountname, protocol, username) == 1) { if (ops->inject_message) { - char *encmsg = NULL; - gcry_error_t err; - OtrlTLV *tlv = otrl_tlv_new(OTRL_TLV_DISCONNECTED, 0, NULL); + char *encmsg = NULL; + gcry_error_t err; + OtrlTLV *tlv = otrl_tlv_new(OTRL_TLV_DISCONNECTED, 0, NULL); - err = otrl_proto_create_data(&encmsg, context, "", tlv, - OTRL_MSGFLAGS_IGNORE_UNREADABLE); - if (!err) { + err = otrl_proto_create_data(&encmsg, context, "", tlv, + OTRL_MSGFLAGS_IGNORE_UNREADABLE); + if (!err) { ops->inject_message(opdata, accountname, protocol, username, encmsg); - } - free(encmsg); + } + free(encmsg); + } } - } - otrl_context_force_plaintext(context); - if (ops->update_context_list) { + otrl_context_force_plaintext(context); + if (ops->update_context_list) { ops->update_context_list(opdata); - } + } } diff --git a/libotr-3.2.0/src/privkey.c b/libotr-3.2.0/src/privkey.c index 78a4a18..498bfae 100644 --- a/libotr-3.2.0/src/privkey.c +++ b/libotr-3.2.0/src/privkey.c @@ -33,19 +33,19 @@ /* Convert a 20-byte hash value to a 45-byte human-readable value */ void otrl_privkey_hash_to_human(char human[45], const unsigned char hash[20]) { - int word, byte; - char *p = human; + int word, byte; + char *p = human; - for(word=0; word<5; ++word) { + for(word=0; word<5; ++word) { for(byte=0; byte<4; ++byte) { - sprintf(p, "%02X", hash[word*4+byte]); - p += 2; + sprintf(p, "%02X", hash[word*4+byte]); + p += 2; } *(p++) = ' '; - } - /* Change that last ' ' to a '\0' */ - --p; - *p = '\0'; + } + /* Change that last ' ' to a '\0' */ + --p; + *p = '\0'; } /* Calculate a human-readable hash of our DSA public key. Return it in @@ -54,21 +54,21 @@ void otrl_privkey_hash_to_human(char human[45], const unsigned char hash[20]) char *otrl_privkey_fingerprint(OtrlUserState us, char fingerprint[45], const char *accountname, const char *protocol) { - unsigned char hash[20]; - OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); + unsigned char hash[20]; + OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); - if (p) { + if (p) { /* Calculate the hash */ gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data, p->pubkey_datalen); /* Now convert it to a human-readable format */ otrl_privkey_hash_to_human(fingerprint, hash); - } else { + } else { return NULL; - } + } - return fingerprint; + return fingerprint; } /* Calculate a raw hash of our DSA public key. Return it in the passed @@ -77,170 +77,170 @@ char *otrl_privkey_fingerprint(OtrlUserState us, char fingerprint[45], unsigned char *otrl_privkey_fingerprint_raw(OtrlUserState us, unsigned char hash[20], const char *accountname, const char *protocol) { - OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); + OtrlPrivKey *p = otrl_privkey_find(us, accountname, protocol); - if (p) { + if (p) { /* Calculate the hash */ gcry_md_hash_buffer(GCRY_MD_SHA1, hash, p->pubkey_data, p->pubkey_datalen); - } else { + } else { return NULL; - } + } - return hash; + return hash; } /* Create a public key block from a private key */ static gcry_error_t make_pubkey(unsigned char **pubbufp, size_t *publenp, gcry_sexp_t privkey) { - gcry_mpi_t p,q,g,y; - gcry_sexp_t dsas,ps,qs,gs,ys; - size_t np,nq,ng,ny; - enum gcry_mpi_format format = GCRYMPI_FMT_USG; - unsigned char *bufp; - size_t lenp; - - *pubbufp = NULL; - *publenp = 0; - - /* Extract the public parameters */ - dsas = gcry_sexp_find_token(privkey, "dsa", 0); - if (dsas == NULL) { + gcry_mpi_t p,q,g,y; + gcry_sexp_t dsas,ps,qs,gs,ys; + size_t np,nq,ng,ny; + enum gcry_mpi_format format = GCRYMPI_FMT_USG; + unsigned char *bufp; + size_t lenp; + + *pubbufp = NULL; + *publenp = 0; + + /* Extract the public parameters */ + dsas = gcry_sexp_find_token(privkey, "dsa", 0); + if (dsas == NULL) { return gcry_error(GPG_ERR_UNUSABLE_SECKEY); - } - ps = gcry_sexp_find_token(dsas, "p", 0); - qs = gcry_sexp_find_token(dsas, "q", 0); - gs = gcry_sexp_find_token(dsas, "g", 0); - ys = gcry_sexp_find_token(dsas, "y", 0); - gcry_sexp_release(dsas); - if (!ps || !qs || !gs || !ys) { + } + ps = gcry_sexp_find_token(dsas, "p", 0); + qs = gcry_sexp_find_token(dsas, "q", 0); + gs = gcry_sexp_find_token(dsas, "g", 0); + ys = gcry_sexp_find_token(dsas, "y", 0); + gcry_sexp_release(dsas); + if (!ps || !qs || !gs || !ys) { gcry_sexp_release(ps); gcry_sexp_release(qs); gcry_sexp_release(gs); gcry_sexp_release(ys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); - } - p = gcry_sexp_nth_mpi(ps, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(ps); - q = gcry_sexp_nth_mpi(qs, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(qs); - g = gcry_sexp_nth_mpi(gs, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(gs); - y = gcry_sexp_nth_mpi(ys, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(ys); - if (!p || !q || !g || !y) { + } + p = gcry_sexp_nth_mpi(ps, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(ps); + q = gcry_sexp_nth_mpi(qs, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(qs); + g = gcry_sexp_nth_mpi(gs, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(gs); + y = gcry_sexp_nth_mpi(ys, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(ys); + if (!p || !q || !g || !y) { gcry_mpi_release(p); gcry_mpi_release(q); gcry_mpi_release(g); gcry_mpi_release(y); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); - } - - *publenp = 0; - gcry_mpi_print(format, NULL, 0, &np, p); - *publenp += np + 4; - gcry_mpi_print(format, NULL, 0, &nq, q); - *publenp += nq + 4; - gcry_mpi_print(format, NULL, 0, &ng, g); - *publenp += ng + 4; - gcry_mpi_print(format, NULL, 0, &ny, y); - *publenp += ny + 4; - - *pubbufp = malloc(*publenp); - if (*pubbufp == NULL) { + } + + *publenp = 0; + gcry_mpi_print(format, NULL, 0, &np, p); + *publenp += np + 4; + gcry_mpi_print(format, NULL, 0, &nq, q); + *publenp += nq + 4; + gcry_mpi_print(format, NULL, 0, &ng, g); + *publenp += ng + 4; + gcry_mpi_print(format, NULL, 0, &ny, y); + *publenp += ny + 4; + + *pubbufp = malloc(*publenp); + if (*pubbufp == NULL) { gcry_mpi_release(p); gcry_mpi_release(q); gcry_mpi_release(g); gcry_mpi_release(y); return gcry_error(GPG_ERR_ENOMEM); - } - bufp = *pubbufp; - lenp = *publenp; + } + bufp = *pubbufp; + lenp = *publenp; - write_mpi(p,np,"P"); - write_mpi(q,nq,"Q"); - write_mpi(g,ng,"G"); - write_mpi(y,ny,"Y"); + write_mpi(p,np,"P"); + write_mpi(q,nq,"Q"); + write_mpi(g,ng,"G"); + write_mpi(y,ny,"Y"); - gcry_mpi_release(p); - gcry_mpi_release(q); - gcry_mpi_release(g); - gcry_mpi_release(y); + gcry_mpi_release(p); + gcry_mpi_release(q); + gcry_mpi_release(g); + gcry_mpi_release(y); - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } /* Read a sets of private DSA keys from a file on disk into the given * OtrlUserState. */ gcry_error_t otrl_privkey_read(OtrlUserState us, const char *filename) { - FILE *privf; - gcry_error_t err; - - /* Open the privkey file. We use rb mode so that on WIN32, fread() - * reads the same number of bytes that fstat() indicates are in the - * file. */ - privf = fopen(filename, "rb"); - if (!privf) { + FILE *privf; + gcry_error_t err; + + /* Open the privkey file. We use rb mode so that on WIN32, fread() + * reads the same number of bytes that fstat() indicates are in the + * file. */ + privf = fopen(filename, "rb"); + if (!privf) { err = gcry_error_from_errno(errno); return err; - } + } - err = otrl_privkey_read_FILEp(us, privf); + err = otrl_privkey_read_FILEp(us, privf); - fclose(privf); - return err; + fclose(privf); + return err; } /* Read a sets of private DSA keys from a FILE* into the given * OtrlUserState. The FILE* must be open for reading. */ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) { - int privfd; - struct stat st; - char *buf; - const char *token; - size_t tokenlen; - gcry_error_t err; - gcry_sexp_t allkeys; - size_t i; - - if (!privf) return gcry_error(GPG_ERR_NO_ERROR); - - /* Release any old ideas we had about our keys */ - otrl_privkey_forget_all(us); - - /* Load the data into a buffer */ - privfd = fileno(privf); - if (fstat(privfd, &st)) { + int privfd; + struct stat st; + char *buf; + const char *token; + size_t tokenlen; + gcry_error_t err; + gcry_sexp_t allkeys; + size_t i; + + if (!privf) return gcry_error(GPG_ERR_NO_ERROR); + + /* Release any old ideas we had about our keys */ + otrl_privkey_forget_all(us); + + /* Load the data into a buffer */ + privfd = _fileno(privf); + if (fstat(privfd, &st)) { err = gcry_error_from_errno(errno); return err; - } - buf = malloc(st.st_size); - if (!buf && st.st_size > 0) { + } + buf = malloc(st.st_size); + if (!buf && st.st_size > 0) { return gcry_error(GPG_ERR_ENOMEM); - } - if (fread(buf, st.st_size, 1, privf) != 1) { + } + if (fread(buf, st.st_size, 1, privf) != 1) { err = gcry_error_from_errno(errno); free(buf); return err; - } + } - err = gcry_sexp_new(&allkeys, buf, st.st_size, 0); - free(buf); - if (err) { + err = gcry_sexp_new(&allkeys, buf, st.st_size, 0); + free(buf); + if (err) { return err; - } + } - token = gcry_sexp_nth_data(allkeys, 0, &tokenlen); - if (tokenlen != 8 || strncmp(token, "privkeys", 8)) { + token = gcry_sexp_nth_data(allkeys, 0, &tokenlen); + if (tokenlen != 8 || strncmp(token, "privkeys", 8)) { gcry_sexp_release(allkeys); return gcry_error(GPG_ERR_UNUSABLE_SECKEY); - } + } - /* Get each account */ - for(i=1; i<gcry_sexp_length(allkeys); ++i) { + /* Get each account */ + for(i=1; i<gcry_sexp_length(allkeys); ++i) { gcry_sexp_t names, protos, privs; char *name, *proto; gcry_sexp_t accounts; @@ -252,9 +252,9 @@ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) /* It's really an "account" S-exp? */ token = gcry_sexp_nth_data(accounts, 0, &tokenlen); if (tokenlen != 7 || strncmp(token, "account", 7)) { - gcry_sexp_release(accounts); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + gcry_sexp_release(accounts); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } /* Extract the name, protocol, and privkey S-exps */ names = gcry_sexp_find_token(accounts, "name", 0); @@ -262,28 +262,28 @@ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) privs = gcry_sexp_find_token(accounts, "private-key", 0); gcry_sexp_release(accounts); if (!names || !protos || !privs) { - gcry_sexp_release(names); - gcry_sexp_release(protos); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + gcry_sexp_release(names); + gcry_sexp_release(protos); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } /* Extract the actual name and protocol */ token = gcry_sexp_nth_data(names, 1, &tokenlen); if (!token) { - gcry_sexp_release(names); - gcry_sexp_release(protos); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + gcry_sexp_release(names); + gcry_sexp_release(protos); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } name = malloc(tokenlen + 1); if (!name) { - gcry_sexp_release(names); - gcry_sexp_release(protos); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_ENOMEM); + gcry_sexp_release(names); + gcry_sexp_release(protos); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_ENOMEM); } memmove(name, token, tokenlen); name[tokenlen] = '\0'; @@ -291,19 +291,19 @@ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) token = gcry_sexp_nth_data(protos, 1, &tokenlen); if (!token) { - free(name); - gcry_sexp_release(protos); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + free(name); + gcry_sexp_release(protos); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_UNUSABLE_SECKEY); } proto = malloc(tokenlen + 1); if (!proto) { - free(name); - gcry_sexp_release(protos); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_ENOMEM); + free(name); + gcry_sexp_release(protos); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_ENOMEM); } memmove(proto, token, tokenlen); proto[tokenlen] = '\0'; @@ -312,11 +312,11 @@ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) /* Make a new OtrlPrivKey entry */ p = malloc(sizeof(*p)); if (!p) { - free(name); - free(proto); - gcry_sexp_release(privs); - gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_ENOMEM); + free(name); + free(proto); + gcry_sexp_release(privs); + gcry_sexp_release(allkeys); + return gcry_error(GPG_ERR_ENOMEM); } /* Fill it in and link it up */ @@ -326,63 +326,63 @@ gcry_error_t otrl_privkey_read_FILEp(OtrlUserState us, FILE *privf) p->privkey = privs; p->next = us->privkey_root; if (p->next) { - p->next->tous = &(p->next); + p->next->tous = &(p->next); } p->tous = &(us->privkey_root); us->privkey_root = p; err = make_pubkey(&(p->pubkey_data), &(p->pubkey_datalen), p->privkey); if (err) { - gcry_sexp_release(allkeys); - otrl_privkey_forget(p); - return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + gcry_sexp_release(allkeys); + otrl_privkey_forget(p); + return gcry_error(GPG_ERR_UNUSABLE_SECKEY); + } } - } - gcry_sexp_release(allkeys); + gcry_sexp_release(allkeys); - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } static gcry_error_t sexp_write(FILE *privf, gcry_sexp_t sexp) { - size_t buflen; - char *buf; + size_t buflen; + char *buf; - buflen = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); - buf = malloc(buflen); - if (buf == NULL && buflen > 0) { + buflen = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = malloc(buflen); + if (buf == NULL && buflen > 0) { return gcry_error(GPG_ERR_ENOMEM); - } - gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, buflen); - - fprintf(privf, "%s", buf); - free(buf); + } + gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, buflen); + + fprintf(privf, "%s", buf); + free(buf); - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } static gcry_error_t account_write(FILE *privf, const char *accountname, const char *protocol, gcry_sexp_t privkey) { - gcry_error_t err; - gcry_sexp_t names, protos; + gcry_error_t err; + gcry_sexp_t names, protos; - fprintf(privf, " (account\n"); + fprintf(privf, " (account\n"); - err = gcry_sexp_build(&names, NULL, "(name %s)", accountname); - if (!err) { + err = gcry_sexp_build(&names, NULL, "(name %s)", accountname); + if (!err) { err = sexp_write(privf, names); gcry_sexp_release(names); - } - if (!err) err = gcry_sexp_build(&protos, NULL, "(protocol %s)", protocol); - if (!err) { + } + if (!err) err = gcry_sexp_build(&protos, NULL, "(protocol %s)", protocol); + if (!err) { err = sexp_write(privf, protos); gcry_sexp_release(protos); - } - if (!err) err = sexp_write(privf, privkey); + } + if (!err) err = sexp_write(privf, privkey); - fprintf(privf, " )\n"); + fprintf(privf, " )\n"); - return err; + return err; } /* Generate a private DSA key for a given account, storing it into a @@ -391,31 +391,31 @@ static gcry_error_t account_write(FILE *privf, const char *accountname, gcry_error_t otrl_privkey_generate(OtrlUserState us, const char *filename, const char *accountname, const char *protocol) { - gcry_error_t err; - FILE *privf; + gcry_error_t err; + FILE *privf; #ifndef WIN32 - mode_t oldmask; + mode_t oldmask; #endif #ifndef WIN32 - oldmask = umask(077); + oldmask = umask(077); #endif - privf = fopen(filename, "w+b"); - if (!privf) { + privf = fopen(filename, "w+b"); + if (!privf) { #ifndef WIN32 umask(oldmask); #endif err = gcry_error_from_errno(errno); return err; - } + } - err = otrl_privkey_generate_FILEp(us, privf, accountname, protocol); + err = otrl_privkey_generate_FILEp(us, privf, accountname, protocol); - fclose(privf); + fclose(privf); #ifndef WIN32 - umask(oldmask); + umask(oldmask); #endif - return err; + return err; } /* Generate a private DSA key for a given account, storing it into a @@ -425,56 +425,56 @@ gcry_error_t otrl_privkey_generate(OtrlUserState us, const char *filename, gcry_error_t otrl_privkey_generate_FILEp(OtrlUserState us, FILE *privf, const char *accountname, const char *protocol) { - gcry_error_t err; - gcry_sexp_t key, parms, privkey; - static const char *parmstr = "(genkey (dsa (nbits 4:1024)))"; - OtrlPrivKey *p; + gcry_error_t err; + gcry_sexp_t key, parms, privkey; + static const char *parmstr = "(genkey (dsa (nbits 4:1024)))"; + OtrlPrivKey *p; - if (!privf) return gcry_error(GPG_ERR_NO_ERROR); + if (!privf) return gcry_error(GPG_ERR_NO_ERROR); - /* Create a DSA key */ - err = gcry_sexp_new(&parms, parmstr, strlen(parmstr), 0); - if (err) { + /* Create a DSA key */ + err = gcry_sexp_new(&parms, parmstr, strlen(parmstr), 0); + if (err) { return err; - } - err = gcry_pk_genkey(&key, parms); - gcry_sexp_release(parms); - if (err) { + } + err = gcry_pk_genkey(&key, parms); + gcry_sexp_release(parms); + if (err) { return err; - } + } - /* Extract the privkey */ - privkey = gcry_sexp_find_token(key, "private-key", 0); - gcry_sexp_release(key); + /* Extract the privkey */ + privkey = gcry_sexp_find_token(key, "private-key", 0); + gcry_sexp_release(key); - /* Output the other keys we know */ - fprintf(privf, "(privkeys\n"); + /* Output the other keys we know */ + fprintf(privf, "(privkeys\n"); - for (p=us->privkey_root; p; p=p->next) { + for (p=us->privkey_root; p; p=p->next) { /* Skip this one if our new key replaces it */ if (!strcmp(p->accountname, accountname) && !strcmp(p->protocol, protocol)) { - continue; + continue; } account_write(privf, p->accountname, p->protocol, p->privkey); - } - account_write(privf, accountname, protocol, privkey); - gcry_sexp_release(privkey); - fprintf(privf, ")\n"); + } + account_write(privf, accountname, protocol, privkey); + gcry_sexp_release(privkey); + fprintf(privf, ")\n"); - fseek(privf, 0, SEEK_SET); + fseek(privf, 0, SEEK_SET); - return otrl_privkey_read_FILEp(us, privf); + return otrl_privkey_read_FILEp(us, privf); } /* Convert a hex character to a value */ static unsigned int ctoh(char c) { - if (c >= '0' && c <= '9') return c-'0'; - if (c >= 'a' && c <= 'f') return c-'a'+10; - if (c >= 'A' && c <= 'F') return c-'A'+10; - return 0; /* Unknown hex char */ + if (c >= '0' && c <= '9') return c-'0'; + if (c >= 'a' && c <= 'f') return c-'a'+10; + if (c >= 'A' && c <= 'F') return c-'A'+10; + return 0; /* Unknown hex char */ } /* Read the fingerprint store from a file on disk into the given @@ -485,19 +485,19 @@ gcry_error_t otrl_privkey_read_fingerprints(OtrlUserState us, void (*add_app_data)(void *data, ConnContext *context), void *data) { - gcry_error_t err; - FILE *storef; + gcry_error_t err; + FILE *storef; - storef = fopen(filename, "rb"); - if (!storef) { + storef = fopen(filename, "rb"); + if (!storef) { err = gcry_error_from_errno(errno); return err; - } + } - err = otrl_privkey_read_fingerprints_FILEp(us, storef, add_app_data, data); + err = otrl_privkey_read_fingerprints_FILEp(us, storef, add_app_data, data); - fclose(storef); - return err; + fclose(storef); + return err; } /* Read the fingerprint store from a FILE* into the given @@ -508,14 +508,14 @@ gcry_error_t otrl_privkey_read_fingerprints_FILEp(OtrlUserState us, void (*add_app_data)(void *data, ConnContext *context), void *data) { - ConnContext *context; - char storeline[1000]; - unsigned char fingerprint[20]; - size_t maxsize = sizeof(storeline); + ConnContext *context; + char storeline[1000]; + unsigned char fingerprint[20]; + size_t maxsize = sizeof(storeline); - if (!storef) return gcry_error(GPG_ERR_NO_ERROR); + if (!storef) return gcry_error(GPG_ERR_NO_ERROR); - while(fgets(storeline, maxsize, storef)) { + while(fgets(storeline, maxsize, storef)) { char *username; char *accountname; char *protocol; @@ -545,23 +545,23 @@ gcry_error_t otrl_privkey_read_fingerprints_FILEp(OtrlUserState us, hex = tab + 1; tab = strchr(hex, '\t'); if (!tab) { - eol = strchr(hex, '\r'); - if (!eol) eol = strchr(hex, '\n'); - if (!eol) continue; - *eol = '\0'; - trust = NULL; + eol = strchr(hex, '\r'); + if (!eol) eol = strchr(hex, '\n'); + if (!eol) continue; + *eol = '\0'; + trust = NULL; } else { - *tab = '\0'; - trust = tab + 1; - eol = strchr(trust, '\r'); - if (!eol) eol = strchr(trust, '\n'); - if (!eol) continue; - *eol = '\0'; + *tab = '\0'; + trust = tab + 1; + eol = strchr(trust, '\r'); + if (!eol) eol = strchr(trust, '\n'); + if (!eol) continue; + *eol = '\0'; } if (strlen(hex) != 40) continue; for(j=0, i=0; i<40; i+=2) { - fingerprint[j++] = (ctoh(hex[i]) << 4) + (ctoh(hex[i+1])); + fingerprint[j++] = (ctoh(hex[i]) << 4) + (ctoh(hex[i+1])); } /* Get the context for this user, adding if not yet present */ context = otrl_context_find(us, username, accountname, protocol, @@ -569,28 +569,28 @@ gcry_error_t otrl_privkey_read_fingerprints_FILEp(OtrlUserState us, /* Add the fingerprint if not already there */ fng = otrl_context_find_fingerprint(context, fingerprint, 1, NULL); otrl_context_set_trust(fng, trust); - } + } - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } /* Write the fingerprint store from a given OtrlUserState to a file on disk. */ gcry_error_t otrl_privkey_write_fingerprints(OtrlUserState us, const char *filename) { - gcry_error_t err; - FILE *storef; + gcry_error_t err; + FILE *storef; - storef = fopen(filename, "wb"); - if (!storef) { + storef = fopen(filename, "wb"); + if (!storef) { err = gcry_error_from_errno(errno); return err; - } + } - err = otrl_privkey_write_fingerprints_FILEp(us, storef); + err = otrl_privkey_write_fingerprints_FILEp(us, storef); - fclose(storef); - return err; + fclose(storef); + return err; } /* Write the fingerprint store from a given OtrlUserState to a FILE*. @@ -598,26 +598,26 @@ gcry_error_t otrl_privkey_write_fingerprints(OtrlUserState us, gcry_error_t otrl_privkey_write_fingerprints_FILEp(OtrlUserState us, FILE *storef) { - ConnContext *context; - Fingerprint *fprint; + ConnContext *context; + Fingerprint *fprint; - if (!storef) return gcry_error(GPG_ERR_NO_ERROR); + if (!storef) return gcry_error(GPG_ERR_NO_ERROR); - for(context = us->context_root; context; context = context->next) { + for(context = us->context_root; context; context = context->next) { /* Don't both with the first (fingerprintless) entry. */ for (fprint = context->fingerprint_root.next; fprint; fprint = fprint->next) { - int i; - fprintf(storef, "%s\t%s\t%s\t", context->username, - context->accountname, context->protocol); - for(i=0;i<20;++i) { + int i; + fprintf(storef, "%s\t%s\t%s\t", context->username, + context->accountname, context->protocol); + for(i=0;i<20;++i) { fprintf(storef, "%02x", fprint->fingerprint[i]); - } - fprintf(storef, "\t%s\n", fprint->trust ? fprint->trust : ""); + } + fprintf(storef, "\t%s\n", fprint->trust ? fprint->trust : ""); + } } - } - return gcry_error(GPG_ERR_NO_ERROR); + return gcry_error(GPG_ERR_NO_ERROR); } /* Fetch the private key from the given OtrlUserState associated with @@ -625,42 +625,42 @@ gcry_error_t otrl_privkey_write_fingerprints_FILEp(OtrlUserState us, OtrlPrivKey *otrl_privkey_find(OtrlUserState us, const char *accountname, const char *protocol) { - OtrlPrivKey *p; - if (!accountname || !protocol) return NULL; + OtrlPrivKey *p; + if (!accountname || !protocol) return NULL; - for(p=us->privkey_root; p; p=p->next) { + for(p=us->privkey_root; p; p=p->next) { if (!strcmp(p->accountname, accountname) && !strcmp(p->protocol, protocol)) { - return p; + return p; + } } - } - return NULL; + return NULL; } /* Forget a private key */ void otrl_privkey_forget(OtrlPrivKey *privkey) { - free(privkey->accountname); - free(privkey->protocol); - gcry_sexp_release(privkey->privkey); - free(privkey->pubkey_data); - - /* Re-link the list */ - *(privkey->tous) = privkey->next; - if (privkey->next) { + free(privkey->accountname); + free(privkey->protocol); + gcry_sexp_release(privkey->privkey); + free(privkey->pubkey_data); + + /* Re-link the list */ + *(privkey->tous) = privkey->next; + if (privkey->next) { privkey->next->tous = privkey->tous; - } + } - /* Free the privkey struct */ - free(privkey); + /* Free the privkey struct */ + free(privkey); } /* Forget all private keys in a given OtrlUserState. */ void otrl_privkey_forget_all(OtrlUserState us) { - while (us->privkey_root) { + while (us->privkey_root) { otrl_privkey_forget(us->privkey_root); - } + } } /* Sign data using a private key. The data must be small enough to be @@ -670,45 +670,45 @@ void otrl_privkey_forget_all(OtrlUserState us) gcry_error_t otrl_privkey_sign(unsigned char **sigp, size_t *siglenp, OtrlPrivKey *privkey, const unsigned char *data, size_t len) { - gcry_mpi_t r,s, datampi; - gcry_sexp_t dsas, rs, ss, sigs, datas; - size_t nr, ns; - const enum gcry_mpi_format format = GCRYMPI_FMT_USG; + gcry_mpi_t r,s, datampi; + gcry_sexp_t dsas, rs, ss, sigs, datas; + size_t nr, ns; + const enum gcry_mpi_format format = GCRYMPI_FMT_USG; - if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA) + if (privkey->pubkey_type != OTRL_PUBKEY_TYPE_DSA) return gcry_error(GPG_ERR_INV_VALUE); - *sigp = malloc(40); - if (sigp == NULL) return gcry_error(GPG_ERR_ENOMEM); - *siglenp = 40; + *sigp = malloc(40); + if (sigp == NULL) return gcry_error(GPG_ERR_ENOMEM); + *siglenp = 40; - if (len) { + if (len) { gcry_mpi_scan(&datampi, GCRYMPI_FMT_USG, data, len, NULL); - } else { + } else { datampi = gcry_mpi_set_ui(NULL, 0); - } - gcry_sexp_build(&datas, NULL, "(%m)", datampi); - gcry_mpi_release(datampi); - gcry_pk_sign(&sigs, datas, privkey->privkey); - gcry_sexp_release(datas); - dsas = gcry_sexp_find_token(sigs, "dsa", 0); - gcry_sexp_release(sigs); - rs = gcry_sexp_find_token(dsas, "r", 0); - ss = gcry_sexp_find_token(dsas, "s", 0); - gcry_sexp_release(dsas); - r = gcry_sexp_nth_mpi(rs, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(rs); - s = gcry_sexp_nth_mpi(ss, 1, GCRYMPI_FMT_USG); - gcry_sexp_release(ss); - gcry_mpi_print(format, NULL, 0, &nr, r); - gcry_mpi_print(format, NULL, 0, &ns, s); - memset(*sigp, 0, 40); - gcry_mpi_print(format, (*sigp)+(20-nr), nr, NULL, r); - gcry_mpi_print(format, (*sigp)+20+(20-ns), ns, NULL, s); - gcry_mpi_release(r); - gcry_mpi_release(s); - - return gcry_error(GPG_ERR_NO_ERROR); + } + gcry_sexp_build(&datas, NULL, "(%m)", datampi); + gcry_mpi_release(datampi); + gcry_pk_sign(&sigs, datas, privkey->privkey); + gcry_sexp_release(datas); + dsas = gcry_sexp_find_token(sigs, "dsa", 0); + gcry_sexp_release(sigs); + rs = gcry_sexp_find_token(dsas, "r", 0); + ss = gcry_sexp_find_token(dsas, "s", 0); + gcry_sexp_release(dsas); + r = gcry_sexp_nth_mpi(rs, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(rs); + s = gcry_sexp_nth_mpi(ss, 1, GCRYMPI_FMT_USG); + gcry_sexp_release(ss); + gcry_mpi_print(format, NULL, 0, &nr, r); + gcry_mpi_print(format, NULL, 0, &ns, s); + memset(*sigp, 0, 40); + gcry_mpi_print(format, (*sigp)+(20-nr), nr, NULL, r); + gcry_mpi_print(format, (*sigp)+20+(20-ns), ns, NULL, s); + gcry_mpi_release(r); + gcry_mpi_release(s); + + return gcry_error(GPG_ERR_NO_ERROR); } /* Verify a signature on data using a public key. The data must be @@ -717,31 +717,31 @@ gcry_error_t otrl_privkey_verify(const unsigned char *sigbuf, size_t siglen, unsigned short pubkey_type, gcry_sexp_t pubs, const unsigned char *data, size_t len) { - gcry_error_t err; - gcry_mpi_t datampi,r,s; - gcry_sexp_t datas, sigs; + gcry_error_t err; + gcry_mpi_t datampi,r,s; + gcry_sexp_t datas, sigs; - if (pubkey_type != OTRL_PUBKEY_TYPE_DSA || siglen != 40) + if (pubkey_type != OTRL_PUBKEY_TYPE_DSA || siglen != 40) return gcry_error(GPG_ERR_INV_VALUE); - if (len) { + if (len) { gcry_mpi_scan(&datampi, GCRYMPI_FMT_USG, data, len, NULL); - } else { + } else { datampi = gcry_mpi_set_ui(NULL, 0); - } - gcry_sexp_build(&datas, NULL, "(%m)", datampi); - gcry_mpi_release(datampi); - gcry_mpi_scan(&r, GCRYMPI_FMT_USG, sigbuf, 20, NULL); - gcry_mpi_scan(&s, GCRYMPI_FMT_USG, sigbuf+20, 20, NULL); - gcry_sexp_build(&sigs, NULL, "(sig-val (dsa (r %m)(s %m)))", r, s); - gcry_mpi_release(r); - gcry_mpi_release(s); - - err = gcry_pk_verify(sigs, datas, pubs); - gcry_sexp_release(datas); - gcry_sexp_release(sigs); - - return err; + } + gcry_sexp_build(&datas, NULL, "(%m)", datampi); + gcry_mpi_release(datampi); + gcry_mpi_scan(&r, GCRYMPI_FMT_USG, sigbuf, 20, NULL); + gcry_mpi_scan(&s, GCRYMPI_FMT_USG, sigbuf+20, 20, NULL); + gcry_sexp_build(&sigs, NULL, "(sig-val (dsa (r %m)(s %m)))", r, s); + gcry_mpi_release(r); + gcry_mpi_release(s); + + err = gcry_pk_verify(sigs, datas, pubs); + gcry_sexp_release(datas); + gcry_sexp_release(sigs); + + return err; } gcry_error_t otrl_account_write(FILE *privf, const char *accountname, const char *protocol, gcry_sexp_t privkey) { |