on 12-21-2005 2:44 PM
Hi,
(I'm not shure if this is the correct forum, please send me a note if I'm wrong here.)
I try to implement a HTTP Content Server for SAP ArchiveLink, but I have troubles with the url signature. I try to use the sapsecu.dll to verify the PKCS#7 signature, but I fail even with the provided example from SAP.
This is my test code to decode the signature (originally passed via base64) but I always receive the errorcode 12, meaning "wrong format".
// SapSecuWrapper.h
#include <string.h>
#include "AMMimeUtils.h"
#include "ssfxxapi.h"
#pragma once
using namespace System;
namespace SapSecuWrapper {
public ref class SapSecuWrapper
{
public:
static int test(void)
{
int b;
char* base64 = "MIIBlgYJKoZIhvcNAQcCoIIBhzCCAYMCAQExCzAJBgUrDgMCGgU
AMAsGCSqGSIb3DQEHATGCAWIwggFeAgEBMBMwDjEMMAoGA1UEAxM
DSUQzAgEAMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZ
IhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wMDA1MDUxNDA2NTFaMCM
GCSqGSIb3DQEJBDEWBBQGYof+huv7Gw7r+UmGzIai+1i3DTCBpwY
FKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61
TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhU
BSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8p
S22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q
12PFp/PjOhh+nBDAwLgIVAJw5q7oYYDAKplAXqFjOuLTC53daAhU
A1GTCFCLfwwgJWul7yfVYfwc84jk=";
secKeyStr;
CBase64Utils* cqp = new CBase64Utils();
char* secKeyStr = cqp->Decode(base64, &b);
SsfOctetstring* a = new SsfOctetstring;
int len = strlen(secKeyStr);
int r = SsfDecode("PKCS7", 5, secKeyStr, len, a, &b);
delete secKeyStr;
delete a;
return r;
}
};
}
Originally I used a .NET code, but to rule out marshalling problems I moved to C++. I first tried the .NET 2.0 functions but I faced problems there as well.
Can anyone help me, or tell my that I'm on the wrong way?
Thank you in advance,
Christoph
Ok. So it works now. The code posted is quite good, the problem was the RSCMSTI function module in the SAP environment which contains a bug! And since we where testing with this method we got stuck...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi I used the above code in asp.net with c# and created the wrapper in vc++ 2010 with name(SapSecUWrapper.dll). Its running in my development environment(Win 7 32 bit) but when I am deploying on server which is Window server 2003 32 Bit, I am getting error stating " Could not load file or assembly "SapSecUWrapper.dll " or one of its dependencies. The specified module could not be found."
I used dependency walker to check whether i am missing any dll. But it doesn't help it out.
Please please help me.
Hi Christoph,
I have a few questions about your implementation of HTTP Content Server for SAP ArchiveLink, you can reply here or contact by mail (see profile). thx
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello,
I'm trying to implement this functionality but keep getting error 5 and 27 as signerresult->uResult.
I've created the C++ library and C# classes in Visual Studio 2005. Please contact me or leave a reply since I'm desperately looking for a solution.
Thanks a lot!
Kind regards,
Guus Creuwels.
<b>C++ class</b>
// SapSecuWrapper.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
#include "ssfxxapi.h"
#pragma once
using namespace System;
namespace ADOS {
public ref class SapSecuWrapper
{
public:
static int CreateProfile(char* psename, char* psepwd) {
return SsfCreateProfile((SsfCharstring)psename, strlen(psename), psepwd, strlen(psepwd), NULL, 0);
}
static int RemoveProfile(char* psename) {
return SsfRemoveProfile((SsfCharstring)psename, strlen(psename));
}
static int putCert(char* psename, char* psepwd, char* _putcert, int _putcert_len)
{
SsfOctetstring putcert = _putcert;
SsfOctetlen putcert_len = _putcert_len;
SsfOctetstring encoded_original_message;
SsfOctetlen encoded_original_message_length;
SsfOctetstring ostroutputdata;
SsfOctetlen ostroutputdata_len;
SigRcpSsfInformationList signerresultlist=NULL;
PtrSigRcpSsfInformation signerresult;
SsfProfileHandle Profile;
SsfCertHandle Certificate;
SsfOctetstring asn1cert;
SsfOctetlen asn1certL;
int rc=0;
int result2=0;
/* SsfEncode the original_message (length 1, contents space). */
rc=SsfEncode("PKCS7",5, " ", 1,
&encoded_original_message, &encoded_original_message_length);
if (rc != 0) return rc;
/* SsfVerify the putcert with encoded_original_message */
rc=SsfVerify("PKCS7",5,
TRUE,
putcert, putcert_len,
encoded_original_message, encoded_original_message_length,
psename, strlen(psename),
psepwd,strlen(psepwd),
&signerresultlist,
&ostroutputdata,&ostroutputdata_len);
if (rc != 0 && rc != 5) return rc;
signerresult = signerresultlist->ptrSigRcp;
result2= signerresult->uResult;
if (result2 != SSF_API_SIGNER_OK && result2 != SSF_API_UNKNOWN_RECIPIENT) return -3;
/* extract certificate */
asn1cert=signerresult->strSigRcpPassword;
asn1certL=signerresult->strSigRcpPasswordL;
/*** Add certificate to the PAB ***/
rc = SsfCertfromASN1(asn1cert,asn1certL,&Certificate);
if (rc != 0) return rc;
/* open profile */
rc=SsfOpenProfile(
psename,strlen(psename),
psepwd,strlen(psepwd),
NULL,0,
&Profile);
if (rc != 0) return rc;
rc=SsfPutCertificate(Profile,Certificate);
if (rc != 0) return rc; // TODO clean up
SsfFreeCertificate(&Certificate);
/* clean up ... */
SsfDELSsfOctetstring(&encoded_original_message,&encoded_original_message_length);
SsfDELSsfOctetstring(&ostroutputdata,&ostroutputdata_len);
SsfDELSigRcpSsfInfoList(&signerresultlist);
rc=SsfCloseProfile(&Profile);
return 0;
}
static int checkUrl(char* psename, char* psepwd, char* _signeduri, int _signeduri_len, char* _signature, int _signature_len)
{
SsfOctetstring signeduri = _signeduri;
SsfOctetlen signeduri_len = _signeduri_len;
SsfOctetstring signature = _signature;
SsfOctetlen signature_length = _signature_len;
SsfOctetstring encoded_signeduri;
SsfOctetlen encoded_signeduri_len;
SsfOctetstring result_signeduri;
SsfOctetlen result_signeduri_len;
SigRcpSsfInformationList signerresultlist=NULL;
PtrSigRcpSsfInformation signerresult;
int rc=0;
int result2=0;
/* load signed URI */
//signeduri_len = read_file("D:\Develop\Ados\SECURITY DOCU\data\httpcsreq_uri.txt", "rt", &signeduri);
//assert (signeduri_len != 0);
//if (signeduri_len == 0) return -999;
/* load signature */
//signature_length = read_file("D:\Develop\Ados\SECURITY DOCU\data\httpcsreq_signature.bin", "rb", &signature);
//assert (signature_length != 0);
//if (signature_length == 0) return -9999;
/* SsfEncode the signed URI. */
//printf("Verifying signature...n");
rc=SsfEncode("PKCS7",5, signeduri, signeduri_len,
&encoded_signeduri, &encoded_signeduri_len);
//assert(rc==0);
if (rc != 0) return rc;
/* SsfVerify the putcert with encoded_original_message */
rc=SsfVerify("PKCS7",5,
FALSE,
signature, signature_length,
encoded_signeduri, encoded_signeduri_len,
psename, strlen(psename),
psepwd, strlen(psepwd),
&signerresultlist,
&result_signeduri,&result_signeduri_len);
//assert(signerresultlist != NULL);
if (signerresultlist == NULL) return -8;
signerresult = signerresultlist->ptrSigRcp;
//assert(signerresult != NULL);
if (signerresult == 0) return -9;
result2= signerresult->uResult;
//printf("SsfVerify returned rc: %d, result: %dn",rc,result2);
//assert(rc==0);
if (rc != 0) return rc;
//printf("Signer is: %.*sn",signerresult->strSigRcpIdL,signerresult->strSigRcpId);
/* TODO: make sure that signer (in signerresult) is allowed to access resource !!! */
/* clean up ... */
SsfDELSsfOctetstring(&encoded_signeduri,&encoded_signeduri_len);
SsfDELSsfOctetstring(&result_signeduri,&result_signeduri_len);
SsfDELSigRcpSsfInfoList(&signerresultlist);
//free(signeduri); signeduri=NULL;
//free(signature); signature=NULL;
//printf("Signature successfully verifiedn");
return 0;
}
static int read_file(const char *FileName, const char *mode, char **ppdata)
{
FILE *stream;
char *pdata = NULL;
int ndata = 0; /* total number of bytes read from file */
int nlastread; /* number of bytes read with last fread call */
/* open file in given mode */
if ((stream = fopen(FileName, mode)) == NULL)
return 0; /* file open error */
/* try to find out the initial size */
if (fseek ( stream, 0, SEEK_END )) {
fclose(stream);
return 0;
}
ndata = ftell ( stream );
fseek( stream, 0, SEEK_SET );
pdata = (char*)malloc(ndata);
if (pdata == NULL) {
fclose(stream);
return 0;
}
nlastread = fread(pdata, sizeof(char), ndata, stream);
if (nlastread != ndata) {
fclose(stream);
return 0;
}
*ppdata = pdata;
fclose(stream); /* close file */
return ndata; /* return number of bytes read from file */
}
static int write_file(const char *FileName, const char *mode, char *pdata, int ndata)
{
FILE *stream;
if ((stream = fopen(FileName, mode)) == NULL)
return -1;
ndata = fwrite(pdata, sizeof(char), ndata, stream);
fclose(stream);
return ndata;
}
};
}
regards,
Christoph
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi I used the above code in asp.net with c# and created the wrapper in vc++ 2010 with name(SapSecUWrapper.dll). Its running in my development environment(Win 7 32 bit) but when I am deploying on server which is Window server 2003 32 Bit, I am getting error stating " Could not load file or assembly "SapSecUWrapper.dll " or one of its dependencies. The specified module could not be found."
I used dependency walker to check whether i am missing any dll. But it doesn't help it out.
Please please help me.
I finally worked it out. For other frustrated users, here's my C#/C++/sapseculib solution:
I used a solution with a C# project und a C++ project. The C++ part is referenced via project reference in the C# code.
Maybe the "unsafe" blocks could be replaced with more secure code, but at least it works - if someone has better ideas, feel free to post.
<b>C# class</b>
using System;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using ADOS;
namespace ADOS {
class Seculib {
static void Main() {
int r;
Seculib sl = new Seculib();
sl.Pse = @"D:DevelopAdosSignatureTestados.pse";
sl.PsePassword = "ados";
r = sl.SetupProfile();
Console.WriteLine("Setup Profile " + r);
byte[] fileBuffer = ReadFile(@"D:DevelopAdosSignatureTestcertificate.cer");
r = sl.PutCertificate(fileBuffer);
Console.WriteLine("Put Certificate " + r);
string uri = "T1EB9074DF46723B49A05CAEAB57DB9B98uCN%3DID320051222141521";
string signatureBase64 = "MIIBlQYJKoZIhvcNAQcCoIIBhjCCAYICAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAWEwggFdAgEBMBMwDjEMMAoGA1UEAxMDSUQzAgEAMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNTEyMjIxMjE1MjFaMCMGCSqGSIb3DQEJBDEWBBR7kkvO4ekHGSjRka2jRmPzRf8HPjCBpwYFKw4DAhswgZ0CQQEkJRHP+mN7d8miwTMN55CUSmo3TO8WGCxgY61TX5k+7NU4XPf1TULjw3GobwaJX13kquPhfVXk+gVy46n4Iw3hAhUBSe/QF4BUj+pJOF9ROBM4u+FEWA8CQQD4mSJbrABjTUWrlnAte8pS22Tq4/FPO7jHSqjijUHfXKTrHL1OEqV3SVWcFy5j/cqBgX/zm8Q12PFp/PjOhh+nBC8wLQIVAQHVFb4PnQgTRr48R+Yqw3WU8pq+AhQo8f2zAxuRr03omwNzFGVGgx0G3A==";
r = sl.ChechUrl(uri, signatureBase64);
Console.WriteLine("Check Url " + r);
Console.ReadKey();
}
private sbyte[] pse;
public string Pse {
set { pse = copyArray(Encoding.ASCII.GetBytes(value)); }
}
private sbyte[] passwd;
public string PsePassword {
set { passwd = copyArray(Encoding.ASCII.GetBytes(value)); }
}
public int SetupProfile() {
int r;
// delete profile
unsafe {
fixed (sbyte* array_pse = pse) {
r = SapSecuWrapper.RemoveProfile(array_pse);
if (r != 0) {
// TODO Log Error cannot remove profile
return r;
}
}
}
// create profile
unsafe {
fixed (sbyte* array_pse = pse, array_passwd = passwd) {
r = SapSecuWrapper.CreateProfile(array_pse, array_passwd);
if (r != 0) {
// TODO Log Error cannot create profile
return r;
}
}
}
return 0; // OK
}
public int PutCertificate(byte[] certificate) {
int r;
// put certificate
sbyte[] fileBuffer2 = copyArray(certificate);
unsafe {
fixed (sbyte* array_pse = pse, array_passwd = passwd, array_fileBuffer = fileBuffer2) {
r = SapSecuWrapper.putCert(array_pse, array_passwd, array_fileBuffer, fileBuffer2.Length);
if (r != 0) {
// TODO Log Error cannot put certificate, errorcode r
return r;
}
}
}
return 0; // OK
}
public int ChechUrl(string uri, string signatureBase64) {
sbyte[] uriBa = copyArray(Encoding.ASCII.GetBytes(uri));
byte[] signature = Convert.FromBase64String(signatureBase64);
sbyte[] signatureBa = copyArray(signature);
unsafe {
fixed (sbyte* array_pse = pse, array_passwd = passwd, array_uri = uriBa, array_signature = signatureBa) {
int r = SapSecuWrapper.checkUrl(array_pse, array_passwd, array_uri, uriBa.Length, array_signature, signatureBa.Length);
if (r != 0) {
// TODO Log Error cannot remove profile, 5 = check failed, <0 internal error else other sapsecu error
return r;
}
}
}
return 0;
}
private static byte[] ReadFile(string fileName) {
FileStream f = new FileStream(fileName, FileMode.Open, FileAccess.Read);
int size = (int)f.Length;
byte[] data = new byte[size];
size = f.Read(data, 0, size);
f.Close();
return data;
}
private static sbyte[] copyArray(byte[] b) {
sbyte[] sb = new sbyte[b.Length];
for (int i = 0; i < b.Length; i++)
sb<i> = (sbyte)b<i>;
return sb;
}
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
80 | |
24 | |
11 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.