2018년 12월 26일 수요일

Bouncy Castle ASN.1 TestCase Reivew

전체적인 소스의 구성을 파악하기 위하여 모든 소스를 리뷰하는 방식보다는 프로그램의 주요 테스트를 하는 TestCase를 살펴보는 것이 빠른 소스 리뷰에 도움이 됩니다.
각 테스트 케이스를 살펴보고 , 거기 사용된 ClassReivew 하도록 하겠습니다.
리뷰의 순서는 TestCase기준으로 알파벳 순으로 정리하였습니다. 알파벳 순으로 정리되었기 때문에 원시 클래스에 가까운 부분의 테스트가 더 이후에 나올 수 있습니다.

BouncyCastle ASN.1 Test케이스의 공통점.

기본적으로 SimpleTest 혹은 Asn1UnitTest 라는 클래스에서 상속 받아 처리하도록 하였으며,
대부분의 경우 해당 TestClass에서 PerformTest() 함수 안에 필요한 실제 테스트의 내용이 들어있습니다.
이후에는 해당 TestClass명을 언급하고 PerformTest()의 내용을 설명하면서 진행하도록 하겠습니다.코드가 중복되거나 같은 영역에 대한 테스트는 삭제합니다.

AdditionalInformationSyntaxTest





사용된 Class는 다음과 같습니다.
AdditionalInformationSyntax
그림에서 보는 바와 같이 기본 클래스인 Asn1Encodeable을 상속 받고 있습니다. ASN1문자열로 반환이 가능하다는 의미입니다.
DirectoryString
ASN.1 정의에 따르면 DirctoryString은 아래와 같으며 해당 부분을 실제로 구현한 것입니다.
DirectoryString ::= CHOICE {
teletexString TeletexString (SIZE (1..MAX)),
printableString PrintableString (SIZE (1..MAX)),
universalString UniversalString (SIZE (1..MAX)),
utf8String UTF8String (SIZE (1..MAX)),
bmpString BMPString (SIZE (1..MAX))
}
다시 정리하면 DirectoryString은 출력가능한 위의 정의된 Type중의 하나여야 한다는 의미입니다.


테스트 코드의 내용 정리


생성시에는 반드시 허용되는 문자열 형식중의 하나가 인자로 전달되어야 하며, 해당인자가 충족하지 않는( new Object()로 생성된 ) 경우는 에러가 발생해야 합니다. 실제로 이 부분은 Spec(X.500)에서 정의된 것과 일치합니다. 인증서 부가 정보에 대한 내용은 X.509에 해당합니다.

AdmissionSyntaxUnitTest

인증서의 규약 자체가 ASN.1으로 서술된 경우가 많습니다.


AdmissionSyntax
ASN.1으로 AdmissionSyntax를 정의하면, 다음과 같습니다. 인증에 관련된 속성을 정의 합니다.
Bouncy Castle 문서 빌드에서 참고.
     AdmissionSyntax ::= SEQUENCE
     {
       admissionAuthority GeneralName OPTIONAL,
       contentsOfAdmissions SEQUENCE OF Admissions
     }
 

     Admissions ::= SEQUENCE
     {
       admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
       namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
       professionInfos SEQUENCE OF ProfessionInfo
     }
 

     NamingAuthority ::= SEQUENCE
     {
       namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
       namingAuthorityUrl IA5String OPTIONAL,
       namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
     }
 

     ProfessionInfo ::= SEQUENCE
     {
       namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
       professionItems SEQUENCE OF DirectoryString (SIZE(1..128)),
       professionOIDs SEQUENCE OF OBJECT IDENTIFIER OPTIONAL,
       registrationNumber PrintableString(SIZE(1..128)) OPTIONAL,
       addProfessionInfo OCTET STRING OPTIONAL
     }
상당히 복잡한 문서인증 구조를 현실화 한 것으로, 위의 ASN.1에서 구성된 내용을 Class화 하여 구성하였습니다. 구조가 복잡해 보이는데 실제로 복잡한 것이 맞습니다. (X.509에서 다루는 예외의 범위가 넓어서 클래스의 구성이 복잡해 집니다.)
각 명칭에 해당하는 Class들이 동일한 이름으로, 생성되어 있을 것을 볼 수 있습니다.


