Ejemplo n.º 1
0
error_t chapProcessChallenge(PppContext *context,
   const ChapChallengePacket *challengePacket, size_t length)
{
   size_t n;
   Md5Context md5Context;

   //Debug message
   TRACE_INFO("\r\nCHAP Challenge packet received\r\n");

   //Make sure the Challenge packet is acceptable
   if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
      return ERROR_FAILURE;

   //Check the length of the packet
   if(length < sizeof(ChapChallengePacket))
      return ERROR_INVALID_LENGTH;

   //Malformed Challenge packet?
   if(length < (sizeof(ChapChallengePacket) + challengePacket->valueSize))
      return ERROR_INVALID_LENGTH;

   //Save the Identifier field
   context->chapFsm.peerIdentifier = challengePacket->identifier;

   //Retrieve the length of the password
   n = strlen(context->password);

   //The response value is the one-way hash calculated over a stream
   //of octets consisting of the identifier, followed by the secret,
   //followed by the challenge value
   md5Init(&md5Context);
   md5Update(&md5Context, &challengePacket->identifier, sizeof(uint8_t));
   md5Update(&md5Context, context->password, n);
   md5Update(&md5Context, challengePacket->value, challengePacket->valueSize);
   md5Final(&md5Context, NULL);

   //Whenever a Challenge packet is received, the peer must send a Response packet
   chapSendResponse(context, md5Context.digest);

   //Switch to the Response-Sent state
   context->chapFsm.peerState = CHAP_STATE_4_RESPONSE_SENT;

   //Successful processing
   return NO_ERROR;
}
Ejemplo n.º 2
0
bool_t chapCheckPassword(PppContext *context, const char_t *password)
{
   size_t n;
   Md5Context md5Context;

   //Retrieve the length of the password
   n = strlen(password);

   //The response value is the one-way hash calculated over a stream
   //of octets consisting of the identifier, followed by the secret,
   //followed by the challenge value
   md5Init(&md5Context);
   md5Update(&md5Context, &context->chapFsm.localIdentifier, sizeof(uint8_t));
   md5Update(&md5Context, password, n);
   md5Update(&md5Context, context->chapFsm.challenge, MD5_DIGEST_SIZE);
   md5Final(&md5Context, NULL);

   //Check the resulting digest value
   if(!memcmp(md5Context.digest, context->chapFsm.response, MD5_DIGEST_SIZE))
      return TRUE;
   else
      return FALSE;
}
Ejemplo n.º 3
0
int md5file(FILE* fp, std::string& digest)
{
    if(!fp)
        return -1;
    unsigned char d[16];
    unsigned char buf[1024];
    md5Context ctx;

    md5Init(&ctx);
    size_t n;
    while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
        md5Update(&ctx, buf, n);
    md5Final(&ctx, d);

    std::stringstream s;
    for (int i = 0; i < 16; ++i)
        s << std::hex << std::setiosflags(std::ios::fixed) << std::setfill('0') << std::setw(2) << static_cast<int>(d[i]);

    digest = s.str();

    if (ferror(fp))
        return -1;
    return 0;
}
Ejemplo n.º 4
0
bool_t httpCheckPassword(HttpConnection *connection,
   const char_t *password, HttpAuthMode mode)
{
   //This flag tells whether the password is valid
   bool_t status = FALSE;

   //Debug message
   TRACE_DEBUG("Password verification...\r\n");

#if (HTTP_SERVER_BASIC_AUTH_SUPPORT == ENABLED)
   //Basic authentication scheme?
   if(mode == HTTP_AUTH_MODE_BASIC)
   {
      //Point to the authentication credentials
      HttpAuthorizationHeader *auth = &connection->request.auth;

      //Make sure authentication credentials have been found
      if(auth->found && auth->mode == HTTP_AUTH_MODE_BASIC)
      {
         //Sanity check
         if(auth->password != NULL)
         {
            //Check whether the password is valid
            if(!strcmp(password, auth->password))
               status = TRUE;
         }
      }
   }
#endif
#if (HTTP_SERVER_DIGEST_AUTH_SUPPORT == ENABLED)
   //Digest authentication scheme?
   if(mode == HTTP_AUTH_MODE_DIGEST)
   {
      //Point to the authentication credentials
      HttpAuthorizationHeader *auth = &connection->request.auth;

      //Make sure authentication credentials have been found
      if(auth->found && auth->mode == HTTP_AUTH_MODE_DIGEST)
      {
         //Sanity check
         if(auth->realm != NULL && auth->realm != NULL &&
            auth->nonce != NULL && auth->qop != NULL &&
            auth->nc != NULL && auth->cnonce != NULL &&
            auth->response != NULL)
         {
            error_t error;
            Md5Context *md5Context;
            char_t ha1[2 * MD5_DIGEST_SIZE + 1];
            char_t ha2[2 * MD5_DIGEST_SIZE + 1];

            //Allocate a memory buffer to hold the MD5 context
            md5Context = osAllocMem(sizeof(Md5Context));

            //MD5 context successfully allocated?
            if(md5Context != NULL)
            {
               //Compute HA1 = MD5(username : realm : password)
               md5Init(md5Context);
               md5Update(md5Context, auth->user, strlen(auth->user));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->realm, strlen(auth->realm));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, password, strlen(password));
               md5Final(md5Context, NULL);

               //Convert MD5 hash to hex string
               httpConvertArrayToHexString(md5Context->digest, MD5_DIGEST_SIZE, ha1);
               //Debug message
               TRACE_DEBUG("  HA1: %s\r\n", ha1);

               //Compute HA2 = MD5(method : uri)
               md5Init(md5Context);
               md5Update(md5Context, connection->request.method, strlen(connection->request.method));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->uri, strlen(auth->uri));
               md5Final(md5Context, NULL);

               //Convert MD5 hash to hex string
               httpConvertArrayToHexString(md5Context->digest, MD5_DIGEST_SIZE, ha2);
               //Debug message
               TRACE_DEBUG("  HA2: %s\r\n", ha2);

               //Compute MD5(HA1 : nonce : nc : cnonce : qop : HA1)
               md5Init(md5Context);
               md5Update(md5Context, ha1, strlen(ha1));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->nonce, strlen(auth->nonce));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->nc, strlen(auth->nc));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->cnonce, strlen(auth->cnonce));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, auth->qop, strlen(auth->qop));
               md5Update(md5Context, ":", 1);
               md5Update(md5Context, ha2, strlen(ha2));
               md5Final(md5Context, NULL);

               //Convert MD5 hash to hex string
               httpConvertArrayToHexString(md5Context->digest, MD5_DIGEST_SIZE, ha1);
               //Debug message
               TRACE_DEBUG("  response: %s\r\n", ha1);

               //Release MD5 context
               osFreeMem(md5Context);

               //Check response
               if(!strcasecmp(auth->response, ha1))
               {
                  //Perform nonce verification
                  error = httpVerifyNonce(connection->serverContext, auth->nonce, auth->nc);

                  //Valid nonce?
                  if(!error)
                  {
                     //Access to the resource is granted
                     status = TRUE;
                  }
                  else
                  {
                     //The client may wish to simply retry the request with a
                     //new encrypted response, without re-prompting the user
                     //for a new username and password
                     connection->response.auth.stale = TRUE;
                  }
               }
            }
         }
      }
   }
#endif

   //Return TRUE is the password is valid, else FALSE
   return status;
}