/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__ */
|