Пример #1
0
int main(int argc, const char *argv[]){
    ClientServerHello *client_hello, *server_hello;
    Handshake *handshake, *server_handshake;
    RecordLayer *record, *server_message, *temp_record, record2;
    ClientKeyExchange *client_key_exchange;
    ServerKeyExchange *server_key_exchange;
    Certificate *certificate;
    CipherSuite *ciphersuite_choosen;
    Finished finished;
    Talker sender;
    int pre_master_secret_size, phase, key_block_size, enc_message_len, dec_message_len;
    unsigned int supported_ciphers;
    uint8_t **pre_master_secret;
    MD5_CTX md5;
    SHA_CTX sha;
    uint8_t *enc_message, *dec_message, *mac, *key_block, *client_write_MAC_secret, *server_write_MAC_secret, *master_secret, *sha_1, *md5_1, *sha_fin, *md5_fin, *mac_test;
    
    client_hello = NULL;
    server_hello = NULL;
    handshake = NULL;
    server_handshake = NULL;
    record = NULL;
    server_message = NULL;
    temp_record = NULL;
    client_key_exchange = NULL;
    server_key_exchange = NULL;
    certificate = NULL;
    ciphersuite_choosen = NULL;
    pre_master_secret_size = 0;
    key_block_size = 0;
    enc_message_len = 0;
    dec_message_len = 0;
    pre_master_secret = NULL;
    phase=0;
    enc_message = NULL;
    dec_message = NULL;
    mac = NULL;
    key_block = NULL;
    client_write_MAC_secret = NULL;
    server_write_MAC_secret = NULL;
    master_secret = NULL;
    sha_1 = NULL;
    md5_1 = NULL;
    sha_fin = NULL;
    md5_fin = NULL;
    mac_test = NULL;
    sender = client;
    SHA1_Init(&sha);
    MD5_Init(&md5);

    
    ///////////////////////////////////////////////////////////////PHASE 1//////////////////////////////////////////////////////////
    
    OpenCommunication(client);

    printf("Insert your favorite cipher:");
    scanf("%x", &supported_ciphers);
    if (supported_ciphers < 0x03 || (0xB <= supported_ciphers && supported_ciphers <= 0x10) || supported_ciphers>=0x17){
        perror("Not valid ciphersuite inserted.");
        exit(1);
    }
    printf("\n\n");
    uint8_t code = (uint8_t)supported_ciphers;
    
    client_hello = ClientServerHello_init(CLIENT_HELLO, 0, &code, 1);
    
    //Wrapping
    handshake = ClientServerHelloToHandshake(client_hello);
    record = HandshakeToRecordLayer(handshake);
    //Sending client hello
    sendPacketByte(record);
    printRecordLayer(record);
	
    SHA1_Update(&sha, record->message, sizeof(uint8_t)*(record->length-5));
    MD5_Update(&md5, record->message, sizeof(uint8_t)*(record->length-5));
    
    FreeRecordLayer(record);
    FreeHandshake(handshake);
    
    //Opening the communication to the server and, when authorized, reading server hello
    OpenCommunication(server);
    while(CheckCommunication() == server){}
    
    server_message = readchannel();
    printRecordLayer(server_message);
    server_handshake = RecordToHandshake(server_message);
    server_hello = HandshakeToClientServerHello(server_handshake);
    
    SHA1_Update(&sha, server_message->message, sizeof(uint8_t)*(server_message->length-5));
    MD5_Update(&md5, server_message->message, sizeof(uint8_t)*(server_message->length-5));
    
    FreeRecordLayer(server_message);
    FreeHandshake(server_handshake);
    
    
    ciphersuite_choosen = CodeToCipherSuite(server_hello->ciphersuite_code[0]);
    
    OpenCommunication(server);
    phase = 2;
    ///////////////////////////////////////////////////////////////PHASE 2//////////////////////////////////////////////////////////
    while(phase == 2){
        while(CheckCommunication() == server){}
        
        server_message = readchannel();
        printRecordLayer(server_message);
        server_handshake = RecordToHandshake(server_message);
        
        switch (server_handshake->msg_type) {
            case CERTIFICATE:
                certificate = HandshakeToCertificate(server_handshake);
                
                SHA1_Update(&sha,server_message->message, sizeof(uint8_t)*(server_message->length-5));
                MD5_Update(&md5,server_message->message, sizeof(uint8_t)*(server_message->length-5));
                
                FreeRecordLayer(server_message);
                FreeHandshake(server_handshake);
                
                OpenCommunication(server);
                break;
            case SERVER_KEY_EXCHANGE:

                server_key_exchange = HandshakeToServerKeyExchange(server_handshake, certificate);
                
                SHA1_Update(&sha, server_message->message, sizeof(uint8_t)*(server_message->length-5));
                MD5_Update(&md5, server_message->message, sizeof(uint8_t)*(server_message->length-5));
                
                Verify_(ciphersuite_choosen, client_hello, server_hello, server_key_exchange->parameters, server_key_exchange->len_parameters, server_key_exchange->signature, server_key_exchange->len_signature, certificate);
                
                FreeRecordLayer(server_message);
                FreeHandshake(server_handshake);
                
                OpenCommunication(server);
                break;
            case SERVER_DONE:
                
                SHA1_Update(&sha, server_message->message, sizeof(uint8_t)*(server_message->length-5));
                MD5_Update(&md5, server_message->message, sizeof(uint8_t)*(server_message->length-5));
                
                FreeRecordLayer(server_message);
                FreeHandshake(server_handshake);
            
                phase = 3;
                break;
            default:
                perror("ERROR: Unattended message in phase 2.\n");
                exit(1);
                break;
        }
    
    }
    
    ///////////////////////////////////////////////////////////////PHASE 3//////////////////////////////////////////////////////////
    while(phase == 3){
        
		///CLIENT_KEY_EXCHANGE///
        pre_master_secret = (uint8_t**)calloc(1, sizeof(uint8_t*));
        client_key_exchange = ClientKeyExchange_init(ciphersuite_choosen, certificate, server_key_exchange, pre_master_secret, &pre_master_secret_size);
        handshake = ClientKeyExchangeToHandshake(client_key_exchange);
        record = HandshakeToRecordLayer(handshake);
        
        sendPacketByte(record);
        printRecordLayer(record);
        OpenCommunication(server);

        SHA1_Update(&sha,record->message, sizeof(uint8_t)*(record->length-5));
        MD5_Update(&md5,record->message, sizeof(uint8_t)*(record->length-5));
        
        FreeClientKeyExchange(client_key_exchange);
        FreeServerKeyExchange(server_key_exchange);
        FreeCertificate(certificate);
        FreeRecordLayer(record);
        FreeHandshake(handshake);

        //MASTER KEY COMPUTATION
        printf("PRE MASTER:\n");
        for (int i = 0; i<pre_master_secret_size; i++) {
            printf("%02X ", (*pre_master_secret)[i]);
        }
        printf("\n");
        
        master_secret = MasterSecretGen(*pre_master_secret, pre_master_secret_size, client_hello, server_hello);
        
        free(*pre_master_secret);
        free(pre_master_secret);
        
        //free(&pre_master_secret);//TODO:rivedere
        
        //TODO: rimuovere questi print
        printf("MASTER KEY:generated\n");
        for (int i=0; i< 48; i++){
            printf("%02X ", master_secret[i]);
        }
        printf("\n\n");
        
        //KEYBLOCK GENERATION
        key_block = KeyBlockGen(master_secret, ciphersuite_choosen, &key_block_size, client_hello, server_hello);

        printf("KEY BLOCK\n");
        for (int i=0; i< key_block_size; i++){
            printf("%02X ", key_block[i]);
        }
        printf("\n\n");
        phase = 4;
        FreeClientServerHello(client_hello);
        FreeClientServerHello(server_hello);
        
    }
    
    ///////////////////////////////////////////////////////////////PHASE 4//////////////////////////////////////////////////////////
    while(CheckCommunication() == server){};
    record = ChangeCipherSpecRecord();
    sendPacketByte(record);
    printRecordLayer(record);

    FreeRecordLayer(record);
    OpenCommunication(server);
    
    while(CheckCommunication() == server){};
    
    //building finished
    
    SHA1_Update(&sha, &sender, sizeof(uint32_t));
    MD5_Update(&md5, &sender, sizeof(uint32_t));
    
    SHA1_Update(&sha,master_secret,sizeof(uint8_t)*48);
    MD5_Update(&md5,master_secret,sizeof(uint8_t)*48);  
    
    SHA1_Update(&sha, pad_1, sizeof(uint8_t)*40);
    MD5_Update(&md5, pad_1, sizeof(uint8_t)*48);
    
    md5_1 = calloc(16, sizeof(uint8_t));
    sha_1 = calloc(20, sizeof(uint8_t));
    
    SHA1_Final(sha_1,&sha);
    MD5_Final(md5_1,&md5);
    
    SHA1_Init(&sha);
    MD5_Init(&md5);
    
    SHA1_Update(&sha, master_secret,sizeof(uint8_t)*48);
    SHA1_Update(&sha, pad_2,sizeof(uint8_t)*40);
    SHA1_Update(&sha, sha_1,sizeof(uint8_t)*20);
    
    MD5_Update(&md5, master_secret,sizeof(uint8_t)*48);
    MD5_Update(&md5, pad_2,sizeof(uint8_t)*48);
    MD5_Update(&md5, md5_1,sizeof(uint8_t)*16);
    
    md5_fin = calloc(16, sizeof(uint8_t));
    sha_fin = calloc(20, sizeof(uint8_t));
    
    SHA1_Final(sha_fin, &sha);
    MD5_Final(md5_fin, &md5);
    
    //Finished allocation:
    finished.hash = (uint8_t*)calloc(36, sizeof(uint8_t));
    
    memcpy(finished.hash, md5_fin, 16*sizeof(uint8_t));
    memcpy(finished.hash + 16, sha_fin, 20*sizeof(uint8_t));
    
    free(sha_1);
    free(md5_1);
    free(md5_fin);
    free(sha_fin);
    

    /* MAC and ENCRYPTION*/
    handshake = FinishedToHandshake(&finished);   
    temp_record = HandshakeToRecordLayer(handshake);
    
    free(finished.hash);
    
    //compute MAC
    client_write_MAC_secret = NULL;
    server_write_MAC_secret = NULL;
    
    client_write_MAC_secret = key_block;
    
    mac = MAC(ciphersuite_choosen, handshake, client_write_MAC_secret);
    
    uint8_t *message_with_mac;
    
    message_with_mac = (uint8_t*)calloc(temp_record->length + ciphersuite_choosen->hash_size - 5, sizeof(uint8_t));
    memcpy(message_with_mac, temp_record->message, temp_record->length);
    memcpy(message_with_mac + (temp_record->length - 5) , mac, ciphersuite_choosen->hash_size);
    free(mac);
    
    // update length
    temp_record->length = temp_record->length + ciphersuite_choosen->hash_size;
    free(temp_record->message);
	temp_record->message = message_with_mac;
    
    uint8_t length_bytes[4];
    int_To_Bytes(temp_record->length, length_bytes);
    //TODO: temp_record to record
    printf("FINISHED:to sent\n");
    printf("%02X ", temp_record->type);
    printf("%02X ", temp_record->version.major);
    printf("%02X ", temp_record->version.minor);
    printf("%02X ", length_bytes[2]);
    printf("%02X ", length_bytes[3]);
    for(int i=0; i<temp_record->length - 5; i++){
        printf("%02X ", temp_record->message[i]);
    }
    printf("\n\n");
    
    enc_message = DecEncryptPacket(temp_record->message, temp_record->length - 5, &enc_message_len, ciphersuite_choosen, key_block, client, 1);
    
    FreeRecordLayer(temp_record);
    FreeHandshake(handshake);
    
    record2.type = HANDSHAKE;
    record2.length = enc_message_len + 5;
    record2.version = std_version;
    record2.message = enc_message;
        
    sendPacketByte(&record2);

    int_To_Bytes(record2.length, length_bytes);
    printf("ENCRYPED FINISHED: sent\n");
    printf("%02X ", record2.type);
    printf("%02X ", record2.version.major);
    printf("%02X ", record2.version.minor);
    printf("%02X ", length_bytes[2]);
    printf("%02X ", length_bytes[3]);
    for(int i=0; i<record2.length - 5; i++){
        printf("%02X ", record2.message[i]);
    }
    printf("\n\n");
    
    free(record2.message);
 
    
    OpenCommunication(server);
    while(CheckCommunication() == server){};
    
    //CHANGE CIPHER SPEC
    server_message = readchannel();
    printRecordLayer(server_message);
    
    OpenCommunication(server);
    while(CheckCommunication() == server){};
    FreeRecordLayer(server_message);
    
    //FINISHED 
    server_message = readchannel();
    
    int_To_Bytes(server_message->length, length_bytes);
    printf("FINISHED ENCRYPED: received\n");
    printf("%02X ", server_message->type);
    printf("%02X ", server_message->version.major);
    printf("%02X ", server_message->version.minor);
    printf("%02X ", length_bytes[2]);
    printf("%02X ", length_bytes[3]);
    for(int i=0; i<server_message->length - 5; i++){
        printf("%02X ", server_message->message[i]);
    }
    printf("\n\n");
    
    dec_message = DecEncryptPacket(server_message->message, server_message->length - 5, &dec_message_len, ciphersuite_choosen, key_block, server, 0);
    
    int_To_Bytes(dec_message_len + 5, length_bytes);
    printf("FINISHED DECRYPTED\n");
    printf("%02X ", server_message->type);
    printf("%02X ", server_message->version.major);
    printf("%02X ", server_message->version.minor);
    printf("%02X ", length_bytes[2]);
    printf("%02X ", length_bytes[3]);
    for(int i = 0; i < dec_message_len; i++){
        printf("%02X ", dec_message[i]);
    }
    printf("\n\n");
    
    
    //MAC verification
    free(server_message->message);
    server_message->message = dec_message;
    
    handshake = RecordToHandshake(server_message);
    handshake->length = dec_message_len;

    handshake->length = handshake->length - ciphersuite_choosen->hash_size;
    handshake->msg_type = FINISHED;
    
    server_write_MAC_secret = key_block + ciphersuite_choosen->hash_size;
    
    mac = dec_message + (dec_message_len - ciphersuite_choosen->hash_size);
    
    mac_test = MAC(ciphersuite_choosen, handshake, server_write_MAC_secret);
    
    if(ByteCompare(mac, mac_test, ciphersuite_choosen->hash_size)==0){
        printf("\nmac verified\n");
    }
    else{
        printf("\nmac not verified\n");
        exit(1);
    }
    
    free(ciphersuite_choosen);
    FreeRecordLayer(server_message);
    FreeHandshake(handshake);
    free(master_secret);
    free(key_block);
    free(mac_test);
   
    return 0;
    
}
Пример #2
0
void Sha1Hash::UpdateData(const uint8* dta, int len)
{
	SHA1_Update(&mC, dta, len);
}
Пример #3
0
int asr_send_payload(asr_client_t asr, const char* filesystem) {
	int i = 0;
	char data[ASR_PAYLOAD_PACKET_SIZE];
	FILE* file = NULL;
	uint32_t bytes = 0;
	uint32_t length = 0;
	double progress = 0;

	file = fopen(filesystem, "rb");
	if (file == NULL) {
		return -1;
	}

	fseek(file, 0, SEEK_END);
	length = ftell(file);
	fseek(file, 0, SEEK_SET);

	int chunk = 0;
	int add_checksum = 0;

	SHA_CTX sha1;

	if (asr->checksum_chunks) {
		SHA1_Init(&sha1);
	}

	int size = 0;
	for (i = length; i > 0; i -= size) {
		size = ASR_PAYLOAD_PACKET_SIZE;
		if (i < ASR_PAYLOAD_PACKET_SIZE) {
			size = i;
		}

		if (add_checksum) {
			add_checksum = 0;
		}

		if (asr->checksum_chunks && ((chunk + size) >= ASR_CHECKSUM_CHUNK_SIZE)) {
			// reduce packet size to match checksum chunk size
			size -= ((chunk + size) - ASR_CHECKSUM_CHUNK_SIZE);
			add_checksum = 1;
		}

		if (fread(data, 1, size, file) != (unsigned int) size) {
			error("Error reading filesystem\n");
			fclose(file);
			return -1;
		}

		if (asr_send_buffer(asr, data, size) < 0) {
			error("ERROR: Unable to send filesystem payload\n");
			fclose(file);
			return -1;
		}

		if (asr->checksum_chunks) {
			SHA1_Update(&sha1, data, size);
			chunk += size;

			if (add_checksum) {
				// get sha1 of last chunk
				SHA1_Final((unsigned char*)data, &sha1);

				// send checksum
				if (asr_send_buffer(asr, data, 20) < 0) {
					error("ERROR: Unable to send chunk checksum\n");
					fclose(file);
					return -1;
				}

				// reset SHA1 context
				SHA1_Init(&sha1);

				// reset chunk byte counter
				chunk = 0;
			}
		}

		bytes += size;
		progress = ((double) bytes/ (double) length);
		if (asr->progress_cb && ((int)(progress*100) > asr->lastprogress)) {
			asr->progress_cb(progress, asr->progress_cb_data);
			asr->lastprogress = (int)(progress*100);
		}
	}

	// if last chunk wasn't terminated with a checksum we do it here
	if (asr->checksum_chunks && !add_checksum) {
		// get sha1 of last chunk
		SHA1_Final((unsigned char*)data, &sha1);

		// send checksum
		if (asr_send_buffer(asr, data, 20) < 0) {
			error("ERROR: Unable to send chunk checksum\n");
			fclose(file);
			return -1;
		}
	}

	fclose(file);
	return 0;
}
Пример #4
0
/* Presently, this is only done wtih RSA PMS, and only on the server side,
 * so isRSA is always true. 
 */
