FFmpeg
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/avformat.h"
20 #include "libavformat/rtmpdh.c"
21 
22 #include <stdio.h>
23 
24 static int test_random_shared_secret(void)
25 {
26  FF_DH *peer1 = NULL, *peer2 = NULL;
27  int ret;
28  uint8_t pubkey1[128], pubkey2[128];
29  uint8_t sharedkey1[128], sharedkey2[128];
30 
31  peer1 = ff_dh_init(1024);
32  peer2 = ff_dh_init(1024);
33  if (!peer1 || !peer2) {
34  ret = AVERROR(ENOMEM);
35  goto fail;
36  }
37  if ((ret = ff_dh_generate_public_key(peer1)) < 0)
38  goto fail;
39  if ((ret = ff_dh_generate_public_key(peer2)) < 0)
40  goto fail;
41  if ((ret = ff_dh_write_public_key(peer1, pubkey1, sizeof(pubkey1))) < 0)
42  goto fail;
43  if ((ret = ff_dh_write_public_key(peer2, pubkey2, sizeof(pubkey2))) < 0)
44  goto fail;
45  if ((ret = ff_dh_compute_shared_secret_key(peer1, pubkey2, sizeof(pubkey2),
46  sharedkey1, sizeof(sharedkey1))) < 0)
47  goto fail;
48  if ((ret = ff_dh_compute_shared_secret_key(peer2, pubkey1, sizeof(pubkey1),
49  sharedkey2, sizeof(sharedkey2))) < 0)
50  goto fail;
51  if (memcmp(sharedkey1, sharedkey2, sizeof(sharedkey1))) {
52  printf("Mismatched generated shared key\n");
53  ret = AVERROR_INVALIDDATA;
54  } else {
55  printf("Generated shared key ok\n");
56  }
57 fail:
58  ff_dh_free(peer1);
59  ff_dh_free(peer2);
60  return ret;
61 }
62 
63 static const char *private_key =
64  "976C18FCADC255B456564F74F3EEDA59D28AF6B744D743F2357BFD2404797EF896EF1A"
65  "7C1CBEAAA3AB60AF3192D189CFF3F991C9CBBFD78119FCA2181384B94011943B6D6F28"
66  "9E1B708E2D1A0C7771169293F03DA27E561F15F16F0AC9BC858C77A80FA98FD088A232"
67  "19D08BE6F165DE0B02034B18705829FAD0ACB26A5B75EF";
68 static const char *public_key =
69  "F272ECF8362257C5D2C3CC2229CF9C0A03225BC109B1DBC76A68C394F256ACA3EF5F64"
70  "FC270C26382BF315C19E97A76104A716FC998A651E8610A3AE6CF65D8FAE5D3F32EEA0"
71  "0B32CB9609B494116A825D7142D17B88E3D20EDD98743DE29CF37A23A9F6A58B960591"
72  "3157D5965FCB46DDA73A1F08DD897BAE88DFE6FC937CBA";
73 static const uint8_t public_key_bin[] = {
74  0xf2, 0x72, 0xec, 0xf8, 0x36, 0x22, 0x57, 0xc5, 0xd2, 0xc3, 0xcc, 0x22,
75  0x29, 0xcf, 0x9c, 0x0a, 0x03, 0x22, 0x5b, 0xc1, 0x09, 0xb1, 0xdb, 0xc7,
76  0x6a, 0x68, 0xc3, 0x94, 0xf2, 0x56, 0xac, 0xa3, 0xef, 0x5f, 0x64, 0xfc,
77  0x27, 0x0c, 0x26, 0x38, 0x2b, 0xf3, 0x15, 0xc1, 0x9e, 0x97, 0xa7, 0x61,
78  0x04, 0xa7, 0x16, 0xfc, 0x99, 0x8a, 0x65, 0x1e, 0x86, 0x10, 0xa3, 0xae,
79  0x6c, 0xf6, 0x5d, 0x8f, 0xae, 0x5d, 0x3f, 0x32, 0xee, 0xa0, 0x0b, 0x32,
80  0xcb, 0x96, 0x09, 0xb4, 0x94, 0x11, 0x6a, 0x82, 0x5d, 0x71, 0x42, 0xd1,
81  0x7b, 0x88, 0xe3, 0xd2, 0x0e, 0xdd, 0x98, 0x74, 0x3d, 0xe2, 0x9c, 0xf3,
82  0x7a, 0x23, 0xa9, 0xf6, 0xa5, 0x8b, 0x96, 0x05, 0x91, 0x31, 0x57, 0xd5,
83  0x96, 0x5f, 0xcb, 0x46, 0xdd, 0xa7, 0x3a, 0x1f, 0x08, 0xdd, 0x89, 0x7b,
84  0xae, 0x88, 0xdf, 0xe6, 0xfc, 0x93, 0x7c, 0xba
85 };
86 static const uint8_t peer_public_key[] = {
87  0x58, 0x66, 0x05, 0x49, 0x94, 0x23, 0x2b, 0x66, 0x52, 0x13, 0xff, 0x46,
88  0xf2, 0xb3, 0x79, 0xa9, 0xee, 0xae, 0x1a, 0x13, 0xf0, 0x71, 0x52, 0xfb,
89  0x93, 0x4e, 0xee, 0x97, 0x05, 0x73, 0x50, 0x7d, 0xaf, 0x02, 0x07, 0x72,
90  0xac, 0xdc, 0xa3, 0x95, 0x78, 0xee, 0x9a, 0x19, 0x71, 0x7e, 0x99, 0x9f,
91  0x2a, 0xd4, 0xb3, 0xe2, 0x0c, 0x1d, 0x1a, 0x78, 0x4c, 0xde, 0xf1, 0xad,
92  0xb4, 0x60, 0xa8, 0x51, 0xac, 0x71, 0xec, 0x86, 0x70, 0xa2, 0x63, 0x36,
93  0x92, 0x7c, 0xe3, 0x87, 0xee, 0xe4, 0xf1, 0x62, 0x24, 0x74, 0xb4, 0x04,
94  0xfa, 0x5c, 0xdf, 0xba, 0xfa, 0xa3, 0xc2, 0xbb, 0x62, 0x27, 0xd0, 0xf4,
95  0xe4, 0x43, 0xda, 0x8a, 0x88, 0x69, 0x60, 0xe2, 0xdb, 0x75, 0x2a, 0x98,
96  0x9d, 0xb5, 0x50, 0xe3, 0x99, 0xda, 0xe0, 0xa6, 0x14, 0xc9, 0x80, 0x12,
97  0xf9, 0x3c, 0xac, 0x06, 0x02, 0x7a, 0xde, 0x74
98 };
99 static const uint8_t shared_secret[] = {
100  0xb2, 0xeb, 0xcb, 0x71, 0xf3, 0x61, 0xfb, 0x5b, 0x4e, 0x5c, 0x4c, 0xcf,
101  0x5c, 0x08, 0x5f, 0x96, 0x26, 0x77, 0x1d, 0x31, 0xf1, 0xe1, 0xf7, 0x4b,
102  0x92, 0xac, 0x82, 0x2a, 0x88, 0xc7, 0x83, 0xe1, 0xc7, 0xf3, 0xd3, 0x1a,
103  0x7d, 0xc8, 0x31, 0xe3, 0x97, 0xe4, 0xec, 0x31, 0x0e, 0x8f, 0x73, 0x1a,
104  0xe4, 0xf6, 0xd8, 0xc8, 0x94, 0xff, 0xa0, 0x03, 0x84, 0x03, 0x0f, 0xa5,
105  0x30, 0x5d, 0x67, 0xe0, 0x7a, 0x3b, 0x5f, 0xed, 0x4c, 0xf5, 0xbc, 0x18,
106  0xea, 0xd4, 0x77, 0xa9, 0x07, 0xb3, 0x54, 0x0b, 0x02, 0xd9, 0xc6, 0xb8,
107  0x66, 0x5e, 0xec, 0xa4, 0xcd, 0x47, 0xed, 0xc9, 0x38, 0xc6, 0x91, 0x08,
108  0xf3, 0x85, 0x9b, 0x69, 0x16, 0x78, 0x0d, 0xb7, 0x74, 0x51, 0xaa, 0x5b,
109  0x4d, 0x74, 0xe4, 0x29, 0x2e, 0x9e, 0x8e, 0xf7, 0xe5, 0x42, 0x83, 0xb0,
110  0x65, 0xb0, 0xce, 0xc6, 0xb2, 0x8f, 0x5b, 0xb0
111 };
112 
113 static int test_ref_data(void)
114 {
115  FF_DH *dh;
116  int ret = AVERROR(ENOMEM);
117  uint8_t pubkey_test[128];
118  uint8_t sharedkey_test[128];
119 
120  dh = ff_dh_init(1024);
121  if (!dh)
122  goto fail;
123  bn_hex2bn(dh->priv_key, private_key, ret);
124  if (!ret)
125  goto fail;
126  bn_hex2bn(dh->pub_key, public_key, ret);
127  if (!ret)
128  goto fail;
129  if ((ret = ff_dh_write_public_key(dh, pubkey_test, sizeof(pubkey_test))) < 0)
130  goto fail;
131  if (memcmp(pubkey_test, public_key_bin, sizeof(pubkey_test))) {
132  printf("Mismatched generated public key\n");
133  ret = AVERROR_INVALIDDATA;
134  goto fail;
135  } else {
136  printf("Generated public key ok\n");
137  }
139  sharedkey_test, sizeof(sharedkey_test))) < 0)
140  goto fail;
141  if (memcmp(shared_secret, sharedkey_test, sizeof(sharedkey_test))) {
142  printf("Mismatched generated shared key\n");
143  ret = AVERROR_INVALIDDATA;
144  } else {
145  printf("Generated shared key ok\n");
146  }
147 fail:
148  ff_dh_free(dh);
149  return ret;
150 }
151 
152 int main(void)
153 {
155  if (test_random_shared_secret() < 0)
156  return 1;
157  if (test_ref_data() < 0)
158  return 1;
159  return 0;
160 }
#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:374
Definition: rtmpdh.h:50
static const uint8_t public_key_bin[]
Definition: rtmpdh.c:73
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&#39;s public value...
Definition: rtmpdh.c:390
void ff_dh_free(FF_DH *dh)
Free a Diffie-Hellmann context.
Definition: rtmpdh.c:269
FFBigNum priv_key
Definition: rtmpdh.h:54
uint8_t
int ff_dh_generate_public_key(FF_DH *dh)
Generate a public key.
Definition: rtmpdh.c:348
static const char * public_key
Definition: rtmpdh.c:68
static const uint8_t peer_public_key[]
Definition: rtmpdh.c:86
int avformat_network_init(void)
Do global initialization of network libraries.
Definition: utils.c:5040
int main(void)
Definition: rtmpdh.c:152
static const uint8_t shared_secret[]
Definition: rtmpdh.c:99
#define fail()
Definition: checkasm.h:122
RTMP Diffie-Hellmann utilities.
static const char * private_key
Definition: rtmpdh.c:63
static int test_ref_data(void)
Definition: rtmpdh.c:113
Main libavformat public API header.
av_cold FF_DH * ff_dh_init(int key_len)
Initialize a Diffie-Hellmann context.
Definition: rtmpdh.c:321
FFBigNum pub_key
Definition: rtmpdh.h:53
static int test_random_shared_secret(void)
Definition: rtmpdh.c:24
printf("static const uint8_t my_array[100] = {\n")
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions