This file is indexed.

/usr/include/arc/credential/Credential.h is in nordugrid-arc-dev 4.2.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
#ifndef __ARC_CREDENTIAL_H__
#define __ARC_CREDENTIAL_H__

#include <stdlib.h>
#include <stdexcept>
#include <iostream>
#include <string>
#include <openssl/asn1.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
#include <openssl/err.h>

#include <arc/Logger.h>
#include <arc/DateTime.h>
#include <arc/UserConfig.h>

#include <arc/credential/CertUtil.h>
#include <arc/credential/PasswordSource.h>

namespace Arc {

  /** \defgroup credential Credential handling classes and functions. */

  /// An exception class for the Credential class.
  /** This is an exception class that is used to handle runtime errors
   * discovered in the Credential class.
   * \ingroup credential
   * \headerfile Credential.h arc/credential/Credential.h
   */
class CredentialError : public std::runtime_error {
  public:
    // Constructor
    /** This is the constructor of the CredentialError class.
     * @param what  An explanation of the error.
     */
    CredentialError(const std::string& what="");
};

typedef enum {CRED_PEM, CRED_DER, CRED_PKCS, CRED_UNKNOWN} Credformat;
/// Signal algorithm
/**
 * \since Added in 4.0.0.
 **/
typedef enum { SIGN_DEFAULT = 0,
               SIGN_SHA1,
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
               SIGN_SHA224,
               SIGN_SHA256,
               SIGN_SHA384,
               SIGN_SHA512
#endif
             } Signalgorithm;

/**Logger to be used by all modules of credentials library*/
extern Logger CredentialLogger;

/// Class for handling X509 credentials.
/**Credential class covers the functionality about general processing about certificate/key
 * files, including:
 *  -# certificate/key parsing, information extracting (such as subject name,
 * issuer name, lifetime, etc.), chain verifying, extension processing about proxy certinfo,
 * extension processing about other general certificate extension (such as voms attributes,
 * it should be the extension-specific code itself to create, parse and verify the extension,
 * not the Credential class. For voms, it is some code about writing and parsing voms-implementing
 * Attribute Certificate/ RFC3281, the voms-attribute is then be looked as a binary part and
 * embedded into extension of X509 certificate/proxy certificate);
 *  -# certificate request, extension embedding and certificate signing, for both proxy certificate
 * and EEC (end entity certificate) certificate.
 *
 * The Credential class supports PEM, DER PKCS12 credentials.
 * \ingroup credential
 * \headerfile Credential.h arc/credential/Credential.h
 */
class Credential {
  public:
    /**Default constructor, only acts as a container for inquiring certificate request,
    *is meaningless for any other use.
    */
    Credential();

    /** Constructor with user-defined keylength. Needed for creation of EE certs, since some
    * applications will only support keys with a certain minimum length > 1024
    */
    Credential(int keybits);

    virtual ~Credential();

    /**Constructor, specific constructor for CA certificate
    *is meaningless for any other use.
    */
    Credential(const std::string& CAfile, const std::string& CAkey,
               const std::string& CAserial,
               const std::string& extfile, const std::string& extsect,
               const std::string& passphrase4key);

    /** Same as previuos constructor but allows password to be
    * supplied from different sources.
    * \since Added in 4.0.0.
    */
    Credential(const std::string& CAfile, const std::string& CAkey,
               const std::string& CAserial,
               const std::string& extfile, const std::string& extsect,
               PasswordSource& passphrase4key);

    /**Constructor, specific constructor for proxy certificate, only acts as a
    * container for constraining certificate signing and/or generating certificate
    * request (only keybits is useful for creating certificate request), is meaningless
    * for any other use.
    *
    * The proxyversion and policylang is for specifying the proxy certificate type and
    * the policy language inside proxy.
    * The definition of proxyversion and policy language is based on
    * http://dev.globus.org/wiki/Security/ProxyCertTypes#RFC_3820_Proxy_Certificates
    * The code is supposed to support proxy version:
    *  - GSI2 (legacy proxy)
    *  - GSI3 (Proxy draft)
    *  - RFC (RFC3820 proxy)
    *
    * and corresponding policy languages
    *  - GSI2 (GSI2, GSI2_LIMITED)
    *  - GSI3
    *  - RFC
    *    - IMPERSONATION_PROXY--1.3.6.1.5.5.7.21.1
    *    - INDEPENDENT_PROXY--1.3.6.1.5.5.7.21.2
    *    - LIMITED_PROXY--1.3.6.1.4.1.3536.1.1.1.9
    *    - RESTRICTED_PROXY--policy language undefined
    *
    * In openssl>=098, there are three types of policy languages:
    *  - id-ppl-inheritAll--1.3.6.1.5.5.7.21.1
    *  - id-ppl-independent--1.3.6.1.5.5.7.21.2
    *  - id-ppl-anyLanguage-1.3.6.1.5.5.7.21.0
    *
    * @param start start time of proxy certificate
    * @param lifetime lifetime of proxy certificate
    * @param keybits modulus size for RSA key generation,
    * it should be greater than 1024 if 'this' class is
    * used for generating X509 request; it should be '0' if
    * 'this' class is used for constraining certificate signing.
    * @param proxyversion proxy certificate version (see above for values)
    * @param policylang policy language of the proxy (see above for values)
    * @param policy path to file with policy content
    * @param pathlength path length constraint
    */
    Credential(Time start, Period lifetime = Period("PT12H"),
              int keybits = 1024, std::string proxyversion = "rfc",
              std::string policylang = "inheritAll", std::string policy = "",
              int pathlength = -1);

    /**Constructor, specific constructor for usual certificate, constructing from
    * credential files. only acts as a container for parsing the certificate and key
    * files, is meaningless for any other use. this constructor will parse the credential
    * information, and put them into "this" object
    * @param cert path to certificate file
    * @param key path to key file
    * @param cadir path to directory of CA certificates
    * @param cafile path to file with CA certificate
    * @param passphrase4key specifies the password for decrypting private key (if needed).
    *    If value is empty then password will be asked interactively. To avoid asking for
    *    password use value provided by NoPassword() method.
    * @param is_file specifies if the cert/key are from file, otherwise they
    *    are supposed to be from string. default is from file
    */
    Credential(const std::string& cert, const std::string& key, const std::string& cadir,
               const std::string& cafile, const std::string& passphrase4key = "",
               const bool is_file = true);

    /** Same as previuos constructor but allows password to be
    * supplied from different sources.
    * \since Added in 4.0.0.
    */
    Credential(const std::string& cert, const std::string& key, const std::string& cadir,
               const std::string& cafile, PasswordSource& passphrase4key,
               const bool is_file = true);

    /**Constructor, specific constructor for usual certificate, constructing from
    * information in UserConfig object. Only acts as a container for parsing the 
    * certificate and key files, is meaningless for any other use. this constructor 
    * will parse the credential information, and put them into "this" object.
    * @param usercfg UserConfig object from which certificate information is obtained
    * @param passphrase4key passphrase for private key
    */
    Credential(const UserConfig& usercfg, const std::string& passphrase4key = "");

    /** Same as previuos constructor but allows password to be
    * supplied from different sources.
    * \since Added in 4.0.0.
    */
    Credential(const UserConfig& usercfg, PasswordSource& passphrase4key);

    /**Initiate nid for proxy certificate extension*/
    static void InitProxyCertInfo(void);

    /** Returns true if credentials are valid.
      Credentials are read from locations specified in UserConfig object.
      This method is deprecated. User per-instance method IsValid() instead.
    */
    static bool IsCredentialsValid(const UserConfig& usercfg);

    /**General method for adding a new nid into openssl's global const*/
    void AddCertExtObj(std::string& sn, std::string& oid);

    /// Set signing algorithm
    /**
     * \since Added in 4.0.0.
     **/
    void SetSigningAlgorithm(Signalgorithm signing_algorithm = SIGN_DEFAULT);

    /// Set key bits
    /**
     * \since Added in 4.0.0.
     **/
    void SetKeybits(int keybits = 0);

    static std::string NoPassword(void) { return std::string("\0",1); };

  private:

    /** Credential object so far is not supposed to be copied */
    Credential(const Credential&);

    void InitCredential(const std::string& cert, const std::string& key, const std::string& cadir,
               const std::string& cafile, PasswordSource& passphrase4key, const bool is_file);

    /**load key from argument keybio, and put key information into argument pkey */
    //void loadKeyString(const std::string& key, EVP_PKEY* &pkey, const std::string& passphrase = "");
    void loadKeyString(const std::string& key, EVP_PKEY* &pkey, PasswordSource& passphrase);
    //void loadKeyFile(const std::string& keyfile, EVP_PKEY* &pkey, const std::string& passphrase = "");
    void loadKeyFile(const std::string& keyfile, EVP_PKEY* &pkey, PasswordSource& passphrase);
    //void loadKey(BIO* bio, EVP_PKEY* &pkey, const std::string& passphrase = "", const std::string& prompt_info = "", const bool is_file = true);

    /**load certificate from argument certbio, and put certificate information into
    * argument cert and certchain
    */
    void loadCertificateString(const std::string& cert, X509* &x509, STACK_OF(X509)** certchain);
    void loadCertificateFile(const std::string& certfile, X509* &x509, STACK_OF(X509)** certchain);
    //void loadCertificate(BIO* bio, X509* &x509, STACK_OF(X509)** certchain, const bool is_file=true);

    /**Initiate cert_verify_context which will be used for certificate verification*/
    void InitVerification(void);

    /**Verify whether the certificate is signed by trusted CAs
     *the verification is not needed for EEC, but needed for verifying a proxy certificate which
     *is generated by the others
     */
    bool Verify(void);

    /**Create a certificate extension based on the arguments
    * name and data. argument crit will be used by
    * X509_EXTENSION_create_by_OBJ which is called inside
    * CreateExtension method.
    */
    X509_EXTENSION* CreateExtension(const std::string& name, const std::string& data, bool crit = false);

    /** Set the start and end time for the proxy credential.
    * After setting, the start time of proxy will not
    * before the later value from issuer's start time
    * and the "start" parameter, and the end time of proxy
    * will not after the ealier value from issuer's end
    * time and the "start" parameter plus "lifetime" paremeter
    */
    bool SetProxyPeriod(X509* tosign, X509* issuer, const Time& start, const Period& lifetime);

    /**Assistant method for signing the proxy request, the method will duplicate some information
    *(subject and extension) from signing certificate
    */
    bool SignRequestAssistant(Credential* proxy, EVP_PKEY* req_pubkey, X509** tosign);

  public:
    /**Log error information related with openssl*/
    void LogError(void) const;

    /************************************/
    /*****Get information from "this" object**/

    /**Get the verification result about certificate chain checking*/
    bool GetVerification(void) const {return verification_valid; };

    /**Get the private key attached to this object*/
    EVP_PKEY* GetPrivKey(void) const;

    /**Get the public key attached to this object*/
    EVP_PKEY* GetPubKey(void) const;

    /**Get the certificate attached to this object*/
    X509* GetCert(void) const;

    /** Get the certificate request, if there is any */
    X509_REQ* GetCertReq(void) const;

    /**Get the certificate chain attached to this object*/
    STACK_OF(X509)* GetCertChain(void) const;

    /**Get the number of certificates in the certificate
     * chain attached to this object
     */
    int GetCertNumofChain(void) const;

    /**Get the certificate format, PEM PKCS12 or DER
    * BIO could be memory or file, they should be processed
    * differently.
    */
    Credformat getFormat_BIO(BIO * in, const bool is_file = true) const;
    Credformat getFormat_str(const std::string& source) const;
 
    /**Get the DN of the certificate attached to this object*/
    std::string GetDN(void) const;

    /**Get the Identity name of the certificate attached to this object,
     * the result will not include proxy CN
     */
    std::string GetIdentityName(void) const;

    /**Get type of the certificate attached to this object*/
    ArcCredential::certType GetType(void) const;

    /**Get issuer of the certificate attached to this object*/
    std::string GetIssuerName(void) const;

    /**Get CA of the certificate attached to this object, if the certificate 
     *is an EEC, GetCAName get the same value as GetIssuerName
     */
    std::string GetCAName(void) const;

    /**Get signing algorithm used to sign the certificate attached to this object
     * \since Added in 4.0.0. 
     **/
    Signalgorithm GetSigningAlgorithm(void) const;

    /**Get key size of the certificate attached to this object
     * \since Added in 4.0.0.
     **/
    int GetKeybits(void) const;

    /**Get the proxy policy attached to the "proxy certificate
     * information" extension of the proxy certificate
     */
    std::string GetProxyPolicy(void) const;

    /**Set the proxy policy attached to the "proxy certificate
     * information" extension of the proxy certificate
     */
    void SetProxyPolicy(const std::string& proxyversion, const std::string& policylang,
        const std::string& policy, int pathlength);

    /**Output the private key into string
     * @param content Filled with private key content
     * @param encryption whether encrypt the output private key or not
     * @param passphrase the passphrase to encrypt the output private key
     */
    bool OutputPrivatekey(std::string &content,  bool encryption = false, const std::string& passphrase ="");

    /**Output the private key into string
     * @param content Filled with private key content
     * @param encryption whether encrypt the output private key or not
     * @param passphrase the source for passphrase to encrypt the output private key
     * \since Added in 4.0.0.
     */
    bool OutputPrivatekey(std::string &content,  bool encryption, PasswordSource& passphrase);

    /**Output the public key into string*/
    bool OutputPublickey(std::string &content);

    /**Output the certificate into string
     * @param content Filled with certificate content
     * @param is_der false for PEM, true for DER
     */
    bool OutputCertificate(std::string &content, bool is_der=false);

    /**Output the certificate chain into string
     * @param content Filled with certificate chain content
     * @param is_der false for PEM, true for DER
     */
    bool OutputCertificateChain(std::string &content, bool is_der=false);

    /**Returns lifetime of certificate or proxy*/
    Period GetLifeTime(void) const;

    /**Returns validity start time of certificate or proxy*/
    Time GetStartTime() const;

    /**Returns validity end time of certificate or proxy*/
    Time GetEndTime() const;

    /**Set lifetime of certificate or proxy*/
    void SetLifeTime(const Period& period);

    /**Set start time of certificate or proxy*/
    void SetStartTime(const Time& start_time);

    /**Returns true if credentials are valid*/
    bool IsValid(void);

    /************************************/
    /*****Generate certificate request, add certificate extension, inquire certificate request,
    *and sign certificate request
    **/

    /**Add an extension to the extension part of the certificate
    *@param name the name of the extension, there OID related with the name
    *should be registered into openssl firstly
    *@param data the data which will be inserted into certificate extension
    *@param crit critical
    */
    bool AddExtension(const std::string& name, const std::string& data, bool crit = false);

    /**Add an extension to the extension part of the certificate
    * @param name the name of the extension, there OID related with the name
    * should be registered into openssl firstly
    * @param binary the data which will be inserted into certificate
    * extension part as a specific extension there should be specific
    * methods defined inside specific X509V3_EXT_METHOD structure
    * to parse the specific extension format.
    * For example, VOMS attribute certificate is a specific
    * extension to proxy certificate. There is specific X509V3_EXT_METHOD
    * defined in VOMSAttribute.h and VOMSAttribute.c for parsing attribute
    * certificate.
    * In openssl, the specific X509V3_EXT_METHOD can be got according to
    * the extension name/id, see X509V3_EXT_get_nid(ext_nid)
    */
    bool AddExtension(const std::string& name, char** binary);

    /**Get the specific extension (named by the parameter) in a certificate
    * this function is only supposed to be called after certificate and key
    * are loaded by the constructor for usual certificate 
    * @param name the name of the extension to get
    */
    std::string GetExtension(const std::string& name);

    /**Generate an EEC request, based on the keybits and signing
    * algorithm information inside this object
    * output the certificate request to output BIO
    *
    * The user will be asked for a private key password
    */
    bool GenerateEECRequest(BIO* reqbio, BIO* keybio, const std::string& dn = "");

    /**Generate an EEC request, output the certificate request to a string*/
    bool GenerateEECRequest(std::string &reqcontent, std::string &keycontent, const std::string& dn = "");

    /**Generate an EEC request, output the certificate request and the key to a file*/
    bool GenerateEECRequest(const char* request_filename, const char* key_filename, const std::string& dn = "");

    /**Generate a proxy request, base on the keybits and signing
    * algorithm information inside this object
    * output the certificate request to output BIO
    */
    bool GenerateRequest(BIO* bio, bool if_der = false);

