summaryrefslogtreecommitdiff
path: root/mysql/mysys_ssl/crypt_genhash_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/mysys_ssl/crypt_genhash_impl.cpp')
-rw-r--r--mysql/mysys_ssl/crypt_genhash_impl.cpp465
1 files changed, 0 insertions, 465 deletions
diff --git a/mysql/mysys_ssl/crypt_genhash_impl.cpp b/mysql/mysys_ssl/crypt_genhash_impl.cpp
deleted file mode 100644
index 80b61dc..0000000
--- a/mysql/mysys_ssl/crypt_genhash_impl.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-
-
-// First include (the generated) my_config.h, to get correct platform defines.
-#include "my_config.h"
-
-#ifdef HAVE_OPENSSL
-
-#ifdef HAVE_YASSL
-#include <sha.hpp>
-#include <openssl/ssl.h>
-#else
-#include <openssl/sha.h>
-#include <openssl/rand.h>
-#endif
-
-#include "crypt_genhash_impl.h"
-
-#include "m_string.h"
-
-#include <stdint.h>
-#include <time.h>
-#include <string.h>
-
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#ifndef HAVE_YASSL
-#define DIGEST_CTX SHA256_CTX
-#define DIGESTInit SHA256_Init
-#define DIGESTUpdate SHA256_Update
-#define DIGESTFinal SHA256_Final
-#define DIGEST_LEN SHA256_DIGEST_LENGTH
-#else
-#define DIGEST_CTX TaoCrypt::SHA256
-#define DIGEST_LEN 32
-void DIGESTInit(DIGEST_CTX *ctx)
-{
- ctx->Init();
-}
-
-void DIGESTUpdate(DIGEST_CTX *ctx, const void *plaintext, int len)
-{
- ctx->Update((const TaoCrypt::byte *)plaintext, len);
-}
-
-void DIGESTFinal(void *txt, DIGEST_CTX *ctx)
-{
- ctx->Final((TaoCrypt::byte *)txt);
-}
-
-#endif // HAVE_YASSL
-
-static const char crypt_alg_magic[] = "$5";
-
-#ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-
-/**
- Size-bounded string copying and concatenation
- This is a replacement for STRLCPY(3)
-*/
-
-size_t
-strlcat(char *dst, const char *src, size_t siz)
-{
- char *d= dst;
- const char *s= src;
- size_t n= siz;
- size_t dlen;
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen= d - dst;
- n= siz - dlen;
- if (n == 0)
- return(dlen + siz);
- while (*s != '\0')
- {
- if (n != 1)
- {
- *d++= *s;
- n--;
- }
- s++;
- }
- *d= '\0';
- return(dlen + (s - src)); /* count does not include NUL */
-}
-
-static const int crypt_alg_magic_len = sizeof (crypt_alg_magic) - 1;
-
-static unsigned char b64t[] = /* 0 ... 63 => ascii - 64 */
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-#define b64_from_24bit(B2, B1, B0, N) \
-{ \
- uint32_t w = ((B2) << 16) | ((B1) << 8) | (B0); \
- int n = (N); \
- while (--n >= 0 && ctbufflen > 0) { \
- *p++ = b64t[w & 0x3f]; \
- w >>= 6; \
- ctbufflen--; \
-} \
-}
-
-#define ROUNDS "rounds="
-#define ROUNDSLEN (sizeof (ROUNDS) - 1)
-
-/**
- Get the integer value after rounds= where ever it occurs in the string.
- if the last char after the int is a , or $ that is fine anything else is an
- error.
-*/
-static uint getrounds(const char *s)
-{
- const char *r;
- const char *p;
- char *e;
- long val;
-
- if (s == NULL)
- return (0);
-
- if ((r = strstr(s, ROUNDS)) == NULL)
- {
- return (0);
- }
-
- if (strncmp(r, ROUNDS, ROUNDSLEN) != 0)
- {
- return (0);
- }
-
- p= r + ROUNDSLEN;
- errno= 0;
- val= strtol(p, &e, 10);
- /*
- An error occurred or there is non-numeric stuff at the end
- which isn't one of the crypt(3c) special chars ',' or '$'
- */
- if (errno != 0 || val < 0 || !(*e == '\0' || *e == ',' || *e == '$'))
- {
- return (0);
- }
-
- return ((uint32_t) val);
-}
-
-/**
- Finds the interval which envelopes the user salt in a crypt password
- The crypt format is assumed to be $a$bbbb$cccccc\0 and the salt is found
- by counting the delimiters and marking begin and end.
-
- @param salt_being[in] Pointer to start of crypt passwd
- @param salt_being[out] Pointer to first byte of the salt
- @param salt_end[in] Pointer to the last byte in passwd
- @param salt_end[out] Pointer to the byte immediatly following the salt ($)
-
- @return The size of the salt identified
-*/
-
-int extract_user_salt(char **salt_begin,
- char **salt_end)
-{
- char *it= *salt_begin;
- int delimiter_count= 0;
- while(it != *salt_end)
- {
- if (*it == '$')
- {
- ++delimiter_count;
- if (delimiter_count == 2)
- {
- *salt_begin= it + 1;
- }
- if (delimiter_count == 3)
- break;
- }
- ++it;
- }
- *salt_end= it;
- return *salt_end - *salt_begin;
-}
-
-const char *sha256_find_digest(char *pass)
-{
- int sz= strlen(pass);
- return pass + sz - SHA256_HASH_LENGTH;
-}
-
-/*
- * Portions of the below code come from crypt_bsdmd5.so (bsdmd5.c) :
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- *
- * $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
- *
- */
-
-/*
- * The below code implements the specification from:
- *
- * From http://people.redhat.com/drepper/SHA-crypt.txt
- *
- * Portions of the code taken from inspired by or verified against the
- * source in the above document which is licensed as:
- *
- * "Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>."
- */
-
-/*
- Due to a Solaris namespace bug DS is a reserved word. To work around this
- DS is undefined.
-*/
-#undef DS
-
-/* ARGSUSED4 */
-extern "C"
-char *
-my_crypt_genhash(char *ctbuffer,
- size_t ctbufflen,
- const char *plaintext,
- size_t plaintext_len,
- const char *switchsalt,
- const char **params)
-{
- int salt_len;
- size_t i;
- char *salt;
- unsigned char A[DIGEST_LEN];
- unsigned char B[DIGEST_LEN];
- unsigned char DP[DIGEST_LEN];
- unsigned char DS[DIGEST_LEN];
- DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS;
- uint rounds = ROUNDS_DEFAULT;
- int srounds = 0;
- bool custom_rounds= false;
- char *p;
- char *P, *Pp;
- char *S, *Sp;
-
- /* Refine the salt */
- salt = (char *)switchsalt;
-
- /* skip our magic string */
- if (strncmp(salt, crypt_alg_magic, crypt_alg_magic_len) == 0)
- {
- salt += crypt_alg_magic_len + 1;
- }
-
- srounds = getrounds(salt);
- if (srounds != 0) {
- rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
- custom_rounds= true;
- p = strchr(salt, '$');
- if (p != NULL)
- salt = p + 1;
- }
-
- salt_len = MIN(strcspn(salt, "$"), CRYPT_SALT_LENGTH);
- //plaintext_len = strlen(plaintext);
-
- /* 1. */
- DIGESTInit(&ctxA);
-
- /* 2. The password first, since that is what is most unknown */
- DIGESTUpdate(&ctxA, plaintext, plaintext_len);
-
- /* 3. Then the raw salt */
- DIGESTUpdate(&ctxA, salt, salt_len);
-
- /* 4. - 8. */
- DIGESTInit(&ctxB);
- DIGESTUpdate(&ctxB, plaintext, plaintext_len);
- DIGESTUpdate(&ctxB, salt, salt_len);
- DIGESTUpdate(&ctxB, plaintext, plaintext_len);
- DIGESTFinal(B, &ctxB);
-
- /* 9. - 10. */
- for (i= plaintext_len; i > MIXCHARS; i -= MIXCHARS)
- DIGESTUpdate(&ctxA, B, MIXCHARS);
- DIGESTUpdate(&ctxA, B, i);
-
- /* 11. */
- for (i= plaintext_len; i > 0; i >>= 1) {
- if ((i & 1) != 0)
- {
- DIGESTUpdate(&ctxA, B, MIXCHARS);
- }
- else
- {
- DIGESTUpdate(&ctxA, plaintext, plaintext_len);
- }
- }
-
- /* 12. */
- DIGESTFinal(A, &ctxA);
-
- /* 13. - 15. */
- DIGESTInit(&ctxDP);
- for (i= 0; i < plaintext_len; i++)
- DIGESTUpdate(&ctxDP, plaintext, plaintext_len);
- DIGESTFinal(DP, &ctxDP);
-
- /* 16. */
- Pp= P= (char *)alloca(plaintext_len);
- for (i= plaintext_len; i >= MIXCHARS; i -= MIXCHARS)
- {
- Pp= (char *)(memcpy(Pp, DP, MIXCHARS)) + MIXCHARS;
- }
- (void) memcpy(Pp, DP, i);
-
- /* 17. - 19. */
- DIGESTInit(&ctxDS);
- for (i= 0; i < 16U + (uint8_t)A[0]; i++)
- DIGESTUpdate(&ctxDS, salt, salt_len);
- DIGESTFinal(DS, &ctxDS);
-
- /* 20. */
- Sp= S= (char *)alloca(salt_len);
- for (i= salt_len; i >= MIXCHARS; i -= MIXCHARS)
- {
- Sp= (char *)(memcpy(Sp, DS, MIXCHARS)) + MIXCHARS;
- }
- (void) memcpy(Sp, DS, i);
-
- /* 21. */
- for (i= 0; i < rounds; i++)
- {
- DIGESTInit(&ctxC);
-
- if ((i & 1) != 0)
- {
- DIGESTUpdate(&ctxC, P, plaintext_len);
- }
- else
- {
- if (i == 0)
- DIGESTUpdate(&ctxC, A, MIXCHARS);
- else
- DIGESTUpdate(&ctxC, DP, MIXCHARS);
- }
-
- if (i % 3 != 0) {
- DIGESTUpdate(&ctxC, S, salt_len);
- }
-
- if (i % 7 != 0) {
- DIGESTUpdate(&ctxC, P, plaintext_len);
- }
-
- if ((i & 1) != 0)
- {
- if (i == 0)
- DIGESTUpdate(&ctxC, A, MIXCHARS);
- else
- DIGESTUpdate(&ctxC, DP, MIXCHARS);
- }
- else
- {
- DIGESTUpdate(&ctxC, P, plaintext_len);
- }
- DIGESTFinal(DP, &ctxC);
- }
-
- /* 22. Now make the output string */
- if (custom_rounds)
- {
- (void) my_snprintf(ctbuffer, ctbufflen,
- "%s$rounds=%zu$", crypt_alg_magic, (size_t)rounds);
- }
- else
- {
- (void) my_snprintf(ctbuffer, ctbufflen,
- "%s$", crypt_alg_magic);
- }
- (void) strncat(ctbuffer, (const char *)salt, salt_len);
- (void) strlcat(ctbuffer, "$", ctbufflen);
-
- p= ctbuffer + strlen(ctbuffer);
- ctbufflen -= strlen(ctbuffer);
-
- b64_from_24bit(DP[ 0], DP[10], DP[20], 4);
- b64_from_24bit(DP[21], DP[ 1], DP[11], 4);
- b64_from_24bit(DP[12], DP[22], DP[ 2], 4);
- b64_from_24bit(DP[ 3], DP[13], DP[23], 4);
- b64_from_24bit(DP[24], DP[ 4], DP[14], 4);
- b64_from_24bit(DP[15], DP[25], DP[ 5], 4);
- b64_from_24bit(DP[ 6], DP[16], DP[26], 4);
- b64_from_24bit(DP[27], DP[ 7], DP[17], 4);
- b64_from_24bit(DP[18], DP[28], DP[ 8], 4);
- b64_from_24bit(DP[ 9], DP[19], DP[29], 4);
- b64_from_24bit(0, DP[31], DP[30], 3);
- *p= '\0';
-
- (void) memset(A, 0, sizeof (A));
- (void) memset(B, 0, sizeof (B));
- (void) memset(DP, 0, sizeof (DP));
- (void) memset(DS, 0, sizeof (DS));
-
- return (ctbuffer);
-}
-
-
-/**
- Generate a random string using ASCII characters but avoid seperator character.
- Stdlib rand and srand are used to produce pseudo random numbers between
- with about 7 bit worth of entropty between 1-127.
-*/
-extern "C"
-void generate_user_salt(char *buffer, int buffer_len)
-{
- char *end= buffer + buffer_len - 1;
-#ifdef HAVE_YASSL
- yaSSL::RAND_bytes((unsigned char *) buffer, buffer_len);
-#else
- RAND_bytes((unsigned char *) buffer, buffer_len);
-#endif
-
- /* Sequence must be a legal UTF8 string */
- for (; buffer < end; buffer++)
- {
- *buffer &= 0x7f;
- if (*buffer == '\0' || *buffer == '$')
- *buffer= *buffer + 1;
- }
- /* Make sure the buffer is terminated properly */
- *end= '\0';
-}
-
-void xor_string(char *to, int to_len, char *pattern, int pattern_len)
-{
- int loop= 0;
- while(loop <= to_len)
- {
- *(to + loop) ^= *(pattern + loop % pattern_len);
- ++loop;
- }
-}
-
-#endif // HAVE_OPENSSL