⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgplicensenumber.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpLicenseNumber.c,v 1.27 2002/11/25 05:45:59 jason Exp $
____________________________________________________________________________*/

#include <ctype.h>
#include <string.h>

/*	We need to include this in order to get the PGP_BETA flag before its use in the license# file	*/
#if PGP_OSX
#include "pgpBuild.h"
#endif

#include "pgpLicenseNumber.h"
#include "pgpLicenseNumberNet.h"
#include "pgpUtilities.h"
#include "pgpPublicKey.h"
#include "pgpMem.h"
#include "pgpHash.h"
#include "pgpSymmetricCipher.h"
#include "pgpKeys.h"
#include "pgpEncode.h"
#include "string.h"
#include "pgpErrors.h"
#include "pgpStrings.h"
#include "pgpEndianConversion.h"
#include "pgpUnicode.h"

#include "pgpLNClientKeys.h" /* keys that are needed for a client */
#ifdef PGP_LICENSE_SERVER
	/* additional private or secret keys that are needed by a server only */
	#include "pgpLNServerKeys.h" 
#endif

#include "stdio.h"

#ifndef PGP_LICENSE_NET
#define PGP_LICENSE_NET 1	/* Enable network LA by default */
#endif

#ifdef PGP_WIN32
#pragma warning (disable: 4057)
#pragma intrinsic(memset)
#define CLEAR_LICENSENUMBER(ppn) memset( ppn, 0, sizeof(LICENSENUMBER) )
#else
#define CLEAR_LICENSENUMBER(ppn) pgpClearMemory( ppn,sizeof(LICENSENUMBER) )
#endif

static const PGPByte beginLicense[]={"-----BEGIN PGP LICENSE AUTHORIZATION-----"};
static const PGPByte endLicense[]={"-----END PGP LICENSE AUTHORIZATION-----"};

static PGPUInt8 base32chars[]={
	"ACDEFGHJKLMNPQRT" "UVWXYZ234679B015"
	"________________" "____________8OIS"	/* similiar looking duplicates */
};

static const PGPByte emptyCustomerName[] = "<blank>";
static const PGPByte * const emptyCompanyName = emptyCustomerName;

// for each field corresponding parameter name is given -- check pgplng and server code
typedef struct _LICENSENUMBER
{
	PGPUInt8 version;		// "version"
	PGPUInt8 productID;		// "prodid"
	PGPUInt16 evalPeriod;	// 0 - is never expires, "evaldays"
	PGPUInt32 numLicenses; // 24 bit, 0 - reserved, "licenses"
	PGPUInt8 flags;			// "flags" = {"eval","enterprise","disk","mail"}
	PGPUInt32 serialNumber;	// "sn"
	PGPUInt8 shaHash[2];
} LICENSENUMBER;

#define LICENSENUMBER_BIN_SIZE 17	/* serialization size, sizeof(LICENSENUMBER) can be more because of alignment */

#define LICENSENUMBER_BASE32_SIZE (LICENSENUMBER_BIN_SIZE*8/5+1) 
		/*upper bound, used for memory allocation only*/

typedef struct PGPLicenseNumber {
	PGPByte ln_encr[LICENSENUMBER_BIN_SIZE];
} PGPLicenseNumber;		// Exported: [17 bytes ln], ln has a version that will tell the size

typedef struct PGPLicenseAuthorization {
	PGPByte		type;
	PGPUInt16	issuanceDate; // days since 9/1/2002
	PGPSize		signatureSize;	
	PGPByte		signature[1];
	// + signatureSize-1 bytes	// Exported: [2 bytes total size] [1 byte type] [2 bytes issuanceDate] [reserved=0] [signature]
} PGPLicenseAuthorization;

static void lnToStream( const LICENSENUMBER *ln, PGPByte ln_stream[LICENSENUMBER_BIN_SIZE] )  {
	PGPUInt32 u;
	PGPByte *p = ln_stream;

	p[0] = ln->version;
	p[1] = ln->productID;

	u = ln->evalPeriod;
	p[2] = (PGPByte)(u >> 8);
	p[3] = (PGPByte)u;

	u = ln->numLicenses;
	p[4] = (PGPByte)(u >> 16);
	p[5] = (PGPByte)(u >> 8);
	p[6] = (PGPByte)u;

	p[7] = ln->flags;

	u = ln->serialNumber;
	p[8] = (PGPByte)(u >> 24);
	p[9] = (PGPByte)(u >> 16);
	p[10] = (PGPByte)(u >> 8);
	p[11] = (PGPByte)u;
	
	p[12] = p[13] = p[14] = 0;
		
	p[15] = ln->shaHash[0];
	p[16] = ln->shaHash[1];
}

