uni2u / difs-cxx

DIFS ndn-cxx
Other
1 stars 3 forks source link

How to enable ECDSA validation #18

Open justin-labry opened 2 years ago

justin-labry commented 2 years ago

안녕하세요,

difs에서 ECDSA validation을 켜는 방법을 정리해봅니다.

build/bin/ndn-repo-ng -c manager.conf 에서 manager.conf에서 ecdsa를 설정해 줘야 합니다. 자세한 내용을 wiki를 참조하시고요 https://named-data.net/doc/ndn-cxx/current/tutorials/security-validator-config.html

간단하게 적용하는것은 아래 내용을 참고하면 될 것 같습니다. https://github.com/uni2u/difs/blob/hash-chain-w-validator/repo-veri.conf

repo
{
  data
  {
    registration-subset 1
    prefix "ndn:/data/"
  }

  cluster
  {
    size 1
    id 0
    prefix "ndn:/example/repo"
  }

  storage
  {
    method "fs"              ; Currently, only sqlite storage engine is supported
    path "/var/lib/ndn/repo/0"  ; Path to repo-ng storage folder
    max-packets 10000000
  }

  tcp_bulk_insert
  {
    ; host "localhost"  ; Set to listen on a different IP address or hostname
    ; port 7376         ; Set to listen on a different port number
  }

  validator
  {
    ;trust-anchor
    ;{
    ;    type file
    ;    file-name "/app/repo.cert"
    ;}
    ; The following rule disables all security in the repo
    rule {
      id "data to get"
      for data
      filter
      {
        type name
        name /
        relation is-prefix-of
      }    
      checker
      {
         type customized
         sig-type sha256-rsa
         key-locator
         {
           type name
           name /example/repo
           relation equal
        }
      }
    } ; end of rule    
    rule {
      id "interest"
      for interest
      filter
      {
        type name
        name /
        relation is-prefix-of
      }    
      checker
      {
         type customized
         sig-type sha256-rsa
         key-locator
         {
           type name
           name /example/repo ;/localhost/identity/digest-sha256
           relation equal
        }
      }
    } ; end of rule
    ; rule {
    ;   id "data"
    ;   for data
    ;   filter
    ;   {
    ;     type name
    ;     name /
    ;     relation is-prefix-of
    ;   }    
    ;   checker
    ;   {
    ;      type customized
    ;      sig-type sha256
    ;      key-locator
    ;      {
    ;        type name
    ;        name /localhost/identity/digest-sha256
    ;        relation is-prefix-of
    ;     }
    ;   }
    ; } ; end of rule
    trust-anchor
    {
      type file
      file-name "/app/repo.cert"
    }
  }
}

또한 export NDN_LOG="ndn.*=TRACE"; build/bin/ndn-repo-ng -c manager.conf 2> log.txt 이런식으로 LOG를 켜서 Validation이 bypass되고 있는지 successful이 라고 나오는지 등을 확인해 보는것도 필요합니다.

1632794786.637001 DEBUG: [ndn.security.Validator] > Start validating data /data10/%00%01 1632794786.637009 TRACE: [ndn.security.ValidationState] > Signature verification bypassed for data /data10/%00%01 1632794786.638381 TRACE: [ndn.security.ValidationState] ~ValidationState

혹시 ecdsa validation 동작 절차 확인 중 궁금한 내용은 댓글 달아주시면 저도 같이 확인해보도록 하겠습니다.

sungho-gurumnet commented 2 years ago

감사합니다! validator 설정이 코드가 아니라 설정파일 통해 셋팅을 해야 하는거였군요! 설정해보고 성능측정해서 결과 공유드리겠습니다

sungho-gurumnet commented 2 years ago

안녕하세요.

validator 관련해서 여전히 설정에 실수한 부분이 있는지 잘 안되네요.

segmentfetcher로 우선 validator 동작 확인을 하고 있고,

    rule {
      id "data to get"
      for data
      filter
      {
        type name
        name /example
        relation is-prefix-of
      }    
      checker
      {
         type customized
         sig-type ecdsa-sha256
         key-locator
         {
           type name
           name /root
           relation is-prefix-of
        }
      }
    } ; end of rule    

설정 파일은 위처럼 셋팅을 하였습니다.

