ssha_pwd.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /*
  13. * slapd hashed password routines
  14. *
  15. */
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <sys/types.h>
  19. #include "pwdstorage.h"
  20. #include "prtime.h"
  21. #include "prlong.h"
  22. #include <pk11func.h>
  23. #include <pk11pqg.h>
  24. #define SHA_SALT_LENGTH 8 /* number of bytes of data in salt */
  25. SECStatus
  26. sha_salted_hash(char *hash_out, const char *pwd, struct berval *salt, unsigned int secOID)
  27. {
  28. PK11Context *ctx;
  29. unsigned int outLen;
  30. unsigned int shaLen;
  31. SECStatus rc;
  32. switch (secOID) {
  33. case SEC_OID_SHA1:
  34. shaLen = SHA1_LENGTH;
  35. break;
  36. case SEC_OID_SHA256:
  37. shaLen = SHA256_LENGTH;
  38. break;
  39. case SEC_OID_SHA384:
  40. shaLen = SHA384_LENGTH;
  41. break;
  42. case SEC_OID_SHA512:
  43. shaLen = SHA512_LENGTH;
  44. break;
  45. default:
  46. /* An unknown secOID was passed in. We shouldn't get here. */
  47. rc = SECFailure;
  48. return rc;
  49. }
  50. if (salt && salt->bv_len) {
  51. ctx = PK11_CreateDigestContext(secOID);
  52. if (ctx == NULL) {
  53. rc = SECFailure;
  54. } else {
  55. PK11_DigestBegin(ctx);
  56. PK11_DigestOp(ctx, (unsigned char*)pwd, strlen(pwd));
  57. PK11_DigestOp(ctx, (unsigned char*)(salt->bv_val), salt->bv_len);
  58. PK11_DigestFinal(ctx, (unsigned char*)hash_out, &outLen, shaLen);
  59. PK11_DestroyContext(ctx, 1);
  60. if (outLen == shaLen)
  61. rc = SECSuccess;
  62. else
  63. rc = SECFailure;
  64. }
  65. }
  66. else {
  67. /*backward compatibility*/
  68. rc = PK11_HashBuf(secOID, (unsigned char*)hash_out, (unsigned char *)pwd, strlen(pwd));
  69. }
  70. return rc;
  71. }
  72. char *
  73. salted_sha_pw_enc( const char *pwd, unsigned int shaLen )
  74. {
  75. char hash[ MAX_SHA_HASH_SIZE + SHA_SALT_LENGTH ];
  76. char *salt = hash + shaLen;
  77. struct berval saltval;
  78. char *enc;
  79. size_t encsize;
  80. char *schemeName;
  81. unsigned int schemeNameLen;
  82. unsigned int secOID;
  83. /* Determine which algorithm we're using */
  84. switch (shaLen) {
  85. case SHA1_LENGTH:
  86. schemeName = SALTED_SHA1_SCHEME_NAME;
  87. schemeNameLen = SALTED_SHA1_NAME_LEN;
  88. secOID = SEC_OID_SHA1;
  89. break;
  90. case SHA256_LENGTH:
  91. schemeName = SALTED_SHA256_SCHEME_NAME;
  92. schemeNameLen = SALTED_SHA256_NAME_LEN;
  93. secOID = SEC_OID_SHA256;
  94. break;
  95. case SHA384_LENGTH:
  96. schemeName = SALTED_SHA384_SCHEME_NAME;
  97. schemeNameLen = SALTED_SHA384_NAME_LEN;
  98. secOID = SEC_OID_SHA384;
  99. break;
  100. case SHA512_LENGTH:
  101. schemeName = SALTED_SHA512_SCHEME_NAME;
  102. schemeNameLen = SALTED_SHA512_NAME_LEN;
  103. secOID = SEC_OID_SHA512;
  104. break;
  105. default:
  106. /* An unknown shaLen was passed in. We shouldn't get here. */
  107. return( NULL );
  108. }
  109. memset(hash, 0, sizeof(hash));
  110. saltval.bv_val = (void*)salt;
  111. saltval.bv_len = SHA_SALT_LENGTH;
  112. /* generate a new random salt */
  113. slapi_rand_array( salt, SHA_SALT_LENGTH );
  114. /* hash the user's key */
  115. if ( sha_salted_hash( hash, pwd, &saltval, secOID ) != SECSuccess ) {
  116. return( NULL );
  117. }
  118. encsize = 3 + schemeNameLen +
  119. LDIF_BASE64_LEN(shaLen + SHA_SALT_LENGTH);
  120. if ( ( enc = slapi_ch_calloc( encsize, sizeof(char) ) ) == NULL ) {
  121. return( NULL );
  122. }
  123. sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, schemeName,
  124. PWD_HASH_PREFIX_END );
  125. (void)PL_Base64Encode( hash, (shaLen + SHA_SALT_LENGTH), enc + 2 + schemeNameLen );
  126. PR_ASSERT(0 == enc[encsize-1]); /* must be null terminated */
  127. return( enc );
  128. }
  129. /*
  130. * Wrapper functions for password encoding
  131. */
  132. char *
  133. salted_sha1_pw_enc( const char *pwd )
  134. {
  135. return salted_sha_pw_enc( pwd, SHA1_LENGTH );
  136. }
  137. char *
  138. salted_sha256_pw_enc( const char *pwd )
  139. {
  140. return salted_sha_pw_enc( pwd, SHA256_LENGTH );
  141. }
  142. char *
  143. salted_sha384_pw_enc( const char *pwd )
  144. {
  145. return salted_sha_pw_enc( pwd, SHA384_LENGTH );
  146. }
  147. char *
  148. salted_sha512_pw_enc( const char *pwd )
  149. {
  150. return salted_sha_pw_enc( pwd, SHA512_LENGTH );
  151. }