Removes ssl from blender. makes the following directorys not needed anymore: blender/intern/keymaker blender/source/blender/src/pub blender/source/blender/encrypt blender/source/blender/decrypt blender/source/blender/sign blender/source/blender/verify It works with The Nan Makefiles and autoconf, could whoever is working on the other build systems update them so we can nuke those directorys? They won't do anything but I figured I'd leave them in for a week or so to make things easyer on people. Kent
399 lines
12 KiB
C
399 lines
12 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* 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; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
* openssl decryption wrapper library
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h> /* memcpy, strcpy */
|
|
#include <stdlib.h>
|
|
|
|
#include "openssl/rsa.h"
|
|
#include "openssl/rc4.h"
|
|
#include "openssl/err.h"
|
|
#include "zlib.h"
|
|
|
|
#include "GEN_messaging.h"
|
|
|
|
#include "BLO_getPubKey.h" // real and stub implemented at writestream ...
|
|
|
|
#include "BLO_readStreamGlue.h"
|
|
#include "BLO_decrypt.h"
|
|
#include "BLO_en_de_cryptHeader.h"
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
struct decryptStructType {
|
|
struct readStreamGlueStruct *streamGlue;
|
|
unsigned int streamDone;
|
|
unsigned char *deCryptKey;
|
|
int deCryptKeyLen; // NOTE: signed int
|
|
unsigned char headerbuffer[EN_DE_CRYPTHEADERSTRUCTSIZE];
|
|
uint32_t datacrc; // crypted data checksum
|
|
struct BLO_en_de_cryptHeaderStruct *streamHeader;
|
|
RC4_KEY rc4_key;
|
|
void *endControl;
|
|
};
|
|
|
|
BLO_decryptStructHandle
|
|
BLO_decrypt_begin(
|
|
void *endControl)
|
|
{
|
|
struct decryptStructType *control;
|
|
control = malloc(sizeof(struct decryptStructType));
|
|
if (!control) return NULL;
|
|
|
|
control->streamGlue = NULL;
|
|
control->streamDone = 0;
|
|
control->deCryptKey = NULL;
|
|
control->deCryptKeyLen = 0;
|
|
strcpy(control->headerbuffer, "");
|
|
control->datacrc = 0;
|
|
|
|
control->streamHeader = malloc(EN_DE_CRYPTHEADERSTRUCTSIZE);
|
|
if (!control->streamHeader) {
|
|
free(control);
|
|
return NULL;
|
|
}
|
|
|
|
control->streamHeader->magic = 0;
|
|
control->streamHeader->length = 0;
|
|
strcpy(control->streamHeader->pubKey, "");
|
|
control->streamHeader->pubKeyLen = 0;
|
|
strcpy(control->streamHeader->cryptedKey, "");
|
|
control->streamHeader->cryptedKeyLen = 0;
|
|
control->streamHeader->datacrc = 0;
|
|
control->streamHeader->headercrc = 0;
|
|
control->endControl = endControl;
|
|
|
|
return((BLO_decryptStructHandle) control);
|
|
}
|
|
|
|
int
|
|
BLO_decrypt_process(
|
|
BLO_decryptStructHandle BLO_decryptHandle,
|
|
unsigned char *data,
|
|
unsigned int dataIn)
|
|
{
|
|
int err = 0;
|
|
struct decryptStructType *BLO_decrypt =
|
|
(struct decryptStructType *) BLO_decryptHandle;
|
|
|
|
if (!BLO_decrypt) {
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_NULL);
|
|
return err;
|
|
}
|
|
|
|
/* First check if we have our header filled in yet */
|
|
if (BLO_decrypt->streamHeader->cryptedKeyLen == 0) {
|
|
unsigned int processed;
|
|
if (dataIn == 0) return err; /* really need data to do anything */
|
|
processed = ((dataIn + BLO_decrypt->streamDone) <=
|
|
EN_DE_CRYPTHEADERSTRUCTSIZE)
|
|
? dataIn : EN_DE_CRYPTHEADERSTRUCTSIZE;
|
|
memcpy(BLO_decrypt->headerbuffer + BLO_decrypt->streamDone,
|
|
data, processed);
|
|
BLO_decrypt->streamDone += processed;
|
|
dataIn -= processed;
|
|
data += processed;
|
|
if (BLO_decrypt->streamDone == EN_DE_CRYPTHEADERSTRUCTSIZE) {
|
|
/* we have the whole header, absorb it */
|
|
struct BLO_en_de_cryptHeaderStruct *header;
|
|
uint32_t crc;
|
|
//static unsigned char rsa_e[] = "\x11";
|
|
static unsigned char rsa_e[] = "\x01\x00\x01";
|
|
RSA *rsa = NULL;
|
|
unsigned char *publisherPubKey;
|
|
int publisherPubKeyLen;
|
|
|
|
header = (struct BLO_en_de_cryptHeaderStruct *)
|
|
BLO_decrypt->headerbuffer;
|
|
crc = crc32(0L, (const Bytef *) header,
|
|
EN_DE_CRYPTHEADERSTRUCTSIZE - 4);
|
|
|
|
if (header->magic == 'A') {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"BLO_en_de_cryptHeaderStruct Magic confirmed\n");
|
|
#endif
|
|
} else {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"ERROR BLO_en_de_cryptHeaderStruct Magic NOT confirmed\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_MAGIC);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
|
|
if (crc == ntohl(header->headercrc)) {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"BLO_en_de_cryptHeader CRC correct\n");
|
|
#endif
|
|
} else {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"ERROR BLO_en_de_cryptHeader CRC NOT correct\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_CRCHEADER);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
BLO_decrypt->streamHeader->length = ntohl(header->length);
|
|
BLO_decrypt->streamHeader->pubKeyLen = ntohl(header->pubKeyLen);
|
|
memcpy(BLO_decrypt->streamHeader->pubKey, header->pubKey,
|
|
BLO_decrypt->streamHeader->pubKeyLen);
|
|
|
|
// case Publisher: get the .BPkey public key
|
|
// case Player/Plugin: simply use the data stream public key
|
|
err = getPubKey(BLO_decrypt->streamHeader->pubKey,
|
|
BLO_decrypt->streamHeader->pubKeyLen,
|
|
&publisherPubKey,
|
|
&publisherPubKeyLen);
|
|
switch (err) {
|
|
case 0:
|
|
// everything OK
|
|
break;
|
|
case 1:
|
|
// publisher without a key
|
|
case 2:
|
|
// publishers keylen !=
|
|
case 3:
|
|
// publishers key !=
|
|
default:
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"ALERT users-pubKey != datastream-pubKey, stop reading\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETSPECERR(BRS_NOTOURPUBKEY);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
break;
|
|
}
|
|
|
|
BLO_decrypt->streamHeader->cryptedKeyLen =
|
|
ntohl(header->cryptedKeyLen);
|
|
memcpy(BLO_decrypt->streamHeader->cryptedKey,
|
|
header->cryptedKey,
|
|
BLO_decrypt->streamHeader->cryptedKeyLen);
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"BLO_decrypt_process gets %u bytes\n",
|
|
(unsigned int) BLO_decrypt->streamHeader->length);
|
|
#endif
|
|
BLO_decrypt->streamHeader->datacrc = ntohl(header->datacrc);
|
|
|
|
// finished absorbing and testing the header, create rsa key from it
|
|
rsa = RSA_new();
|
|
if (rsa == NULL) {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"Error in RSA_new\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETSPECERR(BRS_RSANEWERROR);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
// static exponent
|
|
rsa->e = BN_bin2bn(rsa_e, sizeof(rsa_e)-1, rsa->e);
|
|
|
|
// public part into rsa->n
|
|
rsa->n = BN_bin2bn(publisherPubKey,
|
|
publisherPubKeyLen,
|
|
rsa->n);
|
|
|
|
//DEBUG RSA_print_fp(stdout, rsa, 0);
|
|
|
|
BLO_decrypt->deCryptKey = malloc(RSA_size(rsa) *
|
|
sizeof(unsigned char));
|
|
if (! BLO_decrypt->deCryptKey) {
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_MALLOC);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
RSA_free(rsa);
|
|
return err;
|
|
}
|
|
|
|
// decrypt the cryptkey
|
|
BLO_decrypt->deCryptKeyLen = RSA_public_decrypt(
|
|
BLO_decrypt->streamHeader->cryptedKeyLen,
|
|
BLO_decrypt->streamHeader->cryptedKey,
|
|
BLO_decrypt->deCryptKey,
|
|
rsa, RSA_PKCS1_PADDING);
|
|
if (BLO_decrypt->deCryptKeyLen == -1) {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream,
|
|
"Error in RSA_public_decrypt %s\n",
|
|
ERR_error_string(ERR_get_error(),
|
|
NULL));
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETSPECERR(BRS_DECRYPTERROR);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
RSA_free(rsa);
|
|
return err;
|
|
}
|
|
|
|
// Finally set the RC4 deCryptKey
|
|
RC4_set_key(&(BLO_decrypt->rc4_key),
|
|
BLO_decrypt->deCryptKeyLen,
|
|
BLO_decrypt->deCryptKey);
|
|
|
|
RSA_free(rsa);
|
|
}
|
|
}
|
|
|
|
/* Is there really (still) new data available ? */
|
|
if (dataIn > 0) {
|
|
unsigned char *deCryptBuf = malloc(dataIn);
|
|
if (! deCryptBuf) {
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_MALLOC);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
|
|
BLO_decrypt->streamDone += dataIn;
|
|
|
|
// update datacrc
|
|
BLO_decrypt->datacrc = crc32(
|
|
BLO_decrypt->datacrc, (const Bytef *) data, dataIn);
|
|
|
|
// TODO FIXME we might need to keylength-align the data !
|
|
RC4(&(BLO_decrypt->rc4_key), dataIn, data, deCryptBuf);
|
|
|
|
// give data to streamGlueRead, it will find out what to do next
|
|
err = readStreamGlue(
|
|
BLO_decrypt->endControl,
|
|
&(BLO_decrypt->streamGlue),
|
|
(unsigned char *) deCryptBuf,
|
|
dataIn);
|
|
|
|
free(deCryptBuf);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
/**
|
|
* openssl decrypt final call and cleanup
|
|
* @param BLO_decrypt Pointer to decrypt control structure
|
|
* @retval streamGlueRead return value
|
|
*/
|
|
int
|
|
BLO_decrypt_end(
|
|
BLO_decryptStructHandle BLO_decryptHandle)
|
|
{
|
|
int err = 0;
|
|
struct decryptStructType *BLO_decrypt =
|
|
(struct decryptStructType *) BLO_decryptHandle;
|
|
|
|
if (!BLO_decrypt) {
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_NULL);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
|
|
if (BLO_decrypt->streamDone == BLO_decrypt->streamHeader->length +
|
|
EN_DE_CRYPTHEADERSTRUCTSIZE) {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream, "Crypted data length is correct\n");
|
|
#endif
|
|
} else {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream, "Crypted data length is NOT correct\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_DATALEN);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
|
|
if (BLO_decrypt->datacrc == BLO_decrypt->streamHeader->datacrc) {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream, "Crypted data CRC is correct\n");
|
|
#endif
|
|
} else {
|
|
#ifndef NDEBUG
|
|
fprintf(GEN_errorstream, "Crypted data CRC is NOT correct\n");
|
|
#endif
|
|
err = BRS_SETFUNCTION(BRS_DECRYPT) |
|
|
BRS_SETGENERR(BRS_CRCDATA);
|
|
if (BLO_decrypt->streamGlue) free(BLO_decrypt->streamGlue);
|
|
if (BLO_decrypt->streamHeader) free(BLO_decrypt->streamHeader);
|
|
if (BLO_decrypt->deCryptKey) free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
return err;
|
|
}
|
|
|
|
free(BLO_decrypt->streamGlue);
|
|
free(BLO_decrypt->streamHeader);
|
|
free(BLO_decrypt->deCryptKey);
|
|
free(BLO_decrypt);
|
|
|
|
return err;
|
|
}
|
|
|