요약

  • RFC 2440는 OpenPGP 패킷 태그를 다수 정의했지만 영구적인 새 태그를 추가하는 통상 절차는 의도적으로 두지 않았다. 기능 간 상호작용이 프로토콜 전체의 보안을 저하시킬 수 있기 때문이다.
  • 패킷 헤더의 남은 번호 공간은 사용 허가가 아니었다. 사양은 60~63을 사적 또는 실험적 용도로 예약하고, 새 값에 대한 요청은 보안 영역(Security Area) 검토 또는 적절한 IETF 워킹 그룹으로 보내도록 했다.
  • 서명 내부에서 알 수 없는 하위 패킷은 일반적으로 무시되지만, 서명자가 critical 비트를 설정하면 기능의 의미를 조용히 잃는 것보다 오류를 선호하게 만들 수 있었다. 인식되었다는 것만으로 구현되었다는 뜻은 아니며, 해시 처리되지 않은 메타데이터는 확정적 증거가 아니었다.
  • 이후 버전들은 이 절제를 명시적 레지스트리와 더 강한 검토 규칙으로 만들었다. 할당된 번호, 정상 파싱, 유효한 서명이나 테스트는 각자의 계층만 증명할 뿐, 안전한 조합이나 배포까지 증명하지 않는다.

빈 슬롯이 곧 결정은 아니었다

OpenPGP 패킷에서 사용되지 않은 태그를 발견한 개발자를 상상해 보자. 두 개의 새 클라이언트에 만든 프로토타입이 값을 쓰고 다시 읽어 테스트를 통과했다. 바이트는 맞아 들어간다. 그런데 구형 검증기는 이 기능을 어떻게 다룰까? 발신자가 이를 협상으로 제거할 수 있을까? 다른 패킷이 그 의미를 바꿀 수 있을까? 새로운 의미가 무시된 채 서명이 여전히 수학적으로 유효할 수 있을까? 로컬 왕복 테스트는 이 질문들에 아무것도 답해 주지 않는다.

1998년 11월 RFC 2440의 IESG 노트에 적힌 우려가 바로 이것이었다. 문서는 많은 태그 값을 정의했지만 더 추가하는 통상적인 메커니즘은 두지 않았다. 새 형식의 패킷 헤더가 63까지의 태그를 표현할 수 있었음에도, 사양은 새 기능과 기존 기능 사이의 미묘한 상호작용이 전체 보안을 크게 저하시킬 수 있다고 경고했다. 새 값에 대한 요청—암호화 알고리즘이 그 예였다—은 IESG 보안 영역 디렉터 또는 적절한 워킹 그룹으로 보내도록 했다. 60에서 63까지의 값은 사적 또는 실험적 용도로 남았다. 번호 공간은 존재했지만, 안전한 확장 절차가 자동으로 따라오지는 않았다.

이 노트가 중요한 이유는 OpenPGP가 독립적인 알고리즘들의 모음이 아니기 때문이다. 패킷들은 키, 서명, 암호화 메시지로 조합된다. 하나의 기능은 구형 소프트웨어가 시퀀스를 파싱하는 방식, 신형 소프트웨어가 레거시 필드를 해석하는 방식, 또는 수신자가 서명이 무엇을 커버한다고 믿는지를 바꿀 수 있다. 태그는 문법적으로 사용 가능하면서도 그 상호작용은 아무도 검토하지 않은 상태일 수 있다. RFC 2440은 인코딩 수용력과 프로토콜 허가를 분리했다.

서명이 경계를 드러냈다

같은 긴장은 더 작은 규모인 서명 하위 패킷에서도 나타났다. 하위 호환성 측면에서 낯선 하위 패킷을 무시하는 것이 유리했다. 구형 구현은 자신이 모르는 메타데이터를 실어 온 서명이라도 여전히 처리할 수 있었기 때문이다. 그래서 RFC 2440은 구현이 인식하지 못한 하위 패킷 유형은 무시해야 한다고 명시했다. 그러나 조용한 무시는 서명자가 의존한 기능까지 지워버릴 수도 있었다.

하위 패킷 유형의 7번 비트가 선택지를 제공했다. 이 비트가 알 수 없는 하위 패킷을 critical로 표시하면, 평가자는 그 서명을 오류로 간주해야 한다. 서명자는 의미가 버려진 뒤의 승인보다 눈에 보이는 실패를 선호할 수 있었다. 이것이 만능 보장은 아니었다. 평가자가 규칙을 인식해야 했고, 인식된 하위 패킷이라도 구현되지 않았을 수 있었다. 표준은 이 두 상태를 명시적으로 구분했다.

유효한 서명에 붙은, 인식된 값조차 반드시 서명 권위를 갖는 것은 아니었다. 하위 패킷은 해시 처리된 영역에도, 처리되지 않은(unhashed) 영역에도 나타날 수 있었다. RFC 2440은 해시 처리되지 않은 하위 패킷의 정보는 서명 본체 밖에 있기 때문에 확정적이지 않다고 경고했다. 패킷 판독자는 그것을 볼 수 있고, 검증자는 그것을 파싱할 수 있지만, 어느 사실도 그것이 암호학적으로 커버된다는 뜻은 아니었다. 존재, 파싱됨, 인식됨, 구현됨, 커버됨—이 경계들은 서로 분리되어 있었다.

주의에서 레지스트리로

2007년 RFC 2440를 대체한 RFC 4880은 패킷 할당을 명시적인 IANA 레지스트리로 옮기고, 새 패킷 유형에 IETF 합의를 요구하며 이를 주요 기능으로 다루었다. 수정 감지 동작의 확장에 관한 다운그레이드 및 크로스그레이드 위험도 짚었다. 거버넌스는 더 읽기 쉬워졌지만, 검토가 상호운용성, 구현, 보안 분석을 하나의 체크박스로 압축할 수는 없었다.

2024년에 공개된 RFC 9580은 RFC 4880을 대체하며 차등화된 할당 절차를 유지한다. 일부 OpenPGP 레지스트리는 Specification Required를 사용하고, 패킷 유형과 일부 버전·신원 공간은 더 엄격한 RFC Required 정책을 따른다. 담당 전문가들은 보안 특성과 기존 구현과의 상호운용성을 고려하도록 요청받는다. 이는 초기 공백에 대한 제도적 답이지, 어떤 승인된 확장이 모든 배포 환경에서 안전하다는 증명이 아니다.

이 문서들은 모든 가능한 확장이 유해했다거나, 모든 구현자가 하나의 관행을 따랐다거나, 검토 절차가 모든 상호작용을 예측할 수 있다고 확립하지 않는다. 더 유용한 역사적 사실만 보여준다. 암호 프로토콜에서 하나의 의미를 추가하는 것은 기존 경로의 동작을 바꿀 수 있다는 점이다. 사용 가능한 정수는 형식 안의 주소일 뿐이며, 호환성, 암호학적 커버리지, 사용자 이해, 운영 안전성의 증거가 아니다.

출처