SECStatus
ssl3_MasterKeyDeriveBypass( 
    ssl3CipherSpec *      pwSpec,
    const unsigned char * cr,
    const unsigned char * sr,
    const SECItem *       pms,
    PRBool                isTLS,
    PRBool                isRSA)
{
    unsigned char * key_block    = pwSpec->key_block;
    SECStatus       rv    = SECSuccess;
    PRBool          isFIPS = PR_FALSE;

    SECItem         crsr;

    unsigned char     crsrdata[SSL3_RANDOM_LENGTH * 2];
    PRUint64          md5buf[22];
    PRUint64          shabuf[40];

#define md5Ctx ((MD5Context *)md5buf)
#define shaCtx ((SHA1Context *)shabuf)

    /* first do the consistancy checks */
    if (isRSA) { 
	PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH);
	if (pms->len != SSL3_RSA_PMS_LENGTH) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
	/* caller must test PMS version for rollback */
    }

    /* initialize the client random, server random block */
    crsr.type   = siBuffer;
    crsr.data   = crsrdata;
    crsr.len    = sizeof crsrdata;
    PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
    PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
    PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len));

    /* finally do the key gen */
    if (isTLS) {
	SECItem master = { siBuffer, NULL, 0 };

	master.data = key_block;
	master.len = SSL3_MASTER_SECRET_LENGTH;

	rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS);
	if (rv != SECSuccess) {
	    PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
	}
    } else {
	int i;
	unsigned int made = 0;
	for (i = 0; i < 3; i++) {
	    unsigned int    outLen;
	    unsigned char   sha_out[SHA1_LENGTH];

	    SHA1_Begin(shaCtx);
	    SHA1_Update(shaCtx, (unsigned char*) mixers[i], i+1);
	    SHA1_Update(shaCtx, pms->data, pms->len);
	    SHA1_Update(shaCtx, crsr.data, crsr.len);
	    SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
	    PORT_Assert(outLen == SHA1_LENGTH);

	    MD5_Begin(md5Ctx);
	    MD5_Update(md5Ctx, pms->data, pms->len);
	    MD5_Update(md5Ctx, sha_out, outLen);
	    MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
	    PORT_Assert(outLen == MD5_LENGTH);
	    made += outLen;
	}
    }

    /* store the results */
    PORT_Memcpy(pwSpec->raw_master_secret, key_block, 
		SSL3_MASTER_SECRET_LENGTH);
    pwSpec->msItem.data = pwSpec->raw_master_secret;
    pwSpec->msItem.len  = SSL3_MASTER_SECRET_LENGTH;
    PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, 
                                           pwSpec->msItem.len));

    return rv;
}
Пример #5
0
static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
{
    return SHA1_Update(ctx->md_data,data,count);
}
Пример #6
0
static int send_file(int sock, const char *filepath,
                     long file_offset,
                     unsigned char digest[SHA_DIGEST_LENGTH])
{
        int ret = EXIT_FAILURE;
        ssize_t n = 0;
        static size_t total_bytes = 0;
        size_t total_bytes_session = 0, nread = 0;
        char sendbuf[SENDBUF_SIZE];
        int stop_sending = 0;
        SHA_CTX ctx;
        FILE *f;

        if (!filepath)
                filepath = "/tmp/data";

        f = fopen(filepath, "r");
    
        if (!f) {
                fprintf(stderr, "cannot open file %s : %s\n", 
                        filepath, strerror(errno));
                return EXIT_FAILURE;
        }

        if (file_offset > 0) {
                if (fseek(f, file_offset, SEEK_SET) == -1) {
                        fprintf(stderr, "fseek() failed, bad offset %ld\n", 
                                file_offset);
                        fclose(f);
                        return EXIT_FAILURE;
                }
        }

        SHA1_Init(&ctx);

        printf("sending file %s, starting at offset %ld\n", 
               filepath, file_offset);

        while (!stop_sending) {
                long pos = ftell(f);
                size_t count = fread(sendbuf, SENDBUF_SIZE, 1, f);
        
                nread = ftell(f) - pos;
        
                if (count != 1) {
            
                        if (feof(f) != 0) {
                                if (nread == 0) {
                                        printf("\rEOF reached, file successfully sent\n");
                                        ret = EXIT_SUCCESS;
                                        break;
                                }
                        } else if (ferror(f) != 0) {
                                fprintf(stderr, "\rError reading file\n");
                                break;
                        } else {
                                fprintf(stderr, "\rUnknown error when reading file\n");
                                break;
                        }
                }
        
                //printf("Read %zu bytes from file %s\n", nread, filepath);

                count = 0;

                SHA1_Update(&ctx, sendbuf, nread);

                while (!stop_sending && count < nread) {

                        n = send_sv(sock, sendbuf + count, nread - count, 0);

                        if (n < 0) {
                                if (errno == EAGAIN) {
                                        fprintf(stderr, 
                                                "\rEAGAIN, continuing..\n");
                                        continue;
                                } 
                
                                fprintf(stderr, "\rerror sending data: %s\n",
                                        strerror_sv(errno));
                                stop_sending = 1;
                                break;
                        }
            
                        /* 
                           printf("Sent %zd bytes, total bytes=%zu\n", 
                           n, total_bytes_session);
                        */
                        print_tick();

                        count =+ n;
                        total_bytes += n;
                        total_bytes_session += n;
                }
        }
    
        SHA1_Final(digest, &ctx);

        printf("Sent total %zu bytes, session %zu bytes\n", 
               total_bytes, total_bytes_session);
        
        fclose(f);
    
        return ret;
}
Пример #7
0
static bool VerifyAppSignature(const CStdString& appFile, const AppInfo& securityInfo, const AuthorityInfo& authorityInfo)
{
  unsigned char hash[SHA_DIGEST_LENGTH];
  SHA_CTX context;
  RSA *rsa = NULL;
  BIO *bio = NULL;
  bool bSuccedded = false;
  unsigned char buffer[4096];
  unsigned char* signature = (unsigned char*)securityInfo.signature.c_str();
  int signatureLen = securityInfo.signature.size();
  XFILE::CFile file;
  unsigned int bytesRead = 0;

  if(!file.Open(appFile))
  {
    CLog::Log(LOGERROR, "CAppSecurity::%s - failed to open file [%s]", __func__, appFile.c_str());
    return false;
  }

  SHA1_Init(&context);

  while((bytesRead = file.Read(buffer, sizeof buffer)))
  {
    SHA1_Update(&context, buffer, bytesRead);
  }

  SHA1_Final(hash, &context); 
  file.Close();

#ifdef DEBUG
  dump_sha1(hash);
#endif

  do
  {

    signatureLen = unbase64((unsigned char*)securityInfo.signature.c_str(), securityInfo.signature.size(), &signature); 
    if(!signatureLen)
    {
      CLog::Log(LOGERROR, "CAppSecurity::%s - failed to decode signature [%s]", __func__, securityInfo.signature.c_str());
      break;
    }

    bio = BIO_new_mem_buf((void*)authorityInfo.publicKey.data(), authorityInfo.publicKey.size());
    if(!bio)
    {
      CLog::Log(LOGERROR, "CAppSecurity::%s - failed to create BIO from public key[%s]", __func__, authorityInfo.publicKey.c_str());
      break;
    }

    PEM_read_bio_RSA_PUBKEY(bio, &rsa, NULL, NULL);
    if(!rsa)
    {
      CLog::Log(LOGERROR, "CAppSecurity::%s - failed to create RSA public key from BIO", __func__);
      break;
    }
    
    bSuccedded = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, signature, signatureLen, rsa);

   
  } while(false);


  if (rsa)       RSA_free(rsa);
  if (bio)       BIO_free(bio);
  if (signature) free(signature);

  return bSuccedded;
}
Пример #8
0
/*******************************************************************-o-******
 * generate_Ku
 *
 * Parameters:
 *	*hashtype	MIB OID for the transform type for hashing.
 *	 hashtype_len	Length of OID value.
 *	*P		Pre-allocated bytes of passpharase.
 *	 pplen		Length of passphrase.
 *	*Ku		Buffer to contain Ku.
 *	*kulen		Length of Ku buffer.
 *      
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Convert a passphrase into a master user key, Ku, according to the
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
 * as follows:
 *
 * Expand the passphrase to fill the passphrase buffer space, if necessary,
 * concatenation as many duplicates as possible of P to itself.  If P is
 * larger than the buffer space, truncate it to fit.
 *
 * Then hash the result with the given hashtype transform.  Return
 * the result as Ku.
 *
 * If successful, kulen contains the size of the hash written to Ku.
 *
 * NOTE  Passphrases less than USM_LENGTH_P_MIN characters in length
 *	 cause an error to be returned.
 *	 (Punt this check to the cmdline apps?  XXX)
 */
int
generate_Ku(const oid * hashtype, u_int hashtype_len,
            const u_char * P, size_t pplen, u_char * Ku, size_t * kulen)
#if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_OPENSSL) || defined(NETSNMP_USE_INTERNAL_CRYPTO)
{
    int             rval = SNMPERR_SUCCESS,
        nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
#if defined(NETSNMP_USE_INTERNAL_MD5) || defined(NETSNMP_USE_INTERNAL_CRYPTO)
    int             ret;
#endif

    u_int           i, pindex = 0;

    u_char          buf[USM_LENGTH_KU_HASHBLOCK], *bufp;

#ifdef NETSNMP_USE_OPENSSL
    EVP_MD_CTX     *ctx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX));
    unsigned int    tmp_len;
#elif NETSNMP_USE_INTERNAL_CRYPTO
    SHA_CTX csha1;
    MD5_CTX cmd5;
    char    cryptotype = 0;
    unsigned int    tmp_len;
#define TYPE_MD5  1
#define TYPE_SHA1 2
#else
    MDstruct        MD;
#endif
    /*
     * Sanity check.
     */
    if (!hashtype || !P || !Ku || !kulen || (*kulen <= 0)
        || (hashtype_len != USM_LENGTH_OID_TRANSFORM)) {
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
    }

    if (pplen < USM_LENGTH_P_MIN) {
        snmp_log(LOG_ERR, "Error: passphrase chosen is below the length "
                 "requirements of the USM (min=%d).\n",USM_LENGTH_P_MIN);
        snmp_set_detail("The supplied password length is too short.");
        QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
    }


    /*
     * Setup for the transform type.
     */
#ifdef NETSNMP_USE_OPENSSL

#ifndef NETSNMP_DISABLE_MD5
    if (ISTRANSFORM(hashtype, HMACMD5Auth))
        EVP_DigestInit(ctx, EVP_md5());
    else
#endif
        if (ISTRANSFORM(hashtype, HMACSHA1Auth))
        EVP_DigestInit(ctx, EVP_sha1());
    else {
        free(ctx);
        return (SNMPERR_GENERR);
    }
#elif NETSNMP_USE_INTERNAL_CRYPTO
    if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
        MD5_Init(&cmd5);
        cryptotype = TYPE_MD5;
    } else if (ISTRANSFORM(hashtype, HMACSHA1Auth)) {
        SHA1_Init(&csha1);
        cryptotype = TYPE_SHA1;
    } else {
        return (SNMPERR_GENERR);
    }
#else
    MDbegin(&MD);
#endif                          /* NETSNMP_USE_OPENSSL */

    while (nbytes > 0) {
        bufp = buf;
        for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
            *bufp++ = P[pindex++ % pplen];
        }
#ifdef NETSNMP_USE_OPENSSL
        EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);
#elif NETSNMP_USE_INTERNAL_CRYPTO
        if (TYPE_SHA1 == cryptotype) {
            rval = !SHA1_Update(&csha1, buf, USM_LENGTH_KU_HASHBLOCK);
        } else {
            rval = !MD5_Update(&cmd5, buf, USM_LENGTH_KU_HASHBLOCK);
        }
        if (rval != 0) {
            return SNMPERR_USM_ENCRYPTIONERROR;
        }
#elif NETSNMP_USE_INTERNAL_MD5
        if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK * 8)) {
            rval = SNMPERR_USM_ENCRYPTIONERROR;
            goto md5_fin;
        }
#endif                          /* NETSNMP_USE_OPENSSL */
        nbytes -= USM_LENGTH_KU_HASHBLOCK;
    }

#ifdef NETSNMP_USE_OPENSSL
    tmp_len = *kulen;
    EVP_DigestFinal(ctx, (unsigned char *) Ku, &tmp_len);
    *kulen = tmp_len;
    /*
     * what about free() 
     */
#elif NETSNMP_USE_INTERNAL_CRYPTO
    tmp_len = *kulen;
    if (TYPE_SHA1 == cryptotype) {
        SHA1_Final(Ku, &csha1);
    } else {
        MD5_Final(Ku, &cmd5);
    }
    ret = sc_get_properlength(hashtype, hashtype_len);
    if (ret == SNMPERR_GENERR)
        return SNMPERR_GENERR;
    *kulen = ret;
#elif NETSNMP_USE_INTERNAL_MD5
    if (MDupdate(&MD, buf, 0)) {
        rval = SNMPERR_USM_ENCRYPTIONERROR;
        goto md5_fin;
    }
    ret = sc_get_properlength(hashtype, hashtype_len);
    if (ret == SNMPERR_GENERR)
        return SNMPERR_GENERR;
    *kulen = ret;
    MDget(&MD, Ku, *kulen);
  md5_fin:
    memset(&MD, 0, sizeof(MD));
#endif                          /* NETSNMP_USE_INTERNAL_MD5 */


#ifdef NETSNMP_ENABLE_TESTING_CODE
    DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P));
    for (i = 0; i < *kulen; i++)
        DEBUGMSG(("generate_Ku", "%02x", Ku[i]));
    DEBUGMSG(("generate_Ku", "\n"));
