Coverage Report

Created: 2024-09-03 06:23

/src/brpc/src/brpc/policy/dh.cpp
Line
Count
Source (jump to first uncovered line)
1
// [ Modified from code in SRS2 (src/protocol/srs_rtmp_handshake.cpp:140) ]
2
// The MIT License (MIT)
3
// Copyright (c) 2013-2015 SRS(ossrs)
4
// Permission is hereby granted, free of charge, to any person obtaining a copy of
5
// this software and associated documentation files (the "Software"), to deal in
6
// the Software without restriction, including without limitation the rights to
7
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
// the Software, and to permit persons to whom the Software is furnished to do so,
9
// subject to the following conditions:
10
// The above copyright notice and this permission notice shall be included in all
11
// copies or substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
14
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
15
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
16
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
17
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18
19
#include "butil/logging.h"
20
#include "butil/ssl_compat.h"
21
#include "brpc/log.h"
22
#include "brpc/policy/dh.h"
23
24
namespace brpc {
25
namespace policy {
26
27
0
void DHWrapper::clear() {
28
0
    if (_pdh != NULL) {
29
0
        DH_free(_pdh);
30
0
        _pdh = NULL;
31
0
    }
32
0
}
33
    
34
0
int DHWrapper::initialize(bool ensure_128bytes_public_key) {
35
0
    for (;;) {
36
0
        if (do_initialize() != 0) {
37
0
            return -1;
38
0
        }
39
0
        if (ensure_128bytes_public_key) {
40
0
            const BIGNUM* pub_key = NULL;
41
0
            DH_get0_key(_pdh, &pub_key, NULL);
42
0
            int key_size = BN_num_bytes(pub_key);
43
0
            if (key_size != 128) {
44
0
                RPC_VLOG << "regenerate 128B key, current=" << key_size;
45
0
                clear();
46
0
                continue;
47
0
            }
48
0
        }
49
0
        break;
50
0
    }
51
0
    return 0;
52
0
}
53
    
54
0
int DHWrapper::copy_public_key(char* pkey, int* pkey_size) const {
55
0
    const BIGNUM* pub_key = NULL;
56
0
    DH_get0_key(_pdh, &pub_key, NULL);
57
    // copy public key to bytes.
58
    // sometimes, the key_size is 127, seems ok.
59
0
    int key_size = BN_num_bytes(pub_key);
60
0
    CHECK_GT(key_size, 0);
61
        
62
    // maybe the key_size is 127, but dh will write all 128bytes pkey,
63
    // no need to set/initialize the pkey.
64
    // @see https://github.com/ossrs/srs/issues/165
65
0
    key_size = BN_bn2bin(pub_key, (unsigned char*)pkey);
66
0
    CHECK_GT(key_size, 0);
67
        
68
    // output the size of public key.
69
    // @see https://github.com/ossrs/srs/issues/165
70
0
    CHECK_LE(key_size, *pkey_size);
71
0
    *pkey_size = key_size;
72
0
    return 0;
73
0
}
74
    
75
int DHWrapper::copy_shared_key(const void* ppkey, int ppkey_size,
76
0
                           void* skey, int* skey_size) const {
77
0
    BIGNUM* ppk = BN_bin2bn((const unsigned char*)ppkey, ppkey_size, 0);
78
0
    if (ppk == NULL) {
79
0
        LOG(ERROR) << "Fail to BN_bin2bn";
80
0
        return -1;
81
0
    }
82
    // @see https://github.com/ossrs/srs/issues/165
83
0
    int key_size = DH_compute_key((unsigned char*)skey, ppk, _pdh);
84
0
    if (key_size < 0 || key_size > *skey_size) {
85
0
        LOG(ERROR) << "Fail to compute shared key";
86
0
        BN_free(ppk);
87
0
        return -1;
88
0
    }
89
0
    *skey_size = key_size;
90
0
    return 0;
91
0
}
92
    
93
0
int DHWrapper::do_initialize() {
94
0
    BIGNUM* p = get_rfc2409_prime_1024(NULL);
95
0
    if (!p) {
96
0
        return -1;
97
0
    }
98
    // See RFC 2409, Section 6 "Oakley Groups"
99
    // for the reason why 2 is used as generator.
100
0
    BIGNUM* g = NULL;
101
0
    BN_dec2bn(&g, "2");
102
0
    if (!g) {
103
0
        BN_free(p);
104
0
        return -1;
105
0
    }
106
0
    _pdh = DH_new();
107
0
    if (!_pdh) {
108
0
        BN_free(p);
109
0
        BN_free(g);
110
0
        return -1;
111
0
    }
112
0
    DH_set0_pqg(_pdh, p, NULL, g);
113
    
114
    // Generate private and public key
115
0
    if (!DH_generate_key(_pdh)) {
116
0
        LOG(ERROR) << "Fail to DH_generate_key";
117
0
        return -1;
118
0
    }
119
0
    return 0;
120
0
}
121
122
}  // namespace policy
123
} // namespace brpc