Changeset 270532 in webkit


Ignore:
Timestamp:
Dec 8, 2020 2:36:49 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

    r270527 r270532  
     12020-12-08  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  Truitt Savell  <tsavell@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r270531 r270532  
     12020-12-08  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-08  Joonghun Park  <jh718.park@samsung.com>
    230
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp

    r270518 r270532  
    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

    r270518 r270532  
    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

    r270518 r270532  
    150150ExceptionOr<void> RTCRtpSFrameTransformer::setEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t> keyId)
    151151{
     152    if (keyId && *keyId == std::numeric_limits<uint64_t>::max())
     153        return Exception { TypeError, "Key ID is too big" };
     154
     155    auto locker = holdLock(m_keyLock);
     156    return updateEncryptionKey(rawKey, keyId, ShouldUpdateKeys::Yes);
     157}
     158
     159ExceptionOr<void> RTCRtpSFrameTransformer::updateEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t> keyId, ShouldUpdateKeys shouldUpdateKeys)
     160{
     161    ASSERT(!keyId || *keyId != std::numeric_limits<uint64_t>::max());
     162
     163    ASSERT(m_keyLock.isLocked());
     164
    152165    auto saltKeyResult = computeSaltKey(rawKey);
    153166    if (saltKeyResult.hasException())
     
    164177        return encryptionKeyResult.releaseException();
    165178
    166     auto locker = holdLock(m_keyLock);
     179    if (!keyId)
     180        keyId = m_keys.size();
     181
     182    m_keyId = *keyId;
     183    if (shouldUpdateKeys == ShouldUpdateKeys::Yes)
     184        m_keys.set(*keyId + 1, rawKey);
    167185
    168186    m_saltKey = saltKeyResult.releaseReturnValue();
    169187    m_authenticationKey = authenticationKeyResult.releaseReturnValue();
    170188    m_encryptionKey = encryptionKeyResult.releaseReturnValue();
    171 
    172     if (keyId)
    173         m_keyId = *keyId;
    174189
    175190    updateAuthenticationSize();
     
    205220
    206221    if (header->keyId != m_keyId) {
    207         // FIXME: We should search for keys.
    208         return Exception { NotSupportedError };
     222        if (header->keyId == std::numeric_limits<uint64_t>::max())
     223            return Exception { DataError, "Key ID is unknown" };
     224
     225        auto iterator = m_keys.find(header->keyId + 1);
     226        if (iterator == m_keys.end())
     227            return Exception { DataError, "Key ID is unknown" };
     228        auto result = updateEncryptionKey(iterator->value, header->keyId, ShouldUpdateKeys::No);
     229        if (result.hasException())
     230            return result.releaseException();
    209231    }
    210232
  • trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h

    r270518 r270532  
    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

    r270518 r270532  
    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

    r270518 r270532  
    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

    r270518 r270532  
    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.