2018년 12월 21일 금요일

BouncyCastle의 ASN.1 Abstract Classes

NameSpace

모든 필요한 부분들은 Org.BouncyCastle.Asn1 아래에 모여있습니다.


Spec에 없는 것들..

Spec 자체는 구현에 대해서 일일히 설명하지 않습니다. 대략적인 형태의 구성과 (ASN.1의 경우는 데이터를 저장하는 방법에 대한 추상 기술 형태이기 때문에 더더욱 그렇습니다.) 실제로 AsnNull 같은 형태는 Tag가 존재하고, 이를 표현할 Byte이외에는 실제소스에서 어떻게 하느냐는 자유롭습니다.


객체 살펴보기

앞 부분은 주로 추상 클래스에 대해서 언급 하고 있습니다. 실제 테스트 코드를 살펴 보기전에 추상클래스 부터 살펴보는 이유는 대부분의 기능이 추상클래스에서 시작하기 때문입니다.



Asn1OutputStream


FilterStream은 시스템의 일반 Stream을 프레임웍크에서 사용하기 좋도록 한번 더 감싼 Class이며, DerOutputStreamTLV(Tag-Length-Value)를 실제로 구현한 부분입니다.
실제로 내부의 기본 Writing 동작은 DER Encoding을 기반으로 처리합니다.


Asn1Encodable



Asn1Object

이후에 기술할 모든 요소들의 근간이 되는 Class 입니다.
간단히 살펴보면, ByteArray 혹은 Stream에서 부터 생성이 가능합니다. 모든 요소들이 Byte로 부터 변경됨을 알 수있습니다. 이는 앞에서 살펴 본것과 같이, ASN.1 자체가 추상화된 데이터를 전송하기 위한 모델이기 때문입니다.

Asn1Null



ASN에서 NULL을 표현하기 위한 객체 입니다. 이후에 각 Encoding명칭 뒤에 Null이 있는 Class도 이 Class를 상속하여 만들어집니다. (Spec에서의 Tagging을 처리하기 위함입니다.)
내부 구현은 아무것도 없으며 오로지, ToString()Override 되어 있습니다.






Asn1OctetString



OctetSting에 대한 추상 Class입니다. 기본적인 비교연산자와, 객체 생성에 관련된 정적 class가 선언되어 있습니다. 실제 Encoding 객체에서는 다시 재활용됩니다.
Asn1OctecStringParser Interface
GetOctetStream()의 구현을 강제합니다.






Asn1Set

ASN1 Spec에서의 SET을 정의합니다.
전체 셋이 전송된 순서와 상관없이 같다면 같은 것으로 판단합니다. (내부적으로는 순서를 다시한번 정렬하여 확인합니다. - 정렬이라는 단어때문에 혼란할 수 있습니다. 실제로는 비교할때의 정렬을 의미합니다. - 문서상의 Spec에서 이야기하는 Sort는 전송의 원래 순서를 의미합니다. )

Asn1Sequence

ASN.1 SEQUENCE를 정의합니다. 전송한 순서가 유의미 하기때문에 같은 데이터를 구성요소를 가지는 배열이라 하더라도, 순서가 다르면 다른객체로 판단합니다. 속도상의 이유로 SET보다는 SEQUENCE를 활용하는 것이 일반적입니다. (Spec에서 제외된것은 아니며, 일반적으로 속도의 문제로 선택되는 것입니다.)


Asn1TaggedObject

ASN.1 표기법(Tag→Length→ Value)에 따르면 항상 시작은 Object의 종류를 지칭하는 TagNo로 시작됩니다. 이에 대한 정의는 별도로 Spec에 정의 되어 있으며 간략하게 정리하면 다음과 같습니다.
해당 부분은 Asn1Tags Class에 상수로 기술되어 있습니다.


    public class Asn1Tags
    {
        public const int Boolean = 0x01;
        public const int Integer = 0x02;
        public const int BitString = 0x03;
        public const int OctetString = 0x04;
        public const int Null = 0x05;
        public const int ObjectIdentifier = 0x06;
        public const int External = 0x08;
        public const int Enumerated = 0x0a;
        public const int Sequence = 0x10;
        public const int SequenceOf = 0x10; // for completeness
        public const int Set = 0x11;
        public const int SetOf = 0x11; // for completeness
        public const int NumericString = 0x12;
        public const int PrintableString = 0x13;
        public const int T61String = 0x14;
        public const int VideotexString = 0x15;
        public const int IA5String = 0x16;
        public const int UtcTime = 0x17;
        public const int GeneralizedTime = 0x18;
        public const int GraphicString = 0x19;
        public const int VisibleString = 0x1a;
        public const int GeneralString = 0x1b;
        public const int UniversalString = 0x1c;
        public const int BmpString = 0x1e;
        public const int Utf8String = 0x0c;
        public const int Constructed = 0x20;
        public const int Application = 0x40;
        public const int Tagged = 0x80;
    }


→ 실제로 이 정의들은 공식 Spec에 나와있는 것을 코드화 한 것 입니다.
Asn1TaggedObjectParser Interface의 구성은 다음과 같습니다.
     public interface Asn1TaggedObjectParser : IAsn1Convertible
     {
          int TagNo { get; }
          IAsn1Convertible GetObjectParser(int tag, bool isExplicit);
     }


이제까지의 객체 구현을 자세히 살펴보면 DER Encode이 왜 기준이 되는지 이해할 수 있을 것입니다.
이제 DER Encoding을 실로 구현한 객체들을 살펴 보도록 하겠습니다.
→ 여기 까지는 단위테스트가 실제로 이루어 질것이 별로 없습니다. 하위로 구성되어 있는 DER, BER 구현 단계가지 내려가야 실제단위테스트가 이루어 질 수 있습니다.

다음 글에서 뵙겠습니다.

댓글 없음:

댓글 쓰기

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

쿠버네티스 네트워크 정리

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