위의 테스트 코드에서 볼수 있 듯이, ASN.1 자체를 Spec에서 직접 처리하는 기능은 Bouncy Castle의 범위가 아닙니다.
정상적인 케이스를 테스트 하고, 의도한 비 정상적인 케이스를 테스트 합니다.


Asn1SequenceParserTest

단순 Asn1SquenceParser 테스트 항목입니다. 이래적으로 상속없이 분할 단위 테스트로 되어 있습니다. 이미 Spec을 통해 최종적으로 추측 가능한 byte 배열을 알고 있습니다. 이 배열값과, 생성한 class의 결과가 동일한지 여부를 확인하여 테스트 성공 실패 여부를 판단합니다.


* TestDerWriting
DER Sequence 데이터 쓰기의 결과를 확인합니다.
DerInteger
Der Encoding이 적용된 Integer입니다. 생성하기 위한 BigInteger는 별도로 다루겠습니다
DerObjectIdentifier
Object 식별자(OID)DER Encoding 적용 객체입니다.
DerSequenceGenerator
DER 형식으로 Sequence객체를 생성하도록 합니다.
*TestnestedDerWriting
중첩된 객체에 대한 쓰기 결과를 확인합니다. 사용된 객체는 동일하나 테스트 과정에서 중첩쓰기를 테스트 합니다. ( 해당 예제 코드를 살펴보면 이미 완성된 객체를 하위 요소로 갖는 객체의 쓰기를 중첩쓰기라고 합니다.)
* TestBerWriting
BER Sequence 객체의 쓰기를 테스트 합니다.
Element Type은 공통으로 사용 하기 때문에 동일한 객체를 재사용하며,
달라지는 부분은, BerSequenceGenerator를 사용한다는 점입니다.(ENCODING 형식만 변경)
* TestNestedBerWriting
BER Sequence의 중첩 쓰기를 테스트합니다. 테스트의 세부내용은 DER 버전과 동일합니다.
* TestDerReading
이전 테스트 데이터(seqData – byte array) Asn1StreamParser로 읽어들인 후 처음 생성한 객체가 있는지 검사합니다.


Asn1StreamParser
→ 내부적으로 실제로 Tagging 정보를 확인하고 이를 통해서 BER, DER에 맞는 해당 Object를 읽어들일 있는 ReadObject() 항목을 구현합니다. Byte에서실제 객체로 변환하는 구조에 대한 항목은 StreamParserInputStream에 거의 구현되어 있다고 보셔도 무방합니다.


* TestNestedDerReading
이전의 Nested 데이터 검증용 데이터를 기반으로 중첩객체에 대한 데이터 읽기를 시도합니다.

BitStringTest



BitStringASN.1에서 각 비트에 특정한 별칭을 주는 형태로서, 일반적인 프로그래밍 언어에서 BitMask와 동일한 성격입니다.
실제 위의 코드는 상수값을 모르면 확인하기 어려운 부분들이 있습니다. 위에서는 X.509인증서 저장에서 사용되는 ASN.1의 별칭을 코드화 시킨것을 테스트 하는 코드를 담고 있습니다. 이런류의 소스 프로그램에서는 byte 단위의 실제 확인 과정이 매우 중요합니다. (우리 프로그램 끼리만 동작하는 – 정상적이지 않은 프로토콜, 스펙 구현을 상상해 보시면 잘 이해가 되실 것입니다.)


DerUtf8StringTest

DEREncodingUTF8String Class의 테스트입니다.
일반적인 문자열 Encoding 테스트와 유사한 방식을 사용합니다.



TimeTest

상대적으로 최근에 나온 ASN.1 TypeTime에 대한 구현체를 테스트 하는 테스트 코드입니다.
실제적으로는 .NetUtcNow를 가지고 값을 비교하는 형태입니다.



위의 코드들이 주요 ElementClass에 대한 테스트 코드들이라고 생각하시면 됩니다. 나머지 ASN.1의 영역은 주로 Element Class에서 확장된 인증서나 추가 영역이라고 보시면되겠습니다. 테스트 코드들은 직접 소스를 살펴 보시기를 권장해 드립니다

댓글 없음:

댓글 쓰기

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.

쿠버네티스 네트워크 정리

본 문서는 쿠버네티스의 공식문서( https://kubernetes.io/docs/concepts/cluster-administration/networking/ )의 일부를 번역하고 링크를 정리하여 붙이는 것에서 시작한 문서입니다. 일부 링크는 ...