17c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Copyright 2012 Google Inc. All Rights Reserved. 27c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 37c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Licensed under the Apache License, Version 2.0 (the "License"); 47c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// you may not use this file except in compliance with the License. 57c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// You may obtain a copy of the License at 67c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 77c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// http://www.apache.org/licenses/LICENSE-2.0 87c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// 97c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// Unless required by applicable law or agreed to in writing, software 107c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// distributed under the License is distributed on an "AS IS" BASIS, 117c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// See the License for the specific language governing permissions and 137c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet// limitations under the License. 147c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 157c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include "polo/util/poloutil.h" 167c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 177c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet#include <openssl/rand.h> 187c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 197c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetnamespace polo { 207c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetnamespace util { 217c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 227c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetconst std::string PoloUtil::BytesToHexString(const uint8_t* bytes, 237c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet size_t length) { 247c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Use OpenSSL BigNum functions to perform the conversion. 257c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BIGNUM* bn = BN_bin2bn(bytes, length, NULL); 267c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet char* hex = BN_bn2hex(bn); 277c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet std::string hex_string(hex); 287c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_free(bn); 297c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet OPENSSL_free(hex); 307c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return hex_string; 317c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 327c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 337c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetconst size_t PoloUtil::HexStringToBytes(const std::string hex_string, 347c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet uint8_t*& bytes) { 357c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Use OpenSSL BigNum functions to perform the conversion. 367c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BIGNUM* bn = NULL; 377c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_hex2bn(&bn, hex_string.c_str()); 387c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int length = BN_num_bytes(bn); 397c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet bytes = new uint8_t[length]; 407c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_bn2bin(bn, &bytes[0]); 417c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_free(bn); 427c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return length; 437c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 447c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 457c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetconst void PoloUtil::IntToBigEndianBytes(uint32_t value, 467c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet uint8_t*& bytes) { 477c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Use OpenSSL BigNum functions to perform the conversion. 487c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BIGNUM* bn = BN_new(); 497c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_add_word(bn, value); 507c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 517c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Initialize the array to 0 so there will be leading null bytes if the 527c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // number is less than 4 bytes long. 537c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet bytes = new uint8_t[4]; 547c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet for (int i = 0; i < 4; i++) { 557c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet bytes[i] = 0; 567c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 577c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 587c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet int length = BN_num_bytes(bn); 597c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_bn2bin(bn, &bytes[4 - length]); 607c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_free(bn); 617c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 627c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 637c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetconst uint32_t PoloUtil::BigEndianBytesToInt( 647c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet const uint8_t* bytes) { 657c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Use OpenSSL BigNum functions to perform the conversion. 667c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BIGNUM* bn = BN_bin2bn(bytes, 4, NULL); 677c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_ULONG value = bn->d[0]; 687c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet BN_free(bn); 697c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return value; 707c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 717c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 727c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichetuint8_t* PoloUtil::GenerateRandomBytes(size_t length) { 737c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // Use the OpenSSL library to generate the random byte array. The RAND_bytes 747c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet // function is guaranteed to provide secure random bytes. 757c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet uint8_t* buffer = new uint8_t[length]; 767c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet if (RAND_bytes(buffer, length)) { 777c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return buffer; 787c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } else { 797c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet delete buffer; 807c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet return NULL; 817c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet } 827c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} 837c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet 847c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} // namespace util 857c9978567a202d6aa98beac5da5e1b3b34792862Jerome Poichet} // namespace polo 86