static void lnFromStream( const PGPByte ln_stream[LICENSENUMBER_BIN_SIZE], LICENSENUMBER *ln )  {
	const PGPByte *p = ln_stream;

	ln->version = p[0];
	ln->productID = p[1];

	ln->evalPeriod = (PGPUInt16)(p[2] << 8 | p[3]);
	ln->numLicenses = p[4] << 16 | p[5] << 8 | p[6];
	ln->flags = p[7];
	ln->serialNumber = p[8] << 24 | p[9] << 16 | p[10] << 8 | p[11];
	
//	ln->unused[0] = p[12]; ln->unused[1] = p[13]; ln->unused[2] = p[14]; 
		
	ln->shaHash[0] = p[15];
	ln->shaHash[1] = p[16];
}

static void laToStream( const PGPLicenseAuthorization *la, PGPByte *stream )  {
	PGPUInt32 u;

	u = la->signatureSize + 6;
	stream[0] = (PGPByte)(u >> 8);
	stream[1] = (PGPByte)u;

	stream[2] = la->type;

	u = la->issuanceDate;
	stream[3] = (PGPByte)(u >> 8);
	stream[4] = (PGPByte)u;

	stream[5] = 0;	// reserved
	
	pgpCopyMemory( la->signature, stream+6, la->signatureSize );
}

// exact size required to serialize the object
static PGPUInt16 laToStreamSize( const PGPLicenseAuthorization *la )  {
	return (PGPUInt16)(la->signatureSize + 6);
}
// size of the serialized object read from the stream
static PGPUInt16 laFromStreamSize( const PGPByte *stream )  {
	const PGPUInt16 size = (PGPUInt16)(stream[0] << 8 | stream[1]);
	return (PGPUInt16)( size > 128+6 ? 0 : size);
}

/* la should be already allocated, use laPeekSize */
static void laFromStream( const PGPByte *stream, PGPLicenseAuthorization *la )  {
	const PGPUInt16 size = laFromStreamSize( stream );

	if( !size )  {
		la->signatureSize = 0;
		la->type = 0;
		la->issuanceDate = 0;
		return;
	}

	la->signatureSize = size-6;

	la->type = stream[2];
	la->issuanceDate = (PGPUInt16)(stream[3] << 8 | stream[4]);
	pgpCopyMemory( stream+6, la->signature, la->signatureSize );
}


// number of days from the 9/1/02 to the 'curr' time
static const time_t Sep_1_2002_time_t = 0x3d71c901;	// time_t for Sun Sep 01 00:00:01 2002, no DST
static PGPUInt32 daysElapsed( PGPTime curr, PGPBoolean roundUp )  {
	time_t curr_time_t = PGPGetStdTimeFromPGPTime( curr );
	PGPUInt32 days = (PGPUInt32)(-1);

	if( !curr )
		return (PGPUInt32)(-1);

	if( curr_time_t > Sep_1_2002_time_t )  {
		days = ( curr_time_t - Sep_1_2002_time_t ) / 3600;
		days = (days + (roundUp ? 23 : 0))/24;
	}
	else {	
		// 37779 (0x9393) days from the Sep_1_2002_time_t left to overlap 0xffffffff

		// allow one overlap
		curr_time_t /= 3600;
		curr_time_t = (curr_time_t+(roundUp ? 23 : 0)) / 24;
		days = 37779 + curr_time_t;
	}

	return days;
}
#if 0 /* not used, but working */
static PGPTime daysElapsedToTime( PGPUInt32 daysElapsed )  {
	time_t t;
	
	if( daysElapsed > 37779 )	
		return (PGPTime)(-1);	// need to fix after 2037

	t = Sep_1_2002_time_t + daysElapsed*24*3600;
	return PGPGetPGPTimeFromStdTime( t );
}
#endif
#if 0	/* not used, but working */
static void daysElapsedToStr( PGPUInt32 daysElapsed, PGPByte str[16] )  {
	PGPTime t = daysElapsedToTime(daysElapsed);
    struct tm *tm;

	tm = gmtime(&t);

    (void)strftime( str, 16, "%Y%m%d", tm); 
}
#endif
#if 0	/* not used, but working */
static PGPUInt32 strToDaysElapsed( const PGPByte str[16] )  {
	struct tm tm;
	PGPByte s[10] = { '\0', '\0', '\0', '\0', '\0' };
	time_t t;

	pgpClearMemory( &tm, sizeof(tm) );

	s[0] = str[4]; s[1] = str[5];
	tm.tm_mon = atoi(s)-1;

	s[0] = str[6]; s[1] = str[7];
	tm.tm_mday = atoi(s);

	s[0] = str[0]; s[1] = str[1]; s[2] = str[2]; s[3] = str[3];
	tm.tm_year = atoi(s)-1900;

	tm.tm_sec = 1;

	t = mktime( &tm );
	if( t == (time_t)-1 )
		return (PGPUInt32)(-1);

	return daysElapsed( PGPGetPGPTimeFromStdTime( t ), FALSE );
}
#endif

