nss_obfuscate.c revision 625bb2ddf15e8f305a53afa44e87f2146fa930af
/*
SSSD
Password obfuscation logic
Author: Jakub Hrozek <jhrozek@redhat.com>
Copyright (C) Red Hat, Inc 2010
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
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, see <http://www.gnu.org/licenses/>.
*/
/*
* READ ME:
*
* Please note that password obfuscation does not improve security in any
* way. It is just a mechanism to make the password human-unreadable. If you
* need to secure passwords in your application, you should probably take a
* look at storing passwords in NSS-backed database.
*/
#include "config.h"
#include <prerror.h>
#include <pk11func.h>
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
#include "util/crypto/nss/nss_crypto.h"
#define OBF_BUFFER_SENTINEL "\0\1\2\3"
#define OBF_BUFFER_SENTINEL_SIZE 4
static struct crypto_mech_data cmdata[] = {
/* AES with automatic padding, 256b key, 128b block */
/* sentinel */
{ 0, 0, 0 }
};
{
if (meth >= NUM_OBFMETHODS) {
return NULL;
}
}
{
int ret;
struct crypto_mech_data *mech_props;
struct sss_nss_crypto_ctx *cctx;
unsigned char *plaintext;
unsigned char *cryptotext;
int ct_maxsize;
int ctlen;
unsigned int digestlen;
int result_len;
unsigned char *obfbuf;
size_t p = 0;
if (!tmp_ctx) {
return ENOMEM;
}
/* initialize NSS if needed */
ret = nspr_nss_init();
goto done;
}
if (mech_props == NULL) {
goto done;
}
/* Initiualize ctx and generate random encryption and IV key */
if (ret) {
goto done;
}
if (ret) {
"Cannot initialize NSS context properties\n");
goto done;
}
if (!plaintext) {
goto done;
}
/* cryptotext buffer must be at least len(plaintext)+blocksize */
if (!cryptotext) {
goto done;
}
/* sample data we'll encrypt and decrypt */
if (sret != SECSuccess) {
"Cannot execute the encryption operation (err %d)\n",
PR_GetError());
goto done;
}
if (sret != SECSuccess) {
"Cannot execute the digest operation (err %d)\n",
PR_GetError());
goto done;
}
goto done;
}
/* Pack the obfuscation buffer */
/* The buffer consists of:
* uint16_t the type of the cipher
* uint16_t length of the cryptotext in bytes (clen)
* uint8_t[klen] key
* uint8_t[blen] IV
* uint8_t[clen] cryptotext
* 4 bytes of "sentinel" denoting end of the buffer
*/
if (!obfbuf) {
goto done;
}
OBF_BUFFER_SENTINEL_SIZE, &p);
/* Base64 encode the resulting buffer */
goto done;
}
done:
return ret;
}
char **password)
{
int ret;
struct crypto_mech_data *mech_props;
struct sss_nss_crypto_ctx *cctx;
int plainlen;
unsigned int digestlen;
char *pwdbuf;
/* for unmarshaling data */
size_t p = 0;
unsigned char *cryptotext;
unsigned char *keybuf;
unsigned char *ivbuf;
unsigned char sentinel_check[OBF_BUFFER_SENTINEL_SIZE];
if (!tmp_ctx) {
return ENOMEM;
}
/* initialize NSS if needed */
ret = nspr_nss_init();
goto done;
}
/* Base64 decode the incoming buffer */
if (!obfbuf) {
goto done;
}
/* unpack obfuscation buffer */
if (mech_props == NULL) {
goto done;
}
/* check that we got sane mechanism properties and cryptotext size */
if (memcmp(sentinel_check,
OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) {
"Obfuscation buffer seems corrupt, aborting\n");
goto done;
}
/* copy out key, ivbuf and cryptotext */
goto done;
}
goto done;
}
if (cryptotext == NULL) {
goto done;
}
if (ret) {
goto done;
}
if (ret) {
goto done;
}
if (!pwdbuf) {
goto done;
}
if (sret != SECSuccess) {
"Cannot execute the encryption operation (err %d)\n",
PR_GetError());
goto done;
}
if (sret != SECSuccess) {
"Cannot execute the encryption operation (err %d)\n",
PR_GetError());
goto done;
}
done:
return ret;
}