producer 부분에서 sign을 하는 부분은 아래와 같이 id로 하고 있고,

                if(!m_hc) {
                요   // m_keyChain.sign(*data, signingByKey("/root/KEY/%26%A1%98%08%CC%40%B9%19"));
                    // m_keyChain.sign(*data, si)
                    m_keyChain.sign(*data, ndn::security::SigningInfo("id:/root"));
                }

consumer에서 sign 부분은 위의 설정 파일을 사용하도록 하였습니다. ndnsec-cert list -c를 했을때는 아래와 같이 나옵니다

* /root
  +->* /root/KEY/%26%A1%98%08%CC%40%B9%19
       +->* /root/KEY/%26%A1%98%08%CC%40%B9%19/self/%FD%00%00%01%7C%3A%ED%17b
  +->  /root/KEY/%7B%AA%8E%A1%C8o%C9%BD
       +->* /root/KEY/%7B%AA%8E%A1%C8o%C9%BD/self/%FD%00%00%01%7C%3A%EC%C5k
  +->  /root/KEY/%83%CA%E2%E5%81%2FY%1F
       +->* /root/KEY/%83%CA%E2%E5%81%2FY%1F/self/%FD%00%00%01%7C%3A%ED%03%AB

consumer 실행시 아래와 같은 에러가 출력이 되는데, 어떤 문제일까요...?

➜  difs-cxx git:(signatureinfo_nexthash) ✗ ./build/examples/segment_consumer /example/repo2
Hashchain disabled
Error: Segment validation failed: Cannot retrieve certificate (Cannot fetch certificate after all retries `/root/KEY/%26%A1%98%08%CC%40%B9%19`)
justin-labry commented 2 years ago

예, 내일 확인해보겠습니다~~~ 가능하면 빠르게~

sungho-gurumnet commented 2 years ago

감사합니다! 다행히 설정을 잘못을 한 부분을 찾아서 방금 validation 확인을 했습니다. ㅎ trust-anchor를 설정을 안했더군요...

감사합니다.

justin-labry commented 2 years ago

네, 벌써 찾으셨군요! 혹시 또 고민되는 부분있으면 알려주시면 같이 찾아보겠습니다.

justin-labry commented 2 years ago

네, 제가 히스토리를 조금 정리해보면요.

기본적으로 ndn-cxx 0.71까지는 sha256 validation 하는 기능이 구현이 안된 상태고요.

그래서 제가 일단 bypass 할 수 있도록 한 코드는 아래를 참고하시면 됩니다. https://github.com/uni2u/difs-cxx/blob/signatureinfo_nexthash/ndn-cxx/security/validation-policy-config.cpp

void
ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
                                    const ValidationContinuation& continueValidation)
{
  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");

  if (m_shouldBypass) {
    return continueValidation(nullptr, state);
  }

  if (data.getSignatureType() == ndn::tlv::SignatureTypeValue::DigestSha256 ||
      data.getSignatureType() == ndn::tlv::SignatureTypeValue::SignatureHashChainWithSha256) {
    return continueValidation(nullptr, state);
  }

또한 제가 ndn-cxx를 조금 수정해서 sha256 validation이 가능하게 만든 코드는 아래를 참고하시면 됩니다. https://github.com/justin-labry/ndn-cxx/blob/digest-sha256/ndn-cxx/security/validation-policy-config.cpp

void
ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<ValidationState>& state,
                                    const ValidationContinuation& continueValidation)
{
  BOOST_ASSERT_MSG(!hasInnerPolicy(), "ValidationPolicyConfig must be a terminal inner policy");

  Name klName = getKeyLocatorName(data, *state);
  if (!state->getOutcome()) { // already failed
    return;
  }

  if (klName == SigningInfo::getDigestSha256Identity()) {
    bool result = verifyDigest(data, DigestAlgorithm::SHA256);
    if(result) {
      NDN_LOG_DEBUG("digest-sha256 successful.");
      return continueValidation(make_shared<CertificateRequest>(klName), state);
    }else {
      std::ostringstream os;
      os << "DigestAlgorithm:SHA256 check failed.";
      return state->fail({ValidationError::INVALID_SIGNATURE, os.str()});
    }
  }

위처럼 만들어서 sha256 validation을 수행하는 것을 성공했었는데... appMetaInfo에 해시가 적용된 버전에서는 동작에 이상이 있어서 제가 일단 위처럼 바이패스 하는 식으로 진행중에 있었습니다.

혹시 또 궁금한 것이 있으면 알려주세요~