#endif                          /* NETSNMP_ENABLE_TESTING_CODE */


  generate_Ku_quit:
    memset(buf, 0, sizeof(buf));
#ifdef NETSNMP_USE_OPENSSL
    free(ctx);
#endif
    return rval;

}                               /* end generate_Ku() */
Пример #9
0
/**
*ハッシュ値生成関数
* @author University of Tsukuba
* @param *ptr ハッシュ対象データ
* @param lLenIn ハッシュデータ長
* @param lalgorithm ハッシュアルゴリズム
* @param *ptrData  	ハッシュ値
* @param *lLenOut	ハッシュ値データ長
* @return	long	0:正常 -1:異常
* @since 2008.02
* @version 1.0
*/
long IDMan_CmMkHash(void *ptr, long lLenIn, long lalgorithm, void *ptrData, long *lLenOut)
{
	long 			lRet = -1L;
	SHA_CTX 		ctx;
	SHA256_CTX 		ctx2;
	SHA512_CTX 		ctx3;
	char 			szErrBuff[1024];

	ERR_load_crypto_strings();

	IDMan_StMemset(szErrBuff, 0x00, sizeof(szErrBuff));
	/** ハッシュ対象データパラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if ( ptr == 0x00 )
	{ 
		/** −処理を中断する。 */
		return lRet;
	}
	/** ハッシュデータ長パラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if ( lLenIn == 0 ){
		/** −処理を中断する。 */
		return lRet;
	}
	/** ハッシュ値パラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if ( ptrData == 0x00 )
	{
		/** −処理を中断する。 */
		return lRet;
	}
	/** ハッシュ値データ長パラメータチェックを行う。 */
	/** エラー発生した場合、 */
	if ( lLenOut == 0x00 ) 
	{
		/** −処理を中断する。 */
		return lRet;
	}
	else
	{
		/** −戻り値の初期化を行う。 */
		*lLenOut=0;
	}

	/** ハッシュ化を行う。 */
	switch(lalgorithm)
	{
		case 0:
			break;
		/** アルゴリズムが0x220の場合、 */
		case ALGORITHM_SHA1:
			/** −ハッシュ変換 SHA1を行う。 */
			SHA1_Init (&ctx);
			SHA1_Update (&ctx, ptr, lLenIn);
			SHA1_Final (ptrData, &ctx);
			OPENSSL_cleanse (&ctx, sizeof (ctx));
			/** −ハッシュ変換が成功の場合、 */
			if ( ptrData != 0x00)
			{
				/** −−長さを設定する。 */
				*lLenOut = HASH_LEN_SHA1;
				lRet =0;
			}
			/** −ハッシュ変換が失敗の場合、 */
			else
			{
				/** −−エラーログを出力する。 */
				ERR_error_string(ERR_get_error(), szErrBuff);
			}
			break;
		/** アルゴリズムが0x250の場合、 */
		case ALGORITHM_SHA256:
			/** −ハッシュ変換 SHA256を行う。 */
			SHA256_Init (&ctx2);
			SHA256_Update (&ctx2, ptr, lLenIn);
			SHA256_Final (ptrData, &ctx2);
			OPENSSL_cleanse (&ctx2, sizeof (ctx2));
			/** −ハッシュ変換が成功の場合、 */
			if ( ptrData != 0x00)
			{
				/** −−長さを設定する。 */
				*lLenOut = HASH_LEN_SHA256;
				lRet =0;
			}
			/** −ハッシュ変換が失敗の場合、 */
			else
			{
				/** −−エラーログを出力する。 */
				ERR_error_string(ERR_get_error(), szErrBuff);
			}
			break;
		/** アルゴリズムが0x270の場合、 */
		case ALGORITHM_SHA512:
			/** −ハッシュ変換 SHA512を行う。 */
			SHA512_Init (&ctx3);
			SHA512_Update (&ctx3, ptr, lLenIn);
			SHA512_Final (ptrData, &ctx3);
			OPENSSL_cleanse (&ctx3, sizeof (ctx3));
			/** −ハッシュ変換が成功の場合、 */
			if ( ptrData != 0x00)
			{
				/** −−長さを設定する。 */
				*lLenOut = HASH_LEN_SHA512;
				lRet =0;
			}
			/** −ハッシュ変換が失敗の場合、 */
			else
			{
				/** −−エラーログを出力する。 */
				ERR_error_string(ERR_get_error(), szErrBuff);
			}
			break;
		default:
			break;
	}
	return lRet;
}
Пример #10
0
void hashbd(metafile_t *m)
{
	flist_t *f;
	long long ca,cb,f0,f1;
	/* pointer to a place in the file list */
	unsigned char *pos;             /* position in the hash string */
	unsigned char *posf;             /* position in the hash string */
	unsigned char *read_buf;        /* read buffer */
	unsigned char *bf0;        /* read buffer */
	unsigned char *bf1;        /* read buffer */
	ulong remainder;
	SHA_CTX c;                      /* SHA1 hashing context */
	SHA_CTX cf;                      /* SHA1 hashing context */
	read_buf=malloc(1024*1024*10+10);//100000*32);
	bf0=malloc(1024*1024*10+10);//100000*32);
	bf1=malloc(1024*1024*10+10);//100000*32);
	//////////////////////////////////////////////////////
	ca=0;
	cb=0;
	f0=0;
	f1=0;
	for (f = m->file_list; f; f = f->next) {
		if(f->bdmv)
		{
			memcpy(read_buf+ca,f->hash,32);
			ca+=32;
			cb+=f->size;
			////////////////////////
			memcpy(bf1+f1,f->filehash,20);
			f1+=20;
			if(f->size>=1024*1024*1024)
			{
				memcpy(bf0+f0,f->filehash,20);
				f0+=20;
			}
			////////////////////////
		}
		if(f->bdmv==2)
		{

			int i;
			void (*cycle)(ulong*, ulong*, char) = (big_endian) ? crc_be_cycle : crc_le_cycle;

			remainder= starting;
			ulong table2[CRC_TABLE_SIZE];
			crc_fill_table(table2, big_endian, polynomial);
			for (i = 0; i < ca ; i++)
				cycle(table2, &remainder, read_buf[i]);
			
			if (xor_output)
				remainder ^= 0xFFFFFFFF;
			if (reflect_output)
				remainder = crc_reflect(remainder);



			f->hash[35]=remainder%256;
			remainder=remainder/256;
			f->hash[34]=remainder%256;
			remainder=remainder/256;
			f->hash[33]=remainder%256;
			remainder=remainder/256;
			f->hash[32]=remainder%256;

			pos = malloc(SHA_DIGEST_LENGTH);
			SHA1_Init(&c);
			SHA1_Update(&c,read_buf,ca);
			SHA1_Final(pos, &c);
			memcpy(f->hash+36,pos,20);


			char fsize[9]={0};
			long long fs=cb;
			fsize[7]=fs%256;
			fs=fs/256;
			fsize[6]=fs%256;
			fs=fs/256;
			fsize[5]=fs%256;
			fs=fs/256;
			fsize[4]=fs%256;
			fs=fs/256;
			fsize[3]=fs%256;
			fs=fs/256;
			fsize[2]=fs%256;
			fs=fs/256;
			fsize[1]=fs%256;
			fs=fs/256;
			fsize[0]=fs%256;
			remainder= starting;
			ulong table[CRC_TABLE_SIZE];
			crc_fill_table(table, big_endian, polynomial);
			for (i = 0; i < 8 ; i++)
				cycle(table, &remainder, fsize[i]);

			if (xor_output)
				remainder ^= 0xFFFFFFFF;
			if (reflect_output)
				remainder = crc_reflect(remainder);

			f->hash[59]=remainder%256;
			remainder=remainder/256;
			f->hash[58]=remainder%256;
			remainder=remainder/256;
			f->hash[57]=remainder%256;
			remainder=remainder/256;
			f->hash[56]=remainder%256;
			/////////////////////////////////
			posf = malloc(SHA_DIGEST_LENGTH);
			SHA1_Init(&cf);
			if(f0)
				SHA1_Update(&cf,bf0,f0);
			else
				SHA1_Update(&cf,bf1,f1);
			SHA1_Final(posf, &cf);
			memcpy(f->hash+60,posf,20);
			/////////////////////////////////
			f1=0;
			f0=0;
			ca=0;
			cb=0;
			free(pos);
			free(posf);
		}
	}
	free(read_buf);
	free(bf0);
	free(bf1);
}
Пример #11
0
EXPORT unsigned char *make_hash(metafile_t *m)
{
	char *cc;
	flist_t *f;                     /* pointer to a place in the file list */
	unsigned char *hash_string;     /* the hash string */
	unsigned char *lthash_string;     /* the hash string */
	unsigned char *pos;             /* position in the hash string */
	unsigned char *ltpos;             /* position in the hash string */
	unsigned char *read_buf;        /* read buffer */
	unsigned char *read_buf2;        /* read buffer */
	unsigned char *read_buf3;        /* read buffer */
	int fd;                         /* file descriptor */
	ssize_t r;                      /* number of bytes read from file(s) into
	                                   the read buffer */
	SHA_CTX c;                      /* SHA1 hashing context */
	SHA_CTX ltc;                      /* SHA1 hashing context */
#ifndef NO_HASH_CHECK
	off_t counter = 0;              /* number of bytes hashed
	                                   should match size when done */
#endif

	/* allocate memory for the hash string
	   every SHA1 hash is SHA_DIGEST_LENGTH (20) bytes long */
	read_buf = malloc(m->piece_length*2);
	read_buf2 = malloc(m->piece_length);
	read_buf3 = malloc(m->piece_length);
	unsigned int piece_length=m->piece_length;
	unsigned int piece_length8=1<<23;

	hash_string = malloc(m->pieces * SHA_DIGEST_LENGTH);
	/* allocate memory for the read buffer to store 1 piece */

	/* check if we've run out of memory */
	if (hash_string == NULL || read_buf == NULL) {
		fprintf(stderr, "Out of memory.\n");
		exit(EXIT_FAILURE);
	}


	/* initiate pos to point to the beginning of hash_string */
	pos = hash_string;
	/* and initiate r to 0 since we haven't read anything yet */
	r = 0;
	/* go through all the files in the file list */
	for (f = m->file_list; f; f = f->next) {

		lthash_string = malloc(SHA_DIGEST_LENGTH);
		if (lthash_string == NULL) {
			fprintf(stderr, "Out of memory.\n");
			exit(EXIT_FAILURE);
		}
		/* open the current file for reading */
		printf("Hashing %s\n", f->path);
		int loopi,pathlen=strlen(f->path);
		long long patha=0;
		long long pathb=0;
		long long pathc=0;
		long long pathe=0;
		f->rains=NULL;
		f->data=NULL;
		f->datalength=0;
//let cut: py       sh       ini       inf         log        cue        txt        avs        vpy       spy        mpls         bdmv         clpi           miniso             qpfile
//    6845230   7958574  1768843566  1718511918   1735355438 1702191918 1954051118 1937137966 2037413422 2037412654 495740546350 508641436206 452857717550   31370619076046126  28548172593787182
		if(pathlen>3)
			for (loopi=1;loopi<=3;++loopi) {
				patha+=f->path[pathlen-loopi];
				patha*=256;
			}
		if(pathlen>4)
			for (loopi=1;loopi<=4;++loopi) {
				pathb+=f->path[pathlen-loopi];
				pathb*=256;
			}
		if(pathlen>5)
			for (loopi=1;loopi<=5;++loopi) {
				pathc+=f->path[pathlen-loopi];
				pathc*=256;
			}
		if(pathlen>7)
			for (loopi=1;loopi<=7;++loopi) {
				pathe+=f->path[pathlen-loopi];
				pathe*=256;
			}
		patha/=256;
		pathb/=256;
		pathc/=256;
		pathe/=256;
		if((!f->color)||patha==7958574||patha==6845230
			||pathb==1768843566
			||pathb==1718511918
			||pathb==1735355438
			||pathb==1702191918
			||pathb==1954051118
			||pathb==1937137966
			||pathb==2037413422
			||pathb==2037412654
				||pathc==495740546350
				||pathc==508641436206
				||pathc==452857717550
					||pathe==31370619076046126
					||pathe==28548172593787182)
			if(f->size<=2097152)
			{
				cc=(char *)malloc(2097152);
				f->datalength=mkgz(cc,f->path);
				if(f->datalength==0)
					free(cc);
				else
					f->data=cc;
			}
		if(pathb==879783214)
		{
			FILE *mp4;
			mp4=fopen(f->path,"rb");
			char cmt[5]={0xA9,0x67,0x65,0x6E,0};
			//char cmt[5]={0xA9,0x63,0x6d,0x74,0};
			fseek(mp4,0,2);
			long lmp4=ftell(mp4);
			fseek(mp4,lmp4-10000,0);
			if(!rsfind("Koishi",mp4))
			{
				fseek(mp4,lmp4-10000,0);
				if(!rsfind("Yuki",mp4))
				{
					cmt[1]=0x63;
					cmt[2]=0x6d;
					cmt[3]=0x74;
					fseek(mp4,lmp4-10000,0);
					if(!rsfind("RainS!",mp4))
					{
						fclose(mp4);
						mp4=NULL;
					}
				}

			}
			if(mp4&&rsfind(cmt,mp4))
			{
				fseek(mp4,16,1);
				long fs=ftell(mp4);
				while(fgetc(mp4)!='U');
				long rlen=ftell(mp4)-fs;
				fseek(mp4,fs,0);
				char *rains;
				rains=(char *)malloc(rlen);
				rains[rlen-1]=0;
				fread(rains,1,rlen-1,mp4);
				//printf("%s",rains);
				f->rains=rains;
			}
			fclose(mp4);
		}
		//////////////////////////////////////////   sha1 1M hash
			FILE *lt4;
			unsigned char *ltcc,*ltp;
			ltcc=malloc(1024*1024*10+10);
			long lti,ltflen,ltlen,partlen;
			lt4=fopen(f->path,"rb");
			fseek(lt4,0,2);
			ltlen=ltflen=ftell(lt4);
			fseek(lt4,0,0);
			if(ltflen<1024*1024*10)
				fread(ltcc,ltlen,1,lt4);
			else
			{
				ltlen=1024*1024*10;
				partlen=(ltflen-1024*1024)/9;
			//printf("\n%ld\n",ltflen);
				for(lti=0;lti<9;++lti)
				{
			//printf("\n%ld\n",lti*partlen);
					ltp=ltcc+lti*1024*1024;
					fseek(lt4,lti*partlen,0);
					fread(ltp,1024*1024,1,lt4);
				}
				ltp=ltcc+9*1024*1024;
				fseek(lt4,-1024*1024,2);
				fread(ltp,1024*1024,1,lt4);
			}
			ltpos = lthash_string;
			SHA1_Init(&ltc);
			SHA1_Update(&ltc, ltcc, ltlen);
			SHA1_Final(ltpos, &ltc);
			//f->filehash[20]=0;
			memcpy(f->filehash,ltpos,20);
			free(ltpos);
			free(ltcc);
			fclose(lt4);
		//////////////////////////////////////////
		fflush(stdout);
#if defined _LARGEFILE_SOURCE && defined O_LARGEFILE
		if ((fd = open(f->path, O_RDONLY | O_BINARY | O_LARGEFILE)) == -1) {
#else
		if ((fd = open(f->path, O_RDONLY | O_BINARY)) == -1) {
#endif
			fprintf(stderr, "Error opening '%s' for reading: %s\n",
					f->path, strerror(errno));
			exit(EXIT_FAILURE);
		}
		/* fill the read buffer with the contents of the file and append
		   the SHA1 hash of it to the hash string when the buffer is full.
		   repeat until we can't fill the read buffer and we've thus come
		   to the end of the file */
		ulong remainder = starting;

		ulong table[CRC_TABLE_SIZE];

		crc_fill_table(table, big_endian, polynomial);
///////////////////////////////////////
		long ltpieces =(f->size + piece_length8 - 1) / piece_length8;
		f->sha1length=ltpieces*SHA_DIGEST_LENGTH;
		f->sha32length=(ltpieces-1)*4+2*SHA_DIGEST_LENGTH;
		f->sha1 = lthash_string = NULL;
		f->sha1 = malloc(f->sha1length);
		f->sha32 = malloc(f->sha32length);
		if (f->sha1 == NULL) {
			fprintf(stderr, "Out of memory.\n");
			exit(EXIT_FAILURE);
		}
		ltpos = f->sha1;

		int tune=1;
		long long last=f->size;
///////////////////////////////////////
		while (1) {
		ssize_t d;
		if(tune)
			d = read(fd, read_buf + r, m->piece_length); // - r
		else
		{
			if(last<m->piece_length)
				d=last;
			else
				d=m->piece_length;
		}
			last=last-d;

			int err2=0;
			pthread_t sid2;
			if (d < 0) {
				fprintf(stderr, "Error reading from '%s': %s\n",
						f->path, strerror(errno));
				exit(EXIT_FAILURE);
			}

			if (d == 0) /* end of file */
				break;

		if(tune)
		{
			memcpy(read_buf2,read_buf+r*sizeof(char),d*sizeof(char)); //sha1 process distory string

			type_sha1 u_sha1;
			u_sha1.ltcp=&ltc;
			u_sha1.read_buf=read_buf2;
			u_sha1.d=d;
			u_sha1.ltpos=ltpos;
			if(f->color)
			{
				if(piece_length8!=piece_length) // main 24 this 23 (8)
					err2=pthread_create(&sid2, NULL, &sha1p24, &u_sha1);
				else
					err2=pthread_create(&sid2, NULL, &sha1p, &u_sha1);
			}
			if(err2!=0)  
    			{  
        			printf("Create pthread error!\n");  
    				exit(EXIT_FAILURE);
    			}  
		}
			// ltc  read_buf2 d ltpos 
			//SHA1_Init(&ltc);
			//SHA1_Update(&ltc, read_buf2, d);
			//SHA1_Final(ltpos, &ltc);
			if (f->color)
				r += d;

			if (f->color && r >= m->piece_length) {
				SHA1_Init(&c);
				SHA1_Final(pos, &c);
				pos += SHA_DIGEST_LENGTH;
#ifndef NO_HASH_CHECK
				counter += m->piece_length;	/* r == piece_length */
#endif
				r -= m->piece_length;
				if(r!=0)
					memcpy(read_buf,read_buf+m->piece_length*sizeof(char),r*sizeof(char));
			}
			if(f->color&&tune)
				pthread_join(sid2,NULL);
			tune=0;
			break;
		}
		//printf("%ld %ld\n",f->size,last);

		if (xor_output)
			remainder ^= 0xFFFFFFFF;
		if (reflect_output)
			remainder = crc_reflect(remainder);
		//printf("%08X\n", (int) remainder);
		//sprintf(f->hash,"%08X", (int) remainder);
		f->hash[32]=0;

		///////////////////////////////// press crc32_file
		f->hash[3]=remainder%256;
		remainder=remainder/256;
		f->hash[2]=remainder%256;
		remainder=remainder/256;
		f->hash[1]=remainder%256;
		remainder=remainder/256;
		f->hash[0]=remainder%256;

		///////////////////////////////// press sha1_file

		if(f->color)
		{
			ltpos=malloc(SHA_DIGEST_LENGTH);
			SHA1_Init(&ltc);
			SHA1_Update(&ltc, f->sha1,f->sha1length);
			SHA1_Final(ltpos, &ltc);
		}


		int fori;
		for(fori=0;fori<20;++fori)
		{
			if(f->color)
				f->hash[fori+4]=ltpos[fori]^f->filehash[fori];
			else
				f->hash[fori+4]=f->filehash[fori];
		}

		//////////////////////////////// press crc32_size
		char fsize[9]={0};
		long long fs=f->size;
		fsize[7]=fs%256;
		fs=fs/256;
		fsize[6]=fs%256;
		fs=fs/256;
		fsize[5]=fs%256;
		fs=fs/256;
		fsize[4]=fs%256;
		fs=fs/256;
		fsize[3]=fs%256;
		fs=fs/256;
		fsize[2]=fs%256;
		fs=fs/256;
		fsize[1]=fs%256;
		fs=fs/256;
		fsize[0]=fs%256;
		int i;
		void (*cycle)(ulong*, ulong*, char) = (big_endian) ? crc_be_cycle : crc_le_cycle;

		remainder = starting;
		crc_fill_table(table, big_endian, polynomial);
		for (i = 0; i < 8 ; i++)
			cycle(table, &remainder, fsize[i]);
		if (xor_output)
			remainder ^= 0xFFFFFFFF;
		if (reflect_output)
			remainder = crc_reflect(remainder);
		f->hash[27]=remainder%256;
		remainder=remainder/256;
		f->hash[26]=remainder%256;
		remainder=remainder/256;
		f->hash[25]=remainder%256;
		remainder=remainder/256;
		f->hash[24]=remainder%256;
		//////////////////////////////// press crc32_sha1
		remainder = starting;
		crc_fill_table(table, big_endian, polynomial);
		for (i = 0; i < f->sha1length; i++)
			cycle(table, &remainder, f->sha1[i]);
		if (xor_output)
			remainder ^= 0xFFFFFFFF;
		if (reflect_output)
			remainder = crc_reflect(remainder);
		f->hash[31]=remainder%256;
		remainder=remainder/256;
		f->hash[30]=remainder%256;
		remainder=remainder/256;
		f->hash[29]=remainder%256;
		remainder=remainder/256;
		f->hash[28]=remainder%256;


		if(f->color)
		{
		/* precess sha32 */
		memcpy(f->sha32,f->sha1,SHA_DIGEST_LENGTH);
		memcpy(f->sha32+SHA_DIGEST_LENGTH,ltpos,SHA_DIGEST_LENGTH);

		remainder = starting;
		crc_fill_table(table, big_endian, polynomial);
		for (i = SHA_DIGEST_LENGTH; i < f->sha1length; i++)
		{
			cycle(table, &remainder, f->sha1[i]);
			if((i+1)%SHA_DIGEST_LENGTH==0)
			{
				if (xor_output)
					remainder ^= 0xFFFFFFFF;
				if (reflect_output)
					remainder = crc_reflect(remainder);
				f->sha32[ ( (i+1-40)/20 )*4+40+3 ]=remainder%256;
				remainder=remainder/256;
				f->sha32[ ( (i+1-40)/20 )*4+40+2 ]=remainder%256;
				remainder=remainder/256;
				f->sha32[ ( (i+1-40)/20 )*4+40+1 ]=remainder%256;
				remainder=remainder/256;
				f->sha32[ ( (i+1-40)/20 )*4+40 ]=remainder%256;
				remainder = starting;
				crc_fill_table(table, big_endian, polynomial);
			}
		}

		}

		/* now close the file */
		if (close(fd)) {
			fprintf(stderr, "Error closing '%s': %s\n",
					f->path, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	/* finally append the hash of the last irregular piece to the hash string */
	if (r) {
		SHA1_Init(&c);
		SHA1_Update(&c, read_buf, r);
		SHA1_Final(pos, &c);
	}


	/* free the read buffer before we return */
	free(read_buf);
	free(read_buf2);
	free(read_buf3);

	hashbd(m);

	return hash_string;
}
Пример #12
0
Файл: sha1.c Проект: Jille/FBP
void
sha1_file(char *out, int fd) {
	SHA_CTX c;
	unsigned char buf[BUFSIZ];
	ssize_t len;
	static const char hex[]="0123456789abcdef";
	int i;
#ifdef HAS_MMAP
	struct stat st;
#endif

	if(SHA1_Init(&c) == 0) {
		errno = 0;
		err(1, "SHA1_Init() failed; possible cause");
	}

#ifdef HAS_MMAP
	if(fstat(fd, &st) == -1) {
		err(1, "fstat()");
	}

	char *mdata = mmap(NULL, st.st_size, PROT_READ, MAP_NOCORE, fd, 0);
	if(mdata == MAP_FAILED) {
		goto mmap_failed;
	}
	if(SHA1_Update(&c, mdata, st.st_size) == 0) {
		errno = 0;
		err(1, "SHA1_Update() failed; possible cause");
	}
	if(munmap(mdata, st.st_size) == -1) {
		warn("munmap");
	}
	goto done;

mmap_failed:
#endif
	if(lseek(fd, 0, SEEK_SET) == -1) {
		err(1, "lseek");
	}
	while((len = read(fd, buf, sizeof(buf))) > 0) {
		if(SHA1_Update(&c, buf, len) == 0) {
			errno = 0;
			err(1, "SHA1_Update() failed; possible cause");
		}
	}
	if(len == -1) {
		err(1, "read");
	}

#ifdef HAS_MMAP
done:
#endif
	assert(sizeof(buf) > 20);
	if(SHA1_Final(buf, &c) == 0) {
		errno = 0;
		err(1, "SHA1_Final() failed; possible cause");
	}
	for(i = 0; 20 > i; i++) {
		out[i*2] = hex[buf[i] >> 4];
		out[i*2+1] = hex[buf[i] & 0x0f];
	}
}
Пример #13
0
int SL_Crypto_SHA1::update(const unsigned char *input, unsigned int input_len)
{
	return SHA1_Update(&ctx_, input, input_len);
}
Пример #14
0
int rc4_main(int argc, char *argv[])
#endif
	{
	int err=0;
	unsigned int i, j;
	unsigned char *p;
	RC4_KEY key;
	unsigned char obuf[512];
    
	for (i=0; i<6; i++)
		{
		RC4_set_key(&key,keys[i][0],&(keys[i][1]));
    if(errno==ENOMEM)
    {
	    return 1;
	  }  
		memset(obuf,0x00,sizeof(obuf));
   if(errno==ENOMEM)
    {
	    return 1;
	  }  

		RC4(&key,data_len[i],&(data[i][0]),obuf);
   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		
		if (memcmp(obuf,output[i],data_len[i]+1) != 0)
			{
			fprintf(stdout,"error calculating RC4\n");
			fprintf(stdout,"output:");
			for (j=0; j<data_len[i]+1U; j++)
				fprintf(stdout," %02x",obuf[j]);
			fprintf(stdout,"\n");
			fprintf(stdout,"expect:");
			p= &(output[i][0]);
			for (j=0; j<data_len[i]+1U; j++)
				fprintf(stdout," %02x",*(p++));
			fprintf(stdout,"\n");
			err++;
			}
		else
			fprintf(stdout,"test %d ok\n",i);
		}
	fprintf(stdout,"test end processing ");
	for (i=0; i<data_len[3]; i++)
		{
		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
		if(errno==ENOMEM)
    {
	    return 1;
	  }  
		memset(obuf,0x00,sizeof(obuf));
		RC4(&key,i,&(data[3][0]),obuf);
	   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0))
			{
			fprintf(stdout,"error in RC4 length processing\n");
			fprintf(stdout,"output:");
			for (j=0; j<i+1; j++)
				printf(" %02x",obuf[j]);
			fprintf(stdout,"\n");
			fprintf(stdout,"expect:");
			p= &(output[3][0]);
			for (j=0; j<i; j++)
				fprintf(stdout," %02x",*(p++));
			fprintf(stdout," 00\n");
			err++;
			}
		else
			{
			fprintf(stdout,".");
			fflush(stdout);
			}
		}
	fprintf(stdout,"done\n");
	fprintf(stdout,"test multi-call ");
	for (i=0; i<data_len[3]; i++)
		{
		RC4_set_key(&key,keys[3][0],&(keys[3][1]));
	   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		
		memset(obuf,0x00,sizeof(obuf));
		RC4(&key,i,&(data[3][0]),obuf);
	   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		
		RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i]));
	   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		
		if (memcmp(obuf,output[3],data_len[3]+1) != 0)
			{
			fprintf(stdout,"error in RC4 multi-call processing\n");
			fprintf(stdout,"output:");
			for (j=0; j<data_len[3]+1U; j++)
				fprintf(stdout," %02x",obuf[j]);
			fprintf(stdout,"\n");
			fprintf(stdout,"expect:");
			p= &(output[3][0]);
			for (j=0; j<data_len[3]+1U; j++)
				fprintf(stdout," %02x",*(p++));
			err++;
			}
		else
			{
			fprintf(stdout,".");
			fflush(stdout);
			}
		}
	fprintf(stdout,"done\n");
	fprintf(stdout,"bulk test ");
	{   unsigned char buf[513];
	    SHA_CTX c;
	    unsigned char md[SHA_DIGEST_LENGTH];
	    static unsigned char expected[]={
		0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f,
		0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 };

		RC4_set_key(&key,keys[0][0],&(keys[3][1]));
	   if(errno==ENOMEM)
    {
	    return 1;
	  }  
		
		memset(buf,'\0',sizeof(buf));
		SHA1_Init(&c);
			   if(errno==ENOMEM)
    {
	    return 1;
	  }  

		for (i=0;i<2571;i++) {
			RC4(&key,sizeof(buf),buf,buf);
		   if(errno==ENOMEM)
     {
	    return 1;
	   }  

			SHA1_Update(&c,buf,sizeof(buf));
		  if(errno==ENOMEM)
     {
	    return 1;
	   }  

		}
		SHA1_Final(md,&c);
		if(errno==ENOMEM)
    {
	    return 1;
	  }  


		if (memcmp(md,expected,sizeof(md))) {
			fprintf(stdout,"error in RC4 bulk test\n");
			fprintf(stdout,"output:");
			for (j=0; j<sizeof(md); j++)
				fprintf(stdout," %02x",md[j]);
			fprintf(stdout,"\n");
			fprintf(stdout,"expect:");
			for (j=0; j<sizeof(md); j++)
				fprintf(stdout," %02x",expected[j]);
			fprintf(stdout,"\n");
			err++;
		}
		else	fprintf(stdout,"ok\n");
	}
