cmsexample.cpp

The code below shows the normal way to use the QCA::CMS class.

00001 /*
00002  Copyright (C) 2003 Justin Karneges <justin@affinix.com>
00003  Copyright (C) 2005-2006 Brad Hards <bradh@frogmouth.net>
00004 
00005  Permission is hereby granted, free of charge, to any person obtaining a copy
00006  of this software and associated documentation files (the "Software"), to deal
00007  in the Software without restriction, including without limitation the rights
00008  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009  copies of the Software, and to permit persons to whom the Software is
00010  furnished to do so, subject to the following conditions:
00011 
00012  The above copyright notice and this permission notice shall be included in
00013  all copies or substantial portions of the Software.
00014 
00015  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00018  AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00019  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00020  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021 */
00022 
00023 
00024 #include <QtCrypto>
00025 
00026 #include <QCoreApplication>
00027 #include <QDebug>
00028 
00029 int main(int argc, char** argv)
00030 {
00031     // the Initializer object sets things up, and
00032     // also does cleanup when it goes out of scope
00033     QCA::Initializer init;
00034 
00035     QCoreApplication app(argc, argv);
00036 
00037     // We need to ensure that we have certificate handling support
00038     if ( !QCA::isSupported( "cert" ) ) {
00039         qWarning() << "Sorry, no PKI certificate support";
00040         return 1;
00041     }
00042 
00043     // Read in a public key cert
00044     // you could also build this using the fromPEMFile() method
00045     QCA::Certificate pubCert( "User.pem" );
00046     if ( pubCert.isNull() ) {
00047         qWarning() << "Sorry, could not import public key certificate";
00048         return 1;
00049     }
00050     // We are building the certificate into a SecureMessageKey object, via a
00051     // CertificateChain
00052     QCA::SecureMessageKey secMsgKey;
00053     QCA::CertificateChain chain;
00054     chain += pubCert;
00055     secMsgKey.setX509CertificateChain( chain );
00056 
00057     // build up a SecureMessage object, based on our public key certificate
00058     if ( !QCA::isSupported( "cms" ) ) {
00059         qWarning() << "Sorry, no CMS support";
00060         return 1;
00061     }
00062     QCA::CMS cms;
00063     QCA::SecureMessage msg(&cms);
00064     msg.setRecipient(secMsgKey);
00065 
00066     // Some plain text - we use the first command line argument if provided
00067     QByteArray plainText = (argc >= 2) ? argv[1] : "What do ya want for nuthin'";
00068 
00069     // Now use the SecureMessage object to encrypt the plain text.
00070     msg.startEncrypt();
00071     msg.update(plainText);
00072     msg.end();
00073     // I think it is reasonable to wait for 1 second for this
00074     msg.waitForFinished(1000);
00075 
00076     // check to see if it worked
00077     if(!msg.success())
00078     {
00079         qWarning() << "Error encrypting: " << msg.errorCode();
00080         return 1;
00081     }
00082 
00083     // get the result
00084     QByteArray cipherText = msg.read();
00085     QCA::Base64 enc;
00086     qDebug() << "'" << plainText.data() << "' encrypts to (in base 64): ";
00087     qDebug() << enc.arrayToString( cipherText );
00088     qDebug() << "Message uses" << msg.hashName() << "hashing algorithm";
00089     qDebug();
00090 
00091     // Show we can decrypt it with the private key
00092 
00093     // Read in a private key
00094     QCA::PrivateKey privKey;
00095     QCA::ConvertResult convRes;
00096     QCA::SecureArray passPhrase = "start";
00097     privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &convRes );
00098     if ( convRes != QCA::ConvertGood ) {
00099         qWarning() << "Sorry, could not import Private Key";
00100         return 1;
00101     }
00102 
00103     QCA::SecureMessageKey secMsgKey2;
00104     // needed?
00105     secMsgKey2.setX509CertificateChain( chain );
00106     secMsgKey2.setX509PrivateKey(privKey);
00107     QCA::SecureMessageKeyList privKeyList;
00108     privKeyList += secMsgKey2;
00109 
00110     // build up a SecureMessage object, based on the private key
00111     // you could re-use the existing QCA::CMS object (cms), but
00112     // this example simulates encryption and one end, and decryption
00113     // at the other
00114     QCA::CMS anotherCms;
00115     anotherCms.setPrivateKeys( privKeyList );
00116 
00117     QCA::SecureMessage msg2( &anotherCms );
00118 
00119     msg2.startDecrypt();
00120     msg2.update( cipherText );
00121     msg2.end();
00122 
00123     // I think it is reasonable to wait for 1 second for this
00124     msg2.waitForFinished(1000);
00125 
00126     // check to see if it worked
00127     if(!msg2.success())
00128     {
00129         qWarning() << "Error encrypting: " << msg2.errorCode();
00130         return 1;
00131     }
00132 
00133     QCA::SecureArray plainTextResult = msg2.read();
00134 
00135     qDebug() << enc.arrayToString( cipherText )
00136              << " (in base 64) decrypts to: "
00137              << plainTextResult.data();
00138 
00139     if (msg2.wasSigned()) {
00140         qDebug() << "Message was signed at "
00141                  << msg2.signer().timestamp();
00142     } else {
00143         qDebug() << "Message was not signed";
00144     }
00145 
00146     qDebug() << "Message used" << msg2.hashName() << "hashing algorithm";
00147 
00148     qDebug();
00149 
00150     // Now we want to try a signature
00151     QByteArray text("Got your message");
00152 
00153     // Re-use the CMS and SecureMessageKeyList objects from the decrypt...
00154     QCA::SecureMessage signing( &anotherCms );
00155     signing.setSigners(privKeyList);
00156 
00157     signing.startSign(QCA::SecureMessage::Detached);
00158     signing.update(text);
00159     signing.end();
00160 
00161     // I think it is reasonable to wait for 1 second for this
00162     signing.waitForFinished(1000);
00163 
00164     // check to see if it worked
00165     if(!signing.success())
00166     {
00167         qWarning() << "Error signing: " << signing.errorCode();
00168         return 1;
00169     }
00170 
00171     // get the result
00172     QByteArray signature = signing.signature();
00173 
00174     qDebug() << "'" << text.data() << "', signature (converted to base 64), is: ";
00175     qDebug() << enc.arrayToString( signature );
00176     qDebug() << "Message uses" << signing.hashName() << "hashing algorithm";
00177     qDebug();
00178 
00179 
00180     // Now we go back to the first CMS, and re-use that.
00181     QCA::SecureMessage verifying( &cms );
00182 
00183     // You have to pass the signature to startVerify(),
00184     // and the message to update()
00185     verifying.startVerify(signature);
00186     verifying.update(text);
00187     verifying.end();
00188 
00189     verifying.waitForFinished(1000);
00190 
00191     // check to see if it worked
00192     if(!verifying.success())
00193     {
00194         qWarning() << "Error verifying: " << verifying.errorCode();
00195         return 1;
00196     }
00197 
00198     QCA::SecureMessageSignature sign;
00199     sign = verifying.signer();
00200     // todo: dump some data out about the signer
00201 
00202     if(verifying.verifySuccess())
00203     {
00204         qDebug() << "Message verified";
00205     } else {
00206         qDebug() << "Message failed to verify:" << verifying.errorCode();
00207     }
00208 
00209     return 0;
00210 }
00211 

Generated on Fri Jul 6 13:22:42 2007 for Qt Cryptographic Architecture by  doxygen 1.4.6