~myers-1/pyopenssl/npn

« back to all changes in this revision

Viewing changes to src/crypto/crypto.c

  • Committer: Jean-Paul Calderone
  • Date: 2010-06-22 14:54:40 UTC
  • mfrom: (128.1.9 sign_verify)
  • Revision ID: exarkun@divmod.com-20100622145440-jllnndhqr76p4x13
Merge crypto.sign and crypto.verify addition

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * crypto.c
3
3
 *
4
4
 * Copyright (C) AB Strakt 2001, All rights reserved
 
5
 * Copyright (C) Keyphrene 2004, All rights reserved
5
6
 * Copyright (C) Jean-Paul Calderone 2008-2009, All rights reserved
6
7
 *
7
8
 * Main file of crypto sub module.
590
591
    return NULL;
591
592
}
592
593
 
 
594
static char crypto_sign_doc[] = "\n\
 
595
Sign data with a digest\n\
 
596
\n\
 
597
@param pkey: Pkey to sign with\n\
 
598
@param data: data to be signed\n\
 
599
@param digest: message digest to use\n\
 
600
@return: signature\n\
 
601
";
 
602
 
 
603
static PyObject *
 
604
crypto_sign(PyObject *spam, PyObject *args) {
 
605
    PyObject *buffer;
 
606
    crypto_PKeyObj *pkey;
 
607
    char *data = NULL;
 
608
    char *digest_name;
 
609
    int err;
 
610
    unsigned int sig_len;
 
611
    const EVP_MD *digest;
 
612
    EVP_MD_CTX md_ctx;
 
613
    unsigned char sig_buf[512];
 
614
 
 
615
    if (!PyArg_ParseTuple(args, "O!ss:sign", &crypto_PKey_Type,
 
616
                          &pkey, &data, &digest_name)) {
 
617
        return NULL;
 
618
    }
 
619
 
 
620
    if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
 
621
        PyErr_SetString(PyExc_ValueError, "No such digest method");
 
622
        return NULL;
 
623
    }
 
624
 
 
625
    EVP_SignInit(&md_ctx, digest);
 
626
    EVP_SignUpdate(&md_ctx, data, strlen(data));
 
627
    sig_len = sizeof(sig_buf);
 
628
    err = EVP_SignFinal(&md_ctx, sig_buf, &sig_len, pkey->pkey);
 
629
 
 
630
    if (err != 1) {
 
631
        exception_from_error_queue(crypto_Error);
 
632
        return NULL;
 
633
    }
 
634
 
 
635
    buffer = PyString_FromStringAndSize((char*)sig_buf, sig_len);
 
636
    return buffer;
 
637
}
 
638
 
 
639
static char crypto_verify_doc[] = "\n\
 
640
Verify a signature\n\
 
641
\n\
 
642
@param cert: signing certificate (X509 object)\n\
 
643
@param signature: signature returned by sign function\n\
 
644
@param data: data to be verified\n\
 
645
@param digest: message digest to use\n\
 
646
@return: None if the signature is correct, raise exception otherwise\n\
 
647
";
 
648
 
 
649
static PyObject *
 
650
crypto_verify(PyObject *spam, PyObject *args) {
 
651
    crypto_X509Obj *cert;
 
652
    unsigned char *signature;
 
653
    int sig_len;
 
654
    char *data, *digest_name;
 
655
    int err;
 
656
    const EVP_MD *digest;
 
657
    EVP_MD_CTX md_ctx;
 
658
    EVP_PKEY *pkey;
 
659
 
 
660
    if (!PyArg_ParseTuple(args, "O!t#ss:verify", &crypto_X509_Type, &cert, &signature, &sig_len,
 
661
                          &data, &digest_name)) {
 
662
        return NULL;
 
663
    }
 
664
 
 
665
    if ((digest = EVP_get_digestbyname(digest_name)) == NULL){
 
666
        PyErr_SetString(PyExc_ValueError, "No such digest method");
 
667
        return NULL;
 
668
    }
 
669
 
 
670
    pkey = X509_get_pubkey(cert->x509);
 
671
    if (pkey == NULL) {
 
672
        PyErr_SetString(PyExc_ValueError, "No public key");
 
673
        return NULL;
 
674
    }
 
675
 
 
676
    EVP_VerifyInit(&md_ctx, digest);
 
677
    EVP_VerifyUpdate(&md_ctx, data, strlen((char*)data));
 
678
    err = EVP_VerifyFinal(&md_ctx, signature, sig_len, pkey);
 
679
    EVP_PKEY_free(pkey);
 
680
 
 
681
    if (err != 1) {
 
682
        exception_from_error_queue(crypto_Error);
 
683
        return NULL;
 
684
    }
 
685
 
 
686
    Py_INCREF(Py_None);
 
687
    return Py_None;
 
688
}
593
689
 
594
690
/* Methods in the OpenSSL.crypto module (i.e. none) */
595
691
static PyMethodDef crypto_methods[] = {
603
699
    { "load_crl",         (PyCFunction)crypto_load_crl,         METH_VARARGS, crypto_load_crl_doc },
604
700
    { "load_pkcs7_data", (PyCFunction)crypto_load_pkcs7_data, METH_VARARGS, crypto_load_pkcs7_data_doc },
605
701
    { "load_pkcs12", (PyCFunction)crypto_load_pkcs12, METH_VARARGS, crypto_load_pkcs12_doc },
 
702
    { "sign", (PyCFunction)crypto_sign, METH_VARARGS, crypto_sign_doc },
 
703
    { "verify", (PyCFunction)crypto_verify, METH_VARARGS, crypto_verify_doc },
606
704
    { "X509_verify_cert_error_string", (PyCFunction)crypto_X509_verify_cert_error_string, METH_VARARGS, crypto_X509_verify_cert_error_string_doc },
607
705
    { "_exception_from_error_queue", (PyCFunction)crypto_exception_from_error_queue, METH_NOARGS, crypto_exception_from_error_queue_doc },
608
706
    { NULL, NULL }