nss_obfuscate.c revision 4a6a5421113ab662a665c62ed6a24b61a5a36950
/*
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 <nss.h>
#include <pk11func.h>
#include <base64.h>
#include <talloc.h>
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
#define OBF_BUFFER_SENTINEL "\0\1\2\3"
#define OBF_BUFFER_SENTINEL_SIZE 4
} while(0)
struct sss_nss_crypto_ctx {
};
struct crypto_mech_data {
};
static struct crypto_mech_data cmdata[] = {
/* AES with automatic padding, 256b key, 128b block */
/* sentinel */
{ 0, 0, 0 }
};
{
if (meth >= NUM_OBFMETHODS) {
return NULL;
}
}
struct crypto_mech_data *mech_props,
{
int ret;
PR_GetError()));
goto done;
}
if (sret != SECSuccess) {
PR_GetError()));
goto done;
}
PR_GetError()));
goto done;
}
/* randkeydata is valid until randkey is. Copy with talloc to
* get a nice memory hierarchy symmetrical in encrypt
* and decrypt case */
if (!key) {
goto done;
}
goto done;
}
done:
return ret;
}
{
return EOK;
}
struct crypto_mech_data *mech_props,
struct sss_nss_crypto_ctx **_cctx)
{
struct sss_nss_crypto_ctx *cctx;
int ret;
if (!cctx) {
return ENOMEM;
}
PR_GetError()));
goto done;
}
done:
return ret;
}
struct crypto_mech_data *mech_props,
bool do_encrypt,
struct sss_nss_crypto_ctx *cctx)
{
int ret;
/* turn the raw key into a key object */
PR_GetError()));
goto done;
}
/* turn the raw IV into a initialization vector object */
PR_GetError()));
goto done;
}
/* Create cipher context */
PORT_GetError()));
goto done;
}
done:
return ret;
}
/* NSS wraps b64 encoded buffers with CRLF automatically after 64 chars. This
* function strips the CRLF double-chars. The buffer can be decoded with plain
* NSS calls */
unsigned char *inbuf,
{
char *b64encoded = NULL;
int i, j, b64size;
char *outbuf;
if (!b64encoded) return NULL;
return NULL;
}
for (i=0, j=0; i < b64size; i++) {
continue;
}
}
return outbuf;
}
{
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;
}
if (ret) {
goto done;
}
/* generate random encryption and IV key */
goto done;
}
goto done;
}
if (ret) {
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) {
PR_GetError()));
goto done;
}
if (sret != SECSuccess) {
PR_GetError()));
goto done;
}
/* Pack the obfuscation buffer */
/* The buffer consists of:
* uint16_t the type of the cipher
* uint32_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;
unsigned int obflen;
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 */
DEBUG(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;
}
goto done;
}
if (ret) {
goto done;
}
if (!pwdbuf) {
goto done;
}
cryptotext, ctsize);
if (sret != SECSuccess) {
PR_GetError()));
goto done;
}
if (sret != SECSuccess) {
PR_GetError()));
goto done;
}
done:
return ret;
}