pike.git / lib / modules / SSL.pmod / Connection.pike

version» Context lines:

pike.git/lib/modules/SSL.pmod/Connection.pike:253:    Buffer hb_msg = Buffer();    hb_msg->add_int(HEARTBEAT_MESSAGE_request, 1);    hb_msg->add_int(16, 2);    int now = gethrtime();    hb_msg->add(heartbeat_encode->crypt(sprintf("%8c%8c", now, 0)));    // No padding.    return heartbeat_packet(hb_msg);   }      // Verify that a certificate chain is acceptable - private int verify_certificate_chain(array(string) certs) + private array(Standards.X509.TBSCertificate) +  verify_certificate_chain(array(string) certs)   {    // If we're not requiring the certificate, and we don't provide one,    // that should be okay.    if((context->auth_level < AUTHLEVEL_require) && !sizeof(certs)) -  return 1; +  return ({});       // A lack of certificates when we reqiure and must verify the    // certificates is probably a failure.    if(!sizeof(certs))    return 0;       // See if the issuer of the certificate is acceptable. This means    // the issuer of the certificate must be one of the authorities.    if(sizeof(context->authorities_cache))    {
pike.git/lib/modules/SSL.pmod/Connection.pike:300:    // next we must verify the chain to see if the chain is unbroken       mapping result =    Standards.X509.verify_certificate_chain(certs,    context->trusted_issuers_cache,    context->require_trust);    if(result->verified)    {    // This data isn't actually used internally.    session->cert_data = result; -  return 1; +  return [array(Standards.X509.TBSCertificate)]result->certificates;    }       return 0;   }      // Decodes certificate data. Leaves session->peer_certificate_chain   // either 0 or with an array with 1 or more certificates. If   // certificates are received session->peer_public_key is updated with   // the public key object. If that is an ECC object, the curve is set   // in session->curve. - int(0..1) handle_certificates(Stdio.Buffer input) + int(0..1) handle_certificates(Buffer packet)   {    // FIXME: Throw exception if called more than once?    -  +  Stdio.Buffer input = packet->read_hbuffer(3);    array(string(8bit)) certs = ({ });    while(sizeof(input))    certs += ({ input->read_hstring(3) });    // No need to check remainder input, as the above loop will either    // drain input fully or read out of bounds and trigger a decode    // error alert packet.    -  if( !verify_certificate_chain(certs) ) +  if(sizeof(packet))    { -  +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, +  "Unknown additional data in packet.\n")); +  return 0; +  } +  +  // This array is in the reverse order of the certs array. +  array(Standards.X509.TBSCertificate) decoded = +  verify_certificate_chain(certs); +  if( !decoded ) +  {    send_packet(alert(ALERT_fatal, ALERT_bad_certificate,    "Bad server certificate chain.\n"));    return 0;    }    if( !sizeof(certs) )    return 1;       session->peer_certificate_chain = certs;    -  mixed error=catch { -  session->peer_public_key = Standards.X509.decode_certificate( -  certs[0])->public_key->pkc; +  session->peer_public_key = decoded[-1]->public_key->pkc;   #if constant(Crypto.ECC.Curve)    if (session->peer_public_key->get_curve) {    session->curve =    ([object(Crypto.ECC.Curve.ECDSA)]session->peer_public_key)->    get_curve();    }   #endif -  }; +     -  if(error) -  { -  session->peer_certificate_chain = UNDEFINED; -  send_packet(alert(ALERT_fatal, ALERT_bad_certificate, -  sprintf("Failed to decode peer certificate. %s\n", -  describe_backtrace(error)))); -  return 0; -  } -  +     return 1;   }      //! Generate new pending cipher states.   void new_cipher_states();      //! Derive the master secret from the premaster_secret   //! and the random seeds, and configure the keys.   void derive_master_secret(string(8bit) premaster_secret)   {