C++ problem trying to use a certificate? Can't c (General questions)
Hi,
I'm using WodFtpDLX (starting with the ConsoleApp sample), and I'm stuck trying to figure out how to create an ICertificate object, load a file cert into it, and attach it to a IwodFtpDLXComPtr object. I can't find any MSVC 6.0 C++ MFC/ATL sample code that does this, and the documentation is less than helpful.
When I try to put:
ICertificate *m_Certificate;
in my code, the compiler generates the following:
error C2259: 'ICertificate' : cannot instantiate abstract class due to following members: (blah blah blah)
In desperation I tried this:
hr = pFtpCom->Certificate.CreateInstance (IID_ICertificate, NULL);
but it fails with a Class not registered error, even though wodCertificate.DLL IS registered?
PLEASE HELP!
Thanks,
Tim
Re: C++ problem trying to use a certificate?
Hi again,
I mistyped my problem a bit, but it still doesn't work.
Although I can compile ICertificate *m_Certificate; , I can't actually use that pointer for anything. I can't call new() on it, and I can't call CreateInstance() on it.
I also can't include the real wodCertificate.tlh header because it conflicts with wodFtpDlx.tlh .
Please provide some sample code that shows how to load a file-based certificate into a IwodFtpDLXComPtr object.
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Tim,
I have add new sample (under VC section) that is used to create new keys using wodCertificate. Can you download wodFtpDLX again (or request update if you're licensed user) and try it out?
As for help with your project - can you zip what you currently have and send over to techsupport@weonlydo.com ? I need to see what kind of VC project you're working on.
Regards,
Kreso
Re: C++ problem trying to use a certificate?
Hi Kreso,
Thanks for the new sample project for creating certificates. (You may want to fix this line in the code:
#import E:\WeOnlyDo\wodFtpDLX\Code\CertMng\Debug\wodCertificate.dll no_namespace named_guids
I don't think this is the correct file location for most people.)
But I already had this sample (from another download), and it doesn't help me at all with the problem.
The problem is simple:
The documentation on page 109 of the wodFtpDLX.pdf says that to use SSL you need to create a new ICertificate object, load a cert file into it, and attach it to the FTP object. That's fine, but there is no C++ example on how to do this (IMO, because you can't do it!).
Basically, I cannot combine the cert sample code with the \FtpDLXSamples\VC\ATL\ConsoleApp sample code so that I can use both the certificate interface and the FTPDlx interface at the same time because their interfaces conflict with each other.
If you try to do the following:
// import wodKeys
#import C:\WINDOWS\SYSTEM32\wodCertificate.dll no_namespace named_guids
#include Debug/wodCertificate.tlh
// import wodFtpDLX
#import C:\WINDOWS\SYSTEM32\wodFtpDLX.DLL no_namespace named_guids
#include Debug/wodFtpDlx.tlh
You will get 65 compiler errors!?
So please provide an example of how to load a cert file and attach it to a FTPDlx object in C++ (like you describe on page 109 of the PDF docs).
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Tim,
ok, I'll prepare such sample for you.
In the meantime, if you have compile errors to due same names, you can remove no_namespace from #import directive. That should help.
Re: C++ problem trying to use a certificate? Can
Hi Kreso,
Thanks.
FYI, removing the no_namespace flag did help get past the conflicting interfaces problem, but trying to compile this:
hr = m_Certificate->CreateInstance (CLSID_Certificate, NULL);
results in this:
error C2039: 'CreateInstance' : is not a member of 'ICertificate'
c:ftpdlxsamplesvcatlconsoleappdebugwodftpdlx.tlh(156) : see declaration of 'ICertificate'
Obviously I'm doing something wrong, but I'm not sure what.
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Ok, I have added new sample. Can you please download wodFtpDLX again and look at sample
Samples\VC\ATL\Console with certificate authentication
I hope it shows what you need.
Please let me know if it helps.
Kreso
Re: C++ problem trying to use a certificate? Can
Hi,
Thanks!
I see what you changed to make it compile. Although it's not quite as clean as I would like, your changes makes sense (sort of).
However, when I try to run the new compiled sample (using the WOD sample client.cer file in the Load() method) it throws an exception in Connect() function?
Can you try running the new sample and let me know why it might be crashing?
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
You have to catch the error. Try something like this:
[code] try
{
_bstr_t fn = Client.cer ;
pCert->Load(fn);
} catch (_com_error &err)
{
short s = (short)err.Error();
printf ( Unable to load certificate.\nErr d\r\n , s);
}
[/code]
Re: C++ problem trying to use a certificate?
Hi,
I don't think you understood my last message... I said the exception is being thrown in the Connect() method. The pCert->Load() is working fine. The original ConsoleApp works fine, so something you changed is causing the crash?
Maybe you can test this new sample yourself (using certificate authentication with FTPDlx) with one of your certificates and let me know what you find.
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Tim,
did you try to catch the error the same way as I have shown for pCert->Load? If you catch it, you will see error code.
VC likes to show it as unhandled crash - but this is just an exception. If you step into the code of Connect, you will see...
Re: C++ problem trying to use a certificate? Can
Hi,
I realized that I needed to catch the exception after my last post. [:doh:]
The error I'm getting is 30026 (Failed to load key or certificate. Password invalid?) if I just call
hr = pCert->Load ( c:\certs\client.cer );
or 30007 (Please set login, and password/certificate first.) if I also call
hr = pCert->LoadKey ( c:\certs\client.key );
Note that neither Load() or LoadKey() generates an error, and I'm using the WOD certificates & keys.
I'm using your SmallServer FTP server which has loaded the corresponding server certs.
Do I need to load both the cert and the priv key to successfully connect?
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Tim,
do you really want to authenticate with FTP server using your certificate? Protocol is FTPS, right?
If you do, make sure you call Load and LoadKey, make sure you set Authentication to authCertificiate and then you're ready.
But are you sure you want that? Or you just want to connect to SSL server and you assume you need certificate too? No, you don't in that case.
Re: C++ problem trying to use a certificate?
Hi Kreso,
I realize that cert authentication isn't needed to do FTPS, but yes, we must use cert-based authentication. This is a requirement for our product (some of our customers are very security-minded, and will even want to use their own certificates & keys).
I am doing as you suggested, but I'm still getting the errors I mentioned.
Could you test using cert authentication with FTPDlx using your new sample code? Or do you want my slightly-modified version that also calls LoadKey()?
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
I don't know how it works with other FTPS servers, but I have created sample for you with our wodFTPServer.
Server is written in VB. Start it. It will accept only client with 'client.cer' and 'client.key' certificate, noone else.
Then start VC sample that is also in the archive, and try to connect. You'll see how it works.
Hope this helps!
Kreso
Oh, yes, you can download sample here:
http://www.weonlydo.com/forum/files/FTPS_ClientServerSample.zip
Re: C++ problem trying to use a certificate? Can
Hi,
THANKS! We've almost got it working. [:smile:]
Your new code works much better (or maybe it was a problem with the certificates/keys?). Rather than using the VB sample, I am using the VC 4. FTPS with certificate stored in file server sample with the new client sample and it almost completely works!
I say almost because the following commands work fine:
pFtpCom->PutFile (lUploadFilename);
pFtpCom->GetFile (lLocalFilename, lRemoteFilename);
But calling pFtpCom->ListDir(); causes a lock-up (not an exception, just blocks on this call forever)? It's not a problem with the server because other FTP clients can get a dir listing just fine.
Any ideas?
Thanks again for the help,
Tim
Re: C++ problem trying to use a certificate? Can
Is it also running on localhost? I guess Passive/nonPassive isn't the issue here?
Re: C++ problem trying to use a certificate? Can
Tim,
nice, you have just found a bug in wodFTPServer.
Fixed it, now it works as it should. Please download wodFTPServer again from our website and try these things out again.
Kreso
Re: C++ problem trying to use a certificate? Can
Hi Kreso,
COOL! I downloaded the new version and it works great. [:cool:]
I've got user/pass + cert authentication (require both) working fine (although only the cert event fires, not both of them like I would expect).
I'm learning more of the APIs, and so far the only other thing I'm a bit fuzzy on is how to verify the client's public key against the server's private key. I don't see a method or API that lets me do this? I can compare the 2 public keys to each other, but that's not real PKI authentication...
Thanks for the help,
-Tim
Re: C++ problem trying to use a certificate? Can
Tim,
it's a matter of opinion. I think comparing two public keys is enough, assuming user does have corresponding private key to sign data with it. wodFTPServer (or any other server) does verify that signature, so you have just to allow specific certificate (and it's private key) to be used.
Re: C++ problem trying to use a certificate? Can
Hi,
If the server is validating the signature then I tend to agree with you. Hopefully this won't be an issue...
A couple more questions and then I'll leave you alone for a while:
How can I tell if a loaded key is DSA or RSA?
Can I use PublicKeyOpenSSH property for both DSA & RSA keys (what's the best way to compare the public keys regardless of the type)?
What C++ data type is the ValidTo cert property (A CTime object)?
Thanks,
Tim
Re: C++ problem trying to use a certificate? Can
Tim,
unfortunatelly, you can't tell if loaded key is RSA/DSA, we didn't provide such option at the beginning, and now we can't change interface anymore. You can load both, wodKeys can store them both. I guess if you try to print them out using PublicKeyOpenSSH you'll see that some key isn't loaded if you get exception or empty response :)
As for CTime, I don't honestly know how MFC translates that. In Automation OLE world this is DATE which I believe is a double real value. You have to check generated wrapper to see how it translates for you.