Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/verify/intern/BLO_verify.c')
-rw-r--r--source/blender/verify/intern/BLO_verify.c423
1 files changed, 423 insertions, 0 deletions
diff --git a/source/blender/verify/intern/BLO_verify.c b/source/blender/verify/intern/BLO_verify.c
new file mode 100644
index 00000000000..f9c71be1432
--- /dev/null
+++ b/source/blender/verify/intern/BLO_verify.c
@@ -0,0 +1,423 @@
+/**
+ * $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 verify wrapper library
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "openssl/rsa.h"
+#include "openssl/ripemd.h"
+#include "openssl/objects.h"
+#include "zlib.h"
+
+#include "GEN_messaging.h"
+
+#include "BLO_readStreamGlue.h"
+#include "BLO_verify.h"
+#include "BLO_sign_verify_Header.h" /* used by verify and encrypt */
+
+#include "BLO_signer_info.h" // external signer info struct
+
+static struct BLO_SignerInfo g_SignerInfo = {"", "", ""};
+
+struct verifyStructType {
+ struct readStreamGlueStruct *streamGlue;
+ unsigned int streamDone;
+ unsigned char headerbuffer[SIGNVERIFYHEADERSTRUCTSIZE];
+ uint32_t datacrc;
+ struct BLO_sign_verify_HeaderStruct *streamHeader;
+ RIPEMD160_CTX ripemd160_ctx;
+ struct BLO_SignerHeaderStruct *signerHeader;
+ unsigned char signerHeaderBuffer[SIGNERHEADERSTRUCTSIZE];
+ void *endControl;
+};
+
+ BLO_verifyStructHandle
+BLO_verify_begin(
+ void *endControl)
+{
+ struct verifyStructType *control;
+ control = malloc(sizeof(struct verifyStructType));
+ if (!control) return NULL;
+
+ control->streamGlue = NULL;
+ control->streamDone = 0;
+ memset(control->headerbuffer, 0, SIGNVERIFYHEADERSTRUCTSIZE);
+ control->datacrc = 0;
+
+ control->streamHeader = malloc(SIGNVERIFYHEADERSTRUCTSIZE);
+ 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->signature, "");
+ control->streamHeader->signatureLen = 0;
+ control->streamHeader->datacrc = 0;
+ control->streamHeader->headercrc = 0;
+
+ RIPEMD160_Init(&(control->ripemd160_ctx));
+
+ control->signerHeader = malloc(SIGNERHEADERSTRUCTSIZE);
+ if (!control->signerHeader) {
+ free(control->streamHeader);
+ free(control);
+ return NULL;
+ }
+ memset(control->signerHeader->name, 0, MAXSIGNERLEN);
+ memset(control->signerHeader->email, 0, MAXSIGNERLEN);
+ memset(control->signerHeader->homeUrl, 0, MAXSIGNERLEN);
+ memset(control->signerHeader->text, 0, MAXSIGNERLEN);
+ memset(control->signerHeader->pubKeyUrl1, 0, MAXSIGNERLEN);
+ memset(control->signerHeader->pubKeyUrl2, 0, MAXSIGNERLEN);
+
+ control->endControl = endControl;
+ return((BLO_verifyStructHandle) control);
+}
+
+ int
+BLO_verify_process(
+ BLO_verifyStructHandle BLO_verifyHandle,
+ unsigned char *data,
+ unsigned int dataIn)
+{
+ int err = 0;
+ struct verifyStructType *BLO_verify =
+ (struct verifyStructType *) BLO_verifyHandle;
+
+ if (!BLO_verify) {
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_NULL);
+ return err;
+ }
+
+ /* First check if we have our header filled in yet */
+ if (BLO_verify->streamHeader->length == 0) {
+ unsigned int processed;
+ if (dataIn == 0) return err; /* really need data to do anything */
+ processed = ((dataIn + BLO_verify->streamDone) <=
+ SIGNVERIFYHEADERSTRUCTSIZE)
+ ? dataIn : SIGNVERIFYHEADERSTRUCTSIZE;
+ memcpy(BLO_verify->headerbuffer + BLO_verify->streamDone,
+ data, processed);
+ BLO_verify->streamDone += processed;
+ dataIn -= processed;
+ data += processed;
+ if (BLO_verify->streamDone == SIGNVERIFYHEADERSTRUCTSIZE) {
+ /* we have the whole header, absorb it */
+ struct BLO_sign_verify_HeaderStruct *header;
+ uint32_t crc;
+
+ header = (struct BLO_sign_verify_HeaderStruct *)
+ BLO_verify->headerbuffer;
+ crc = crc32(0L, (const Bytef *) header,
+ SIGNVERIFYHEADERSTRUCTSIZE - 4);
+
+ if (header->magic == 'A') {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "BLO_sign_verify_HeaderStruct Magic confirmed\n");
+#endif
+ } else {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "ERROR BLO_sign_verify_HeaderStruct Magic NOT confirmed\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_MAGIC);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ return err;
+ }
+
+ if (crc == ntohl(header->headercrc)) {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,"BLO_sign_verify_Header CRC correct\n");
+#endif
+ } else {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,"ERROR BLO_sign_verify_Header CRC NOT correct\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_CRCHEADER);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ return err;
+ }
+ BLO_verify->streamHeader->length = ntohl(header->length);
+ BLO_verify->streamHeader->pubKeyLen = ntohl(header->pubKeyLen);
+ memcpy(BLO_verify->streamHeader->pubKey, header->pubKey,
+ BLO_verify->streamHeader->pubKeyLen);
+ BLO_verify->streamHeader->signatureLen =
+ ntohl(header->signatureLen);
+ memcpy(BLO_verify->streamHeader->signature, header->signature,
+ BLO_verify->streamHeader->signatureLen);
+ BLO_verify->streamHeader->datacrc = ntohl(header->datacrc);
+
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "BLO_verify_process gets %u bytes\n",
+ (unsigned int) BLO_verify->streamHeader->length);
+#endif
+
+ }
+ }
+
+ /* Is there really (still) new data available ? */
+ if (dataIn > 0) {
+ // BLO_SignerHeaderStruct
+ if (BLO_verify->signerHeader->name[0] == 0) {
+ // we don't have our signerHeader complete yet
+ unsigned int processed;
+ processed = ((dataIn + BLO_verify->streamDone -
+ SIGNVERIFYHEADERSTRUCTSIZE) <= SIGNERHEADERSTRUCTSIZE)
+ ? dataIn : SIGNERHEADERSTRUCTSIZE;
+ memcpy(BLO_verify->signerHeaderBuffer +
+ BLO_verify->streamDone - SIGNVERIFYHEADERSTRUCTSIZE,
+ data, processed);
+ BLO_verify->streamDone += processed;
+ dataIn -= processed;
+ data += processed;
+ if (BLO_verify->streamDone == SIGNVERIFYHEADERSTRUCTSIZE +
+ SIGNERHEADERSTRUCTSIZE) {
+ // we have the whole header, absorb it
+ struct BLO_SignerHeaderStruct *signerHeader;
+ signerHeader = (struct BLO_SignerHeaderStruct *)
+ BLO_verify->signerHeaderBuffer;
+ strncpy(BLO_verify->signerHeader->name,
+ signerHeader->name, MAXSIGNERLEN-1);
+ strncpy(BLO_verify->signerHeader->email,
+ signerHeader->email, MAXSIGNERLEN-1);
+ strncpy(BLO_verify->signerHeader->homeUrl,
+ signerHeader->homeUrl, MAXSIGNERLEN-1);
+ strncpy(BLO_verify->signerHeader->text,
+ signerHeader->text, MAXSIGNERLEN-1);
+ strncpy(BLO_verify->signerHeader->pubKeyUrl1,
+ signerHeader->pubKeyUrl1, MAXSIGNERLEN-1);
+ strncpy(BLO_verify->signerHeader->pubKeyUrl2,
+ signerHeader->pubKeyUrl2, MAXSIGNERLEN-1);
+
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "name %s\nemail %s\nhomeUrl %s\ntext %s\n",
+ BLO_verify->signerHeader->name,
+ BLO_verify->signerHeader->email,
+ BLO_verify->signerHeader->homeUrl,
+ BLO_verify->signerHeader->text);
+ fprintf(GEN_errorstream,
+ "pubKeyUrl1 %s\npubKeyUrl2 %s\n",
+ BLO_verify->signerHeader->pubKeyUrl1,
+ BLO_verify->signerHeader->pubKeyUrl2);
+#endif
+ // also update the signature and crc checksum
+ RIPEMD160_Update(&(BLO_verify->ripemd160_ctx),
+ BLO_verify->signerHeaderBuffer,
+ SIGNERHEADERSTRUCTSIZE);
+
+ // update datacrc
+ BLO_verify->datacrc = crc32(
+ BLO_verify->datacrc, (const Bytef *)
+ BLO_verify->signerHeaderBuffer,
+ SIGNERHEADERSTRUCTSIZE);
+ }
+ }
+ }
+
+ /* Is there really (still) new data available ? */
+ if (dataIn > 0) {
+ RIPEMD160_Update(&(BLO_verify->ripemd160_ctx), data, dataIn);
+
+ // update datacrc
+ BLO_verify->datacrc = crc32(
+ BLO_verify->datacrc, (const Bytef *) data, dataIn);
+
+ BLO_verify->streamDone += dataIn;
+
+ // give data to streamGlueRead, it will find out what to do next
+ err = readStreamGlue(
+ BLO_verify->endControl,
+ &(BLO_verify->streamGlue),
+ (unsigned char *) data,
+ dataIn);
+ }
+ return err;
+}
+
+/**
+ * openssl verify final call and cleanup
+ * @param BLO_verify Pointer to verify control structure
+ * @retval streamGlueRead return value
+ */
+ int
+BLO_verify_end(
+ BLO_verifyStructHandle BLO_verifyHandle)
+{
+ int err = 0;
+ unsigned char *digest;
+ static unsigned char rsa_e[] = "\x01\x00\x01";
+ RSA *rsa = NULL;
+ int verifySuccess;
+ struct verifyStructType *BLO_verify =
+ (struct verifyStructType *) BLO_verifyHandle;
+
+ if (!BLO_verify) {
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_NULL);
+ return err;
+ }
+
+ if (BLO_verify->streamDone == BLO_verify->streamHeader->length +
+ SIGNVERIFYHEADERSTRUCTSIZE) {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream, "Signed data length is correct\n");
+#endif
+ } else {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream, "Signed data length is NOT correct\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_DATALEN);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ return err;
+ }
+
+ if (BLO_verify->datacrc == BLO_verify->streamHeader->datacrc) {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream, "Signed data CRC is correct\n");
+#endif
+ } else {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream, "Signed data CRC is NOT correct\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_CRCDATA);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ return err;
+ }
+
+ digest = malloc(RIPEMD160_DIGEST_LENGTH);
+ if (!digest) {
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETGENERR(BRS_MALLOC);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ return err;
+ }
+
+ RIPEMD160_Final(digest, &(BLO_verify->ripemd160_ctx));
+
+ rsa = RSA_new();
+ if (rsa == NULL) {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream, "Error in RSA_new\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETSPECERR(BRS_RSANEWERROR);
+ free(digest);
+ if (BLO_verify->streamGlue) free(BLO_verify->streamGlue);
+ if (BLO_verify->streamHeader) free(BLO_verify->streamHeader);
+ if (BLO_verify->signerHeader) free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ 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(BLO_verify->streamHeader->pubKey,
+ BLO_verify->streamHeader->pubKeyLen,
+ rsa->n);
+ //DEBUG RSA_print_fp(stdout, rsa, 0);
+
+ // verify the signature
+ verifySuccess = RSA_verify(NID_ripemd160, digest, RIPEMD160_DIGEST_LENGTH,
+ BLO_verify->streamHeader->signature,
+ BLO_verify->streamHeader->signatureLen, rsa);
+ if (verifySuccess == 1) {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "Signature verified\n");
+#endif
+ } else {
+#ifndef NDEBUG
+ fprintf(GEN_errorstream,
+ "Signature INCORRECT\n");
+#endif
+ err = BRS_SETFUNCTION(BRS_VERIFY) |
+ BRS_SETSPECERR(BRS_SIGFAILED);
+ }
+
+// copy signer information to external struct
+
+ strncpy(g_SignerInfo.name, BLO_verify->signerHeader->name, MAXSIGNERLEN-1);
+ strncpy(g_SignerInfo.email, BLO_verify->signerHeader->email, MAXSIGNERLEN-1);
+ strncpy(g_SignerInfo.homeUrl, BLO_verify->signerHeader->homeUrl, MAXSIGNERLEN-1);
+//
+ free(digest);
+ free(BLO_verify->streamGlue);
+ free(BLO_verify->streamHeader);
+ free(BLO_verify->signerHeader);
+ free(BLO_verify);
+ RSA_free(rsa);
+
+ return err;
+}
+
+struct BLO_SignerInfo *BLO_getSignerInfo(){
+ return &g_SignerInfo;
+}
+
+int BLO_isValidSignerInfo(struct BLO_SignerInfo *info){
+ return info->name[0] != 0;
+}
+
+void BLO_clrSignerInfo(struct BLO_SignerInfo *info)
+{
+ info->name[0] = 0;
+}
+