    /**Generate a proxy request, output the certificate request to a string*/
    bool GenerateRequest(std::string &content, bool if_der = false);

    /**Generate a proxy request, output the certificate request to a file*/
    bool GenerateRequest(const char* filename, bool if_der = false);

    /**Inquire the certificate request from BIO, and put the request
    * information to X509_REQ inside this object,
    * and parse the certificate type from the PROXYCERTINFO
    * of request' extension
    * @param reqbio the BIO containing the certificate request
    * @param if_eec true if EEC request
    * @param if_der false for PEM; true for DER
    */
    bool InquireRequest(BIO* reqbio, bool if_eec = false, bool if_der = false);

    /**Inquire the certificate request from a string*/
    bool InquireRequest(std::string &content, bool if_eec = false, bool if_der = false);

    /**Inquire the certificate request from a file*/
    bool InquireRequest(const char* filename, bool if_eec = false, bool if_der = false);

    /**Sign request based on the information inside proxy, and
     * output the signed certificate to output BIO
     * @param proxy Credential object holding proxy information
     * @param outputbio BIO to hold the signed certificate
     * @param if_der false for PEM, true for DER
     */
    bool SignRequest(Credential* proxy, BIO* outputbio, bool if_der = false);

    /**Sign request and output the signed certificate to a string
     * @param proxy Credential object holding proxy information
     * @param content string to hold the signed certificate
     * @param if_der false for PEM, true for DER
     */
    bool SignRequest(Credential* proxy, std::string &content, bool if_der = false);

    /**Sign request and output the signed certificate to a file
     * @param proxy Credential object holding proxy information
     * @param filename path to file where certificate will be written
     * @param if_der false for PEM, true for DER
     */
    bool SignRequest(Credential* proxy, const char* filename, bool if_der = false);

    /**Self sign a certificate. This functionality is specific for creating a CA credential
    * by using this Credential class. 
    * @param dn  the DN for the subject
    * @param extfile  the configuration file which includes the extension information, typically the openssl.cnf file
    * @param extsect  the section/group name for the extension, e.g. in openssl.cnf, usr_cert and v3_ca
    * @param certfile the certificate file, which contains the signed certificate 
    */
    bool SelfSignEECRequest(const std::string& dn, const char* extfile, const std::string& extsect, const char* certfile);

    //The following three methods is about signing an EEC certificate by implementing the same
    //functionality as a normal CA
    /**Sign eec request, and output the signed certificate to output BIO*/
    bool SignEECRequest(Credential* eec, const std::string& dn, BIO* outputbio);

    /**Sign request and output the signed certificate to a string*/
    bool SignEECRequest(Credential* eec, const std::string& dn, std::string &content);

    /**Sign request and output the signed certificate to a file*/
    bool SignEECRequest(Credential* eec, const std::string& dn, const char* filename);

  private:
    // PKI files
    std::string cacertfile_;
    std::string cacertdir_;
    std::string certfile_;
    std::string keyfile_;

    // Verification context
    ArcCredential::cert_verify_context verify_ctx_;

    //Verification result
    bool verification_valid;

    //Certificate structures
    X509 *           cert_;    //certificate
    ArcCredential::certType cert_type_;
    EVP_PKEY *       pkey_;    //private key
    STACK_OF(X509) * cert_chain_;  //certificates chain which is parsed
                                   //from the certificate, after
                                   //verification, the ca certificate
                                   //will be included
    ArcCredential::PROXYCERTINFO* proxy_cert_info_;
    Credformat       format;
    Time        start_;
    Period      lifetime_;

    //Certificate request
    X509_REQ* req_;
    RSA* rsa_key_;
    EVP_MD* signing_alg_;
    int keybits_;

    //Proxy policy
    std::string proxyversion_;
    std::string policy_;
    std::string policylang_;
    int proxyver_;
    int pathlength_;

    //Extensions for certificate, such as certificate policy, attributes, etc.
    STACK_OF(X509_EXTENSION)* extensions_;

    //CA functionality related information
    std::string CAserial_;
    std::string extfile_;
    std::string extsect_;

    static X509_NAME *parse_name(char *subject, long chtype, int multirdn);
};

}// namespace Arc

#endif /* __ARC_CREDENTIAL_H__ */