-int chal_reply_h(connection_t *c)
-{
- char hishash[MAX_STRING_SIZE];
- char myhash[SHA_DIGEST_LENGTH];
-cp
- if(sscanf(c->buffer, "%*d "MAX_STRING, hishash) != 1)
- {
- syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "CHAL_REPLY", c->name, c->hostname);
- return -1;
- }
-
- /* Check if the length of the hash is all right */
-
- if(strlen(hishash) != SHA_DIGEST_LENGTH*2)
- {
- syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply length"));
- return -1;
- }
-
- /* Convert the hash to binary format */
-
- hex2bin(hishash, hishash, SHA_DIGEST_LENGTH);
-
- /* Calculate the hash from the challenge we sent */
-
- SHA1(c->hischallenge, RSA_size(c->rsa_key), myhash);
-
- /* Verify the incoming hash with the calculated hash */
-
- if(memcmp(hishash, myhash, SHA_DIGEST_LENGTH))
- {
- syslog(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply"));
- if(debug_lvl >= DEBUG_SCARY_THINGS)
- {
- bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
- hishash[SHA_DIGEST_LENGTH*2] = '\0';
- syslog(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
- }
- return -1;
- }
-
- /* Identity has now been positively verified.
- Send an acknowledgement with the rest of the information needed.
- */
-
- c->allow_request = ACK;
-cp
- return send_ack(c);
+bool send_chal_reply(connection_t *c) {
+ char hash[EVP_MAX_MD_SIZE * 2 + 1];
+ EVP_MD_CTX *ctx;
+
+ /* Calculate the hash from the challenge we received */
+
+ ctx = EVP_MD_CTX_create();
+
+ if(!ctx) {
+ abort();
+ }
+
+ if(!EVP_DigestInit(ctx, c->indigest)
+ || !EVP_DigestUpdate(ctx, c->mychallenge, RSA_size(myself->connection->rsa_key))
+ || !EVP_DigestFinal(ctx, (unsigned char *)hash, NULL)) {
+ EVP_MD_CTX_destroy(ctx);
+ logger(LOG_ERR, "Error during calculation of response for %s (%s): %s",
+ c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+ return false;
+ }
+
+ EVP_MD_CTX_destroy(ctx);
+
+ /* Convert the hash to a hexadecimal formatted string */
+
+ bin2hex(hash, hash, EVP_MD_size(c->indigest));
+ hash[EVP_MD_size(c->indigest) * 2] = '\0';
+
+ /* Send the reply */
+
+ return send_request(c, "%d %s", CHAL_REPLY, hash);
+}
+
+bool chal_reply_h(connection_t *c) {
+ char hishash[MAX_STRING_SIZE];
+ char myhash[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX *ctx;
+
+ if(sscanf(c->buffer, "%*d " MAX_STRING, hishash) != 1) {
+ logger(LOG_ERR, "Got bad %s from %s (%s)", "CHAL_REPLY", c->name,
+ c->hostname);
+ return false;
+ }
+
+ /* Check if the length of the hash is all right */
+
+ if(strlen(hishash) != (size_t)EVP_MD_size(c->outdigest) * 2) {
+ logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name,
+ c->hostname, "wrong challenge reply length");
+ return false;
+ }
+
+ /* Convert the hash to binary format */
+
+ if(!hex2bin(hishash, hishash, EVP_MD_size(c->outdigest))) {
+ logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash");
+ return false;
+ }
+
+ /* Calculate the hash from the challenge we sent */
+
+ ctx = EVP_MD_CTX_create();
+
+ if(!ctx) {
+ abort();
+ }
+
+ if(!EVP_DigestInit(ctx, c->outdigest)
+ || !EVP_DigestUpdate(ctx, c->hischallenge, RSA_size(c->rsa_key))
+ || !EVP_DigestFinal(ctx, (unsigned char *)myhash, NULL)) {
+ EVP_MD_CTX_destroy(ctx);
+ logger(LOG_ERR, "Error during calculation of response from %s (%s): %s",
+ c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+ return false;
+ }
+
+ EVP_MD_CTX_destroy(ctx);
+
+ /* Verify the incoming hash with the calculated hash */
+
+ if(memcmp(hishash, myhash, EVP_MD_size(c->outdigest))) {
+ logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name,
+ c->hostname, "wrong challenge reply");
+
+ ifdebug(SCARY_THINGS) {
+ bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
+ hishash[SHA_DIGEST_LENGTH * 2] = '\0';
+ logger(LOG_DEBUG, "Expected challenge reply: %s", hishash);
+ }
+
+ return false;
+ }
+
+ /* Identity has now been positively verified.
+ Send an acknowledgement with the rest of the information needed.
+ */
+
+ c->allow_request = ACK;
+
+ if(!c->outgoing) {
+ send_chal_reply(c);
+ }
+
+ return send_ack(c);