]> WPIA git - cassiopeia.git/blobdiff - src/crypto/X509.cpp
fmt: whitespace, padding and indentation formatting
[cassiopeia.git] / src / crypto / X509.cpp
index a068957b4071a2646f3d2b8d475b991aae8bdf4c..e304b908abb5a8d0cee172f62961e9697ac25df5 100644 (file)
@@ -11,7 +11,7 @@ X509Req::X509Req( X509_REQ* csr ) : req( csr, X509_REQ_free ) {
     EVP_PKEY* pkt = X509_REQ_get_pubkey( req.get() );
 
     if( !pkt ) {
-        throw "Error extracting public key";
+        throw std::runtime_error( "Error extracting public key" );
     }
 
     pk = std::shared_ptr<EVP_PKEY>( pkt, EVP_PKEY_free );
@@ -19,21 +19,21 @@ X509Req::X509Req( X509_REQ* csr ) : req( csr, X509_REQ_free ) {
 
 X509Req::X509Req( std::string spkac ) {
     if( spkac.compare( 0, 6, "SPKAC=" ) != 0 ) {
-        throw "Error: not a SPKAC";
+        throw std::runtime_error( "Error: not a SPKAC" );
     }
 
     spkac = spkac.substr( 6 );
     NETSCAPE_SPKI* spki_p = NETSCAPE_SPKI_b64_decode( spkac.c_str(), spkac.size() );
 
     if( !spki_p ) {
-        throw "Error: decode failed";
+        throw std::runtime_error( "Error: decode failed" );
     }
 
     spki = std::shared_ptr<NETSCAPE_SPKI>( spki_p, NETSCAPE_SPKI_free );
     EVP_PKEY* pkt_p = NETSCAPE_SPKI_get_pubkey( spki.get() );
 
     if( !pkt_p ) {
-        throw "Error: reading SPKAC Pubkey failed";
+        throw std::runtime_error( "Error: reading SPKAC Pubkey failed" );
     }
 
     pk = std::shared_ptr<EVP_PKEY>( pkt_p, EVP_PKEY_free );
@@ -56,10 +56,10 @@ std::shared_ptr<X509Req> X509Req::parseCSR( std::string content ) {
     X509_REQ* req = PEM_read_bio_X509_REQ( in.get(), NULL, NULL, NULL );
 
     if( !req ) {
-        throw "Error parsing CSR";
+        throw std::runtime_error( "Error parsing CSR" );
     }
 
-    return std::shared_ptr<X509Req>( new X509Req( req ) );
+    return std::shared_ptr<X509Req>( new X509Req( req ) ); // TODO ask
 }
 
 std::shared_ptr<X509Req> X509Req::parseSPKAC( std::string content ) {
@@ -94,19 +94,19 @@ X509Cert::X509Cert() {
     X509* c = X509_new();
 
     if( !c ) {
-        throw "malloc failed";
+        throw std::runtime_error( "malloc failed" );
     }
 
     target = std::shared_ptr<X509>( c, X509_free );
 
     if( !X509_set_version( c, 2 ) ) {
-        throw "Setting X509-version to 3 failed";
+        throw std::runtime_error( "Setting X509-version to 3 failed" );
     }
 
     X509_NAME* subjectP = X509_NAME_new();
 
     if( !subjectP ) {
-        throw "malloc failure";
+        throw std::runtime_error( "malloc failure in construct." );
     }
 
     subject = std::shared_ptr<X509_NAME>( subjectP, X509_NAME_free );
@@ -114,13 +114,13 @@ X509Cert::X509Cert() {
 
 void X509Cert::addRDN( int nid, std::string data ) {
     if( ! X509_NAME_add_entry_by_NID( subject.get(), nid, MBSTRING_UTF8, ( unsigned char* )const_cast<char*>( data.data() ), data.size(), -1, 0 ) ) {
-        throw "malloc failure";
+        throw std::runtime_error( "malloc failure in RDN" );
     }
 }
 
 void X509Cert::setIssuerNameFrom( std::shared_ptr<X509> caCert ) {
     if( !X509_set_issuer_name( target.get(), X509_get_subject_name( caCert.get() ) ) ) {
-        throw "Error setting Issuer name";
+        throw std::runtime_error( "Error setting Issuer name" );
     }
 }
 
@@ -128,12 +128,14 @@ void X509Cert::setPubkeyFrom( std::shared_ptr<X509Req> req ) {
     std::shared_ptr<EVP_PKEY> pktmp = req->getPkey();
 
     if( !X509_set_pubkey( target.get(), pktmp.get() ) ) {
-        throw "Setting public key failed.";
+        throw std::runtime_error( "Setting public key failed." );
     }
 }
 
 void X509Cert::setSerialNumber( BIGNUM* num ) {
-    BN_to_ASN1_INTEGER( num , target->cert_info->serialNumber );
+    ASN1_INTEGER *i = BN_to_ASN1_INTEGER( num, NULL);
+    X509_set_serialNumber( target.get(), i );
+    ASN1_INTEGER_free( i );
 }
 
 void X509Cert::setTimes( uint32_t before, uint32_t after ) {
@@ -154,7 +156,7 @@ static X509_EXTENSION* do_ext_i2d( int ext_nid, int crit, ASN1_VALUE* ext_struc
         goto merr;
     }
 
-    if( !( ext_oct = M_ASN1_OCTET_STRING_new() ) ) {
+    if( !( ext_oct = ASN1_OCTET_STRING_new() ) ) {
         goto merr;
     }
 
@@ -167,24 +169,24 @@ static X509_EXTENSION* do_ext_i2d( int ext_nid, int crit, ASN1_VALUE* ext_struc
         goto merr;
     }
 
-    M_ASN1_OCTET_STRING_free( ext_oct );
+    ASN1_OCTET_STRING_free( ext_oct );
     return ext;
 
 merr:
-    throw "memerr";
+    throw std::runtime_error( "memerr" );
 }
 
-void X509Cert::setExtensions( std::shared_ptr<X509> caCert, std::vector<std::shared_ptr<SAN>>& sans, Profile& prof ) {
+void X509Cert::setExtensions( std::shared_ptr<X509> caCert, std::vector<std::shared_ptr<SAN>>& sans, Profile& prof, std::string crlURL, std::string crtURL ) {
     add_ext( caCert, target, NID_basic_constraints, "critical,CA:FALSE" );
     add_ext( caCert, target, NID_subject_key_identifier, "hash" );
-    add_ext( caCert, target, NID_authority_key_identifier, "keyid,issuer:always" );
+    add_ext( caCert, target, NID_authority_key_identifier, "keyid:always" );
     std::string ku = std::string( "critical," ) + prof.ku;
     add_ext( caCert, target, NID_key_usage, ku.c_str() );
     add_ext( caCert, target, NID_ext_key_usage, prof.eku.c_str() );
-    add_ext( caCert, target, NID_info_access, "OCSP;URI:http://ocsp.cacert.org" );
-    add_ext( caCert, target, NID_crl_distribution_points, "URI:http://crl.cacert.org/class3-revoke.crl" );
+    add_ext( caCert, target, NID_info_access, ( "OCSP;URI:http://ocsp.cacert.org,caIssuers;URI:" + crtURL ).c_str() );
+    add_ext( caCert, target, NID_crl_distribution_points, ( "URI:" + crlURL ).c_str() );
 
-    if( sans.size() == 0 ) {
+    if( sans.empty() ) {
         return;
     }
 
@@ -200,16 +202,16 @@ void X509Cert::setExtensions( std::shared_ptr<X509> caCert, std::vector<std::sha
         GENERAL_NAME* gen = GENERAL_NAME_new();
 
         if( !gen ) {
-            throw "Malloc failure.";
+            throw std::runtime_error( "Malloc failure." );
         }
 
         gen->type = name->type == "DNS" ? GEN_DNS : name->type == "email" ? GEN_EMAIL : 0; // GEN_EMAIL;
 
         if( !gen->type
-                || !( gen->d.ia5 = M_ASN1_IA5STRING_new() )
+                || !( gen->d.ia5 = ASN1_IA5STRING_new() )
                 || !ASN1_STRING_set( gen->d.ia5, name->content.data(), name->content.size() ) ) {
             GENERAL_NAME_free( gen );
-            throw "initing iasting5 failed";
+            throw std::runtime_error( "initing iasting5 failed" );
         }
 
         sk_GENERAL_NAME_push( gens.get(), gen );
@@ -223,7 +225,7 @@ void X509Cert::setExtensions( std::shared_ptr<X509> caCert, std::vector<std::sha
 
 std::shared_ptr<SignedCertificate> X509Cert::sign( std::shared_ptr<EVP_PKEY> caKey, std::string signAlg ) {
     if( !X509_set_subject_name( target.get(), subject.get() ) ) {
-        throw "error setting subject";
+        throw std::runtime_error( "error setting subject" );
     }
 
     const EVP_MD* md;
@@ -235,38 +237,43 @@ std::shared_ptr<SignedCertificate> X509Cert::sign( std::shared_ptr<EVP_PKEY> caK
     } else if( signAlg == "sha256" ) {
         md = EVP_sha256();
     } else if( signAlg == "sha1" ) {
-        md = EVP_sha1();
+        throw std::runtime_error( "Refusing to sign with weak signature algorithm (SHA-1)." );
+    } else if( signAlg == "md5" ) {
+        throw std::runtime_error( "Refusing to sign with weak signature algorithm (MD5)." );
     } else {
-        throw "Unknown md-type";
+        throw std::runtime_error( "Unknown signature algorithm" );
     }
 
     if( !X509_sign( target.get(), caKey.get(), md ) ) {
-        throw "Signing failed.";
+        throw std::runtime_error( "Signing failed." );
     }
 
     //X509_print_fp( stdout, target.get() );
 
     std::shared_ptr<BIO> mem = std::shared_ptr<BIO>( BIO_new( BIO_s_mem() ), BIO_free );
+
     if( !mem ) {
-        throw "Failed to allocate memory for the signed certificate.";
+        throw std::runtime_error( "Failed to allocate memory for the signed certificate." );
     }
+
     PEM_write_bio_X509( mem.get(), target.get() );
 
     BUF_MEM* buf = NULL;
     BIO_get_mem_ptr( mem.get(), &buf );
 
-    std::shared_ptr<SignedCertificate> res = std::shared_ptr<SignedCertificate>( new SignedCertificate() );
+    auto res = std::make_shared<SignedCertificate>();
     res->certificate = std::string( buf->data, buf->data + buf->length );
 
-    std::shared_ptr<BIGNUM> ser( ASN1_INTEGER_to_BN( target->cert_info->serialNumber, NULL ), BN_free );
+    std::shared_ptr<BIGNUM> ser( ASN1_INTEGER_to_BN( X509_get_serialNumber( target.get() ), NULL ), BN_free );
+
     if( !ser ) {
-        throw "Failed to retrieve certificate serial of signed certificate.";
+        throw std::runtime_error( "Failed to retrieve certificate serial of signed certificate." );
     }
 
     std::shared_ptr<char> serStr(
         BN_bn2hex( ser.get() ),
-        []( char *p ) {
-            OPENSSL_free(p);
+        []( charp ) {
+            OPENSSL_free( p );
         } ); // OPENSSL_free is a macro...
     res->serial = serStr ? std::string( serStr.get() ) : "";