#ifdef OPENSSL_SYS_NETWARE
    if (err) fprintf(stdout,"ERROR: %d\n", err);
#endif
  fprintf(stdout,"Test case Passed\n");    
	//EXIT(err);
	return(0);
	}
Пример #15
0
int main( int inNumArgs, char **inArgs ) {


    if( inNumArgs != 2 ) {
        usage( inArgs[0] );
        }


    FILE *file = fopen( inArgs[1], "rb" );

    if( file == NULL ) {
        printf( "Failed to open file %s for reading\n\n", inArgs[1] );

        usage( inArgs[0] );
        }

    
    SHA_CTX shaContext;

    SHA1_Init( &shaContext );

               
    int bufferSize = 5000;
    unsigned char *buffer = new unsigned char[ bufferSize ];

    int numRead = bufferSize;

    char error = false;
    
    // read bytes from file until we run out
    while( numRead == bufferSize && !error ) {

        numRead = fread( buffer, 1, bufferSize, file );

        if( numRead > 0 ) {
            SHA1_Update( &shaContext, buffer, numRead );
            }
        else{
            error = true;
            }
        }

    fclose( file ); 
    delete [] buffer;


    if( error ) {
        printf( "Error reading from file %s\n", inArgs[1] );
        }
    else {
        unsigned char *rawDigest = new unsigned char[ SHA1_DIGEST_LENGTH ];
        
        SHA1_Final( rawDigest, &shaContext );
        
        // else hash is correct
        char *digestHexString = hexEncode( rawDigest, SHA1_DIGEST_LENGTH );
        
        printf( "%s  %s\n", digestHexString, inArgs[1] );

        delete [] rawDigest;
        delete [] digestHexString;
        }
    
    return 0;
    }
