Google-Auth

 view release on metacpan or  search on metacpan

XS.xs  view on Meta::CPAN

        ECDSA_SIG *ec_sig = NULL;
    CODE:
        if (sv_derived_from(key_obj_sv, "Google::Auth::PublicKey")) {
            IV tmp = SvIV((SV*)SvRV(key_obj_sv));
            pkey = INT2PTR(EVP_PKEY *, tmp);
        }
        if (!pkey) XSRETURN_NO;

        msg_str = SvPV(message_sv, msg_len);
        sig_str = SvPV(signature_sv, sig_len);

        actual_sig = (unsigned char *)sig_str;
        actual_sig_len = sig_len;

        if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) {
            if (sig_len % 2 == 0) {
                int half_len = sig_len / 2;
                BIGNUM *r_bn = BN_bin2bn((unsigned char *)sig_str, half_len, NULL);
                BIGNUM *s_bn = BN_bin2bn((unsigned char *)sig_str + half_len, half_len, NULL);
                if (r_bn && s_bn) {
                    ec_sig = ECDSA_SIG_new();
                    if (ec_sig) {
                        ECDSA_SIG_set0(ec_sig, r_bn, s_bn);
                        int der_len = i2d_ECDSA_SIG(ec_sig, NULL);
                        if (der_len > 0) {
                            Newx(der_buf, der_len, unsigned char);
                            if (der_buf) {
                                unsigned char *p = der_buf;
                                i2d_ECDSA_SIG(ec_sig, &p);
                                actual_sig = der_buf;
                                actual_sig_len = der_len;
                            }
                        }
                    } else {
                        BN_free(r_bn);
                        BN_free(s_bn);
                    }
                }
            }
        }

        mdctx = EVP_MD_CTX_new();
        if (mdctx) {
            if (EVP_VerifyInit_ex(mdctx, EVP_sha256(), NULL) > 0 &&
                EVP_VerifyUpdate(mdctx, msg_str, msg_len) > 0) {
                verify_res = EVP_VerifyFinal(mdctx, actual_sig, actual_sig_len, pkey);
            }
            EVP_MD_CTX_free(mdctx);
        }

        if (ec_sig) ECDSA_SIG_free(ec_sig);
        if (der_buf) Safefree(der_buf);

        if (verify_res > 0) {
            XSRETURN_YES;
        } else {
            XSRETURN_NO;
        }

SV *
rsa_sign_sha256(SV *private_key_pem_sv, SV *message_sv)
    PREINIT:
        char *pem_str = NULL;
        char *msg_str = NULL;
        STRLEN pem_len, msg_len;
        BIO *bio = NULL;
        EVP_PKEY *pkey = NULL;
        EVP_MD_CTX *mdctx = NULL;
        unsigned char sig[4096];
        unsigned int sig_len = 0;
        SV *retval = NULL;
    CODE:
        pem_str = SvPV(private_key_pem_sv, pem_len);
        msg_str = SvPV(message_sv, msg_len);

        bio = BIO_new_mem_buf(pem_str, pem_len);
        if (!bio) XSRETURN_UNDEF;

        pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
        BIO_free(bio);
        if (!pkey) XSRETURN_UNDEF;

        mdctx = EVP_MD_CTX_new();
        if (!mdctx) {
            EVP_PKEY_free(pkey);
            XSRETURN_UNDEF;
        }

        if (EVP_SignInit_ex(mdctx, EVP_sha256(), NULL) <= 0 ||
            EVP_SignUpdate(mdctx, msg_str, msg_len) <= 0 ||
            EVP_SignFinal(mdctx, sig, &sig_len, pkey) <= 0) {
            EVP_MD_CTX_free(mdctx);
            EVP_PKEY_free(pkey);
            XSRETURN_UNDEF;
        }

        EVP_MD_CTX_free(mdctx);
        EVP_PKEY_free(pkey);

        retval = newSVpv((char *)sig, sig_len);
        RETVAL = retval;
    OUTPUT:
        RETVAL

MODULE = Google::Auth   PACKAGE = Google::Auth::PublicKey

void
DESTROY(self)
        SV *self
    PREINIT:
        EVP_PKEY *pkey = NULL;
    CODE:
        if (sv_derived_from(self, "Google::Auth::PublicKey")) {
            IV tmp = SvIV((SV*)SvRV(self));
            pkey = INT2PTR(EVP_PKEY *, tmp);
            if (pkey) {
                EVP_PKEY_free(pkey);
            }
        }



( run in 1.224 second using v1.01-cache-2.11-cpan-8dfa8b56332 )