Changeset 270507 in webkit


Ignore:
Timestamp:
Dec 7, 2020 9:22:32 AM (20 months ago)
Author:
youenn@apple.com
Message:

Allow RTCRtpSFrameTransform to handle multiple keys
https://bugs.webkit.org/show_bug.cgi?id=219598

Reviewed by Eric Carlson.

Source/WebCore:

Keep a map of ID to Key material when setEncryptionKey is called.
Use that map on decryption side to get key material from key ID.
Add internals API to validate key retrieval is done correctly.
If setEncryptionKey key ID is not set, we use the map size which allows to use 0, 1, 2 and so on...

Test: webrtc/sframe-keys.html

  • Modules/mediastream/RTCRtpSFrameTransform.cpp:

(WebCore::RTCRtpSFrameTransform::keyIdForTesting const):

  • Modules/mediastream/RTCRtpSFrameTransform.h:
  • Modules/mediastream/RTCRtpSFrameTransformer.cpp:

(WebCore::RTCRtpSFrameTransformer::setEncryptionKey):
(WebCore::RTCRtpSFrameTransformer::updateEncryptionKey):
(WebCore::RTCRtpSFrameTransformer::decryptFrame):

  • Modules/mediastream/RTCRtpSFrameTransformer.h:

(WebCore::RTCRtpSFrameTransformer::keyId const):

  • testing/Internals.cpp:

(WebCore::Internals::sframeKeyId):

  • testing/Internals.h:
  • testing/Internals.idl:

LayoutTests:

  • webrtc/sframe-keys-expected.txt: Added.
  • webrtc/sframe-keys.html: Added.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r270506 r270507  
     12020-12-07  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow RTCRtpSFrameTransform to handle multiple keys
     4        https://bugs.webkit.org/show_bug.cgi?id=219598
     5
     6        Reviewed by Eric Carlson.
     7
     8        * webrtc/sframe-keys-expected.txt: Added.
     9        * webrtc/sframe-keys.html: Added.
     10
    1112020-12-07  Youenn Fablet  <youenn@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r270506 r270507  
     12020-12-07  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow RTCRtpSFrameTransform to handle multiple keys
     4        https://bugs.webkit.org/show_bug.cgi?id=219598
     5
     6        Reviewed by Eric Carlson.
     7
     8        Keep a map of ID to Key material when setEncryptionKey is called.
     9        Use that map on decryption side to get key material from key ID.
     10        Add internals API to validate key retrieval is done correctly.
     11        If setEncryptionKey key ID is not set, we use the map size which allows to use 0, 1, 2 and so on...
     12
     13        Test: webrtc/sframe-keys.html
     14
     15        * Modules/mediastream/RTCRtpSFrameTransform.cpp:
     16        (WebCore::RTCRtpSFrameTransform::keyIdForTesting const):
     17        * Modules/mediastream/RTCRtpSFrameTransform.h:
     18        * Modules/mediastream/RTCRtpSFrameTransformer.cpp:
     19        (WebCore::RTCRtpSFrameTransformer::setEncryptionKey):
     20        (WebCore::RTCRtpSFrameTransformer::updateEncryptionKey):
     21        (WebCore::RTCRtpSFrameTransformer::decryptFrame):
     22        * Modules/mediastream/RTCRtpSFrameTransformer.h:
     23        (WebCore::RTCRtpSFrameTransformer::keyId const):
     24        * testing/Internals.cpp:
     25        (WebCore::Internals::sframeKeyId):
     26        * testing/Internals.h:
     27        * testing/Internals.idl:
     28
    1292020-12-07  Youenn Fablet  <youenn@apple.com>
    230
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp

    r270506 r270507  
    8181}
    8282
     83uint64_t RTCRtpSFrameTransform::keyIdForTesting() const
     84{
     85    return m_transformer->keyId();
     86}
     87
    8388bool RTCRtpSFrameTransform::isAttached() const
    8489{
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h

    r270506 r270507  
    6161
    6262    WEBCORE_EXPORT uint64_t counterForTesting() const;
     63    WEBCORE_EXPORT uint64_t keyIdForTesting() const;
    6364
    6465    ExceptionOr<RefPtr<ReadableStream>> readable();
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp

    r270506 r270507  
    150150ExceptionOr<void> RTCRtpSFrameTransformer::setEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t> keyId)
    151151{
     152    auto locker = holdLock(m_keyLock);
     153    return updateEncryptionKey(rawKey, keyId, ShouldUpdateKeys::Yes);
     154}
     155
     156ExceptionOr<void> RTCRtpSFrameTransformer::updateEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t> keyId, ShouldUpdateKeys shouldUpdateKeys)
     157{
     158    ASSERT(m_keyLock.isLocked());
     159
    152160    auto saltKeyResult = computeSaltKey(rawKey);
    153161    if (saltKeyResult.hasException())
     
    164172        return encryptionKeyResult.releaseException();
    165173
    166     auto locker = holdLock(m_keyLock);
     174    if (!keyId)
     175        keyId = m_keys.size();
     176
     177    m_keyId = *keyId;
     178    if (shouldUpdateKeys == ShouldUpdateKeys::Yes)
     179        m_keys.set(*keyId, rawKey);
    167180
    168181    m_saltKey = saltKeyResult.releaseReturnValue();
    169182    m_authenticationKey = authenticationKeyResult.releaseReturnValue();
    170183    m_encryptionKey = encryptionKeyResult.releaseReturnValue();
    171 
    172     if (keyId)
    173         m_keyId = *keyId;
    174184
    175185    updateAuthenticationSize();
     
    205215
    206216    if (header->keyId != m_keyId) {
    207         // FIXME: We should search for keys.
    208         return Exception { NotSupportedError };
     217        auto iterator = m_keys.find(header->keyId);
     218        if (iterator == m_keys.end())
     219            return Exception { DataError, "Key ID is unknown" };
     220        auto result = updateEncryptionKey(iterator->value, iterator->key, ShouldUpdateKeys::No);
     221        if (result.hasException())
     222            return result.releaseException();
    209223    }
    210224
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h

    r270506 r270507  
    2929
    3030#include "ExceptionOr.h"
     31#include <wtf/HashMap.h>
    3132#include <wtf/Lock.h>
    3233#include <wtf/ThreadSafeRefCounted.h>
     
    5354    const Vector<uint8_t>& saltKey() const { return m_saltKey; }
    5455
     56    uint64_t keyId() const { return m_keyId; }
    5557    uint64_t counter() const { return m_counter; }
    5658    void setCounter(uint64_t counter) { m_counter = counter; }
     
    6163    ExceptionOr<Vector<uint8_t>> decryptFrame(const uint8_t*, size_t);
    6264    ExceptionOr<Vector<uint8_t>> encryptFrame(const uint8_t*, size_t);
     65
     66    enum class ShouldUpdateKeys { No, Yes };
     67    ExceptionOr<void> updateEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t>, ShouldUpdateKeys = ShouldUpdateKeys::Yes);
    6368
    6469    ExceptionOr<Vector<uint8_t>> computeSaltKey(const Vector<uint8_t>&);
     
    7681    Vector<uint8_t> m_encryptionKey;
    7782    Vector<uint8_t> m_saltKey;
     83    HashMap<uint64_t, Vector<uint8_t>> m_keys;
    7884
    7985    bool m_isEncrypting { false };
  • trunk/Source/WebCore/testing/Internals.cpp

    r270256 r270507  
    15821582}
    15831583
     1584uint64_t Internals::sframeKeyId(const RTCRtpSFrameTransform& transform)
     1585{
     1586    return transform.keyIdForTesting();
     1587}
     1588
    15841589void Internals::setEnableWebRTCEncryption(bool value)
    15851590{
  • trunk/Source/WebCore/testing/Internals.h

    r270256 r270507  
    611611    void setWebRTCVP9VTBSupport(bool);
    612612    uint64_t sframeCounter(const RTCRtpSFrameTransform&);
     613    uint64_t sframeKeyId(const RTCRtpSFrameTransform&);
    613614    void setEnableWebRTCEncryption(bool);
    614615    void setUseDTLS10(bool);
  • trunk/Source/WebCore/testing/Internals.idl

    r270256 r270507  
    804804    [Conditional=WEB_RTC] undefined setWebRTCVP9VTBSupport(boolean allowed);
    805805    [Conditional=WEB_RTC] unsigned long long sframeCounter(RTCRtpSFrameTransform transform);
     806    [Conditional=WEB_RTC] unsigned long long sframeKeyId(RTCRtpSFrameTransform transform);
    806807
    807808    [Conditional=MEDIA_STREAM] undefined setMockAudioTrackChannelNumber(MediaStreamTrack track, unsigned short count);
Note: See TracChangeset for help on using the changeset viewer.