1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "polo/util/poloutil.h"
16
17 #include <openssl/rand.h>
18
19 namespace polo {
20 namespace util {
21
BytesToHexString(const uint8_t * bytes,size_t length)22 const std::string PoloUtil::BytesToHexString(const uint8_t* bytes,
23 size_t length) {
24 // Use OpenSSL BigNum functions to perform the conversion.
25 BIGNUM* bn = BN_bin2bn(bytes, length, NULL);
26 char* hex = BN_bn2hex(bn);
27 std::string hex_string(hex);
28 BN_free(bn);
29 OPENSSL_free(hex);
30 return hex_string;
31 }
32
HexStringToBytes(const std::string hex_string,uint8_t * & bytes)33 const size_t PoloUtil::HexStringToBytes(const std::string hex_string,
34 uint8_t*& bytes) {
35 // Use OpenSSL BigNum functions to perform the conversion.
36 BIGNUM* bn = NULL;
37 BN_hex2bn(&bn, hex_string.c_str());
38 int length = BN_num_bytes(bn);
39 bytes = new uint8_t[length];
40 BN_bn2bin(bn, &bytes[0]);
41 BN_free(bn);
42 return length;
43 }
44
IntToBigEndianBytes(uint32_t value,uint8_t * & bytes)45 const void PoloUtil::IntToBigEndianBytes(uint32_t value,
46 uint8_t*& bytes) {
47 // Use OpenSSL BigNum functions to perform the conversion.
48 BIGNUM* bn = BN_new();
49 BN_add_word(bn, value);
50
51 // Initialize the array to 0 so there will be leading null bytes if the
52 // number is less than 4 bytes long.
53 bytes = new uint8_t[4];
54 for (int i = 0; i < 4; i++) {
55 bytes[i] = 0;
56 }
57
58 int length = BN_num_bytes(bn);
59 BN_bn2bin(bn, &bytes[4 - length]);
60 BN_free(bn);
61 }
62
BigEndianBytesToInt(const uint8_t * bytes)63 const uint32_t PoloUtil::BigEndianBytesToInt(
64 const uint8_t* bytes) {
65 // Use OpenSSL BigNum functions to perform the conversion.
66 BIGNUM* bn = BN_bin2bn(bytes, 4, NULL);
67 BN_ULONG value = bn->d[0];
68 BN_free(bn);
69 return value;
70 }
71
GenerateRandomBytes(size_t length)72 uint8_t* PoloUtil::GenerateRandomBytes(size_t length) {
73 // Use the OpenSSL library to generate the random byte array. The RAND_bytes
74 // function is guaranteed to provide secure random bytes.
75 uint8_t* buffer = new uint8_t[length];
76 if (RAND_bytes(buffer, length)) {
77 return buffer;
78 } else {
79 delete buffer;
80 return NULL;
81 }
82 }
83
84 } // namespace util
85 } // namespace polo
86