~ubuntu-branches/ubuntu/trusty/rtmpdump/trusty

« back to all changes in this revision

Viewing changes to librtmp/handshake.h

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2010-07-05 19:57:14 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100705195714-f4hefj53rge6g7vr
Tags: 2.3-1
* New upstream release:
  + debian/patches/02_fix_gnutls_teardown.diff:
    - Dropped, merged upstream.
  + debian/librtmp0.install,
    debian/librtmp0.symbols,
    debian/control,
    debian/librtmp-dev.install,
    debian/rules:
    - Add shared library package.
  + debian/patches/01_unbreak_makefile.diff:
    - Refreshed and fixed the clean rule too.
  + debian/patches/02_strtime-visibility.patch:
    - Hide the private strtime symbol by making it static
      to prevent any symbol conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *
18
18
 *  You should have received a copy of the GNU Lesser General Public License
19
19
 *  along with librtmp see the file COPYING.  If not, write to
20
 
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
21
 *  Boston, MA  02110-1301, USA.
21
22
 *  http://www.gnu.org/copyleft/lgpl.html
22
23
 */
23
24
 
35
36
#define HMAC_finish(ctx, dig, dlen)     dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig)
36
37
 
37
38
typedef arc4_context *  RC4_handle;
38
 
#define RC4_setup(h)    *h = malloc(sizeof(arc4_context))
 
39
#define RC4_alloc(h)    *h = malloc(sizeof(arc4_context))
39
40
#define RC4_setkey(h,l,k)       arc4_setup(h,k,l)
40
41
#define RC4_encrypt(h,l,d)      arc4_crypt(h,l,(unsigned char *)d,(unsigned char *)d)
41
42
#define RC4_encrypt2(h,l,s,d)   arc4_crypt(h,l,(unsigned char *)s,(unsigned char *)d)
 
43
#define RC4_free(h)     free(h)
42
44
 
43
45
#elif defined(USE_GNUTLS)
44
46
#include <gcrypt.h>
51
53
#define HMAC_finish(ctx, dig, dlen)     dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen); gcry_md_close(ctx)
52
54
 
53
55
typedef gcry_cipher_hd_t        RC4_handle;
54
 
#define RC4_setup(h)    gcry_cipher_open(h, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)
 
56
#define RC4_alloc(h)    gcry_cipher_open(h, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)
55
57
#define RC4_setkey(h,l,k)       gcry_cipher_setkey(h,k,l)
56
58
#define RC4_encrypt(h,l,d)      gcry_cipher_encrypt(h,(void *)d,l,NULL,0)
57
59
#define RC4_encrypt2(h,l,s,d)   gcry_cipher_encrypt(h,(void *)d,l,(void *)s,l)
 
60
#define RC4_free(h)     gcry_cipher_close(h)
58
61
 
59
62
#else   /* USE_OPENSSL */
60
63
#include <openssl/sha.h>
68
71
#define HMAC_finish(ctx, dig, dlen)     HMAC_Final(&ctx, dig, &dlen); HMAC_CTX_cleanup(&ctx)
69
72
 
70
73
typedef RC4_KEY *       RC4_handle;
71
 
#define RC4_setup(h)    *h = malloc(sizeof(RC4_KEY))
 
74
#define RC4_alloc(h)    *h = malloc(sizeof(RC4_KEY))
72
75
#define RC4_setkey(h,l,k)       RC4_set_key(h,l,k)
73
76
#define RC4_encrypt(h,l,d)      RC4(h,l,(uint8_t *)d,(uint8_t *)d)
74
77
#define RC4_encrypt2(h,l,s,d)   RC4(h,l,(uint8_t *)s,(uint8_t *)d)
 
78
#define RC4_free(h)     free(h)
75
79
#endif
76
80
 
77
81
#define FP10
112
116
  unsigned int digestLen = 0;
113
117
  HMAC_CTX ctx;
114
118
 
115
 
  RC4_setup(rc4keyIn);
116
 
  RC4_setup(rc4keyOut);
 
119
  RC4_alloc(rc4keyIn);
 
120
  RC4_alloc(rc4keyOut);
117
121
 
118
122
  HMAC_setup(ctx, secretKey, 128);
119
123
  HMAC_crunch(ctx, pubKeyIn, 128);
283
287
  HMACsha256(message, messageLen, key, keyLen, digest);
284
288
}
285
289
 
286
 
static bool
 
290
static int
287
291
VerifyDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key,
288
292
             size_t keyLen)
289
293
{
354
358
  out[7] = v1;
355
359
}
356
360
 
357
 
static bool
358
 
HandShake(RTMP * r, bool FP9HandShake)
 
361
static int
 