Пример #16
0
int dec(char *sopath,char *filename)
{
	//printf("you are in the enc program\n");
        SHA_CTX md;
	DES_key_schedule schedule1;
	DES_key_schedule schedule2;
	DES_key_schedule schedule3;
        FILE *fp;
	char DES_output[9],DES_input[9];
        unsigned char buffer[10];
	char ch;
        unsigned char digest[20],file_digest[20];
        int count,i,len_of_pass,verify=0,n,last_byte_size,to_read_upto,count_buf_size,temp_count;
	unsigned char random_bits1[20],random_bits2[20],DES_key1[8],DES_key2[8],DES_key3[8],IV[8];
	char *buf,*buff;
	

	if(RAND_bytes(random_bits1,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
	if(RAND_bytes(random_bits2,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
/**************************************
COMPUTE SHA1 OF FILE
**************************************/

        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"(%s file does not exist)\n",filename);
                exit(1);
        }
	count=0;
	while(fread(&ch,1,1,fp))
{
	if(count==0)
	{
	if(ch!='H')
	{
	fprintf(stderr,"(%s is not generated  by the enc command)\n",filename);
	exit(1);	
	}
	}
	if(count==1)
	{
	if(ch!='W')
	{
	fprintf(stderr,"(%s is not generated by the enc command)\n",filename);
	}
	}
	if(count==2)
	{
	if(ch!='4')
	{
	fprintf(stderr,"(%s is not generated by the enc command)\n",filename);
	}
	}
        count++;
}
	fclose(fp);
        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"(%s is not generated  by enc command)\n",filename);
                exit(1);
        }
	

        SHA1_Init(&md);
        while((count=fread(&buffer,1,10,fp)))
        {
                SHA1_Update(&md,buffer,count);
        }
        SHA1_Final(file_digest,&md);

/*        for(i=0;i<20;i++)
        {
                printf("%02x",file_digest[i]);
        }*/

/**************************************
ASK FOR PASSWORD FOR DES
**************************************/
buf=(char *)malloc(4096*sizeof(char));
buff=(char *)malloc(4096*sizeof(char));
des_read_pw(buf,buff,4096,"Enter passphrase for DES decryption: ",verify);

//printf("buff=%s",buf);
//printf("buff2=%s\n",buff);
len_of_pass=strlen(buf);
//printf("len_of_pass=%d\n",len_of_pass);

/**************************************
GENERATE SHA1 OF THE PASSWORD
**************************************/

	SHA1_Init(&md);

	//free(&md);
	//SHA1_Update(&md,"yesnomaybe",10);
	SHA1_Update(&md,buf,strlen(buf));
	SHA1_Final(digest,&md);

	//printf("The SHA1 of password is\n");
        for(i=0;i<20;i++)
        {
                //printf("%02x",digest[i]);
        }

        //printf("\n");
	

/*******************************************
COMPUTE SHA1 OF X AND RANDOM BITS(RB1) 1
*******************************************/
/*	SHA1_Init(&md);
	SHA1_Update(&md,digest,20);
	SHA1_Update(&md,HW4_random_bits_1,20);
	SHA1_Final(X_RB1,&md);
	for(i=0;i<20;i++)
	{
		//printf("%02x",X_RB1[i]);
	}
	//printf("\n");*/

/******************************************
COMPUTE SHA1 OF RB1(Y) AND RANDOM BITS 2(RB2)
******************************************/
/*	SHA1_Init(&md);
        SHA1_Update(&md,X_RB1,20);
        SHA1_Update(&md,HW4_random_bits_2,20);
        SHA1_Final(X_RB2,&md);
        for(i=0;i<20;i++)
        {
                //printf("%02x",X_RB2[i]);
        }
        //printf("\n");*/

/***************************************
COMPUTER IV AND 3 DES KEYS
***************************************/
//	SC_3des_key_gen(NULL,digest,IV,DES_key1,DES_key2,DES_key3);

	SmartcardState pss=(SmartcardState)NULL;
void *handle=NULL;
//void *vp =NULL;
SC_Init_Func *pfn_init=NULL;
SC_Cleanup_Func *pfn_cleanup=NULL;
SC_GetSignatureSize_Func *pfn_getsigsize=NULL;
SC_3DesKeyGen_Func *pfn_sc_dec=NULL;

handle = dlopen(sopath, RTLD_NOW|RTLD_GLOBAL);
if (handle==NULL)
{
//fprintf(stderr, "%s\n",sopath);
fprintf(stderr, "%s\n",
dlerror());
fprintf(stderr,"dlopen() failed\n");
exit(1);
}
pfn_init = (SC_Init_Func*)dlsym(handle,"SC_init");


pfn_cleanup = (SC_Cleanup_Func*)dlsym(handle,"SC_cleanup");


pfn_getsigsize = (SC_GetSignatureSize_Func*)dlsym(handle,"SC_get_signature_size");

pfn_sc_dec = (SC_3DesKeyGen_Func *)dlsym(handle,"SC_3des_key_gen");

if(pfn_init==NULL || pfn_cleanup==NULL || pfn_getsigsize==NULL || pfn_sc_dec==NULL)
{
fprintf(stderr,"(cannot find smartcard functions in this library)\n");
exit(1);
}


pss = (pfn_init)();
//printf("sig size is %d\n", (pfn_getsigsize)(pss));
//int sz=(pfn_getsigsize)(pss);

(pfn_sc_dec) (pss,digest,IV,DES_key1,DES_key2,DES_key3);

(pfn_cleanup)(pss);
dlclose(handle);


/*	for(i=0;i<8;i++)
	IV[i]=X_RB1[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key1[j]=X_RB1[i];
	for(i=0;i<8;i++)
	DES_key2[i]=X_RB2[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key3[j]=X_RB2[i];
	printf("IV=");
	for(i=0;i<8;i++)
	printf("%02x",IV[i]);
	printf("\nDES KEY 1=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key1[i]);
	printf("\nDES key 2=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key2[i]);
	printf("\nDES key 3=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key3[i]);
	printf("\n");*/


	
	
	DES_set_odd_parity((DES_cblock *)DES_key1);
	DES_set_odd_parity((DES_cblock *)DES_key2);
	DES_set_odd_parity((DES_cblock *)DES_key3);
	
	DES_key_sched((DES_cblock *)DES_key1,&schedule1);
	DES_set_key((DES_cblock *)DES_key1,&schedule1); 

        DES_key_sched((DES_cblock *)DES_key2,&schedule2);
        DES_set_key((DES_cblock *)DES_key2,&schedule2);

        DES_key_sched((DES_cblock *)DES_key3,&schedule3);
        DES_set_key((DES_cblock *)DES_key3,&schedule3);

/******************************************
READ FILE 8 BYTES AT A TIME AND ENCRYPT IT
******************************************/

	if((fp=fopen(filename,"rb"))==NULL)
	{
		fprintf(stderr,"{input file %s does not exist}\n",filename);
		exit(1);
	}
	i=0;
	while((count=fread(&ch,1,1,fp)))
	{
	i++;
	if(i==4)
	{
	last_byte_size=(int)ch;
	}
	}//while ends
	fclose(fp);
//	printf("last_bytes_size=%d",last_byte_size);
//	printf("\ntotal count=%d\n",i);
	to_read_upto=i-20;
//	printf("to read upto=%d\n",to_read_upto);
        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"{input file %s does not exist}\n",filename);
                exit(1);
        }
	n=0;count_buf_size=0;i=0;temp_count=0;
	for(i=0;i<4;i++)
	fread(&ch,1,1,fp);
	n=4;

	while(!feof(fp))
	{
	if(n==(to_read_upto-8))
	{
	  //	printf("\nlast byte reading\n");
		for(i=0;i<8;i++)
		DES_input[i]=fgetc(fp);
		DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
		
		for(i=0;i<last_byte_size;i++)
		printf("%c",DES_output[i]);	
		exit(1);
	}	
	for(i=0;i<8;i++)
	{
		if(n==(to_read_upto+1))
		exit(1);
	n++;
	DES_input[i]=fgetc(fp);
	}
	DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
	for(i=0;i<8;i++)
	printf("%c",DES_output[i]);
	}//while feof ends
		
	
/*	while((count=fread(&ch,1,1,fp)))
	{
//		printf("%c",ch);
		n++;
		if(n>4)//skip first four bytes of encrypted file
		{
		if(n==to_read_upto+1)
		break;
			
		DES_input[count_buf_size]=ch;	
		printf("%c",DES_input[count_buf_size]);
		
	
		count_buf_size++;
		if(count_buf_size==7)
		{	
			//for(i=0;i<8;i++)
			//printf("%c",DES_input[i]);
			temp_count++;
			DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
			if(n==to_read_upto-7)
			{
//			printf("in other loop\n");
//			for(i=0;i<last_byte_size;i++)
//			printf("%c",DES_output[i]);
			}
			else
			{
//			for(i=0;i<8;i++)
//			printf("%c",DES_output[i]);
			count_buf_size=0;
			}
		}
		}//if count >4 ends
	}	
//	printf("count=%d\n",temp_count);
//	printf("loop count=%d\n",n);
	for(i=0;i<20;i++)
	printf("%c",file_digest[i]);
	//printf("%s\n",file_digest);*/
		

	return 1;


}
Пример #17
0
static int send_memory_buffer(int sock, size_t bytes_to_send,
                              unsigned char digest[SHA_DIGEST_LENGTH])
{
        char sendbuf[SENDBUF_SIZE];
        ssize_t n = 0;
        size_t total_bytes = 0;
        SHA_CTX ctx;
        int ret = EXIT_FAILURE;

        SHA1_Init(&ctx);

        printf("Sending %zu bytes of randomized data\n", bytes_to_send);

        while (!should_exit) {
                size_t count = 0, i;
                size_t bufsize = 
                        bytes_to_send < SENDBUF_SIZE ? 
                        bytes_to_send : SENDBUF_SIZE;

                if (bytes_to_send == 0) {
                        ret = EXIT_SUCCESS;
                        break;
                }
                for (i = 0; i < bufsize; i += sizeof(long)) {
                        long *l = (long *)&sendbuf[i];
                        *l = random();
                }
        
                SHA1_Update(&ctx, sendbuf, bufsize);

                while (!should_exit && count < bufsize) {
            
                        n = send_sv(sock, sendbuf + count, 
                                    bufsize - count, 0);
            
                        if (n < 0) {
                                if (errno == EAGAIN) {
                                        fprintf(stderr, 
                                                "client: EAGAIN\n");
                                        continue;
                                } else if (errno == EPIPE) {
                                        printf("client closed abruptly\n");
                                        should_exit = 1;
                                        ret = EXIT_SUCCESS;
                                        break;
                                }
                
                                fprintf(stderr, "client: error: %d - %s\n",
                                        errno, strerror_sv(errno));

                                should_exit = 1;
                                break;
                        }
             
                        count += n;
                        total_bytes += n;
                        /*
                        printf("Sent %zd bytes, total %zu bytes\n", 
                               n, total_bytes);
                        */
                }
                bytes_to_send -= count;
        }

        SHA1_Final(digest, &ctx);
    
        printf("Sent total %zu bytes\n", total_bytes);

        return ret;
}
Пример #18
0
/**
 * Test the SHA1_Update() function
 * @return int number of tests failed in this function
 */
