示例#1
0
static bool
_mongoc_scram_verify_server_signature (mongoc_scram_t *scram,
                                       uint8_t        *verification,
                                       uint32_t        len)
{
   /* ServerKey := HMAC(SaltedPassword, "Server Key") */
#if !defined(__APPLE__)
   uint32_t hash_len;
#endif
   uint8_t server_key[MONGOC_SCRAM_HASH_SIZE];
   char encoded_server_signature[MONGOC_SCRAM_B64_HASH_SIZE];
   int32_t encoded_server_signature_len;
   uint8_t server_signature[MONGOC_SCRAM_HASH_SIZE];

#if defined(__APPLE__)
   CCHmac (kCCHmacAlgSHA1,
           scram->salted_password,
           MONGOC_SCRAM_HASH_SIZE,
           (uint8_t *)MONGOC_SCRAM_SERVER_KEY,
           strlen (MONGOC_SCRAM_SERVER_KEY),
           server_key);

   /* ServerSignature := HMAC(ServerKey, AuthMessage) */
   CCHmac (kCCHmacAlgSHA1,
           server_key,
           MONGOC_SCRAM_HASH_SIZE,
           scram->auth_message,
           scram->auth_messagelen,
           server_signature);
#else
   HMAC (EVP_sha1 (),
         scram->salted_password,
         MONGOC_SCRAM_HASH_SIZE,
         (uint8_t *)MONGOC_SCRAM_SERVER_KEY,
         strlen (MONGOC_SCRAM_SERVER_KEY),
         server_key,
         &hash_len);

   /* ServerSignature := HMAC(ServerKey, AuthMessage) */
   HMAC (EVP_sha1 (),
         server_key,
         MONGOC_SCRAM_HASH_SIZE,
         scram->auth_message,
         scram->auth_messagelen,
         server_signature,
         &hash_len);
#endif

   encoded_server_signature_len =
      mongoc_b64_ntop (server_signature, sizeof (server_signature),
                       encoded_server_signature,
                       sizeof (encoded_server_signature));

   return (len == encoded_server_signature_len) &&
          (memcmp (verification, encoded_server_signature, len) == 0);
}
示例#2
0
static bool
_mongoc_scram_generate_client_proof (mongoc_scram_t *scram,
                                     uint8_t *outbuf,
                                     uint32_t outbufmax,
                                     uint32_t *outbuflen)
{
   uint8_t client_key[MONGOC_SCRAM_HASH_SIZE];
   uint8_t stored_key[MONGOC_SCRAM_HASH_SIZE];
   uint8_t client_signature[MONGOC_SCRAM_HASH_SIZE];
   unsigned char client_proof[MONGOC_SCRAM_HASH_SIZE];
   int i;
   int r = 0;

   /* ClientKey := HMAC(saltedPassword, "Client Key") */
   mongoc_crypto_hmac_sha1 (&scram->crypto,
                            scram->salted_password,
                            MONGOC_SCRAM_HASH_SIZE,
                            (uint8_t *) MONGOC_SCRAM_CLIENT_KEY,
                            strlen (MONGOC_SCRAM_CLIENT_KEY),
                            client_key);

   /* StoredKey := H(client_key) */
   mongoc_crypto_sha1 (
      &scram->crypto, client_key, MONGOC_SCRAM_HASH_SIZE, stored_key);

   /* ClientSignature := HMAC(StoredKey, AuthMessage) */
   mongoc_crypto_hmac_sha1 (&scram->crypto,
                            stored_key,
                            MONGOC_SCRAM_HASH_SIZE,
                            scram->auth_message,
                            scram->auth_messagelen,
                            client_signature);

   /* ClientProof := ClientKey XOR ClientSignature */

   for (i = 0; i < MONGOC_SCRAM_HASH_SIZE; i++) {
      client_proof[i] = client_key[i] ^ client_signature[i];
   }

   r = mongoc_b64_ntop (client_proof,
                        sizeof (client_proof),
                        (char *) outbuf + *outbuflen,
                        outbufmax - *outbuflen);

   if (-1 == r) {
      return false;
   }

   *outbuflen += r;

   return true;
}
示例#3
0
static bool
_mongoc_scram_verify_server_signature (mongoc_scram_t *scram,
                                       uint8_t *verification,
                                       uint32_t len)
{
   uint8_t server_key[MONGOC_SCRAM_HASH_SIZE];
   char encoded_server_signature[MONGOC_SCRAM_B64_HASH_SIZE];
   int32_t encoded_server_signature_len;
   uint8_t server_signature[MONGOC_SCRAM_HASH_SIZE];

   /* ServerKey := HMAC(SaltedPassword, "Server Key") */
   mongoc_crypto_hmac_sha1 (&scram->crypto,
                            scram->salted_password,
                            MONGOC_SCRAM_HASH_SIZE,
                            (uint8_t *) MONGOC_SCRAM_SERVER_KEY,
                            strlen (MONGOC_SCRAM_SERVER_KEY),
                            server_key);

   /* ServerSignature := HMAC(ServerKey, AuthMessage) */
   mongoc_crypto_hmac_sha1 (&scram->crypto,
                            server_key,
                            MONGOC_SCRAM_HASH_SIZE,
                            scram->auth_message,
                            scram->auth_messagelen,
                            server_signature);

   encoded_server_signature_len =
      mongoc_b64_ntop (server_signature,
                       sizeof (server_signature),
                       encoded_server_signature,
                       sizeof (encoded_server_signature));
   if (encoded_server_signature_len == -1) {
      return false;
   }

   return (len == encoded_server_signature_len) &&
          (mongoc_memcmp (verification, encoded_server_signature, len) == 0);
}
示例#4
0
/* generate client-first-message:
 * n,a=authzid,n=encoded-username,r=client-nonce
 *
 * note that a= is optional, so we aren't dealing with that here
 */