362
HandShake(RTMP * r, int FP9HandShake)
359
363
{
360
364
  int i, offalg = 0;
361
365
  int dhposClient = 0;
362
366
  int digestPosClient = 0;
363
 
  bool encrypted = r->Link.protocol & RTMP_FEATURE_ENC;
 
367
  int encrypted = r->Link.protocol & RTMP_FEATURE_ENC;
364
368
 
365
369
  RC4_handle keyIn = 0;
366
370
  RC4_handle keyOut = 0;
374
378
  getoff *getdh = NULL, *getdig = NULL;
375
379
 
376
380
  if (encrypted || r->Link.SWFSize)
377
 
    FP9HandShake = true;
 
381
    FP9HandShake = TRUE;
378
382
  else
379
 
    FP9HandShake = false;
 
383
    FP9HandShake = FALSE;
380
384
 
381
385
  r->Link.rc4keyIn = r->Link.rc4keyOut = 0;
382
386
 
436
440
            {
437
441
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
438
442
                  __FUNCTION__);
439
 
              return false;
 
443
              return FALSE;
440
444
            }
441
445
 
442
446
          dhposClient = getdh(clientsig, RTMP_SIG_SIZE);
446
450
            {
447
451
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't generate Diffie-Hellmann public key!",
448
452
                  __FUNCTION__);
449
 
              return false;
 
453
              return FALSE;
450
454
            }
451
455
 
452
456
          if (!DHGetPublicKey(r->Link.dh, &clientsig[dhposClient], 128))
453
457
            {
454
458
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't write public key!", __FUNCTION__);
455
 
              return false;
 
459
              return FALSE;
456
460
            }
457
461
        }
458
462
 
474
478
#endif
475
479
 
476
480
  if (!WriteN(r, (char *)clientsig-1, RTMP_SIG_SIZE + 1))
477
 
    return false;
 
481
    return FALSE;
478
482
 
479
483
  if (ReadN(r, (char *)&type, 1) != 1)  /* 0x03 or 0x06 */
480
 
    return false;
 
484
    return FALSE;
481
485
 
482
486
  RTMP_Log(RTMP_LOGDEBUG, "%s: Type Answer   : %02X", __FUNCTION__, type);
483
487
 
486
490
        __FUNCTION__, clientsig[-1], type);
487
491
 
488
492
  if (ReadN(r, (char *)serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
489
 
    return false;
 
493
    return FALSE;
490
494
 
491
495
  /* decode server response */
492
496
  memcpy(&uptime, serversig, 4);
497
501
      serversig[5], serversig[6], serversig[7]);
498
502
 
499
503
  if (FP9HandShake && type == 3 && !serversig[4])
500
 
    FP9HandShake = false;
 
504
    FP9HandShake = FALSE;
501
505
 
502
506
#ifdef _DEBUG
503
507
  RTMP_Log(RTMP_LOGDEBUG, "Server signature:");
523
527
          if (!VerifyDigest(digestPosServer, serversig, GenuineFMSKey, 36))
524
528
            {
525
529
              RTMP_Log(RTMP_LOGERROR, "Couldn't verify the server digest");     /* continuing anyway will probably fail */
526
 
              return false;
 
530
              return FALSE;
527
531
            }
528
532
        }
529
533
 
557
561
          if (len < 0)
558
562
            {
559
563
              RTMP_Log(RTMP_LOGDEBUG, "%s: Wrong secret key position!", __FUNCTION__);
560
 
              return false;
 
564
              return FALSE;
561
565
            }
562
566
 
563
567
          RTMP_Log(RTMP_LOGDEBUG, "%s: Secret key: ", __FUNCTION__);
630
634
  RTMP_LogHex(RTMP_LOGDEBUG, reply, RTMP_SIG_SIZE);
631
635
#endif
632
636
  if (!WriteN(r, (char *)reply, RTMP_SIG_SIZE))
633
 
    return false;
 
637
    return FALSE;
634
638
 
635
639
  /* 2nd part of handshake */
636
640
  if (ReadN(r, (char *)serversig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
637
 
    return false;
 
641
    return FALSE;
638
642
 
639
643
#ifdef _DEBUG
640
644
  RTMP_Log(RTMP_LOGDEBUG, "%s: 2nd handshake: ", __FUNCTION__);
694
698
           SHA256_DIGEST_LENGTH) != 0)
695
699
        {
696
700
          RTMP_Log(RTMP_LOGWARNING, "%s: Server not genuine Adobe!", __FUNCTION__);
697
 
          return false;
 
701
          return FALSE;
698
702
        }
699
703
      else
700
704
        {
731
735
    }
732
736
 
733
737
  RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
734
 
  return true;
 
738
  return TRUE;
735
739
}
736
740
 
737
 
static bool
 
741
static int
738
742
SHandShake(RTMP * r)
739
743
{
740
744
  int i, offalg = 0;
742
746
  int digestPosServer = 0;
743
747
  RC4_handle keyIn = 0;
744
748
  RC4_handle keyOut = 0;
745
 
  bool FP9HandShake = false;
746
 
  bool encrypted;
 
749
  int FP9HandShake = FALSE;
 
750
  int encrypted;
747
751
  int32_t *ip;
748
752
 
749
753
  uint8_t clientsig[RTMP_SIG_SIZE];
753
757
  getoff *getdh = NULL, *getdig = NULL;
754
758
 
755
759
  if (ReadN(r, (char *)&type, 1) != 1)  /* 0x03 or 0x06 */
756
 
    return false;
 
760
    return FALSE;
757
761
 
758
762
  if (ReadN(r, (char *)clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
759
 
    return false;
 
763
    return FALSE;
760
764
 
761
765
  RTMP_Log(RTMP_LOGDEBUG, "%s: Type Requested : %02X", __FUNCTION__, type);
762
766
  RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
763
767
 
764
768
  if (type == 3)
765
769
    {
766
 
      encrypted = false;
 
770
      encrypted = FALSE;
767
771
    }
768
772
  else if (type == 6 || type == 8)
769
773
    {
770
774
      offalg = 1;
771
 
      encrypted = true;
772
 
      FP9HandShake = true;
 
775
      encrypted = TRUE;
 
776
      FP9HandShake = TRUE;
773
777
      r->Link.protocol |= RTMP_FEATURE_ENC;
774
778
      /* use FP10 if client is capable */
775
779
      if (clientsig[4] == 128)
779
783
    {
780
784
      RTMP_Log(RTMP_LOGERROR, "%s: Unknown version %02x",
781
785
          __FUNCTION__, type);
782
 
      return false;
 
786
      return FALSE;
783
787
    }
784
788
 
785
789
  if (!FP9HandShake && clientsig[4])
786
 
    FP9HandShake = true;
 
790
    FP9HandShake = TRUE;
787
791
 
788
792
  serversig[-1] = type;
789
793
 
828
832
            {
829
833
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
830
834
                  __FUNCTION__);
831
 
              return false;
 
835
              return FALSE;
832
836
            }
833
837
 
834
838
          dhposServer = getdh(serversig, RTMP_SIG_SIZE);
838
842
            {
839
843
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't generate Diffie-Hellmann public key!",
840
844
                  __FUNCTION__);
841
 
              return false;
 
845
              return FALSE;
842
846
            }
843
847
 
844
848
          if (!DHGetPublicKey
845
849
              (r->Link.dh, (uint8_t *) &serversig[dhposServer], 128))
846
850
            {
847
851
              RTMP_Log(RTMP_LOGERROR, "%s: Couldn't write public key!", __FUNCTION__);
848
 
              return false;
 
852
              return FALSE;
849
853
            }
850
854
        }
851
855
 
865
869
  RTMP_LogHex(RTMP_LOGDEBUG2, serversig, RTMP_SIG_SIZE);
866
870
 
867
871
  if (!WriteN(r, (char *)serversig-1, RTMP_SIG_SIZE + 1))
868
 
    return false;
 
872
    return FALSE;
869
873
 
870
874
  /* decode client response */
871
875
  memcpy(&uptime, clientsig, 4);
895
899
          if (!VerifyDigest(digestPosClient, clientsig, GenuineFPKey, 30))
896
900
            {
897
901
              RTMP_Log(RTMP_LOGERROR, "Couldn't verify the client digest");     /* continuing anyway will probably fail */
898
 
              return false;
 
902
              return FALSE;
899
903
            }
900
904
        }
901
905
 
931
935
          if (len < 0)
932
936
            {
933
937
              RTMP_Log(RTMP_LOGDEBUG, "%s: Wrong secret key position!", __FUNCTION__);
934
 
              return false;
 
938
              return FALSE;
935
939
            }
936
940
 
937
941
          RTMP_Log(RTMP_LOGDEBUG, "%s: Secret key: ", __FUNCTION__);
994
998
  RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
995
999
 
996
1000
  if (!WriteN(r, (char *)clientsig, RTMP_SIG_SIZE))
997
 
    return false;
 
1001
    return FALSE;
998
1002
 
999
1003
  /* 2nd part of handshake */
1000
1004
  if (ReadN(r, (char *)clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
1001
 
    return false;
 
1005
    return FALSE;
1002
1006
 
1003
1007
  RTMP_Log(RTMP_LOGDEBUG2, "%s: 2nd handshake: ", __FUNCTION__);
1004
1008
  RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
1049
1053
           SHA256_DIGEST_LENGTH) != 0)
1050
1054
        {
1051
1055
          RTMP_Log(RTMP_LOGWARNING, "%s: Client not genuine Adobe!", __FUNCTION__);
1052
 
          return false;
 
1056
          return FALSE;
1053
1057
        }
1054
1058
      else
1055
1059
        {
1085
1089
    }
1086
1090
 
1087
1091
  RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
1088
 
  return true;
 
1092
  return TRUE;
1089
1093
}