int sha1_test_SHA1_Update(void)
{
	unsigned char inputdata_1[65] =
	{
	    0x7C, 0x53, 0x50, 0x53, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
	    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
	    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
	    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 
	    0x00, 
	};
	unsigned char inputdata_2[28] =
	{
	    0x77, 0x68, 0x61, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x79, 0x61, 0x20, 0x77, 0x61, 0x6E, 0x74, 0x20, 
	    0x66, 0x6F, 0x72, 0x20, 0x6E, 0x6F, 0x74, 0x68, 0x69, 0x6E, 0x67, 0x3F, 
	};
	unsigned char context_before_update_1[94] =
	{
	    0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 
	    0xF0, 0xE1, 0xD2, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0x5A, 0x8B, 
	    0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xC1, 0xCD, 0xC6, 0x21, 0x5A, 0xCD, 0x4A, 
	    0xDC, 0xC1, 0x9D, 0xB7, 0xB4, 0x8E, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	};
	unsigned char context_after_update_1[94] =
	{
	    0xA7, 0x8E, 0x4D, 0x62, 0x03, 0x18, 0x2B, 0x3F, 0xE4, 0xB9, 0x54, 0x95, 0xF5, 0x65, 0xC0, 0x28, 
	    0x8E, 0xB9, 0xFC, 0xA9, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x30, 0x5A, 0x8B, 
	    0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0xC1, 0xCD, 0xC6, 0x21, 0x5A, 0xCD, 0x4A, 
	    0xDC, 0xC1, 0x9D, 0xB7, 0xB4, 0x8E, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	};
	unsigned char context_after_update_2[94] =
	{
	    0xA7, 0x8E, 0x4D, 0x62, 0x03, 0x18, 0x2B, 0x3F, 0xE4, 0xB9, 0x54, 0x95, 0xF5, 0x65, 0xC0, 0x28, 
	    0x8E, 0xB9, 0xFC, 0xA9, 0xE0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x61, 0x68, 0x77, 
	    0x20, 0x6F, 0x64, 0x20, 0x77, 0x20, 0x61, 0x79, 0x20, 0x74, 0x6E, 0x61, 0x20, 0x72, 0x6F, 0x66, 
	    0x68, 0x74, 0x6F, 0x6E, 0x3F, 0x67, 0x6E, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 
	};
	int local_error_count = 0;
	SHA_CTX context;

	memcpy(&context, context_before_update_1, sizeof(context_before_update_1));

	SHA1_Update(&context, inputdata_1, sizeof(inputdata_1) - 1);

	if(memcmp(&context, context_after_update_1, sizeof(context_after_update_1) - 1) != 0)
	{
		local_error_count++;
		IPSEC_LOG_TST("sha1_test_SHA1_Update", "FAILURE", ("SHA1_Update() failed")) ;
		printf("     INPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", inputdata_1, 0, sizeof(inputdata_1) - 1);
		printf("     OUTPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", (char*)&context, 0, sizeof(context));
		printf("     EXPECTED OUTPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", context_after_update_1, 0, sizeof(context_after_update_1));
	}

	memcpy(&context, context_after_update_1, sizeof(context_after_update_1));

	SHA1_Update(&context, inputdata_2, sizeof(inputdata_2));

	if(memcmp(&context, context_after_update_2, sizeof(context_after_update_2)) != 0)
	{
		local_error_count++;
		IPSEC_LOG_TST("sha1_test_SHA1_Update", "FAILURE", ("SHA1_Update() failed")) ;
		printf("     INPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", inputdata_2, 0, sizeof(inputdata_2));
		printf("     OUTPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", (char*)&context, 0, sizeof(context));
		printf("     EXPECTED OUTPUT:\n") ;
		IPSEC_DUMP_BUFFER("          ", context_after_update_2, 0, sizeof(context_after_update_2));
	}

	return local_error_count;
}
Пример #19
0
static bool
verifyTorrent (tr_torrent * tor, bool * stopFlag)
{
  time_t end;
  SHA_CTX sha;
  int fd = -1;
  int64_t filePos = 0;
  bool changed = 0;
  bool hadPiece = 0;
  time_t lastSleptAt = 0;
  uint32_t piecePos = 0;
  tr_file_index_t fileIndex = 0;
  tr_file_index_t prevFileIndex = !fileIndex;
  tr_piece_index_t pieceIndex = 0;
  const time_t begin = tr_time ();
  const size_t buflen = 1024 * 128; /* 128 KiB buffer */
  uint8_t * buffer = tr_valloc (buflen);

  SHA1_Init (&sha);

  tr_logAddTorDbg (tor, "%s", "verifying torrent...");
  tr_torrentSetChecked (tor, 0);
  while (!*stopFlag && (pieceIndex < tor->info.pieceCount))
    {
      uint32_t leftInPiece;
      uint32_t bytesThisPass;
      uint64_t leftInFile;
      const tr_file * file = &tor->info.files[fileIndex];

      /* if we're starting a new piece... */
      if (piecePos == 0)
        hadPiece = tr_cpPieceIsComplete (&tor->completion, pieceIndex);

      /* if we're starting a new file... */
      if (!filePos && (fd<0) && (fileIndex!=prevFileIndex))
        {
          char * filename = tr_torrentFindFile (tor, fileIndex);
          fd = filename == NULL ? -1 : tr_open_file_for_scanning (filename);
          tr_free (filename);
          prevFileIndex = fileIndex;
        }

      /* figure out how much we can read this pass */
      leftInPiece = tr_torPieceCountBytes (tor, pieceIndex) - piecePos;
      leftInFile = file->length - filePos;
      bytesThisPass = MIN (leftInFile, leftInPiece);
      bytesThisPass = MIN (bytesThisPass, buflen);

      /* read a bit */
      if (fd >= 0)
        {
          const ssize_t numRead = tr_pread (fd, buffer, bytesThisPass, filePos);
          if (numRead > 0)
            {
              bytesThisPass = (uint32_t)numRead;
              SHA1_Update (&sha, buffer, bytesThisPass);
#if defined HAVE_POSIX_FADVISE && defined POSIX_FADV_DONTNEED
              posix_fadvise (fd, filePos, bytesThisPass, POSIX_FADV_DONTNEED);
#endif
            }
        }

      /* move our offsets */
      leftInPiece -= bytesThisPass;
      leftInFile -= bytesThisPass;
      piecePos += bytesThisPass;
      filePos += bytesThisPass;

      /* if we're finishing a piece... */
      if (leftInPiece == 0)
        {
          time_t now;
          bool hasPiece;
          uint8_t hash[SHA_DIGEST_LENGTH];

          SHA1_Final (hash, &sha);
          hasPiece = !memcmp (hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH);

          if (hasPiece || hadPiece)
            {
              tr_torrentSetHasPiece (tor, pieceIndex, hasPiece);
              changed |= hasPiece != hadPiece;
            }

          tr_torrentSetPieceChecked (tor, pieceIndex);
          now = tr_time ();
          tor->anyDate = now;

          /* sleeping even just a few msec per second goes a long
           * way towards reducing IO load... */
          if (lastSleptAt != now)
            {
              lastSleptAt = now;
              tr_wait_msec (MSEC_TO_SLEEP_PER_SECOND_DURING_VERIFY);
            }

          SHA1_Init (&sha);
          pieceIndex++;
          piecePos = 0;
        }

      /* if we're finishing a file... */
      if (leftInFile == 0)
        {
          if (fd >= 0)
            {
              tr_close_file (fd);
              fd = -1;
            }
          fileIndex++;
          filePos = 0;
        }
    }

  /* cleanup */
  if (fd >= 0)
    tr_close_file (fd);
  free (buffer);

  /* stopwatch */
  end = tr_time ();
  tr_logAddTorDbg (tor, "Verification is done. It took %d seconds to verify %"PRIu64" bytes (%"PRIu64" bytes per second)",
             (int)(end-begin), tor->info.totalSize,
             (uint64_t)(tor->info.totalSize/ (1+ (end-begin))));

  return changed;
}
Пример #20
0
static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data,
                            size_t count) {
  MD5_SHA1_CTX *ctx = md_ctx->md_data;
  CHECK(MD5_Update(&ctx->md5, data, count) &&
        SHA1_Update(&ctx->sha1, data, count));
}
Пример #21
0
int main(int argc, char *argv[])
   {
   int ret;
   struct stat sbuf;
   unsigned char databuff[65535];  /* data read work buffer */
   unsigned char datahash[20];     /* hash of data file */
   unsigned char digest[20];
   SHA_CTX sha;
   FILE *datafile;
   const char *datafilename = NULL;
   FILE *sigfile;
   const char *sigfilename = NULL;
   FILE *keyfile;
   const char *kfilename = NULL;
   EVP_PKEY *pkey;
   RSA  *rsa;
   uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1;
   int plain;
   unsigned char padded[4096];
   unsigned char plainarray[4096];
   TPM_SIGN_INFO tsi;
   STACK_TPM_BUFFER(tsi_ser);
   STACK_TPM_BUFFER(signature);
   int i;
   
   for (i=1 ; i<argc ; i++) {
       if (!strcmp(argv[i], "-ss")) {
	   i++;
	   if (i < argc) {
	       if (!strcmp(argv[i], "info")) {
		   sigscheme = TPM_SS_RSASSAPKCS1v15_INFO;
	       }
	       else if (!strcmp(argv[i], "der")) {
		   sigscheme = TPM_SS_RSASSAPKCS1v15_DER;
	       }
	       else {
		   printf("Bad parameter for -ss\n");
		   printUsage();
	       }
	   }
	   else {
	       printf("Missing parameter for -ss\n");
	       printUsage();
	   }
       }
       else if (strcmp(argv[i],"-if") == 0) {
	   i++;
	   if (i < argc) {
	       datafilename = argv[i];
	   }
	   else {
	       printf("-if option needs a value\n");
	       printUsage();
	       exit(2);
	   }
       }
       else if (strcmp(argv[i],"-is") == 0) {
	   i++;
	   if (i < argc) {
	       sigfilename = argv[i];
	   }
	   else {
	       printf("-is option needs a value\n");
	       printUsage();
	   }
       }
       else if (strcmp(argv[i],"-ik") == 0) {
	   i++;
	   if (i < argc) {
	       kfilename = argv[i];
	   }
	   else {
	       printf("-ik option needs a value\n");
	       printUsage();
	       exit(2);
	   }
       }
       else if (!strcmp(argv[i], "-h")) {
	   printUsage();
       }
       else if (!strcmp(argv[i], "-v")) {
	   TPM_setlog(1);
       }
       else {
	   printf("\n%s is not a valid option\n", argv[i]);
	   printUsage();
       }
   }
   if ((datafilename == NULL) ||
       (sigfilename == NULL) ||
       (kfilename == NULL)) {
       printf("Missing parameter\n");
       printUsage();
   }
   /*
   ** read and hash the data file
   */
   datafile = fopen(datafilename,"rb");
   if (datafile == NULL)
      {
	  printf("Unable to open data file '%s'\n",datafilename);
	  exit(2);
      }
   SHA1_Init(&sha);
   for (;;)
      {
      ret = fread(databuff,1,sizeof databuff,datafile);
      if (ret < 0)
         {
	     printf("I/O Error while reading data file '%s'\n",datafilename);
	     exit(3);
         }
      SHA1_Update(&sha,databuff,ret);
      if (ret < (int)sizeof(databuff)) break;
      }
   fclose(datafile);
   SHA1_Final(datahash,&sha);
   /*
   ** get size of signature file
   */
   stat(sigfilename,&sbuf);
   signature.used = (int)sbuf.st_size;
   sigfile = fopen(sigfilename,"rb");
   if (sigfile == NULL)
      {
	  printf("Unable to open signature file '%s'\n",sigfilename);
	  exit(4);
      }
   /*
   ** read the signature file
   */
   ret = fread(signature.buffer,1,signature.used,sigfile);
   if (ret != (int)signature.used)
      {
	  printf("I/O Error while reading signature file '%s'\n",sigfilename);
	  exit(5);
      }
   fclose(sigfile);
   /*
   ** read the key file
   */
   keyfile = fopen(kfilename,"rb");
   if (keyfile == NULL)
      {
	  printf("Unable to open public key file '%s'\n",kfilename);
	  exit(6);
      }
   pkey = PEM_read_PUBKEY(keyfile,NULL,NULL,NULL);
   if (pkey == NULL)
      {
	  printf("I/O Error while reading public key file '%s'\n",kfilename);
	  exit(7);
      }
   rsa = EVP_PKEY_get1_RSA(pkey);
   if (rsa == NULL)
      {
      printf("Error while converting public key \n");
      exit(8);
      }

   switch (sigscheme) {
   default:
   case TPM_SS_RSASSAPKCS1v15_SHA1:
       ret = RSA_verify(NID_sha1,datahash,20,
                        signature.buffer,signature.used,
                        rsa);
       if (ret != 1) {
          printf("Verification Failed\n");
          exit(100);
       }
       break;
   case TPM_SS_RSASSAPKCS1v15_DER:
       plain = RSA_public_decrypt(signature.used, signature.buffer,
                                  plainarray, rsa, RSA_NO_PADDING);
       if (plain == -1) {
          printf("Verification (DER) had an error\n");
          exit(100);
       }
       ret = RSA_padding_add_PKCS1_type_1(padded,plain,datahash,sizeof(datahash));
       if (ret != 1) {
          printf("Could not add the padding.\n");
          exit(100);
       }
       if (memcmp(padded, plainarray, plain) != 0) {
          printf("Verfication (DER) failed.\n");
          exit(100);
       }
       break;
   case TPM_SS_RSASSAPKCS1v15_INFO:
       // the nonce is the digest of the hashed data!!
       TSS_sha1(datahash, 20, digest);
       tsi.tag = TPM_TAG_SIGNINFO;
       memcpy(tsi.fixed,"SIGN",4);
       tsi.data.size = TPM_HASH_SIZE;
       tsi.data.buffer = datahash;
       memcpy(tsi.replay, digest, TPM_HASH_SIZE);
       
       /* need to calcualte the digest of the TPM_SIGN_INFO structure */
       ret = TPM_WriteSignInfo(&tsi_ser, &tsi);
       if ((ret & ERR_MASK)) {
           printf("Could not serialize TPM_SIGN_INFO structure.\n");
           exit(100);
       }
       ret = TPM_ValidateSignature(sigscheme,
                                   &tsi_ser,
                                   &signature,
                                   rsa);
       if (ret != 0) {
           printf("Verification (INFO) failed.\n");
           exit(-1);
       }
       break;
   }
   RSA_free(rsa);
   EVP_PKEY_free(pkey);
   exit(0);
   }
Пример #22
0
static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
  CHECK(SHA1_Update(ctx->md_data, data, count));
}
Пример #23
0
SECStatus
ssl3_KeyAndMacDeriveBypass(
    ssl3CipherSpec *      pwSpec,
    const unsigned char * cr,
    const unsigned char * sr,
    PRBool                isTLS,
    PRBool                isExport)
{
    const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def;
    unsigned char * key_block    = pwSpec->key_block;
    unsigned char * key_block2   = NULL;
    unsigned int    block_bytes  = 0;
    unsigned int    block_needed = 0;
    unsigned int    i;
    unsigned int    keySize;            /* actual    size of cipher keys */
    unsigned int    effKeySize;		/* effective size of cipher keys */
    unsigned int    macSize;		/* size of MAC secret */
    unsigned int    IVSize;		/* size of IV */
    SECStatus       rv    = SECFailure;
    SECStatus       status = SECSuccess;
    PRBool          isFIPS = PR_FALSE;

    SECItem         srcr;
    SECItem         crsr;

    unsigned char     srcrdata[SSL3_RANDOM_LENGTH * 2];
    unsigned char     crsrdata[SSL3_RANDOM_LENGTH * 2];
    PRUint64          md5buf[22];
    PRUint64          shabuf[40];

#define md5Ctx ((MD5Context *)md5buf)
#define shaCtx ((SHA1Context *)shabuf)

    static const SECItem zed  = { siBuffer, NULL, 0 };

    if (pwSpec->msItem.data == NULL ||
        pwSpec->msItem.len  != SSL3_MASTER_SECRET_LENGTH) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return rv;
    }

    PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, 
                                           pwSpec->msItem.len));

    /* figure out how much is needed */
    macSize    = pwSpec->mac_size;
    keySize    = cipher_def->key_size;
    effKeySize = cipher_def->secret_key_size;
    IVSize     = cipher_def->iv_size;
    if (keySize == 0) {
	effKeySize = IVSize = 0; /* only MACing */
    }
    block_needed = 2 * (macSize + effKeySize + ((!isExport) * IVSize));

    /*
     * clear out our returned keys so we can recover on failure
     */
    pwSpec->client.write_key_item     = zed;
    pwSpec->client.write_mac_key_item = zed;
    pwSpec->server.write_key_item     = zed;
    pwSpec->server.write_mac_key_item = zed;

    /* initialize the server random, client random block */
    srcr.type   = siBuffer;
    srcr.data   = srcrdata;
    srcr.len    = sizeof srcrdata;
    PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH);
    PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH);

    /* initialize the client random, server random block */
    crsr.type   = siBuffer;
    crsr.data   = crsrdata;
    crsr.len    = sizeof crsrdata;
    PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH);
    PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH);
    PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len));

    /*
     * generate the key material:
     */
    if (isTLS) {
	SECItem       keyblk;

	keyblk.type = siBuffer;
	keyblk.data = key_block;
	keyblk.len  = block_needed;

	status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk,
			  isFIPS);
	if (status != SECSuccess) {
	    goto key_and_mac_derive_fail;
	}
	block_bytes = keyblk.len;
    } else {
	/* key_block = 
	 *     MD5(master_secret + SHA('A' + master_secret + 
	 *                      ServerHello.random + ClientHello.random)) +
	 *     MD5(master_secret + SHA('BB' + master_secret + 
	 *                      ServerHello.random + ClientHello.random)) +
	 *     MD5(master_secret + SHA('CCC' + master_secret + 
	 *                      ServerHello.random + ClientHello.random)) +
	 *     [...];
	 */
	unsigned int made = 0;
	for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) {
	    unsigned int    outLen;
	    unsigned char   sha_out[SHA1_LENGTH];

	    SHA1_Begin(shaCtx);
	    SHA1_Update(shaCtx, (unsigned char*)(mixers[i]), i+1);
	    SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len);
	    SHA1_Update(shaCtx, srcr.data, srcr.len);
	    SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH);
	    PORT_Assert(outLen == SHA1_LENGTH);

	    MD5_Begin(md5Ctx);
	    MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len);
	    MD5_Update(md5Ctx, sha_out, outLen);
	    MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH);
	    PORT_Assert(outLen == MD5_LENGTH);
	    made += MD5_LENGTH;
	}
	block_bytes = made;
    }
    PORT_Assert(block_bytes >= block_needed);
    PORT_Assert(block_bytes <= sizeof pwSpec->key_block);
    PRINT_BUF(100, (NULL, "key block", key_block, block_bytes));

    /*
     * Put the key material where it goes.
     */
    key_block2 = key_block + block_bytes;
    i = 0;			/* now shows how much consumed */

    /* 
     * The key_block is partitioned as follows:
     * client_write_MAC_secret[CipherSpec.hash_size]
     */
    buildSSLKey(&key_block[i],macSize, &pwSpec->client.write_mac_key_item, \
                "Client Write MAC Secret");
    i += macSize;

    /* 
     * server_write_MAC_secret[CipherSpec.hash_size]
     */
    buildSSLKey(&key_block[i],macSize, &pwSpec->server.write_mac_key_item, \
                "Server Write MAC Secret");
    i += macSize;

    if (!keySize) {
	/* only MACing */
	buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, \
	            "Client Write Key (MAC only)");
	buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, \
	            "Server Write Key (MAC only)");
	buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, \
	            "Client Write IV (MAC only)");
	buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, \
	            "Server Write IV (MAC only)");
    } else if (!isExport) {
	/* 
	** Generate Domestic write keys and IVs.
	** client_write_key[CipherSpec.key_material]
	*/
	buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, \
	            "Domestic Client Write Key");
	i += keySize;

	/* 
	** server_write_key[CipherSpec.key_material]
	*/
	buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \
	            "Domestic Server Write Key");
	i += keySize;

	if (IVSize > 0) {
	    /* 
	    ** client_write_IV[CipherSpec.IV_size]
	    */
	    buildSSLKey(&key_block[i], IVSize, &pwSpec->client.write_iv_item, \
	                "Domestic Client Write IV");
	    i += IVSize;

	    /* 
	    ** server_write_IV[CipherSpec.IV_size]
	    */
	    buildSSLKey(&key_block[i], IVSize, &pwSpec->server.write_iv_item, \
	                "Domestic Server Write IV");
	    i += IVSize;
	}
	PORT_Assert(i <= block_bytes);

    } else if (!isTLS) { 
	/*
	** Generate SSL3 Export write keys and IVs.
	*/
	unsigned int    outLen;

	/*
	** client_write_key[CipherSpec.key_material]
	** final_client_write_key = MD5(client_write_key +
	**                   ClientHello.random + ServerHello.random);
	*/
	MD5_Begin(md5Ctx);
	MD5_Update(md5Ctx, &key_block[i], effKeySize);
	MD5_Update(md5Ctx, crsr.data, crsr.len);
	MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
	i += effKeySize;
	buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \
	            "SSL3 Export Client Write Key");
	key_block2 += keySize;

	/*
	** server_write_key[CipherSpec.key_material]
	** final_server_write_key = MD5(server_write_key +
	**                    ServerHello.random + ClientHello.random);
	*/
	MD5_Begin(md5Ctx);
	MD5_Update(md5Ctx, &key_block[i], effKeySize);
	MD5_Update(md5Ctx, srcr.data, srcr.len);
	MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
	i += effKeySize;
	buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \
	            "SSL3 Export Server Write Key");
	key_block2 += keySize;
	PORT_Assert(i <= block_bytes);

	if (IVSize) {
	    /*
	    ** client_write_IV = 
	    **	MD5(ClientHello.random + ServerHello.random);
	    */
	    MD5_Begin(md5Ctx);
	    MD5_Update(md5Ctx, crsr.data, crsr.len);
	    MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
	    buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, \
	                "SSL3 Export Client Write IV");
	    key_block2 += IVSize;

	    /*
	    ** server_write_IV = 
	    **	MD5(ServerHello.random + ClientHello.random);
	    */
	    MD5_Begin(md5Ctx);
	    MD5_Update(md5Ctx, srcr.data, srcr.len);
	    MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH);
	    buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, \
	                "SSL3 Export Server Write IV");
	    key_block2 += IVSize;
	}

	PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
    } else {
	/*
	** Generate TLS Export write keys and IVs.
	*/
	SECItem       secret ;
	SECItem       keyblk ;

	secret.type = siBuffer;
	keyblk.type = siBuffer;
	/*
	** client_write_key[CipherSpec.key_material]
	** final_client_write_key = PRF(client_write_key, 
	**                              "client write key",
	**                              client_random + server_random);
	*/
	secret.data = &key_block[i];
	secret.len  = effKeySize;
	i          += effKeySize;
	keyblk.data = key_block2;
	keyblk.len  = keySize;
	status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS);
	if (status != SECSuccess) {
	    goto key_and_mac_derive_fail;
	}
	buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \
	            "TLS Export Client Write Key");
	key_block2 += keySize;

	/*
	** server_write_key[CipherSpec.key_material]
	** final_server_write_key = PRF(server_write_key,
	**                              "server write key",
	**                              client_random + server_random);
	*/
	secret.data = &key_block[i];
	secret.len  = effKeySize;
	i          += effKeySize;
	keyblk.data = key_block2;
	keyblk.len  = keySize;
	status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS);
	if (status != SECSuccess) {
	    goto key_and_mac_derive_fail;
	}
	buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \
	            "TLS Export Server Write Key");
	key_block2 += keySize;

	/*
	** iv_block = PRF("", "IV block", client_random + server_random);
	** client_write_IV[SecurityParameters.IV_size]
	** server_write_IV[SecurityParameters.IV_size]
	*/
	if (IVSize) {
	    secret.data = NULL;
	    secret.len  = 0;
	    keyblk.data = key_block2;
	    keyblk.len  = 2 * IVSize;
	    status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS);
	    if (status != SECSuccess) {
		goto key_and_mac_derive_fail;
	    }
	    buildSSLKey(key_block2,          IVSize, \
	                &pwSpec->client.write_iv_item, \
			"TLS Export Client Write IV");
	    buildSSLKey(key_block2 + IVSize, IVSize, \
	                &pwSpec->server.write_iv_item, \
			"TLS Export Server Write IV");
	    key_block2 += 2 * IVSize;
	}
	PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block);
    }
    rv = SECSuccess;

key_and_mac_derive_fail:

    MD5_DestroyContext(md5Ctx, PR_FALSE);
    SHA1_DestroyContext(shaCtx, PR_FALSE);

    if (rv != SECSuccess) {
	PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
    }

    return rv;
}
Пример #24
0
void
trap_init(const char *ver)
{
  int r;
  uint8_t digest[20];
  struct sigaction sa, old;
  char path[256];

  SHA_CTX binsum;
  int fd;

  r = readlink("/proc/self/exe", self, sizeof(self) - 1);
  if(r == -1)
    self[0] = 0;
  else
    self[r] = 0;
  
  if((fd = open("/proc/self/exe", O_RDONLY)) != -1) {
    struct stat st;
    if(!fstat(fd, &st)) {
      char *m = malloc(st.st_size);
      if(m != NULL) {
	if(read(fd, m, st.st_size) == st.st_size) {
	  SHA1_Init(&binsum);
	  SHA1_Update(&binsum, (void *)m, st.st_size);
	  SHA1_Final(digest, &binsum);
	}
	free(m);
      }
    }
    close(fd);
  }
  
  snprintf(line1, sizeof(line1),
	   "PRG: %s (%s) "
	   "[%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
	   "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x] "
	   "CWD: %s ", ver, tvheadend_version,
	   digest[0],
	   digest[1],
	   digest[2],
	   digest[3],
	   digest[4],
	   digest[5],
	   digest[6],
	   digest[7],
	   digest[8],
	   digest[9],
	   digest[10],
	   digest[11],
	   digest[12],
	   digest[13],
	   digest[14],
	   digest[15],
	   digest[16],
	   digest[17],
	   digest[18],
	   digest[19],
	   getcwd(path, sizeof(path)));

  memcpy(tvh_binshasum, digest, 20);

  dl_iterate_phdr(callback, NULL);
  

  memset(&sa, 0, sizeof(sa));

  sigset_t m;
  sigemptyset(&m);
  sigaddset(&m, SIGSEGV);
  sigaddset(&m, SIGBUS);
  sigaddset(&m, SIGILL);
  sigaddset(&m, SIGABRT);
  sigaddset(&m, SIGFPE);

  sa.sa_sigaction = traphandler;
  sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
  sigaction(SIGSEGV, &sa, &old);
  sigaction(SIGBUS,  &sa, &old);
  sigaction(SIGILL,  &sa, &old);
  sigaction(SIGABRT, &sa, &old);
  sigaction(SIGFPE,  &sa, &old);

  sigprocmask(SIG_UNBLOCK, &m, NULL);
}
Пример #25
0
/**
 * Construct a new x509 object.
 * @return 0 if ok. < 0 if there was a problem.
 */
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
    int begin_tbs, end_tbs;
    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
    X509_CTX *x509_ctx;
    BI_CTX *bi_ctx;

    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
    x509_ctx = *ctx;

    /* get the certificate size */
    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    begin_tbs = offset;         /* start of the tbs */
    end_tbs = begin_tbs;        /* work out the end of the tbs */
    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
    {
        if (asn1_version(cert, &offset, x509_ctx))
            goto end_cert;
    }

    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* make sure the signature is ok */
    if (asn1_signature_type(cert, &offset, x509_ctx))
    {
        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
        goto end_cert;
    }

    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
            asn1_validity(cert, &offset, x509_ctx) ||
            asn1_name(cert, &offset, x509_ctx->cert_dn) ||
            asn1_public_key(cert, &offset, x509_ctx))
    {
        goto end_cert;
    }

    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;