// Base32 encode binary license data
static PGPError pgpEncode32(
			  const PGPByte *inBytes, PGPSize inSize, 
			  PGPByte outBytes[kPGPLicenseNumberMaxSize])
{
	PGPUInt32 bits,bitcnt,value,bytenum,shift,memamt;
	PGPError err;

	err=kPGPError_NoErr;

	bits=inSize*8;

	memamt=((bits+4)/5)+1;  // +1 for convenience NULL terminate
	if( memamt > kPGPLicenseNumberMaxSize )  {
		outBytes[0] = '\0';
		return kPGPError_OutOfMemory;
	}

	pgpClearMemory(outBytes,memamt);
	
	for(bitcnt=0;bitcnt<bits;bitcnt+=5)
	{
		bytenum=bitcnt/8;
		shift=bitcnt%8;

		value = inBytes[bytenum];
		if( bytenum < inSize-1 )
			value |= (inBytes[bytenum+1] << 8);
		value = (value >> shift) & 0x1f;
		
		outBytes[bitcnt/5]=base32chars[value];
	}

	return err;
}

// Base32 decode license data
static PGPError pgpDecode32(const PGPByte *inBytes,
			  PGPByte outBytes[kPGPLicenseNumberMaxSize], PGPSize *outSize )
{
	PGPUInt32 chcnt,numbits,memamt,place,bytenum,shift,value;
	PGPError err;
	PGPSize inSize;
	PGPByte *pc;
	
	if (!inBytes)
		return kPGPError_BadParams;
	
	inSize = strlen( inBytes );

	err=kPGPError_NoErr;
	outBytes[0] = '\0';
	*outSize = 0;

	numbits=inSize*5;
	memamt=(numbits+7)/8;

	if(memamt+1 > kPGPLicenseNumberMaxSize)
		return kPGPError_BufferTooSmall;

	/* check that last base 32 character carries the value no greater then needed */
	pc = strchr( base32chars, inBytes[inSize-1] );
	if( pc==NULL || *pc == '_' )  /* wrong character */
		return kPGPError_CorruptData;
	value=(PGPUInt32)(pc - base32chars) / sizeof(base32chars[0]);
	if( value > 32 )
		value -= 32;		/* we hit duplicate */
	shift = (inSize*5) % 8;	/* extra bits that must be zero */
	if( shift > 5 )
		return kPGPError_CorruptData;
	shift = 5 - shift;		/* now shift is number of bits that last base char encodes  */
	if( shift > 0 && value > ~((PGPUInt32)(-1)<<shift) )
		return kPGPError_CorruptData;
	
	pgpClearMemory( outBytes, memamt+1 );

	for(chcnt=0;chcnt<inSize;chcnt++)
	{
		place=chcnt*5;
		bytenum=place/8;
		shift=place%8;
		
		pc = strchr( base32chars, inBytes[chcnt] );
		if( pc==NULL || *pc == '_' )  /* wrong character */
			return kPGPError_CorruptData;
		value=(PGPUInt32)(pc - base32chars) / sizeof(base32chars[0]);
		if( value > 32 )
			value -= 32;	/* we hit duplicate */
		
		outBytes[bytenum] |= (PGPByte)(value << shift);
		if( shift > 8-5 )  {
			outBytes[bytenum+1] |= (value >> (8-shift));
			*outSize = bytenum + 1;
		}
		else
			*outSize = bytenum;
	}

	return err;
}


#define TC_E_PARSE kPGPError_CorruptData
#define SKIPWS(c) while (isspace ((int) (*(c)))) c++
static const unsigned char BaseChars[] = 
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define BaseChar(c) BaseChars[c]
static const unsigned char BaseVals[] = {
  0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,62, 0xff,0xff,0xff,63,
  52,53,54,55, 56,57,58,59, 60,61,0xff,0xff, 0xff,0xff,0xff,0xff,
  0xff, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
  15,16,17,18, 19,20,21,22, 23,24,25,0xff, 0xff,0xff,0xff,0xff,
  0xff,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
  41,42,43,44, 45,46,47,48, 49,50,51,0xff, 0xff,0xff,0xff,0xff
};
#define BaseVal(c) BaseVals[c]

PGPError 
tc_encode_base64 (PGPMemoryMgrRef mem, unsigned char **out, size_t *outlen,
		      const unsigned char *in, size_t inlen )
{
  unsigned char *curpos;
  unsigned char a, b, c;

  /* determine how long the output will be.  if it is not a multple of 3
   * bytes, increase length so that it is so that the pad characters are
   * accounted for.
   */
  if (inlen % 3 != 0)
    *outlen = inlen + 3 - inlen % 3;
  else
    *outlen = inlen;

  /* base64 encoding creates 4 output chars for every 3 input chars */
  *outlen = 4 * (*outlen) / 3;

  if ((*out = PGPNewData(mem, *outlen + 1, 0)) == NULL)
	  return kPGPError_OutOfMemory;

  curpos = *out;

  while (inlen)
  {
    a = *in++;
    inlen--;

    *curpos++ = BaseChar (a >> 2);

    if (inlen)
      b = *in++;
    else
      b = 0;

    *curpos++ = BaseChar (((a & 0x03) << 4) | (b >> 4));

    if (!inlen)
    {
      *curpos++ = '=';
      *curpos++ = '=';
      break;
    }
    inlen--;

    if (inlen)
      c = *in++;
    else
      c = 0;

    *curpos++ = BaseChar (((b & 0x0f) << 2) | (c >> 6));

    if (!inlen)
    {
      *curpos++ = '=';
      break;
    }
    inlen--;

    *curpos++ = BaseChar (c & 0x3f);
  }

  *curpos = 0;

  return kPGPError_NoErr;
}

PGPError
tc_decode_base64 (PGPMemoryMgrRef mem, unsigned char **out,
		  size_t *outlen, const unsigned char *in )
{
  unsigned char *curpos;
  unsigned char a, b;
  PGPError err = kPGPError_NoErr;

  *outlen = (3 * strlen ((PGPByte *) in)) / 4; /* maximum length */
  if ((*out = PGPNewData(mem, *outlen, 0)) == NULL)
	  return kPGPError_OutOfMemory;

  curpos = *out;

  SKIPWS (in);
  while (*in)
  {
    a = *in++;
    SKIPWS (in);
    if (!*in)  {
      err = TC_E_PARSE;
	  break;
	}
    b = *in++;
    SKIPWS (in);
    if (!*in)  {
      err = TC_E_PARSE;
	  break;
	}

    *curpos++ = (BaseVal (a) << 2) | (BaseVal (b) >> 4);

    a = b;
    b = *in++;
    SKIPWS (in);
    if (!*in)  {
      err = TC_E_PARSE;
	  break;
	}

    if (b == '=')
      break;

    *curpos++ = (BaseVal (a) << 4) | (BaseVal (b) >> 2);

    a = b;
    b = *in++;
    SKIPWS (in);

    if (b == '=')
      break;

    *curpos++ = (BaseVal (a) << 6) | BaseVal (b);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -