OSSCA Chromium

기여 목록 / 8312049

[WebCrypto] Fix exportKey() and wrapKey() error ordering

BlinkfixMerged

WebCrypto의 exportKey()와 wrapKey()가 스펙과 다른 순서로 에러를 검사하던 문제를 고쳤습니다. export를 지원하지 않는 알고리즘의 키에 대해 NotSupportedError 대신 InvalidAccessError를 던지고 있었습니다. 6파일 +118/−8, 새 WPT 1개 추가.

문제 설명

  • issue url: https://crbug.com/41264071
  • 스펙은 exportKey 6단계, wrapKey 11단계에서 "키의 알고리즘이 export key 연산을 지원하는지"를 먼저 보고 NotSupportedError를 던집니다. [[extractable]] 검사(InvalidAccessError)는 그다음 단계입니다.
  • Blink는 앞의 검사를 아예 건너뛰고 있었습니다. 코드에도 TODO(crbug.com/628416)로 순서가 스펙과 다르다는 주석이 남아 있었습니다.
  • HKDF, PBKDF2 키는 non-extractable로만 import할 수 있어서 두 조건이 항상 동시에 참이고, 그래서 이 순서 차이가 실제로 드러납니다.

해결 내용

  1. web_crypto_algorithm.h의 연산 enum에 kWebCryptoOperationExportKey를 추가했습니다.
  2. web_crypto_algorithm.cc의 알고리즘 정보 표에 ExportKey 열을 채웠습니다. HKDF, PBKDF2, SHA 계열만 kUndefined(미지원)입니다.
  3. subtle_crypto.cc의 exportKey(), wrapKey()에서 extractable 검사보다 먼저 export 지원 여부를 확인하도록 했습니다. 기존 TODO 주석은 지웠습니다.
  4. normalize_algorithm.cc에 새 enum 값의 문자열 매핑("exportKey")을 추가했습니다.
// 14.3.10.6: If the name member of the [[algorithm]] internal slot of key
//            does not identify a registered algorithm that supports the
//            export key operation, then throw a NotSupportedError.
const WebCryptoAlgorithmInfo* algorithm_info =
    WebCryptoAlgorithm::LookupAlgorithmInfo(key->Key().Algorithm().Id());
if (algorithm_info->operation_to_params_type[kWebCryptoOperationExportKey] ==
    WebCryptoAlgorithmInfo::kUndefined) {
  exception_state.ThrowDOMException(
      DOMExceptionCode::kNotSupportedError,
      StrCat({algorithm_info->name, ": Unsupported operation: exportKey"}));
  return EmptyPromise();
}

동작이 바뀐 HKDF exportKey 웹 테스트는 기대값을 다시 만들었습니다.

-error is: InvalidAccessError: Failed to execute 'exportKey' on 'SubtleCrypto': key is not extractable
+error is: NotSupportedError: Failed to execute 'exportKey' on 'SubtleCrypto': HKDF: Unsupported operation: exportKey

리뷰 과정

  • dcheng@: wrapKey 쪽 주석에 exportKey가 나오는 게 오타인지 질문 → 오타가 아니라 "exportKey는 항상 지원된다"는 전제가 깨졌기 때문에 wrapKey 쪽 검사도 더는 건너뛸 수 없다는 뜻이라고 답했습니다.
  • davidben@: supports()의 연산 목록에도 exportKey를 넣어야 하지 않느냐는 지적 → 이 CL은 WPT 하나로 범위를 유지하고, TODO를 남긴 뒤 후속 CL에서 WPT와 함께 처리하기로 합의했습니다.
  • 후속 CL: 8471207 "[WebCrypto] Fix supports() for exportKey and wrapKey"

테스트 방법

  • 새 WPT WebCryptoAPI/export-key-error-order.https.any.js를 추가했습니다.
    • HKDF, PBKDF2 키로 exportKey(), wrapKey() 호출 시 NotSupportedError
    • 대조군: non-extractable AES-CBC 키는 여전히 InvalidAccessError
  • 수정 코드 없이 테스트만 먼저 올린 패치셋(PS2)에서 새 WPT가 mac-rel에서 실패하는 것을 확인했고, 수정 후 통과했습니다.
  • 수정을 넣은 PS3에서 기존 crypto/subtle/hkdf/exportKey.html이 실패해 PS4에서 기대값을 갱신했습니다.
  • CQ 통과 후 머지. 추가한 WPT는 upstream으로 자동 export되어 web-platform-tests/wpt#62737로 머지되었습니다.

배운 점

  • Chromium에서 처음 WPT 관련 이슈를 진행해보면서 새로운 도메인을 익힐 수 있었습니다.
  • WebCrypto 모듈을 살펴보면서 상당히 복잡하게 구현되어 있어 어려움이 있었지만 AI와 함께 잘 이겨낼 수 있었습니다.

참고 자료