static bool
_mongoc_scram_start (mongoc_scram_t *scram,
                     uint8_t *outbuf,
                     uint32_t outbufmax,
                     uint32_t *outbuflen,
                     bson_error_t *error)
{
   uint8_t nonce[24];
   const char *ptr;
   bool rval = true;

   BSON_ASSERT (scram);
   BSON_ASSERT (outbuf);
   BSON_ASSERT (outbufmax);
   BSON_ASSERT (outbuflen);

   /* auth message is as big as the outbuf just because */
   scram->auth_message = (uint8_t *) bson_malloc (outbufmax);
   scram->auth_messagemax = outbufmax;

   /* the server uses a 24 byte random nonce.  so we do as well */
   if (1 != _mongoc_rand_bytes (nonce, sizeof (nonce))) {
      bson_set_error (error,
                      MONGOC_ERROR_SCRAM,
                      MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
                      "SCRAM Failure: could not generate a cryptographically "
                      "secure nonce in sasl step 1");
      goto FAIL;
   }

   scram->encoded_nonce_len = mongoc_b64_ntop (nonce,
                                               sizeof (nonce),
                                               scram->encoded_nonce,
                                               sizeof (scram->encoded_nonce));

   if (-1 == scram->encoded_nonce_len) {
      bson_set_error (error,
                      MONGOC_ERROR_SCRAM,
                      MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
                      "SCRAM Failure: could not encode nonce");
      goto FAIL;
   }

   if (!_mongoc_scram_buf_write ("n,,n=", -1, outbuf, outbufmax, outbuflen)) {
      goto BUFFER;
   }

   for (ptr = scram->user; *ptr; ptr++) {
      /* RFC 5802 specifies that ',' and '=' and encoded as '=2C' and '=3D'
       * respectively in the user name */
      switch (*ptr) {
      case ',':

         if (!_mongoc_scram_buf_write (
                "=2C", -1, outbuf, outbufmax, outbuflen)) {
            goto BUFFER;
         }

         break;
      case '=':

         if (!_mongoc_scram_buf_write (
                "=3D", -1, outbuf, outbufmax, outbuflen)) {
            goto BUFFER;
         }

         break;
      default:

         if (!_mongoc_scram_buf_write (ptr, 1, outbuf, outbufmax, outbuflen)) {
            goto BUFFER;
         }

         break;
      }
   }

   if (!_mongoc_scram_buf_write (",r=", -1, outbuf, outbufmax, outbuflen)) {
      goto BUFFER;
   }

   if (!_mongoc_scram_buf_write (scram->encoded_nonce,
                                 scram->encoded_nonce_len,
                                 outbuf,
                                 outbufmax,
                                 outbuflen)) {
      goto BUFFER;
   }

   /* we have to keep track of the conversation to create a client proof later
    * on.  This copies the message we're crafting from the 'n=' portion onwards
    * into a buffer we're managing */
   if (!_mongoc_scram_buf_write ((char *) outbuf + 3,
                                 *outbuflen - 3,
                                 scram->auth_message,
                                 scram->auth_messagemax,
                                 &scram->auth_messagelen)) {
      goto BUFFER_AUTH;
   }

   if (!_mongoc_scram_buf_write (",",
                                 -1,
                                 scram->auth_message,
                                 scram->auth_messagemax,
                                 &scram->auth_messagelen)) {
      goto BUFFER_AUTH;
   }

   goto CLEANUP;

BUFFER_AUTH:
   bson_set_error (
      error,
      MONGOC_ERROR_SCRAM,
      MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
      "SCRAM Failure: could not buffer auth message in sasl step1");

   goto FAIL;

BUFFER:
   bson_set_error (error,
                   MONGOC_ERROR_SCRAM,
                   MONGOC_ERROR_SCRAM_PROTOCOL_ERROR,
                   "SCRAM Failure: could not buffer sasl step1");

   goto FAIL;

FAIL:
   rval = false;

CLEANUP:

   return rval;
}
示例#5
0
static bool
_mongoc_scram_generate_client_proof (mongoc_scram_t *scram,
                                     uint8_t        *outbuf,
                                     size_t          outbufmax,
                                     size_t         *outbuflen)
{
   /* ClientKey := HMAC(saltedPassword, "Client Key") */
   uint8_t client_key[MONGOC_SCRAM_HASH_SIZE];
   uint8_t stored_key[MONGOC_SCRAM_HASH_SIZE];
   uint8_t client_signature[MONGOC_SCRAM_HASH_SIZE];
   unsigned char client_proof[MONGOC_SCRAM_HASH_SIZE];
#if !defined(__APPLE__)
   uint32_t hash_len = 0;
#endif
   int i;
   int r = 0;

#if defined(__APPLE__)
   CCHmac (kCCHmacAlgSHA1,
           scram->salted_password,
           MONGOC_SCRAM_HASH_SIZE,
           (uint8_t *)MONGOC_SCRAM_CLIENT_KEY,
           strlen (MONGOC_SCRAM_CLIENT_KEY),
           client_key);
    
   /* StoredKey := H(client_key) */
   CC_SHA1 (client_key, MONGOC_SCRAM_HASH_SIZE, stored_key);

   /* ClientSignature := HMAC(StoredKey, AuthMessage) */
   CCHmac (kCCHmacAlgSHA1,
           stored_key,
           MONGOC_SCRAM_HASH_SIZE,
           scram->auth_message,
           scram->auth_messagelen,
           client_signature);
#else
   HMAC (EVP_sha1 (),
         scram->salted_password,
         MONGOC_SCRAM_HASH_SIZE,
         (uint8_t *)MONGOC_SCRAM_CLIENT_KEY,
         strlen (MONGOC_SCRAM_CLIENT_KEY),
         client_key,
         &hash_len);

   /* StoredKey := H(client_key) */
   SHA1 (client_key, MONGOC_SCRAM_HASH_SIZE, stored_key);

   /* ClientSignature := HMAC(StoredKey, AuthMessage) */
   HMAC (EVP_sha1 (),
         stored_key,
         MONGOC_SCRAM_HASH_SIZE,
         scram->auth_message,
         scram->auth_messagelen,
         client_signature,
         &hash_len);
#endif

   /* ClientProof := ClientKey XOR ClientSignature */

   for (i = 0; i < MONGOC_SCRAM_HASH_SIZE; i++) {
      client_proof[i] = client_key[i] ^ client_signature[i];
   }

   r = mongoc_b64_ntop (client_proof, sizeof (client_proof),
                        (char *)outbuf + *outbuflen,
                        outbufmax - *outbuflen);

   if (-1 == r) {
      return false;
   }

   *outbuflen += r;

   return true;
}