X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2FX509.cpp;h=92d7773f22f4cbff36b0b5cb4a179f030018087a;hb=7a72391242e316a16992e0874a118999486afb87;hp=5d38e3cb241547561a1336b6281fafbed2330165;hpb=858fcca3a53da84a306f55d1811bf119bf8d862f;p=cassiopeia.git diff --git a/src/X509.cpp b/src/X509.cpp index 5d38e3c..92d7773 100644 --- a/src/X509.cpp +++ b/src/X509.cpp @@ -1,5 +1,6 @@ #include "X509.h" +#include #include #include @@ -17,7 +18,33 @@ X509Req::X509Req( X509_REQ* csr ) { pk = std::shared_ptr( pkt, EVP_PKEY_free ); } +X509Req::X509Req( std::string spkac ) { + if( spkac.compare( 0, 6, "SPKAC=" ) != 0 ) { + throw "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"; + } + + spki = std::shared_ptr( spki_p, NETSCAPE_SPKI_free ); + EVP_PKEY* pkt_p = NETSCAPE_SPKI_get_pubkey( spki.get() ); + + if( !pkt_p ) { + throw "Error: reading SPKAC Pubkey failed"; + } + + pk = std::shared_ptr( pkt_p, EVP_PKEY_free ); +} + int X509Req::verify() { + if( !req ) { + return NETSCAPE_SPKI_verify( spki.get(), pk.get() ); + } + return X509_REQ_verify( req.get(), pk.get() ); } @@ -36,6 +63,10 @@ std::shared_ptr X509Req::parse( std::string filename ) { return std::shared_ptr( new X509Req( req ) ); } +std::shared_ptr X509Req::parseSPKAC( std::string content ) { + return std::shared_ptr( new X509Req( content ) ); +} + int add_ext( std::shared_ptr issuer, std::shared_ptr subj, int nid, const char* value ) { X509_EXTENSION* ex; X509V3_CTX ctx; @@ -72,6 +103,20 @@ X509Cert::X509Cert() { if( !X509_set_version( c, 2 ) ) { throw "Setting X509-version to 3 failed"; } + + X509_NAME* subjectP = X509_NAME_new(); + + if( !subjectP ) { + throw "malloc failure"; + } + + subject = std::shared_ptr( subjectP, X509_NAME_free ); +} + +void X509Cert::addRDN( int nid, std::string data ) { + if( ! X509_NAME_add_entry_by_NID( subject.get(), nid, MBSTRING_UTF8, ( unsigned char* )const_cast( data.data() ), data.size(), -1, 0 ) ) { + throw "malloc failure"; + } } void X509Cert::setIssuerNameFrom( std::shared_ptr caCert ) { @@ -88,11 +133,11 @@ void X509Cert::setPubkeyFrom( std::shared_ptr req ) { } } -void X509Cert::setSerialNumber( int num ) { - ASN1_INTEGER_set( target.get()->cert_info->serialNumber, num ); +void X509Cert::setSerialNumber( BIGNUM* num ) { + BN_to_ASN1_INTEGER( num , target->cert_info->serialNumber ); } -void X509Cert::setTimes( long before, long after ) { +void X509Cert::setTimes( uint32_t before, uint32_t after ) { X509_gmtime_adj( X509_get_notBefore( target.get() ), before ); X509_gmtime_adj( X509_get_notAfter( target.get() ), after ); } @@ -139,6 +184,10 @@ void X509Cert::setExtensions( std::shared_ptr caCert, std::vector gens = std::shared_ptr( sk_GENERAL_NAME_new_null(), []( GENERAL_NAMES * ref ) { @@ -172,17 +221,41 @@ void X509Cert::setExtensions( std::shared_ptr caCert, std::vector caKey ) { - if( !X509_sign( target.get(), caKey.get(), EVP_sha512() ) ) { +std::shared_ptr X509Cert::sign( std::shared_ptr caKey, std::string signAlg ) { + if( !X509_set_subject_name( target.get(), subject.get() ) ) { + throw "error setting subject"; + } + + const EVP_MD* md; + + if( signAlg == "sha512" ) { + md = EVP_sha512(); + } else if( signAlg == "sha384" ) { + md = EVP_sha384(); + } else if( signAlg == "sha256" ) { + md = EVP_sha256(); + } else if( signAlg == "sha1" ) { + md = EVP_sha1(); + } else { + throw "Unknown md-type"; + } + + if( !X509_sign( target.get(), caKey.get(), md ) ) { throw "Signing failed."; } - X509_print_fp( stdout, target.get() ); + //X509_print_fp( stdout, target.get() ); std::shared_ptr mem = std::shared_ptr( BIO_new( BIO_s_mem() ), BIO_free ); PEM_write_bio_X509( mem.get(), target.get() ); BUF_MEM* buf; BIO_get_mem_ptr( mem.get(), &buf ); - std::string output( buf->data, buf->data + buf->length ); - return output; + std::shared_ptr res = std::shared_ptr( new SignedCertificate() ); + res->certificate = std::string( buf->data, buf->data + buf->length ); + BIGNUM* ser = ASN1_INTEGER_to_BN( target->cert_info->serialNumber, NULL ); + char* serStr = BN_bn2hex( ser ); + res->serial = std::string( serStr ); + OPENSSL_free( serStr ); + BN_free( ser ); + return res; }