#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
    if (x509_ctx->sig_type == SIG_TYPE_MD5)
    {
        MD5_CTX md5_ctx;
        uint8_t md5_dgst[MD5_SIZE];
        MD5_Init(&md5_ctx);
        MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD5_Final(md5_dgst, &md5_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
    {
        SHA1_CTX sha_ctx;
        uint8_t sha_dgst[SHA1_SIZE];
        SHA1_Init(&sha_ctx);
        SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        SHA1_Final(sha_dgst, &sha_ctx);
        x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_MD2)
    {
        MD2_CTX md2_ctx;
        uint8_t md2_dgst[MD2_SIZE];
        MD2_Init(&md2_ctx);
        MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD2_Final(md2_dgst, &md2_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
    }

    if (cert[offset] == ASN1_V3_DATA)
    {
        int suboffset;

        ++offset;
        get_asn1_length(cert, &offset);

        if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
        {
            if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
            {
                int altlen;

                if ((altlen = asn1_next_obj(cert, 
                                            &suboffset, ASN1_SEQUENCE)) > 0)
                {
                    int endalt = suboffset + altlen;
                    int totalnames = 0;

                    while (suboffset < endalt)
                    {
                        int type = cert[suboffset++];
                        int dnslen = get_asn1_length(cert, &suboffset);

                        if (type == ASN1_CONTEXT_DNSNAME)
                        {
                            x509_ctx->subject_alt_dnsnames = (char**)
                                    realloc(x509_ctx->subject_alt_dnsnames, 
                                       (totalnames + 2) * sizeof(char*));
                            x509_ctx->subject_alt_dnsnames[totalnames] = 
                                    (char*)malloc(dnslen + 1);
                            x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
                            memcpy(x509_ctx->subject_alt_dnsnames[totalnames], 
                                    cert + suboffset, dnslen);
                            x509_ctx->subject_alt_dnsnames[
                                    totalnames][dnslen] = 0;
                            ++totalnames;
                        }

                        suboffset += dnslen;
                    }
                }
            }
        }
    }

    offset = end_tbs;   /* skip the rest of v3 data */
    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
            asn1_signature(cert, &offset, x509_ctx))
        goto end_cert;
#endif
    ret = X509_OK;
end_cert:
    if (len)
    {
        *len = cert_size;
    }

    if (ret)
    {
#ifdef CONFIG_SSL_FULL_MODE
        printf("Error: Invalid X509 ASN.1 file (%s)\n",
                        x509_display_error(ret));
#endif
        x509_free(x509_ctx);
        *ctx = NULL;
    }

    return ret;
}
Пример #26
0
void
ssl_sha1_update(SSL_SHA1 * sha1, uint8 * data, uint32 len)
{
	SHA1_Update(sha1, data, len);
}
Пример #27
0
void crypto_sha1_update(CryptoSha1 sha1, const BYTE* data, UINT32 length)
{
	SHA1_Update(&sha1->sha_ctx, data, length);
}
Пример #28
0
void crypto_sha1_update(CryptoSha1 sha1, uint8* data, uint32 length)
{
	SHA1_Update(&sha1->sha_ctx, data, length);
}
Пример #29
0
static int
radius_auth(struct radius_attrib **attriblist, chap_state *cstate)
{
	int ret;
	struct radius_attrib *recvattriblist;
	struct radius_attrib *attrib;
#ifdef CHAPMS
	int ms_chap2_success = 0;
#endif
#ifdef MPPE
	int mppe_send_key = 0, mppe_recv_key = 0, mppe_policy = 0, mppe_types = 0;
#endif

	if (nas_ip_address != -1) {
		if (!radius_add_attrib(
				attriblist, PW_VENDOR_NONE, PW_NAS_IP_ADDRESS,
				nas_ip_address, NULL, 0)) {
			return 0;
		}
	}
	else if (nas_identifier[0]) {
		if (!radius_add_attrib(
				attriblist, PW_VENDOR_NONE, PW_NAS_IDENTIFIER,
				0, nas_identifier, strlen(nas_identifier))) {
			return 0;
		}
	}

	if (nas_real_port_number != -1) {
		if (!radius_add_attrib(
				attriblist, PW_VENDOR_NONE, PW_NAS_PORT_ID,
				nas_real_port_number, NULL, 0)) {
			return 0;
		}
	}

	if (nas_port_type != -1) {
		if (!radius_add_attrib(
				attriblist, PW_VENDOR_NONE, PW_NAS_PORT_TYPE,
				nas_port_type, NULL, 0)) {
			return 0;
		}
	}

	if (!radius_add_attrib(
			attriblist, PW_VENDOR_NONE, PW_SERVICE_TYPE,
			PW_FRAMED_USER, NULL, 0)) {
		return 0;
	}

	if (!radius_add_attrib(
			attriblist, PW_VENDOR_NONE, PW_FRAMED_PROTOCOL,
			PW_PPP, NULL, 0)) {
		return 0;
	}

	if (ipcp_wantoptions[0].hisaddr) {
		if (!radius_add_attrib(
				attriblist, PW_VENDOR_NONE,
				PW_FRAMED_IP_ADDRESS,
				ntohl(ipcp_wantoptions[0].hisaddr), NULL, 0)) {
			return 0;
		}
	}

	recvattriblist = NULL;
	ret = radius_send_access_request(
			radius_server, radius_auth_port, radius_secret,
			*attriblist, &recvattriblist);
	if (ret < 0) {
		error("RADIUS: server failed");
		ret = 0;
	}
	else if (ret == PW_AUTHENTICATION_ACK) {
		ret = 1; /* Default to success unless an attribute makes us fail */
		for (attrib=recvattriblist; ret && attrib!=NULL; attrib=attrib->next) {
			if (attrib->vendor == PW_VENDOR_NONE) {
				switch (attrib->type) {
				case PW_SERVICE_TYPE:
					if (ntohl(attrib->u.value) != PW_FRAMED_USER) {
						error("RADIUS: service type '%d' is not framed", ntohl(attrib->u.value));
						ret = 0;
					}
					break;

				case PW_FRAMED_PROTOCOL:
					if (ntohl(attrib->u.value) != PW_PPP) {
						error("RADIUS: framed protocol '%d' is not ppp", ntohl(attrib->u.value));
						ret = 0;
					}
					break;

				case PW_FRAMED_IP_ADDRESS:
					if (attrib->u.value == htonl(0xffffffff)) {
						radius_allow_any_ip = 1;
					}
					else if (attrib->u.value == htonl(0xfffffffe)) {
						radius_allow_server_ip = 1;
					}
					else {
						radius_remote_ip_addr = attrib->u.value;
					}
					break;

				case PW_FRAMED_IP_NETMASK:
					if (attrib->u.value && attrib->u.value != 0xffffffff) {
						netmask = attrib->u.value;
					}
					break;

				case PW_FRAMED_COMPRESSION:
					if (ntohl(attrib->u.value) == PW_NONE) {
						ipcp_wantoptions[0].neg_vj = 0;
						ipcp_allowoptions[0].neg_vj = 0;
					}
					else if (ntohl(attrib->u.value) == PW_VAN_JACOBSEN_TCP_IP) {
						ipcp_wantoptions[0].neg_vj = 1;
						ipcp_allowoptions[0].neg_vj = 1;
					}
					break;

				case PW_REPLY_MESSAGE:
					strncpy(radius_reply_message,attrib->u.string,AUTH_STRING_LEN);
					radius_reply_message[AUTH_STRING_LEN] = 0;
					notice(radius_reply_message);
					break;

#if 0
				case PW_FRAMED_ROUTE:
					/* XXX: store route for adding/removing in ip-up/ip-down */
					break;

				case PW_FRAMED_MTU:
					/* XXX: set the MTU? */
					break;
#endif

				case PW_IDLE_TIMEOUT:
					if (attrib->u.value != 0) {
						idle_time_limit = ntohl(attrib->u.value);
					}
					break;

				case PW_SESSION_TIMEOUT:
					if (attrib->u.value != 0) {
						maxconnect = ntohl(attrib->u.value);
					}
					break;

				case PW_CLASS:
					radius_class_length = attrib->length;
					if (radius_class_length > sizeof(radius_class))
						radius_class_length = sizeof(radius_class);
					memcpy(radius_class, attrib->u.string, radius_class_length);
					break;

				default:
					notice("RADIUS: ignoring unsupported attribute %d",
							attrib->type);
					break;
				}
			}
#ifdef CHAPMS
			else if (attrib->vendor == PW_VENDOR_MICROSOFT) {
				switch (attrib->type) {
				case PW_MS_CHAP2_SUCCESS:
					if (ms_chap2_success) {
						error("RADIUS: duplicate MS_CHAP2_SUCCESS");
						ret = 0;
						break;
					}
					ms_chap2_success = 1;

					if (!cstate || (cstate->chal_type != CHAP_MICROSOFT_V2)) {
						error("RADIUS: unexpected MS_CHAP2_SUCCESS");
						ret = 0;
						break;
					}

					if (attrib->length != 43) {
						error("RADIUS: invalid MS_CHAP2_SUCCESS length '%d'", attrib->length);
						ret = 0;
						break;
					}
					if (strncmp(attrib->u.string+1, "S=", 2)) {
						error("RADIUS: invalid MS_CHAP2_SUCCESS");
						ret = 0;
						break;
					}
					memcpy(cstate->response, attrib->u.string+1, attrib->length-1);
					cstate->response[attrib->length-1] = '\0';
					break;

#ifdef MPPE
				case PW_MS_CHAP_MPPE_KEYS: {
					unsigned char Digest[SHA_DIGEST_LENGTH];
					SHA_CTX Context;
    
					if (!cstate || (cstate->chal_type != CHAP_MICROSOFT)) {
						error("RADIUS: unexpected MS_CHAP_MPPE_KEYS");
						ret = 0;
						break;
					}

					if (attrib->length != 32) {
						error("RADIUS: invalid MS_CHAP_MPPE_KEYS length '%d'", attrib->length);
						ret = 0;
						break;
					}

					memcpy(mppe_master_send_key_40, attrib->u.string, 8);
					memcpy(mppe_master_recv_key_40, attrib->u.string, 8);

					SHA1_Init(&Context);
					SHA1_Update(&Context, attrib->u.string + 8, 16);
					SHA1_Update(&Context, attrib->u.string + 8, 16);
					SHA1_Update(&Context, cstate->challenge, 8);
					SHA1_Final(Digest, &Context);

					memcpy(mppe_master_send_key_128, Digest, 16);
					memcpy(mppe_master_recv_key_128, Digest, 16);
					mppe_send_key = mppe_recv_key = 1;
					break;
				}

				case PW_MS_MPPE_SEND_KEY:
					if (!cstate || (cstate->chal_type != CHAP_MICROSOFT_V2)) {
						error("RADIUS: unexpected MS_MPPE_SEND_KEY");
						ret = 0;
						break;
					}
					if (attrib->length != 34) {
						error("RADIUS: invalid MS_MPPE_SEND_KEY length '%d'", attrib->length);
						ret = 0;
						break;
					}
					if ((attrib->u.string[0] & 0x80) == 0) {
						error("RADIUS: invalid MS_MPPE_SEND_KEY salt '%02x%02x'", (unsigned char)attrib->u.string[0], (unsigned char)attrib->u.string[1]);
						ret = 0;
						break;
					}
					if (attrib->u.string[2] != 16) {
						error("RADIUS: invalid MS_MPPE_SEND_KEY keylength '%d'", attrib->u.string[2]);
						ret = 0;
						break;
					}
					memcpy(mppe_master_send_key_128, attrib->u.string+3, 16);
					memcpy(mppe_master_send_key_40, attrib->u.string+3, 8);
					mppe_send_key = 1;
					break;

				case PW_MS_MPPE_RECV_KEY:
					if (!cstate || (cstate->chal_type != CHAP_MICROSOFT_V2)) {
						error("RADIUS: unexpected MS_MPPE_RECV_KEY");
						ret = 0;
						break;
					}
					if (attrib->length != 34) {
						error("RADIUS: invalid MS_MPPE_RECV_KEY length '%d'", attrib->length);
						ret = 0;
						break;
					}
					if ((attrib->u.string[0] & 0x80) == 0) {
						error("RADIUS: invalid MS_MPPE_RECV_KEY salt '%02x%02x'", (unsigned char)attrib->u.string[0], (unsigned char)attrib->u.string[1]);
						ret = 0;
						break;
					}
					if (attrib->u.string[2] != 16) {
						error("RADIUS: invalid MS_MPPE_RECV_KEY keylength '%d'", attrib->u.string[2]);
						ret = 0;
						break;
					}
					memcpy(mppe_master_recv_key_128, attrib->u.string+3, 16);
					memcpy(mppe_master_recv_key_40, attrib->u.string+3, 8);
					mppe_recv_key = 1;
					break;

				case PW_MS_MPPE_ENCRYPTION_POLICY:
					if (!radius_check_integer_length(attrib)) {
						ret = 0;
						break;
					}

					if (attrib->u.value == htonl(1)) {
						/* Encryption allowed */
						ccp_allowoptions[0].mppe = 1;
						ccp_wantoptions[0].mppe = 0;
						mppe_policy = 1;
					}
					else if (attrib->u.value == htonl(2)) {
						/* Encryption required */
						/* XXX: current version of ppd doesn't support
						 * requiring encryption. */
						ccp_allowoptions[0].mppe = ccp_wantoptions[0].mppe = 1;
						mppe_policy = 1;
					}
					break;

				case PW_MS_MPPE_ENCRYPTION_TYPES:
					if (!radius_check_integer_length(attrib)) {
						ret = 0;
						break;
					}

					ccp_allowoptions[0].mppe_40
						= ccp_wantoptions[0].mppe_40
						= (attrib->u.value & htonl(2)) ? 1 : 0;
					ccp_allowoptions[0].mppe_128
						= ccp_wantoptions[0].mppe_128
						= (attrib->u.value & htonl(4)) ? 1 : 0;
					mppe_types = 1;
					break;
#endif /* MPPE */

#if 0
				case PW_MS_PRIMARY_DNS_SERVER:
				case PW_MS_SECONDARY_DNS_SERVER:
				case PW_MS_PRIMARY_NBNS_SERVER:
				case PW_MS_SECONDARY_NBNS_SERVER:
					break;
#endif

				default:
					notice("RADIUS: ignoring Microsoft attribute %d",
							attrib->type);
					break;
				}
			}
#endif /* CHAPMS */
			else {
				notice("RADIUS: ignoring vendor %d attribute %d",
						attrib->vendor, attrib->type);
			}
		}
#ifdef CHAPMS
		if (ret && cstate && (cstate->chal_type == CHAP_MICROSOFT_V2)
				&& !ms_chap2_success) {
			error("RADIUS: MSCHAPv2 success attribute not found");
			ret = 0;
		}
#endif
#ifdef MPPE
		if (mppe_send_key && mppe_recv_key) {
			if (mppe_policy && mppe_types) {
				mppe_allowed = 1;
			} else if (!mppe_policy) {
				mppe_allowed = 1;
			}
		}
#endif
	}
	else if (ret == PW_AUTHENTICATION_REJECT) {
		for (attrib=recvattriblist; attrib!=NULL; attrib=attrib->next) {
			if (attrib->vendor == PW_VENDOR_NONE
					&& attrib->type == PW_REPLY_MESSAGE) {
				strncpy(radius_reply_message,attrib->u.string,AUTH_STRING_LEN);
				radius_reply_message[AUTH_STRING_LEN] = 0;
				error("%s", radius_reply_message);
			}
		}
		ret = 0;
	}
	else if (ret == PW_ACCESS_CHALLENGE) {
		error("RADIUS: server sent unexpected CHAP challenge");
		ret = 0;
	}
	else {
		error("RADIUS: server sent unexpected response '%d'", ret);
		ret = 0;
	}

	radius_free_attrib(recvattriblist);

	return ret;
}
void command_read(GenericSocket &channel, int fd, int start, int length, int flash_sector_size, int chunk_size, bool verbose)
{
	int64_t file_offset;
	unsigned char sector_buffer[flash_sector_size];
	unsigned char sector_hash[SHA_DIGEST_LENGTH];
	unsigned char file_hash[SHA_DIGEST_LENGTH];
	int sector, sector_buffer_length, sector_attempt;
	int chunk_offset, chunk_attempt;
	uint64_t data_offset;
	int current, checksummed;
	struct timeval time_start, time_now;
	std::string sha_local_hash_text;
	std::string sha_remote_hash_text;
	std::string send_string;
	std::string reply;
	std::string operation;
	std::vector<int> int_value;
	std::vector<std::string> string_value;
	SHA_CTX sha_file_ctx;

	gettimeofday(&time_start, 0);

	std::cout << "start read from " << start << ", length: " << length << ", flash buffer size: " << flash_sector_size << ", chunk size: " << chunk_size << std::endl;

	SHA1_Init(&sha_file_ctx);

	sector = 0;
	current = start;
	checksummed = 0;

	for(current = start; current < (start + length); current += flash_sector_size)
	{
		for(sector_attempt = max_attempts; sector_attempt > 0; sector_attempt--)
		{
			if(verbose)
				std::cout << "receiving sector: " << sector << ", length: " << flash_sector_size << ", try #" << (max_attempts - sector_attempt) << std::endl;

			send_string = std::string("flash-read ") + std::to_string(current);
			process(channel, send_string, reply, "OK flash-read: read bytes: ([0-9]+), from address: ([0-9]+) \\([0-9]+\\), checksum: ([0-9a-f]+)", string_value, int_value, verbose);

			if(int_value[0] != flash_sector_size)
				throw(std::string("local sector size (") + std::to_string(flash_sector_size) + ") != remote sector size (" + std::to_string(int_value[0]) + ")");

			if(int_value[1] != current)
				throw(std::string("local address (") + std::to_string(current) + ") != remote address (" + std::to_string(int_value[1]) + ")");

			sha_remote_hash_text = string_value[2];

			for(chunk_offset = 0; chunk_offset < (int)flash_sector_size; chunk_offset += chunk_size)
			{
				for(chunk_attempt = max_attempts; chunk_attempt > 0; chunk_attempt--)
				{
					try
					{
						if(verbose)
							std::cout << "receiving chunk: " << chunk_offset / chunk_size << " (offset " << chunk_offset
									<< ", length: " << chunk_size << ", try #" << max_attempts - chunk_attempt << std::endl;

						send_string = std::string("flash-receive ") + std::to_string(chunk_offset) + " " + std::to_string(chunk_size);
						process(channel, send_string, reply, "OK flash-receive: sending bytes: ([0-9]+), from offset: ([0-9]+), data: @.*",
								string_value, int_value, verbose, 2000, chunk_size + 60, true);

						if(int_value[0] != chunk_size)
							throw(std::string("local chunk length (") + std::to_string(chunk_size) + ") != remote chunk length (" + std::to_string(int_value[0]) + ")");

						if(int_value[1] != chunk_offset)
							throw(std::string("local chunk offset (") + std::to_string(chunk_offset) + ") != remote chunk offset (" + std::to_string(int_value[1]) + ")");

						if((data_offset = reply.find('@')) == std::string::npos)
							throw(std::string("data offset could not be found"));

						if((reply.length() - data_offset - 1) != (unsigned int)chunk_size)
							throw(std::string("received data != chunk size"));

						memcpy(sector_buffer + chunk_offset, reply.data() + data_offset + 1, chunk_size);

						break;
					}
					catch(const std::string &e)
					{
						if(!verbose)
							std::cout << std::endl;

						std::cout << "! receive chunk failed: " << e;
						std::cout << ", sector " << sector << "/" << length / flash_sector_size;
						std::cout << ", chunk " << chunk_offset / chunk_size;
						std::cout << ", attempt #" << max_attempts - chunk_attempt;
						std::cout << std::endl;
					}
				}

				if(chunk_attempt <= 0)
					throw(std::string("sending chunk failed too many times"));
			}

			SHA1(sector_buffer, flash_sector_size, sector_hash);
			sha_local_hash_text = sha_hash_to_text(sector_hash);

			if(verbose)
			{
				std::cout << "sector " << sector << " read";
				std::cout << ", local hash: " << sha_local_hash_text;
				std::cout << ", remote hash: " << sha_remote_hash_text;
				std::cout << ", try #" << (max_attempts - sector_attempt) << std::endl;
			}

			if(sha_local_hash_text != sha_remote_hash_text)
				throw(std::string("local hash (") + sha_local_hash_text + ") != remote hash (" + sha_remote_hash_text + ")");

			break;
		}

		if(sector_attempt <= 0)
			throw(std::string("! receiving sector failed too many times"));

		if((file_offset = lseek(fd, 0, SEEK_CUR)) < 0)
			throw(std::string("i/o error in seek"));

		if((int)(file_offset + flash_sector_size) < length)
			sector_buffer_length = flash_sector_size;
		else
			sector_buffer_length = length - file_offset;

		if(write(fd, sector_buffer, sector_buffer_length) <= 0)
			throw(std::string("i/o error in write"));

		SHA1_Update(&sha_file_ctx, sector_buffer, flash_sector_size);
		checksummed += flash_sector_size;

		sector++;

		if(verbose)
			std::cout << "receive sector success at " << current << std::endl;
		else
		{
			int seconds, useconds;
			double duration, rate;

			gettimeofday(&time_now, 0);

			seconds = time_now.tv_sec - time_start.tv_sec;
			useconds = time_now.tv_usec - time_start.tv_usec;
			duration = seconds + (useconds / 1000000.0);
			rate = file_offset / 1024.0 / duration;

			std::cout << std::setfill(' ');
			std::cout << "received "	<< std::setw(3) << (file_offset / 1024) << " kbytes";
			std::cout << " in "			<< std::setw(4) << std::setprecision(2) << std::fixed << duration << " seconds";
			std::cout << " at rate "	<< std::setw(3) << std::setprecision(0) << std::fixed << rate << " kbytes/s";
			std::cout << ", received "	<< std::setw(2) << sector << " sectors";
			std::cout << ", "			<< std::setw(3) << ((file_offset * 100) / length) << "%       \r";
			std::cout.flush();
		}
	}

	std::cout << std::endl << "checksumming " << checksummed / flash_sector_size << " sectors..." << std::endl;

	SHA1_Final(file_hash, &sha_file_ctx);
	sha_local_hash_text = sha_hash_to_text(file_hash);

	send_string = std::string("flash-checksum ") + std::to_string(start) +  " " + std::to_string(checksummed);
	process(channel, send_string, reply, "OK flash-checksum: checksummed bytes: ([0-9]+), from address: ([0-9]+), checksum: ([0-9a-f]+)\\s*", string_value, int_value, verbose);

	if(verbose)
	{
		std::cout << "local checksum:  " << sha_local_hash_text << std::endl;
		std::cout << "remote checksum: " << string_value[2] << std::endl;
	}

	if(int_value[0] != checksummed)
		throw(std::string("checksum failed: checksummed bytes differs, local: ") + std::to_string(checksummed) +  ", remote: " + std::to_string(int_value[0]));

	if(int_value[1] != start)
		throw(std::string("checksum failed: start address differs, local: ") +  std::to_string(start) + ", remote: " + std::to_string(int_value[1]));

	if(string_value[2] != sha_local_hash_text)
		throw(std::string("checksum failed: SHA hash differs, local: ") + sha_local_hash_text + ", remote: " + string_value[2]);

	std::cout << "checksumming done" << std::endl;
}