FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtmpdh.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavformat/rtmpdh.c"
20 
21 #include <stdio.h>
22 
23 static int test_random_shared_secret(void)
24 {
25  FF_DH *peer1 = NULL, *peer2 = NULL;
26  int ret;
27  uint8_t pubkey1[128], pubkey2[128];
28  uint8_t sharedkey1[128], sharedkey2[128];
29 
30  peer1 = ff_dh_init(1024);
31  peer2 = ff_dh_init(1024);
32  if (!peer1 || !peer2) {
33  ret = AVERROR(ENOMEM);
34  goto fail;
35  }
36  if ((ret = ff_dh_generate_public_key(peer1)) < 0)
37  goto fail;
38  if ((ret = ff_dh_generate_public_key(peer2)) < 0)
39  goto fail;
40  if ((ret = ff_dh_write_public_key(peer1, pubkey1, sizeof(pubkey1))) < 0)
41  goto fail;
42  if ((ret = ff_dh_write_public_key(peer2, pubkey2, sizeof(pubkey2))) < 0)
43  goto fail;
44  if ((ret = ff_dh_compute_shared_secret_key(peer1, pubkey2, sizeof(pubkey2),
45  sharedkey1, sizeof(sharedkey1))) < 0)
46  goto fail;
47  if ((ret = ff_dh_compute_shared_secret_key(peer2, pubkey1, sizeof(pubkey1),
48  sharedkey2, sizeof(sharedkey2))) < 0)
49  goto fail;
50  if (memcmp(sharedkey1, sharedkey2, sizeof(sharedkey1))) {
51  printf("Mismatched generated shared key\n");
52  ret = AVERROR_INVALIDDATA;
53  } else {
54  printf("Generated shared key ok\n");
55  }
56 fail:
57  ff_dh_free(peer1);
58  ff_dh_free(peer2);
59  return ret;
60 }
61 
62 static const char *private_key =
63  "976C18FCADC255B456564F74F3EEDA59D28AF6B744D743F2357BFD2404797EF896EF1A"
64  "7C1CBEAAA3AB60AF3192D189CFF3F991C9CBBFD78119FCA2181384B94011943B6D6F28"
65  "9E1B708E2D1A0C7771169293F03DA27E561F15F16F0AC9BC858C77A80FA98FD088A232"
66  "19D08BE6F165DE0B02034B18705829FAD0ACB26A5B75EF";
67 static const char *public_key =
68  "F272ECF8362257C5D2C3CC2229CF9C0A03225BC109B1DBC76A68C394F256ACA3EF5F64"
69  "FC270C26382BF315C19E97A76104A716FC998A651E8610A3AE6CF65D8FAE5D3F32EEA0"
70  "0B32CB9609B494116A825D7142D17B88E3D20EDD98743DE29CF37A23A9F6A58B960591"
71  "3157D5965FCB46DDA73A1F08DD897BAE88DFE6FC937CBA";
72 static const uint8_t public_key_bin[] = {
73  0xf2, 0x72, 0xec, 0xf8, 0x36, 0x22, 0x57, 0xc5, 0xd2, 0xc3, 0xcc, 0x22,
74  0x29, 0xcf, 0x9c, 0x0a, 0x03, 0x22, 0x5b, 0xc1, 0x09, 0xb1, 0xdb, 0xc7,
75  0x6a, 0x68, 0xc3, 0x94, 0xf2, 0x56, 0xac, 0xa3, 0xef, 0x5f, 0x64, 0xfc,
76  0x27, 0x0c, 0x26, 0x38, 0x2b, 0xf3, 0x15, 0xc1, 0x9e, 0x97, 0xa7, 0x61,
77  0x04, 0xa7, 0x16, 0xfc, 0x99, 0x8a, 0x65, 0x1e, 0x86, 0x10, 0xa3, 0xae,
78  0x6c, 0xf6, 0x5d, 0x8f, 0xae, 0x5d, 0x3f, 0x32, 0xee, 0xa0, 0x0b, 0x32,
79  0xcb, 0x96, 0x09, 0xb4, 0x94, 0x11, 0x6a, 0x82, 0x5d, 0x71, 0x42, 0xd1,
80  0x7b, 0x88, 0xe3, 0xd2, 0x0e, 0xdd, 0x98, 0x74, 0x3d, 0xe2, 0x9c, 0xf3,
81  0x7a, 0x23, 0xa9, 0xf6, 0xa5, 0x8b, 0x96, 0x05, 0x91, 0x31, 0x57, 0xd5,
82  0x96, 0x5f, 0xcb, 0x46, 0xdd, 0xa7, 0x3a, 0x1f, 0x08, 0xdd, 0x89, 0x7b,
83  0xae, 0x88, 0xdf, 0xe6, 0xfc, 0x93, 0x7c, 0xba
84 };
85 static const uint8_t peer_public_key[] = {
86  0x58, 0x66, 0x05, 0x49, 0x94, 0x23, 0x2b, 0x66, 0x52, 0x13, 0xff, 0x46,
87  0xf2, 0xb3, 0x79, 0xa9, 0xee, 0xae, 0x1a, 0x13, 0xf0, 0x71, 0x52, 0xfb,
88  0x93, 0x4e, 0xee, 0x97, 0x05, 0x73, 0x50, 0x7d, 0xaf, 0x02, 0x07, 0x72,
89  0xac, 0xdc, 0xa3, 0x95, 0x78, 0xee, 0x9a, 0x19, 0x71, 0x7e, 0x99, 0x9f,
90  0x2a, 0xd4, 0xb3, 0xe2, 0x0c, 0x1d, 0x1a, 0x78, 0x4c, 0xde, 0xf1, 0xad,
91  0xb4, 0x60, 0xa8, 0x51, 0xac, 0x71, 0xec, 0x86, 0x70, 0xa2, 0x63, 0x36,
92  0x92, 0x7c, 0xe3, 0x87, 0xee, 0xe4, 0xf1, 0x62, 0x24, 0x74, 0xb4, 0x04,
93  0xfa, 0x5c, 0xdf, 0xba, 0xfa, 0xa3, 0xc2, 0xbb, 0x62, 0x27, 0xd0, 0xf4,
94  0xe4, 0x43, 0xda, 0x8a, 0x88, 0x69, 0x60, 0xe2, 0xdb, 0x75, 0x2a, 0x98,
95  0x9d, 0xb5, 0x50, 0xe3, 0x99, 0xda, 0xe0, 0xa6, 0x14, 0xc9, 0x80, 0x12,
96  0xf9, 0x3c, 0xac, 0x06, 0x02, 0x7a, 0xde, 0x74
97 };
98 static const uint8_t shared_secret[] = {
99  0xb2, 0xeb, 0xcb, 0x71, 0xf3, 0x61, 0xfb, 0x5b, 0x4e, 0x5c, 0x4c, 0xcf,
100  0x5c, 0x08, 0x5f, 0x96, 0x26, 0x77, 0x1d, 0x31, 0xf1, 0xe1, 0xf7, 0x4b,
101  0x92, 0xac, 0x82, 0x2a, 0x88, 0xc7, 0x83, 0xe1, 0xc7, 0xf3, 0xd3, 0x1a,
102  0x7d, 0xc8, 0x31, 0xe3, 0x97, 0xe4, 0xec, 0x31, 0x0e, 0x8f, 0x73, 0x1a,
103  0xe4, 0xf6, 0xd8, 0xc8, 0x94, 0xff, 0xa0, 0x03, 0x84, 0x03, 0x0f, 0xa5,
104  0x30, 0x5d, 0x67, 0xe0, 0x7a, 0x3b, 0x5f, 0xed, 0x4c, 0xf5, 0xbc, 0x18,
105  0xea, 0xd4, 0x77, 0xa9, 0x07, 0xb3, 0x54, 0x0b, 0x02, 0xd9, 0xc6, 0xb8,
106  0x66, 0x5e, 0xec, 0xa4, 0xcd, 0x47, 0xed, 0xc9, 0x38, 0xc6, 0x91, 0x08,
107  0xf3, 0x85, 0x9b, 0x69, 0x16, 0x78, 0x0d, 0xb7, 0x74, 0x51, 0xaa, 0x5b,
108  0x4d, 0x74, 0xe4, 0x29, 0x2e, 0x9e, 0x8e, 0xf7, 0xe5, 0x42, 0x83, 0xb0,
109  0x65, 0xb0, 0xce, 0xc6, 0xb2, 0x8f, 0x5b, 0xb0
110 };
111 
112 static int test_ref_data(void)
113 {
114  FF_DH *dh;
115  int ret = AVERROR(ENOMEM);
116  uint8_t pubkey_test[128];
117  uint8_t sharedkey_test[128];
118 
119  dh = ff_dh_init(1024);
120  if (!dh)
121  goto fail;
122  bn_hex2bn(dh->priv_key, private_key, ret);
123  if (!ret)
124  goto fail;
125  bn_hex2bn(dh->pub_key, public_key, ret);
126  if (!ret)
127  goto fail;
128  if ((ret = ff_dh_write_public_key(dh, pubkey_test, sizeof(pubkey_test))) < 0)
129  goto fail;
130  if (memcmp(pubkey_test, public_key_bin, sizeof(pubkey_test))) {
131  printf("Mismatched generated public key\n");
132  ret = AVERROR_INVALIDDATA;
133  goto fail;
134  } else {
135  printf("Generated public key ok\n");
136  }
138  sharedkey_test, sizeof(sharedkey_test))) < 0)
139  goto fail;
140  if (memcmp(shared_secret, sharedkey_test, sizeof(sharedkey_test))) {
141  printf("Mismatched generated shared key\n");
142  ret = AVERROR_INVALIDDATA;
143  } else {
144  printf("Generated shared key ok\n");
145  }
146 fail:
147  ff_dh_free(dh);
148  return ret;
149 }
150 
151 int main(void)
152 {
153  if (test_random_shared_secret() < 0)
154  return 1;
155  if (test_ref_data() < 0)
156  return 1;
157  return 0;
158 }
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_dh_write_public_key(FF_DH *dh, uint8_t *pub_key, int pub_key_len)
Write the public key into the given buffer.
Definition: rtmpdh.c:322
static const uint8_t public_key_bin[]
Definition: rtmpdh.c:72
int ff_dh_compute_shared_secret_key(FF_DH *dh, const uint8_t *pub_key, int pub_key_len, uint8_t *secret_key, int secret_key_len)
Compute the shared secret key from the private FF_DH value and the other party's public value...
Definition: rtmpdh.c:338
uint8_t
int ff_dh_generate_public_key(FF_DH *dh)
Generate a public key.
Definition: rtmpdh.c:296
static const char * public_key
Definition: rtmpdh.c:67
static const uint8_t peer_public_key[]
Definition: rtmpdh.c:85
int main(void)
Definition: rtmpdh.c:151
#define AVERROR(e)
Definition: error.h:43
static const uint8_t shared_secret[]
Definition: rtmpdh.c:98
#define fail()
Definition: checkasm.h:81
void ff_dh_free(FF_DH *dh)
Free a Diffie-Hellmann context.
RTMP Diffie-Hellmann utilities.
static const char * private_key
Definition: rtmpdh.c:62
static int test_ref_data(void)
Definition: rtmpdh.c:112
av_cold FF_DH * ff_dh_init(int key_len)
Initialize a Diffie-Hellmann context.
Definition: rtmpdh.c:269
static int test_random_shared_secret(void)
Definition: rtmpdh.c:23