github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/support_libraries/tao_support/taosupport.cc (about)

     1  //  Copyright (c) 2014, Google Inc.  All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  #include <string>
    14  #include <vector>
    15  #include <stdlib.h>
    16  
    17  #include <gflags/gflags.h>
    18  #include <glog/logging.h>
    19  
    20  #include "tao/fd_message_channel.h"
    21  #include "tao/tao_rpc.h"
    22  #include "tao/util.h"
    23  
    24  #include "agile_crypto_support.h"
    25  #include "ssl_helpers.h"
    26  #include "taosupport.h"
    27  
    28  #include <openssl/ssl.h>
    29  #include <openssl/rsa.h>
    30  #include <openssl/x509.h>
    31  #include <openssl/x509v3.h>
    32  #include <openssl/rand.h>
    33  
    34  #include "keys.pb.h"
    35  #include "domain_policy.pb.h"
    36  #include "auth.h"
    37  
    38  using std::string;
    39  using std::unique_ptr;
    40  
    41  using tao::Base64WDecode;
    42  using tao::Base64WEncode;
    43  using tao::FDMessageChannel;
    44  using tao::InitializeApp;
    45  using tao::MarshalSpeaksfor;
    46  using tao::Tao;
    47  using tao::TaoRPC;
    48  
    49  #include <google/protobuf/io/coded_stream.h>
    50  #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
    51  #include <google/protobuf/stubs/common.h>
    52  using google::protobuf::io::CodedInputStream;
    53  using google::protobuf::io::CodedOutputStream;
    54  using google::protobuf::io::StringOutputStream;
    55  using google::protobuf::io::ArrayInputStream;
    56  using tao::MarshalSpeaksfor;
    57  
    58  #define BUFSIZE 8192
    59  
    60  void SerializeTermToString(tao::Term* term, string* name) {
    61    if (dynamic_cast<tao::Prin*> (term)) {
    62      tao::Prin* prin = dynamic_cast<tao::Prin*>(term);
    63      *name += prin->type_ + "("; 
    64      SerializeTermToString(prin->keyhash_.get(), name);
    65      *name += ")";
    66      tao::SubPrin* w = prin->ext_.get();
    67      for (std::vector<std::unique_ptr<tao::PrinExt>>::iterator
    68             it = w->elts_.begin(); it != w->elts_.end(); ++it) {
    69        *name += ".";
    70        tao::PrinExt* prinExt = (*it).get();
    71        *name += prinExt->name_ + "(";
    72        SerializeTermToString(prinExt->args_[0].get(), name);
    73        *name += ")";
    74      }
    75    } else if (dynamic_cast<tao::Bytes*> (term)) {
    76      tao::Bytes* bytes = dynamic_cast<tao::Bytes*> (term);
    77      string* hex = ByteToHexLeftToRight((int)bytes->elt_.size(), (byte*)bytes->elt_.data());
    78      *name += *hex;
    79      delete hex;
    80    }
    81  }
    82  
    83  TaoChannel::~TaoChannel() {
    84  }
    85  
    86  void TaoProgramData::ClearProgramData() {
    87    initialized_ = false;
    88    marshalled_tao_name_.clear();
    89    tao_name_.clear();
    90    policy_cert_.clear();
    91  
    92    tao_ = nullptr;
    93  
    94    // Clear keys
    95    memset((byte*)verifying_key_, 0, sizeof(*verifying_key_));
    96    memset((byte*)program_signing_key_, 0, sizeof(*program_signing_key_));
    97    memset((byte*)crypting_key_, 0, sizeof(*crypting_key_));
    98  
    99    if (policy_certificate_ != nullptr) {
   100      X509_free(policy_certificate_);
   101    }
   102    policy_certificate_ = nullptr;
   103  }
   104  
   105  TaoProgramData::TaoProgramData() {
   106    initialized_ = false;
   107    tao_ = nullptr;
   108    cipher_suite_.clear();
   109    tao_name_.clear();
   110    policy_cert_.clear();
   111    policy_certificate_ = nullptr;
   112    program_signing_key_ = nullptr;
   113    verifying_key_ = nullptr;
   114    crypting_key_ = nullptr;
   115    program_cert_.clear();
   116    program_certificate_ = nullptr;
   117  }
   118  
   119  TaoProgramData::~TaoProgramData() {
   120    ClearProgramData();
   121  }
   122  
   123  void TaoProgramData::SetPolicyCertificate(X509* c) {
   124    policy_certificate_ = c;
   125  }
   126  
   127  bool TaoProgramData::GetTaoName(string* name) {
   128    if (!initialized_)
   129      return false;
   130    *name = tao_name_;
   131    return true;
   132  }
   133  
   134  bool TaoProgramData::GetPolicyCert(string* cert) {
   135    if (!initialized_)
   136      return false;
   137    *cert = policy_cert_;
   138    return true;
   139  }
   140  
   141  X509* TaoProgramData::GetPolicyCertificate() {
   142    if (!initialized_)
   143      return nullptr;
   144    return policy_certificate_;
   145  }
   146  
   147  bool TaoProgramData::GetCipherSuite(string* keyType) {
   148    if (!initialized_)
   149      return false;
   150    *keyType = cipher_suite_;
   151    return true;
   152  }
   153  
   154  void TaoProgramData::SetProgramCertificate(X509* certificate) {
   155    program_certificate_ = certificate;
   156  }
   157  
   158  EVP_PKEY* TaoProgramData::GetProgramKey() {
   159    return program_signing_key_->sk_;
   160  }
   161  
   162  bool TaoProgramData::GetProgramKeyType(string* key_type) {
   163    if (!SignerAlgorithmNameFromCipherSuite(cipher_suite_, key_type)) {
   164      return false;
   165    }
   166    return true;
   167  }
   168  
   169  bool TaoProgramData::GetProgramCert(string* cert) {
   170    *cert = program_cert_;
   171    return true;
   172  }
   173  
   174  X509* TaoProgramData::GetProgramCertificate() {
   175    return program_certificate_;
   176  }
   177  
   178  std::list<string>* TaoProgramData::GetProgramCertChain() {
   179    if (!initialized_)
   180      return nullptr;
   181    return &program_cert_chain_;
   182  }
   183  
   184  void TaoProgramData::Print() {
   185    if (!initialized_) {
   186      printf("Program object is NOT initialized\n");
   187      return;
   188    }
   189    printf("Program object is initialized\n");
   190    printf("Cipher suite: %s\n", cipher_suite_.c_str());
   191    printf("Tao name: %s\n", marshalled_tao_name_.c_str());
   192    printf("Policy cert: ");
   193    PrintBytes(policy_cert_.size(), (byte*)policy_cert_.data());printf("\n");
   194    printf("Program key: "); printf("TODO"); printf("\n");
   195    printf("Program cert: ");PrintBytes(program_cert_.size(), (byte*)program_cert_.data());printf("\n");
   196    printf("Program path: %s\n", program_path_.c_str());
   197  }
   198  
   199  void TaoChannel::Print() {
   200    printf("Peer name: %s\n", peer_name_.c_str());
   201  }
   202  
   203  bool TaoProgramData::Attest(string& to_attest, string* attested) {
   204    return tao_->Attest(to_attest, attested);
   205  }
   206  
   207  bool TaoProgramData::SealMaterial(string& data, string* sealed) {
   208    return tao_->Seal(data, Tao::SealPolicyDefault, sealed);
   209  }
   210  
   211  bool TaoProgramData::UnsealMaterial(string& sealed, string* unsealed) {
   212    string policy;
   213    return tao_->Unseal(sealed, unsealed, &policy);
   214  }
   215  
   216  bool TaoProgramData::InitCounter(string& label, int64_t& c) {
   217  printf("Calling tao_->TaoProgramData::InitCounter(%llx)\n", c);
   218    return tao_->InitCounter(label, c);
   219  }
   220  
   221  bool TaoProgramData::GetCounter(string& label, int64_t* c) {
   222    return tao_->GetCounter(label, c);
   223  }
   224  
   225  bool TaoProgramData::RollbackProtectedSeal(string& label, string& data, string* sealed) {
   226    return tao_->RollbackProtectedSeal(label, data, Tao::SealPolicyDefault, sealed);
   227  }
   228  
   229  bool TaoProgramData::RollbackProtectedUnseal(string& sealed, string* data, string* policy) {
   230    return tao_->RollbackProtectedUnseal(sealed, data, policy);
   231  }
   232  
   233  bool TaoProgramData::InitTao(string& cipher_suite, FDMessageChannel* msg, Tao* tao,
   234         string& policy_key_path, string& host_key_path, string& program_path, string& network,
   235         string& address, string& port, bool useSimpleService) {
   236  
   237    cipher_suite_ = cipher_suite;
   238    msg_ = msg;
   239    tao_ = tao;
   240    program_path_ = program_path;
   241    network_ = network;
   242    address_ = address;
   243    port_ = port;
   244    useSimpleService_ = useSimpleService;
   245    host_cert_file_name_ = host_key_path + "/cert";
   246    policy_cert_file_name_ = policy_key_path + "/cert";
   247  
   248    // Read policy cert from config.
   249    if (!ReadFile(policy_cert_file_name_, &policy_cert_)) {
   250      printf("Can't read policy cert.\n");
   251      return false;
   252    }
   253  
   254    // Translate policy cert.
   255    policy_verifying_key_ = VerifierFromCertificate(policy_cert_);
   256    
   257    byte* pc = (byte*)policy_cert_.data();
   258    policy_certificate_ = d2i_X509(nullptr, (const byte**)&pc, policy_cert_.size());
   259    if (policy_certificate_ == nullptr) {
   260      printf("Can't DER parse policy cert.\n");
   261      return false;
   262    }
   263  
   264    // Read host cert
   265    if (!ReadFile(host_cert_file_name_, &host_cert_)) {
   266      printf("Can't read host cert %s.\n", host_cert_file_name_.c_str());
   267      return false;
   268    }
   269  
   270    // Read host cert chain
   271  
   272    // Extend principal name, with hash of policy public key.
   273    string policy_principal_bytes;
   274    if (!UniversalKeyName(policy_verifying_key_, &policy_principal_bytes)) {
   275      return false;
   276    }
   277  
   278    std::vector<std::unique_ptr<tao::PrinExt>> v;
   279  
   280    std::vector<std::unique_ptr<tao::Term>> w;
   281    w.push_back(tao::make_unique<tao::Bytes>(policy_principal_bytes.data()));
   282    v.push_back(tao::make_unique<tao::PrinExt> ("PolicyKey", std::move(w)));
   283    tao::SubPrin p(std::move(v));
   284    string subprin;
   285    {
   286      StringOutputStream raw_output_stream(&subprin);
   287      CodedOutputStream output_stream(&raw_output_stream);
   288      p.Marshal(&output_stream);
   289    }
   290  
   291    // Extend Tao name with policy key.
   292    if (!tao_->ExtendTaoName(subprin)) {
   293      printf("Can't extend name.\n");
   294      return false;
   295    }
   296  
   297    // Retrieve extended name.
   298    if (!tao->GetTaoName(&marshalled_tao_name_)) {
   299      printf("Can't get tao name.\n");
   300      return false;
   301    }
   302  
   303    tao::Prin unmarshalled_tao_name;
   304    {
   305      ArrayInputStream raw_input_stream(marshalled_tao_name_.data(),
   306                                        marshalled_tao_name_.size());
   307      CodedInputStream input_stream(&raw_input_stream);
   308      if (!unmarshalled_tao_name.Unmarshal(&input_stream)) {
   309          printf("Can't unmarshal tao name\n");
   310      }
   311    }
   312    SerializeTermToString((tao::Term*)&unmarshalled_tao_name, &tao_name_);
   313  
   314    if (!GetProgramData()) {
   315      printf("Can't init program keys.\n");
   316      return false;
   317    }
   318    initialized_ = true;
   319    return true;
   320  }
   321  
   322  bool TaoProgramData::RequestDomainServiceCert(string& request_string) {
   323  
   324    // Set up a fake SSL channel, key does't matter
   325    if (policy_certificate_ == nullptr) {
   326      printf("Policy cert is null.\n");
   327      return false;
   328    }
   329  
   330    X509_REQ* req = X509_REQ_new();;
   331    X509* cert = X509_new();
   332    string common_name("Fred");
   333    string issuer("Self");
   334    string keyUsage("critical,digitalSignature,keyEncipherment,keyAgreement,keyCertSign");
   335    string extendedKeyUsage("serverAuth,clientAuth");
   336  
   337    tao::CryptoKey sck;
   338    string key_type;
   339    if (!SignerAlgorithmNameFromCipherSuite(cipher_suite_, &key_type)) {
   340      printf("RequestDomainServiceCert: Can't get signer alg name.\n");
   341      return false;
   342    }
   343    if (!GenerateCryptoKey(key_type, &sck)) {
   344      printf("RequestDomainServiceCert: Can't get signer key.\n");
   345      return false;
   346    }
   347    Signer* s = CryptoKeyToSigner(sck);
   348    if (s == nullptr) {
   349      printf("RequestDomainServiceCert: Can't translate key.\n");
   350      return false;
   351    }
   352  
   353    if (!GenerateX509CertificateRequest(s->sk_, common_name, false, req)) {
   354      printf("RequestDomainServiceCert: Can't generate x509 request\n");
   355      return false;
   356    }
   357  
   358    if (!SignX509Certificate(s->sk_, true, true, issuer, 
   359                             keyUsage, extendedKeyUsage, 86400,
   360                             s->sk_, req, false, cert)) {
   361      printf("RequestDomainServiceCert: Can't sign x509 request\n");
   362      return false;
   363    }
   364  
   365    // Open request channel.
   366    SslChannel domainChannel;
   367    if (!domainChannel.InitClientSslChannel(network_, address_, port_,
   368          cert, cert, key_type, s->sk_,
   369          SSL_NO_SERVER_VERIFY_NO_CLIENT_VERIFY)) {
   370      printf("RequestDomainServiceCert: Can't init ssl channel to domain server.\n");
   371      return false;
   372    }
   373  
   374    // Send request to Domain service and get response.
   375    int bytes_written = SslMessageWrite(domainChannel.GetSslChannel(),
   376                            (int)request_string.size(),
   377                            (byte*)request_string.data());
   378    if (bytes_written <= 0) {
   379      printf("RequestDomainServiceCert: Domain channel write failure.\n");
   380      return false;
   381    }
   382    byte read_buf[BUFSIZE];
   383    string response_buf;
   384    int bytes_read = 0;
   385    while ((bytes_read = SslMessageRead(domainChannel.GetSslChannel(), BUFSIZE, read_buf))
   386             == 0);
   387    if (bytes_read <= 0) {
   388      printf("RequestDomainServiceCert: Domain channel read failure (%d).\n", bytes_read);
   389      return false;
   390    }
   391  
   392    // Get response and populate this with cert and cert chain.
   393    response_buf.assign((const char*)read_buf, bytes_read);
   394    domain_policy::DomainCertResponse response;
   395    if (!response.ParseFromString(response_buf)) {
   396      printf("Domain channel parse failure.\n");
   397      return false;
   398    }
   399    program_cert_.assign((const char*)response.signed_cert().data(),
   400                         response.signed_cert().size());
   401    for (int j = 0; j < response.cert_chain_size(); j++) {
   402        program_cert_chain_.push_back(string(response.cert_chain(j)));
   403    }
   404  
   405    return true;
   406  }
   407  
   408  bool TaoProgramData::SaveProgramData(tao_support::SavedProgramData& pd, string* out) {
   409    // Serialize and Seal
   410    string serialized;
   411    if (!pd.SerializeToString(&serialized)) {
   412      return false;
   413    }
   414    if (!SealMaterial(serialized, out)) {
   415      return false;
   416    }
   417    return true;
   418  }
   419  
   420  bool TaoProgramData::RecoverProgramData(string in, tao_support::SavedProgramData* pd) {
   421    // Unseal and deserialize
   422    string unsealed;
   423    if (!UnsealMaterial(in, &unsealed)) {
   424      return false;
   425    }
   426    if (!pd->ParseFromString(unsealed)) {
   427      return false;
   428    }
   429    return true;
   430  }
   431  
   432  bool TaoProgramData::InitProgramKeys(tao_support::SavedProgramData* pd) {
   433    string crypter_alg_name;
   434    if (!CrypterAlgorithmNameFromCipherSuite(cipher_suite_, &crypter_alg_name)) {
   435      printf("InitializeProgramKeys: can't get CrypterAlgorithmNameFromCipherSuite.\n");
   436      return false;
   437    }
   438    string signer_alg_name;
   439    if (!SignerAlgorithmNameFromCipherSuite(cipher_suite_, &signer_alg_name)) {
   440      printf("InitializeProgramKeys: Can't get SignerAlgorithmNameFromCipherSuite.\n");
   441      return false;
   442    }
   443    tao::CryptoKey eck;
   444    if (!GenerateCryptoKey(crypter_alg_name, &eck)) {
   445      printf("InitializeProgramKeys: Can't generate crypter key.\n");
   446      return false;
   447    }
   448    tao::CryptoKey sck;
   449    if (!GenerateCryptoKey(signer_alg_name, &sck)) {
   450      printf("InitializeProgramKeys: Can't generate signer key.\n");
   451      return false;
   452    }
   453  
   454    crypting_key_ = CryptoKeyToCrypter(eck);
   455    if (crypting_key_ == nullptr) {
   456      printf("InitializeProgramKeys: couldn't convert crypter crypto key to crypter.\n");
   457      return false;
   458    }
   459    program_signing_key_ = CryptoKeyToSigner(sck);
   460    if (program_signing_key_ == nullptr) {
   461      printf("InitializeProgramKeys: couldn't convert signer crypto key to crypter.\n");
   462      return false;
   463    }
   464    verifying_key_ = VerifierFromSigner(program_signing_key_);
   465    if (verifying_key_ == nullptr) {
   466      printf("InitializeProgramKeys: .\n");
   467      return false;
   468    }
   469  
   470    string key_bytes;
   471    if (!UniversalKeyName(verifying_key_, &key_bytes)) {
   472      printf("InitializeProgramKeys: couldn't get KeyPrincipalBytes.\n");
   473      return false;
   474    }
   475  
   476    // Construct a delegation statement.
   477    string msf;
   478    if (!MarshalSpeaksfor(key_bytes, marshalled_tao_name_, &msf)) {
   479      printf("InitializeProgramKeys: couldn't MarshalSpeaksfor.\n");
   480      return false;
   481    }
   482    
   483    // Get an attestation using delegation and program key;
   484    string attestation_string;
   485    if (!Attest(msf, &attestation_string)) {
   486      printf("InitializeProgramKeys: couldn't Attest.\n");
   487      return false;
   488    }
   489  
   490    // Der serialize key
   491    byte der_subj_key[8196];
   492    byte* ptr = der_subj_key;
   493    int der_subj_key_size = i2d_PUBKEY(GetProgramKey(), &ptr);
   494    if (der_subj_key_size <= 0) {
   495      printf("Can't i2d ECC public key\n");
   496      return false;
   497    }
   498  
   499    // Make cert request.
   500    domain_policy::DomainCertRequest request;
   501    request.set_attestation(attestation_string);
   502    request.set_key_type(signer_alg_name);
   503    request.set_subject_public_key(der_subj_key, der_subj_key_size);
   504    string* der = request.add_cert_chain();
   505    *der = host_cert_;
   506    for (std::list<string>::iterator it = host_cert_chain_.begin();
   507        it != host_cert_chain_.end(); ++it) {
   508      string* der = request.add_cert_chain();
   509      *der = *it;
   510    }
   511    
   512  
   513    string request_string;
   514    if (!request.SerializeToString(&request_string)) {
   515      printf("InitializeProgramKey: couldn't serialize request.\n");
   516      return false;
   517    }
   518  
   519    // Get Program Cert.
   520    if (!RequestDomainServiceCert(request_string)) {
   521      printf("InitializeProgramKeys: couldn't RequestDomainServiceCert.\n");
   522      return false;
   523    }
   524  
   525    string crypting_key_blob;
   526    string signing_key_blob;
   527  
   528    if (!eck.SerializeToString(&crypting_key_blob)) {
   529      printf("InitializeProgramKeys: can't serialize crypting key.\n");
   530      return false;
   531    }
   532    if (!sck.SerializeToString(&signing_key_blob)) {
   533      printf("InitializeProgramKeys: can't serialize crypting key.\n");
   534      return false;
   535    }
   536  
   537    byte* pc = (byte*)program_cert_.data();
   538    program_certificate_ = d2i_X509(nullptr, (const byte**)&pc, program_cert_.size());
   539    if (program_certificate_ == nullptr) {
   540      printf("Can't DER parse program cert.\n");
   541      return false;
   542    }
   543  
   544    pd->set_crypto_suite(cipher_suite_);
   545    pd->set_file_path(program_path_);
   546    pd->set_policy_cert(policy_cert_);
   547    pd->set_program_name(tao_name_);
   548    pd->set_signing_key_blob(signing_key_blob);
   549    pd->set_crypting_key_blob(crypting_key_blob);
   550    pd->set_delegation(attestation_string);
   551    pd->set_program_cert(program_cert_);
   552  
   553    // Save program cert chain
   554    for (std::list<string>::iterator it = program_cert_chain_.begin();
   555        it != program_cert_chain_.end(); ++it) {
   556      string* next  = pd->add_signer_cert_chain();
   557      *next = *it;
   558    }
   559  
   560    return true;
   561  }
   562  
   563  bool TaoProgramData::GetProgramData() {
   564  
   565    string protected_keys_file_name(program_path_);
   566    protected_keys_file_name += "/protectedProgramKeys";
   567    string cert_file_name;
   568    cert_file_name = protected_keys_file_name + "_cert";
   569  
   570    string encrypted_saved_program_data;
   571    tao_support::SavedProgramData program_data;
   572  
   573    // By now we should have config paths, addresses and tao set.
   574  
   575    if (!ReadFile(protected_keys_file_name, &encrypted_saved_program_data)) {
   576      // need to init keys
   577      if (!InitProgramKeys(&program_data)) {
   578        printf("GetProgramData: can't InitProgramKeys\n");
   579        return false;
   580      }
   581      if (!SaveProgramData(program_data, &encrypted_saved_program_data)) {
   582        printf("GetProgramData: can't SaveProgramData\n");
   583        return false;
   584      }
   585      if (!WriteFile(protected_keys_file_name, encrypted_saved_program_data)) {
   586        printf("GetProgramData: can't write savedProgramData\n");
   587        return false;
   588      }
   589      // Save cert too.
   590      if (!WriteFile(cert_file_name, program_cert_)) {
   591        printf("GetProgramData: can't write program cert\n");
   592        return false;
   593      }
   594    } else {
   595      // decrypt program keys
   596      if (!RecoverProgramData(encrypted_saved_program_data, &program_data)) {
   597        printf("GetProgramData: can't RecoverProgramData\n");
   598        return false;
   599      }
   600    }
   601  
   602    // Fill corresponding TaoProgramData values
   603    if (!program_data.has_file_path()) {
   604        printf("GetProgramData: no program path\n");
   605        return false;
   606    }
   607    if (!program_data.has_policy_cert()) {
   608        printf("GetProgramData: no policy certt\n");
   609        return false;
   610    }
   611    if (!program_data.has_program_name()) {
   612        return false;
   613    }
   614    if (!program_data.has_signing_key_blob()) {
   615        printf("GetProgramData: no signing key blob\n");
   616        return false;
   617    }
   618    if (!program_data.has_crypting_key_blob()) {
   619        printf("GetProgramData: no crypting key blob\n");
   620        return false;
   621    }
   622    if (!program_data.has_crypto_suite()) {
   623        printf("GetProgramData: no crypto suite\n");
   624        return false;
   625    }
   626    if (!program_data.has_program_cert()) {
   627        printf("GetProgramData: no program cert\n");
   628        return false;
   629    }
   630  
   631    tao::CryptoKey sck;
   632    tao::CryptoKey cck;
   633    if (!sck.ParseFromString(program_data.signing_key_blob())) {
   634        printf("GetProgramData: can't decode signing key blob\n");
   635        return false;
   636    }
   637    program_signing_key_ = CryptoKeyToSigner(sck);
   638    if (program_signing_key_ == nullptr) {
   639        printf("GetProgramData: can't convert signer cryptokey to signer\n");
   640        return false;
   641    }
   642    if (!cck.ParseFromString(program_data.crypting_key_blob())) {
   643        printf("GetProgramData: can't decode crypting key blob\n");
   644        return false;
   645    }
   646    crypting_key_ = CryptoKeyToCrypter(cck);
   647    if (crypting_key_ == nullptr) {
   648        printf("GetProgramData: can't convert crypter cryptokey to crypter\n");
   649        return false;
   650    }
   651    verifying_key_ = VerifierFromSigner(program_signing_key_);
   652    if (verifying_key_ == nullptr) {
   653        printf("GetProgramData: can't get VerifierFromSigner\n");
   654        return false;
   655    }
   656  
   657    if (program_data.has_delegation()) {
   658        printf("GetProgramData: no delegation\n");
   659    }
   660  
   661    byte* pc = (byte*)program_data.program_cert().data();
   662    program_certificate_ = d2i_X509(nullptr, (const byte**)&pc, program_data.program_cert().size());
   663    if (program_certificate_ == nullptr) {
   664      printf("Can't DER parse program cert.\n");
   665      return false;
   666    }
   667  
   668    for (int i = 0; i < program_data.signer_cert_chain().size(); i++) {
   669      string der_cert = program_data.signer_cert_chain(i);
   670      program_cert_chain_.push_back(der_cert);
   671    }
   672  
   673    return true;
   674  }
   675  
   676  TaoChannel::TaoChannel() {
   677    peerCertificate_ = nullptr;
   678  }
   679  
   680  bool TaoChannel::OpenTaoChannel(TaoProgramData& client_program_data,
   681                      string& serverAddress, string& port) {
   682  
   683    string key_type;
   684    if (!client_program_data.GetProgramKeyType(&key_type)) {
   685        printf("OpenTaoChannel: No private key type.\n");
   686        return false;
   687    }
   688  
   689    // Open TLS channel with Program cert.
   690    string network("tcp");
   691    if (!peer_channel_.InitClientSslChannel(network, serverAddress, port,
   692                      client_program_data.GetPolicyCertificate(),
   693                      client_program_data.GetProgramCertificate(),
   694                      key_type,
   695                      client_program_data.GetProgramKey(),
   696                      SSL_SERVER_VERIFY_CLIENT_VERIFY)) {
   697      printf("OpenTaoChannel: Can't Init Ssl channel.\n");
   698      return false;
   699    }
   700  
   701    // Get peer name from organizational unit.
   702    peerCertificate_ = peer_channel_.GetPeerCert();
   703    if (peerCertificate_ != nullptr) {
   704      X509_NAME* name = X509_get_subject_name(peerCertificate_);
   705      int nid = OBJ_txt2nid("OU");
   706      char buf[BUFSIZE];
   707      if (X509_NAME_get_text_by_NID(name, nid, buf, BUFSIZE) == 1) {
   708        peer_name_ = buf ;
   709      }
   710    }
   711  
   712    return true;
   713  }
   714  
   715  void TaoChannel::CloseTaoChannel() {
   716    peer_channel_.Close();
   717  }
   718  
   719  bool TaoChannel::SendRequest(int size, byte* out) {
   720    int k = SslMessageWrite(peer_channel_.GetSslChannel(), size, out);
   721    return k > 0;
   722  }
   723  
   724  bool TaoChannel::GetRequest(int* size, byte* in) {
   725    int k = SslMessageRead(peer_channel_.GetSslChannel(), *size, in);
   726    if (k <= 0) {
   727      printf("Can't read request channel.\n");
   728      return false;
   729    }
   730    *size = k;
   731    return true;
   732  }