~ubuntu-branches/ubuntu/trusty/nordugrid-arc/trusty-proposed

« back to all changes in this revision

Viewing changes to src/hed/libs/credential/Credential.cpp

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2013-11-29 13:39:10 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20131129133910-altaxrfowczzl2ev
Tags: 4.0.0-1
4.0.0 Release (Closes: #715131) (LP: #1049798)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 
8
8
#include <fstream>
9
9
#include <fcntl.h>
10
 
#include <openssl/ui.h>
 
10
//#include <openssl/ui.h>
11
11
#include <openssl/ssl.h>
12
12
#include <openssl/evp.h>
13
13
 
25
25
using namespace ArcCredential;
26
26
 
27
27
namespace Arc {
 
28
 
 
29
  #define DEFAULT_DIGEST   ((EVP_MD*)EVP_sha1())
 
30
  #define DEFAULT_KEYBITS  (1024)
 
31
 
28
32
  CredentialError::CredentialError(const std::string& what) : std::runtime_error(what) { }
29
33
 
30
34
  Logger CredentialLogger(Logger::rootLogger, "Credential");
31
35
 
32
 
#if 0
33
 
#define PASS_MIN_LENGTH 4
34
 
  static int passwordcb(char* pwd, int len, int verify, void* passphrase) {
35
 
    int j, r;
36
 
    //char prompt[128];
37
 
    const char* prompt;
38
 
    if(passphrase) {
39
 
      j=strlen((const char*)passphrase);
40
 
      j=(j > len)?len:j;
41
 
      memcpy(pwd,passphrase,j);
42
 
      return(j);
43
 
    }
44
 
    prompt=EVP_get_pw_prompt();
45
 
    if (prompt == NULL)
46
 
      prompt="Enter PEM pass phrase:";
47
 
 
48
 
    for(;;) {
49
 
      //if(!verify)
50
 
      //  snprintf(prompt, sizeof(prompt), "Enter passphrase to decrypte the key file: ");
51
 
      //else
52
 
      //  snprintf(prompt, sizeof(prompt), "Enter passphrase to encrypte the key file: ");
53
 
      r = EVP_read_pw_string(pwd, len, prompt, verify);
54
 
      if(r != 0) {
55
 
        CredentialLogger.msg(ERROR,"Failed to read input passphrase");
56
 
        memset(pwd,0,(unsigned int)len);
57
 
        return(-1);
58
 
      }
59
 
      j = strlen(pwd);
60
 
      if(verify && (j < PASS_MIN_LENGTH)) {
61
 
        CredentialLogger.msg(ERROR,"Input phrase is too short (at least %d char)",PASS_MIN_LENGTH);
62
 
      }
63
 
      else { return j; }
64
 
    }
65
 
  }
66
 
#endif
67
 
 
68
36
  static int ssl_err_cb(const char *str, size_t, void *u) {
69
37
    Logger& logger = *((Logger*)u);
70
38
    logger.msg(DEBUG, "OpenSSL error string: %s", str);
73
41
 
74
42
#define PASS_MIN_LENGTH (0)
75
43
  typedef struct pw_cb_data {
76
 
    const void *password;
77
 
    const char *prompt_info;
 
44
    PasswordSource *password;
78
45
  } PW_CB_DATA;
79
46
 
80
47
  static int passwordcb(char *buf, int bufsiz, int verify, void *cb_tmp) {
81
 
    UI *ui = NULL;
82
 
    int res = 0;
83
 
    const char *prompt_info = NULL;
84
 
    const char *password = NULL;
85
48
    PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
86
49
 
87
 
    if (bufsiz <= 1) return res;
 
50
    if (bufsiz <= 1) return 0;
88
51
    if (cb_data) {
89
 
      if (cb_data->password) password = (const char*)(cb_data->password);
90
 
      if (cb_data->prompt_info) prompt_info = cb_data->prompt_info;
91
 
    }
92
 
 
93
 
    if (password) {
94
 
      res = strlen(password);
95
 
      if (res > (bufsiz-1)) res = bufsiz-1;
96
 
      if(buf) memcpy(buf, password, res+1);
97
 
      return res;
98
 
    }
99
 
 
100
 
    ui = UI_new();
101
 
    if (!ui) return res;
102
 
 
103
 
    int ok = 0;
104
 
    char *buf1 = NULL;
105
 
    char *buf2 = NULL;
106
 
    int ui_flags = 0;
107
 
    char *prompt = NULL;
108
 
 
109
 
    prompt = UI_construct_prompt(ui, "pass phrase", cb_data->prompt_info);
110
 
 
111
 
    ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
112
 
//  UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
113
 
 
114
 
    if (ok >= 0) {
115
 
      ok = -1;
116
 
      if((buf1 = (char *)OPENSSL_malloc(bufsiz)) != NULL) {
117
 
        memset(buf1,0,(unsigned int)bufsiz);
118
 
        ok = UI_add_input_string(ui,prompt,ui_flags,buf1,PASS_MIN_LENGTH,bufsiz-1);
119
 
      }
120
 
    }
121
 
    if (ok >= 0 && verify) {
122
 
      ok = -1;
123
 
      if((buf2 = (char *)OPENSSL_malloc(bufsiz)) != NULL) {
124
 
        memset(buf2,0,(unsigned int)bufsiz);
125
 
        ok = UI_add_verify_string(ui,prompt,ui_flags,buf2,PASS_MIN_LENGTH,bufsiz-1,buf1);
126
 
      }
127
 
    }
128
 
    if (ok >= 0) do {
129
 
      ok = UI_process(ui);
130
 
      if(ok == -2) break; // Abort request
131
 
      if(ok == -1) { // Password error
132
 
        unsigned long errcode = ERR_get_error();
133
 
        const char* errstr = ERR_reason_error_string(errcode);
134
 
        if(errstr == NULL) {
135
 
          CredentialLogger.msg(Arc::ERROR, "Password input error - code %lu",errcode);
136
 
        } else if(strstr(errstr,"result too small")) {
137
 
          CredentialLogger.msg(Arc::ERROR, "Password is too short, need at least %u charcters", PASS_MIN_LENGTH);
138
 
        } else if(strstr(errstr,"result too large")) {
139
 
          CredentialLogger.msg(Arc::ERROR, "Password is too long, need at most %u characters", bufsiz-1);
140
 
        } else {
141
 
          CredentialLogger.msg(Arc::ERROR, "%s", errstr);
142
 
        };
143
 
      };
144
 
    } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
145
 
 
146
 
    if (buf2){
147
 
      memset(buf2,0,(unsigned int)bufsiz);
148
 
      OPENSSL_free(buf2);
149
 
    }
150
 
 
151
 
    if (ok >= 0) {
152
 
      if(buf1) {
153
 
        buf1[bufsiz-1] = 0;
154
 
        res = strlen(buf1);
155
 
        if(buf) memcpy(buf,buf1,res+1);
156
 
      }
157
 
    }
158
 
 
159
 
    if (buf1){
160
 
      memset(buf1,0,(unsigned int)bufsiz);
161
 
      OPENSSL_free(buf1);
162
 
    }
163
 
 
164
 
    if (ok == -1){
165
 
      CredentialLogger.msg(Arc::ERROR, "User interface error");
166
 
      ERR_print_errors_cb(&ssl_err_cb, &CredentialLogger);
167
 
      if(buf) memset(buf,0,(unsigned int)bufsiz);
168
 
      res = 0;
169
 
    } else if (ok == -2) {
170
 
      if(buf) memset(buf,0,(unsigned int)bufsiz);
171
 
      res = 0;
172
 
    }
173
 
    UI_free(ui);
174
 
    OPENSSL_free(prompt);
175
 
 
176
 
    return res;
 
52
      if (cb_data->password) {
 
53
        std::string password;
 
54
        if(cb_data->password->Get(password,PASS_MIN_LENGTH,bufsiz) != PasswordSource::PASSWORD) {
 
55
          // It was requested to have key encrypted and no password was provided
 
56
          return 0;
 
57
        }
 
58
        if(buf) strncpy(buf, password.c_str(), bufsiz);
 
59
        int len = password.length();
 
60
        if(len > bufsiz) len = bufsiz;
 
61
        return len;
 
62
      }
 
63
    }
 
64
    // Password is needed but no source defined for password
 
65
    return 0;
177
66
  }
178
67
 
179
68
  void Credential::LogError(void) const {
463
352
    return start_+lifetime_;
464
353
  }
465
354
 
 
355
  Signalgorithm Credential::GetSigningAlgorithm(void) const {
 
356
    Signalgorithm signing_algorithm = SIGN_DEFAULT;
 
357
    if(!cert_) return signing_algorithm;
 
358
    X509_ALGOR* alg = cert_->sig_alg;
 
359
    if(!alg) return signing_algorithm;
 
360
    int sig_nid = OBJ_obj2nid(alg->algorithm);
 
361
    switch(sig_nid) {
 
362
      case NID_sha1WithRSAEncryption: signing_algorithm = SIGN_SHA1; break;
 
363
      case NID_sha224WithRSAEncryption: signing_algorithm = SIGN_SHA224; break;
 
364
      case NID_sha256WithRSAEncryption: signing_algorithm = SIGN_SHA256; break;
 
365
      case NID_sha384WithRSAEncryption: signing_algorithm = SIGN_SHA384; break;
 
366
      case NID_sha512WithRSAEncryption: signing_algorithm = SIGN_SHA512; break;
 
367
    }
 
368
    return signing_algorithm;
 
369
  }
 
370
 
 
371
  int Credential::GetKeybits(void) const {
 
372
    int keybits = 0;
 
373
    if(!cert_) return keybits;
 
374
    EVP_PKEY* pkey = X509_get_pubkey(cert_);
 
375
    if(!pkey) return keybits;
 
376
    keybits = EVP_PKEY_bits(pkey);
 
377
    return keybits;
 
378
  }
 
379
 
466
380
  void Credential::SetLifeTime(const Period& period) {
467
381
    lifetime_ = period;
468
382
  }
471
385
    start_ = start_time;
472
386
  }
473
387
 
 
388
  void Credential::SetSigningAlgorithm(Signalgorithm signing_algorithm) {
 
389
    switch(signing_algorithm) {
 
390
      case SIGN_SHA1: signing_alg_ = ((EVP_MD*)EVP_sha1()); break;
 
391
      case SIGN_SHA224: signing_alg_ = ((EVP_MD*)EVP_sha224()); break;
 
392
      case SIGN_SHA256: signing_alg_ = ((EVP_MD*)EVP_sha256()); break;
 
393
      case SIGN_SHA384: signing_alg_ = ((EVP_MD*)EVP_sha384()); break;
 
394
      case SIGN_SHA512: signing_alg_ = ((EVP_MD*)EVP_sha512()); break;
 
395
      default: signing_alg_ = NULL; break;
 
396
    }
 
397
  }
 
398
 
 
399
  void Credential::SetKeybits(int keybits) {
 
400
    keybits_ = keybits;
 
401
  }
 
402
 
474
403
  bool Credential::IsCredentialsValid(const UserConfig& usercfg) {
475
404
    return
476
405
    Credential(!usercfg.ProxyPath().empty() ? usercfg.ProxyPath() : usercfg.CertificatePath(),
654
583
     } // end switch
655
584
  }
656
585
 
657
 
  void Credential::loadKeyFile(const std::string& keyfile, EVP_PKEY* &pkey, const std::string& passphrase) {
 
586
  void Credential::loadKeyFile(const std::string& keyfile, EVP_PKEY* &pkey, PasswordSource& passphrase) {
658
587
    BIO* b = OpenFileBIO(keyfile);
659
588
    if(!b) {
660
589
        CredentialLogger.msg(ERROR,"Can not find key file: %s", keyfile);
678
607
    loadKeyString(keystr,pkey,passphrase);
679
608
  }
680
609
 
681
 
  void Credential::loadKeyString(const std::string& key, EVP_PKEY* &pkey, const std::string& passphrase) {
 
610
  void Credential::loadKeyString(const std::string& key, EVP_PKEY* &pkey, PasswordSource& passphrase) {
682
611
    AutoBIO keybio(BIO_new_mem_buf((void*)(key.c_str()), key.length()));
683
612
    if(!keybio){
684
613
      CredentialLogger.msg(ERROR,"Can not read key string");
685
614
      LogError();
686
615
      throw CredentialError("Can not read key string");
687
616
    }
688
 
    std::string prompt_info = "private key";
689
617
 
690
618
    //Read key
691
619
    Credformat format;
696
624
    unsigned char* key_chr;
697
625
 
698
626
    switch(format){
699
 
      case CRED_PEM:
 
627
      case CRED_PEM: {
700
628
        PW_CB_DATA cb_data;
701
 
        cb_data.password = (passphrase.empty()) ? NULL : (void*)(passphrase.c_str());
702
 
        cb_data.prompt_info = prompt_info.empty() ? NULL : prompt_info.c_str();
 
629
        cb_data.password = &passphrase;
703
630
        if(!(pkey = PEM_read_bio_PrivateKey(keybio, NULL, passwordcb, &cb_data))) {
704
631
          int reason = ERR_GET_REASON(ERR_peek_error());
705
632
          if(reason == PEM_R_BAD_BASE64_DECODE) 
712
639
            throw CredentialError("Can not read PEM private key: failed to obtain password");
713
640
          throw CredentialError("Can not read PEM private key");
714
641
        }
715
 
        break;
 
642
        } break;
716
643
 
717
644
      case CRED_DER:
718
645
        key_chr = (unsigned char*)(key.c_str());
812
739
  Credential::Credential() : verification_valid(false), cert_(NULL), pkey_(NULL),
813
740
        cert_chain_(NULL), proxy_cert_info_(NULL), format(CRED_UNKNOWN),
814
741
        start_(Time()), lifetime_(Period("PT12H")),
815
 
        req_(NULL), rsa_key_(NULL), signing_alg_((EVP_MD*)EVP_sha1()), keybits_(1024),
 
742
        req_(NULL), rsa_key_(NULL), signing_alg_(NULL), keybits_(0),
816
743
        proxyver_(0), pathlength_(0), extensions_(NULL) {
817
744
 
818
745
    OpenSSLInit();
828
755
  Credential::Credential(const int keybits) : cert_(NULL),
829
756
    pkey_(NULL), cert_chain_(NULL), proxy_cert_info_(NULL),
830
757
    start_(Time()), lifetime_(Period("PT12H")),
831
 
    req_(NULL), rsa_key_(NULL), signing_alg_((EVP_MD*)EVP_sha1()), keybits_(keybits),
 
758
    req_(NULL), rsa_key_(NULL), signing_alg_(NULL), keybits_(keybits),
832
759
    extensions_(NULL) {
833
760
 
834
761
    OpenSSLInit();
845
772
        std::string policylang, std::string policy, int pathlength) :
846
773
        cert_(NULL), pkey_(NULL), cert_chain_(NULL), proxy_cert_info_(NULL),
847
774
        start_(start), lifetime_(lifetime), req_(NULL), rsa_key_(NULL),
848
 
        signing_alg_((EVP_MD*)EVP_sha1()), keybits_(keybits), extensions_(NULL) {
 
775
        signing_alg_(NULL), keybits_(keybits), extensions_(NULL) {
849
776
 
850
777
    OpenSSLInit();
851
778
 
1044
971
 
1045
972
  Credential::Credential(const std::string& certfile, const std::string& keyfile,
1046
973
        const std::string& cadir, const std::string& cafile,
1047
 
        const std::string& passphrase4key, const bool is_file) {
 
974
        PasswordSource& passphrase4key, const bool is_file) {
1048
975
    InitCredential(certfile,keyfile,cadir,cafile,passphrase4key,is_file);
1049
976
  }
 
977
  Credential::Credential(const std::string& certfile, const std::string& keyfile,
 
978
        const std::string& cadir, const std::string& cafile,
 
979
        const std::string& passphrase4key, const bool is_file) {
 
980
    PasswordSource* pass = NULL;
 
981
    if(passphrase4key.empty()) {
 
982
      pass = new PasswordSourceInteractive("private key", false);
 
983
    } else if(passphrase4key[0] == '\0') {
 
984
      pass = new PasswordSourceString("");
 
985
    } else {
 
986
      pass = new PasswordSourceString(passphrase4key);
 
987
    }
 
988
    InitCredential(certfile,keyfile,cadir,cafile,*pass,is_file);
 
989
    delete pass;
 
990
  }
 
991
 
 
992
  Credential::Credential(const UserConfig& usercfg, PasswordSource& passphrase4key) {
 
993
    if (usercfg.CredentialString().empty()) {
 
994
      InitCredential(!usercfg.ProxyPath().empty() ? usercfg.ProxyPath() : usercfg.CertificatePath(),
 
995
                     !usercfg.ProxyPath().empty() ? ""                  : usercfg.KeyPath(),
 
996
                     usercfg.CACertificatesDirectory(), usercfg.CACertificatePath(),
 
997
                     passphrase4key, true);
 
998
    } else {
 
999
      InitCredential(usercfg.CredentialString(), "",
 
1000
                     usercfg.CACertificatesDirectory(), usercfg.CACertificatePath(),
 
1001
                     passphrase4key, false);
 
1002
    }
 
1003
  }
1050
1004
 
1051
1005
  Credential::Credential(const UserConfig& usercfg, const std::string& passphrase4key) {
1052
 
    InitCredential(!usercfg.ProxyPath().empty() ? usercfg.ProxyPath() : usercfg.CertificatePath(),
1053
 
                   !usercfg.ProxyPath().empty() ? ""                  : usercfg.KeyPath(),
1054
 
                   usercfg.CACertificatesDirectory(), usercfg.CACertificatePath(),
1055
 
                   passphrase4key, true);
 
1006
    PasswordSource* pass = NULL;
 
1007
    if(passphrase4key.empty()) {
 
1008
      pass = new PasswordSourceInteractive("private key", false);
 
1009
    } else if(passphrase4key[0] == '\0') {
 
1010
      pass = new PasswordSourceString("");
 
1011
    } else {
 
1012
      pass = new PasswordSourceString(passphrase4key);
 
1013
    }
 
1014
    if (usercfg.CredentialString().empty()) {
 
1015
      InitCredential(!usercfg.ProxyPath().empty() ? usercfg.ProxyPath() : usercfg.CertificatePath(),
 
1016
                     !usercfg.ProxyPath().empty() ? ""                  : usercfg.KeyPath(),
 
1017
                     usercfg.CACertificatesDirectory(), usercfg.CACertificatePath(),
 
1018
                     *pass, true);
 
1019
    } else {
 
1020
      InitCredential(usercfg.CredentialString(), "",
 
1021
                     usercfg.CACertificatesDirectory(), usercfg.CACertificatePath(),
 
1022
                     *pass, false);
 
1023
    }
 
1024
    delete pass;
1056
1025
  }
1057
1026
 
1058
1027
  void Credential::InitCredential(const std::string& certfile, const std::string& keyfile,
1059
1028
        const std::string& cadir, const std::string& cafile,
1060
 
        const std::string& passphrase4key, const bool is_file) {
 
1029
        PasswordSource& passphrase4key, const bool is_file) {
1061
1030
 
1062
1031
    cacertfile_ = cafile;
1063
1032
    cacertdir_ = cadir;
1070
1039
    proxy_cert_info_ = NULL;
1071
1040
    req_ = NULL;
1072
1041
    rsa_key_ = NULL;
1073
 
    signing_alg_ = (EVP_MD*)EVP_sha1();
1074
 
    keybits_ = 1024;
 
1042
    signing_alg_ = NULL;
 
1043
    keybits_ = 0;
1075
1044
    proxyver_ = 0;
1076
1045
    pathlength_ = 0;
1077
1046
    extensions_ = NULL;
1086
1055
      CredentialLogger.msg(ERROR, "Certificate/Proxy path is empty");
1087
1056
      return;
1088
1057
    }
1089
 
 
 
1058
    
1090
1059
    //Initiate the proxy certificate constant and  method which is required by openssl
1091
1060
    if(!proxy_init_) InitProxyCertInfo();
1092
1061
 
1108
1077
          std::ifstream in(certfile.c_str(), std::ios::in);
1109
1078
          std::getline<char>(in, keystr, 0);
1110
1079
          in.close();
1111
 
          if(keystr.find("BEGIN RSA PRIVATE KEY") != std::string::npos)
 
1080
          if(keystr.find("BEGIN RSA PRIVATE KEY") != std::string::npos) {
1112
1081
            loadKeyFile(certfile, pkey_, passphrase4key);
 
1082
          }
1113
1083
        }
1114
1084
        else {
1115
1085
          loadKeyFile(keyfile, pkey_, passphrase4key);
1246
1216
  bool Credential::GenerateEECRequest(BIO* reqbio, BIO* /*keybio*/, const std::string& dn) {
1247
1217
    bool res = false;
1248
1218
    RSA* rsa_key = NULL;
1249
 
    const EVP_MD *digest = signing_alg_;
 
1219
    const EVP_MD *digest = signing_alg_?signing_alg_:DEFAULT_DIGEST;
1250
1220
    EVP_PKEY* pkey;
1251
 
    int keybits = keybits_;
 
1221
    int keybits = keybits_?keybits_:DEFAULT_KEYBITS;
1252
1222
 
1253
1223
#ifdef HAVE_OPENSSL_OLDRSA
1254
1224
    unsigned long prime = RSA_F4;
1419
1389
  bool Credential::GenerateRequest(BIO* reqbio, bool if_der){
1420
1390
    bool res = false;
1421
1391
    RSA* rsa_key = NULL;
1422
 
    int keybits = keybits_;
1423
 
    const EVP_MD *digest = signing_alg_;
 
1392
    int keybits = keybits_?keybits_:DEFAULT_KEYBITS;
 
1393
    const EVP_MD *digest = signing_alg_?signing_alg_:DEFAULT_DIGEST;
1424
1394
    EVP_PKEY* pkey;
1425
1395
 
1426
1396
    if(pkey_) { CredentialLogger.msg(ERROR, "The credential's private key has already been initialized"); return false; };
1636
1606
  }
1637
1607
 
1638
1608
  bool Credential::OutputPrivatekey(std::string &content, bool encryption, const std::string& passphrase) {
 
1609
    if(passphrase.empty()) {
 
1610
 
 
1611
      PasswordSourceInteractive pass("", true);
 
1612
      return OutputPrivatekey(content, encryption, pass);
 
1613
    }
 
1614
    PasswordSourceString pass(passphrase);
 
1615
    return OutputPrivatekey(content, encryption, pass);
 
1616
  }
 
1617
 
 
1618
  bool Credential::OutputPrivatekey(std::string &content, bool encryption, PasswordSource& passphrase) {
1639
1619
    BIO *out = BIO_new(BIO_s_mem());
1640
1620
    EVP_CIPHER *enc = NULL;
1641
1621
    if(!out) return false;
1647
1627
      }
1648
1628
      else {
1649
1629
        enc = (EVP_CIPHER*)EVP_des_ede3_cbc();
1650
 
#if 0
1651
 
        std::string prompt;
1652
 
        prompt = "Enter passphrase to encrypt the PEM key file: ";
1653
 
        if(!PEM_write_bio_RSAPrivateKey(out,rsa_key_,enc,NULL,0,passwordcb,
1654
 
          (passphrase.empty())?NULL:(void*)(passphrase.c_str()))) {
1655
 
          BIO_free_all(out); return false;
1656
 
        }
1657
 
#endif
1658
1630
        PW_CB_DATA cb_data;
1659
 
        cb_data.password = (passphrase.empty()) ? NULL : (void*)(passphrase.c_str());
1660
 
        cb_data.prompt_info = NULL;
1661
 
        if(!PEM_write_bio_RSAPrivateKey(out,rsa_key_,enc,NULL,0, (pem_password_cb *)passwordcb,&cb_data)) {
 
1631
        cb_data.password = &passphrase;
 
1632
        if(!PEM_write_bio_RSAPrivateKey(out,rsa_key_,enc,NULL,0, &passwordcb,&cb_data)) {
1662
1633
          BIO_free_all(out); return false;
1663
1634
        }
1664
1635
      }
1671
1642
      }
1672
1643
      else {
1673
1644
        enc = (EVP_CIPHER*)EVP_des_ede3_cbc();
1674
 
#if 0
1675
 
        std::string prompt;
1676
 
        prompt = "Enter passphrase to encrypt the PEM key file: ";
1677
 
        if(!PEM_write_bio_PrivateKey(out,pkey_,enc,NULL,0,passwordcb,
1678
 
          (passphrase.empty())?NULL:(void*)(passphrase.c_str()))) {
1679
 
          BIO_free_all(out); return false;
1680
 
        }
1681
 
#endif
1682
1645
        PW_CB_DATA cb_data;
1683
 
        cb_data.password = (passphrase.empty()) ? NULL : (void*)(passphrase.c_str());
1684
 
        cb_data.prompt_info = NULL;
1685
 
        if(!PEM_write_bio_PrivateKey(out,pkey_,enc,NULL,0, (pem_password_cb *)passwordcb,&cb_data)) {
 
1646
        cb_data.password = &passphrase;
 
1647
        if(!PEM_write_bio_PrivateKey(out,pkey_,enc,NULL,0, &passwordcb,&cb_data)) {
1686
1648
          BIO_free_all(out); return false;
1687
1649
        }
1688
1650
      }
2284
2246
    }
2285
2247
 
2286
2248
    int md_nid;
2287
 
    char* md_str;
2288
2249
    const EVP_MD* dgst_alg  =NULL;
2289
2250
    EVP_PKEY* issuer_priv = NULL;
2290
2251
    EVP_PKEY* issuer_pub = NULL;
2353
2314
 
2354
2315
    /* Use the signing algorithm in the signer's priv key */
2355
2316
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
2356
 
    if(EVP_PKEY_get_default_digest_nid(issuer_priv, &md_nid) <= 0) {
2357
 
      CredentialLogger.msg(INFO, "There is no digest in issuer's private key object");
2358
 
    }
2359
 
    md_str = (char *)OBJ_nid2sn(md_nid);
2360
 
    if((dgst_alg = EVP_get_digestbyname(md_str)) == NULL) {
2361
 
      CredentialLogger.msg(INFO, "%s is an unsupported digest type", md_str);
 
2317
    {
 
2318
      int dgst_err = EVP_PKEY_get_default_digest_nid(issuer_priv, &md_nid);
 
2319
      if(dgst_err <= 0) {
 
2320
        CredentialLogger.msg(INFO, "There is no digest in issuer's private key object");
 
2321
      } else if((dgst_err == 2) || (!proxy->signing_alg_)) { // mandatory or no digest specified
 
2322
        char* md_str = (char *)OBJ_nid2sn(md_nid);
 
2323
        if(md_str) {
 
2324
          if((dgst_alg = EVP_get_digestbyname(md_str)) == NULL) {
 
2325
            CredentialLogger.msg(INFO, "%s is an unsupported digest type", md_str);
 
2326
            // TODO: if disgest is mandatory then probably there must be error.
 
2327
          }
 
2328
        }
 
2329
      }
2362
2330
    }
2363
2331
#endif
2364
 
    if(dgst_alg == NULL) dgst_alg = proxy->signing_alg_;
 
2332
    if(dgst_alg == NULL) dgst_alg = proxy->signing_alg_?proxy->signing_alg_:DEFAULT_DIGEST;
2365
2333
 
2366
2334
    /* Check whether the digest algorithm is SHA1 or SHA2*/
2367
2335
    md_nid = EVP_MD_type(dgst_alg);
2379
2347
    }
2380
2348
#endif
2381
2349
 
2382
 
    if(!X509_sign(proxy_cert, issuer_priv, proxy->signing_alg_)) {
 
2350
    if(!X509_sign(proxy_cert, issuer_priv, dgst_alg)) {
2383
2351
      CredentialLogger.msg(ERROR, "Failed to sign the proxy certificate"); LogError(); goto err;
2384
2352
    }
2385
2353
    else CredentialLogger.msg(INFO, "Succeeded to sign the proxy certificate");
2469
2437
 
2470
2438
  Credential::Credential(const std::string& CAcertfile, const std::string& CAkeyfile,
2471
2439
       const std::string& CAserial, const std::string& extfile,
 
2440
       const std::string& extsect, PasswordSource& passphrase4key) :
 
2441
       certfile_(CAcertfile), keyfile_(CAkeyfile), verification_valid(false),
 
2442
       cert_(NULL), pkey_(NULL), cert_chain_(NULL), proxy_cert_info_(NULL),
 
2443
       req_(NULL), rsa_key_(NULL), signing_alg_(NULL), keybits_(0),
 
2444
       proxyver_(0), pathlength_(0), extensions_(NULL),
 
2445
       CAserial_(CAserial), extfile_(extfile), extsect_(extsect) {
 
2446
    OpenSSLInit();
 
2447
 
 
2448
    InitVerification();
 
2449
 
 
2450
    //Initiate the proxy certificate constant and  method which is required by openssl
 
2451
    if(!proxy_init_) InitProxyCertInfo();
 
2452
 
 
2453
    extensions_ = sk_X509_EXTENSION_new_null();
 
2454
 
 
2455
    try {
 
2456
      loadCertificateFile(CAcertfile, cert_, &cert_chain_);
 
2457
      if(cert_) check_cert_type(cert_,cert_type_);
 
2458
      loadKeyFile(CAkeyfile, pkey_, passphrase4key);
 
2459
    } catch(std::exception& err){
 
2460
      CredentialLogger.msg(ERROR, "ERROR:%s", err.what());
 
2461
      LogError();
 
2462
    }
 
2463
  }
 
2464
 
 
2465
  Credential::Credential(const std::string& CAcertfile, const std::string& CAkeyfile,
 
2466
       const std::string& CAserial, const std::string& extfile,
2472
2467
       const std::string& extsect, const std::string& passphrase4key) :
2473
2468
       certfile_(CAcertfile), keyfile_(CAkeyfile), verification_valid(false),
2474
2469
       cert_(NULL), pkey_(NULL), cert_chain_(NULL), proxy_cert_info_(NULL),
2475
 
       req_(NULL), rsa_key_(NULL), signing_alg_((EVP_MD*)EVP_sha1()), keybits_(1024),
 
2470
       req_(NULL), rsa_key_(NULL), signing_alg_(NULL), keybits_(0),
2476
2471
       proxyver_(0), pathlength_(0), extensions_(NULL),
2477
2472
       CAserial_(CAserial), extfile_(extfile), extsect_(extsect) {
2478
2473
    OpenSSLInit();
2485
2480
    extensions_ = sk_X509_EXTENSION_new_null();
2486
2481
 
2487
2482
    try {
 
2483
      PasswordSource* pass = NULL;
 
2484
      if(passphrase4key.empty()) {
 
2485
        pass = new PasswordSourceInteractive("private key", false);
 
2486
      } else if(passphrase4key[0] == '\0') {
 
2487
        pass = new PasswordSourceString("");
 
2488
      } else {
 
2489
        pass = new PasswordSourceString(passphrase4key);
 
2490
      }
2488
2491
      loadCertificateFile(CAcertfile, cert_, &cert_chain_);
2489
2492
      if(cert_) check_cert_type(cert_,cert_type_);
2490
 
      loadKeyFile(CAkeyfile, pkey_, passphrase4key);
 
2493
      loadKeyFile(CAkeyfile, pkey_, *pass);
 
2494
      delete pass;
2491
2495
    } catch(std::exception& err){
2492
2496
      CredentialLogger.msg(ERROR, "ERROR:%s", err.what());
2493
2497
      LogError();