I consume a web services client.
I have a certificate with password. I can retrieve the certificate from my store and i can use it in InternetSetOption().
But I don't know how to send the password with the certificate.
Here is an example:
LPWSTR pswzFirstCert = L"xxxxx";// Subject of the first certificate.
LPWSTR pPassword = L"yyyyyy";// Spassword
HCERTSTORE hSystemStore; // The system store handle
PCCERT_CONTEXT pDesiredCert = NULL;
hSystemStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER,L"MY");
if(hSystemStore == NULL)
{
ShowMessage("Not Opened the MY system store.");
return;
}
// Get a certificate that has the string "Full Test Cert" in its subject.
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
pDesiredCert=CertFindCertificateInStore(hSystemStore, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_STR, pswzFirstCert, NULL);
if(pDesiredCert == NULL)
{
ShowMessage("The certificate was not found.");
return;
}
if(hSystemStore)
CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG);
if( InternetSetOption (Data, INTERNET_OPTION_CLIENT_CERT_CONTEXT, (LPVOID)pDesiredCert, sizeof (CERT_CONTEXT) ) == FALSE )
ShowMessage("InternetSetOption failed with error.");
if( InternetSetOption (Data, INTERNET_OPTION_PASSWORD, (LPVOID)pPassword, sizeof (pPassword) ) == FALSE )
ShowMessage("InternetSetOption failed with error.");
if(pDesiredCert)
CertFreeCertificateContext(pDesiredCert);
Related
I am new to driver development and I want to be able to send an IRP request to the ((PDEVICE_EXTENSION)myDevice->DeviceExtension)->lowerDevice. This IRP request should be treated by the lowerDevice the same way as if I were to simply forward the incoming IRP. I am able to successfully build and send the IRP but it errors at the lowerDevice, Access violation - code c0000005. I greatly appreciate any help!
NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
KEVENT event;
PIRP lowerIrp;
IO_STATUS_BLOCK ioStatus;
NTSTATUS status;
PIO_STACK_LOCATION pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
KeInitializeEvent(&event, NotificationEvent, FALSE);
SIZE_T len = max(pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength, pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength);
PVOID InputBuffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, len, 'ITag');
if (!InputBuffer) {
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(InputBuffer, Irp->AssociatedIrp.SystemBuffer, pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength);
Irp->IoStatus.Information = pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;
LARGE_INTEGER startingOffset;
startingOffset.QuadPart = (LONGLONG)0;
lowerIrp = IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
((PDEVICE_EXTENSION)myDevice->DeviceExtension)->lowerDevice,
InputBuffer,
(ULONG)len,
&startingOffset,
&event,
&ioStatus
);
if (NULL == lowerIrp) {
ExFreePool(InputBuffer);
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
IoSetCompletionRoutine(lowerIrp, completionRoutine, NULL, TRUE, TRUE, TRUE);
status = IoCallDriver(((PDEVICE_EXTENSION)myDevice->DeviceExtension)->lowerDevice, lowerIrp);
if (status == STATUS_PENDING) {
status = KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE, // Not alertable
NULL);
status = ioStatus.Status;
}
return status;
}
I am trying to create certificate request programmatically in iOS using openSSL. I got testKey.pem(private key) and test.csr finally and the first works well in linux(by openssl command), however test.csr seams strange and cannot be recognized and used properly. here is my code in OC.
- (void)genCertReq {
if (!X509_REQ_set_version(csr.req, csr.ver)) {
LOG(#"set_version failed");
goto error;
}
[self fillDN];
/* subject name */
if (!X509_REQ_set_subject_name(csr.req, csr.subject)) {
LOG(#"subject_name failed");
goto error;
}
rsaPair = RSA_generate_key(bits, e, NULL, NULL);
const char *keyPathChar = [SPFileManager openFile:testKey];
BIO *bp = NULL;
bp = BIO_new_file(keyPathChar, "w");
PEM_write_bio_RSAPrivateKey(bp, rsaPair, NULL, NULL, 0, NULL, NULL);
BIO_free(bp);
/* pub key */
if (1 != EVP_PKEY_assign_RSA(evpKey, rsaPair)) {
LOG(#"assign_RSA failed");
goto error;
}
if (!X509_REQ_set_pubkey(csr.req, evpKey)) {
LOG(#"set_pubkey failed");
goto error;
}
/* attribute */
csr.md = EVP_sha1();
if (!X509_REQ_digest(csr.req, csr.md, (unsigned char *)csr.mdout, (unsigned int *)&csr.mdlen)) {
LOG(#"req_digest failed");
goto error;
}
if (!X509_REQ_sign(csr.req, evpKey, csr.md)) {
LOG(#"req_sign failed");
goto error;
}
const char *csrPathChar = [SPFileManager openFile:csrName];
bp = BIO_new_file(csrPathChar, "w");
PEM_write_bio_X509_REQ(bp, csr.req);
BIO_free(bp);
OpenSSL_add_all_algorithms();
if (X509_REQ_verify(csr.req, evpKey) < 0) {
LOG(#"req_verify failed");
goto error;
}
X509_REQ_free(csr.req);
return;
error:
X509_REQ_free(csr.req);
return;
}
testKey.pem is in PKCS1 format and looks like --BEGIN RSA PRIVATE KEY---, and test.csr looks like ---BEGIN CERTIFICATE REQUEST--- which however I don't think is right.
Any help will be appreciated, thanks.
I need to show SSL certificate details of displayed URL in a UIWebView something like Google's Chrome browser shows:
How to obtain this data from UIWebView.
We are intercepting the call at the network level (rather than the UIWebView), and using [NSURLConnectionDelegate connection:willSendRequestForAuthenticationChallenge:]. This gives you a NSURLAuthenticationChallenge instance, and if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust then NSURLAuthenticationChallenge.protectionSpace.serverTrust is a SecTrustRef.
Given the SecTrustRef, you can follow SecCertificateRef: How to get the certificate information? and do something like this:
#import <Security/Security.h>
#import <openssl/x509.h>
X509* X509CertificateFromSecTrust(SecTrustRef trust) {
SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
CFDataRef certDataRef = SecCertificateCopyData(cert);
NSData *certData = (__bridge NSData *)certDataRef;
const void* certDataBytes = certData.bytes;
X509* result = d2i_X509(NULL, (const unsigned char**)&certDataBytes, certData.length);
CFRelease(certDataRef);
return result;
}
static NSString* X509NameField(X509_NAME* name, char* key) {
if (name == NULL)
return nil;
int nid = OBJ_txt2nid(key);
int index = X509_NAME_get_index_by_NID(name, nid, -1);
X509_NAME_ENTRY *nameEntry = X509_NAME_get_entry(name, index);
if (nameEntry == NULL)
return nil;
ASN1_STRING *nameASN1 = X509_NAME_ENTRY_get_data(nameEntry);
if (nameASN1 == NULL)
return nil;
unsigned char *issuerName = ASN1_STRING_data(nameASN1);
return [NSString stringWithUTF8String:(char *)issuerName];
}
NSString* X509CertificateGetSubjectCommonName(X509* cert) {
if (cert == NULL)
return nil;
X509_NAME *subjectName = X509_get_subject_name(cert);
return X509NameField(subjectName, "CN"); // Common name.
}
NSString* X509CertificateGetIssuerName(X509* certX509) {
if (certX509 == NULL)
return nil;
X509_NAME *issuerX509Name = X509_get_issuer_name(certX509);
if (issuerX509Name == NULL)
return nil;
return X509NameField(issuerX509Name, "O"); // organization
}
This is not a simple piece of work. You'll need to understand OpenSSL's X509 code, the Security framework, and whatever you're doing at the network layer for SSL trust checks. There might be other ways that you can get hold of a SecTrustRef or SecCertificateRef, but I'm not using them if there are.
I am trying to write a service in Go that takes the parameters given by GameCenter in
//GKLocalPlayer
- (void)generateIdentityVerificationSignatureWithCompletionHandler:(void (^)(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error))completionHandler
Inside the completionHandler of the method, I am sending the public key URL, base 64 encoded signature, base 64 encoded salt, timestamp and the user's game center ID to my Go service. Inside my Go (in Google App Engine), this is what I am doing:
Get the certificate from the public key URL
Decode signature and salt
Form the payload based on player ID, bundle ID, timestamp and
salt
Use X509.CheckSignature to verify that the payload matches the
signature when it's hased with the public key
*I know that I still need to verify with the certificate authority but I am skipping that for now (if you know how to do that in Go for this case, please please please share!)
Problem: CheckSignature is returning crypto/rsa: verification error and I really think that I am doing everything as instructed by Apple
https://developer.apple.com/library/ios/documentation/GameKit/Reference/GKLocalPlayer_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40009587-CH1-SW25
And the code that I have so far:
func (v *ValidationRequest) ValidateGameCenter(publicKeyUrl string, playerId string, bundleId string, signature string, salt string, timestamp uint64) error {
client := urlfetch.Client(v.Context)
resp, err := client.Get(publicKeyUrl)
if err != nil {
v.Context.Errorf("%v", err.Error())
return err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
v.Context.Errorf("%v", err.Error())
return err
}
cert, err := x509.ParseCertificate(body)
if err != nil {
v.Context.Errorf("%v", err.Error())
return err
}
signatureBytes, err := base64.StdEncoding.DecodeString(signature)
saltBytes, err:= base64.StdEncoding.DecodeString(salt)
payload, err := formPayload(v, playerId, bundleId, timestamp, saltBytes)
if err != nil {
v.Context.Errorf("%v", err.Error())
return err
}
err = cert.CheckSignature(cert.SignatureAlgorithm, payload, signatureBytes)
if err != nil {
v.Context.Errorf("%v", err.Error())
return err
}
return nil
}
func formPayload(v *ValidationRequest, playerId string, bundleId string, timestamp uint64, salt []byte) ([]byte, error) {
bundleIdBytes := []byte(bundleId)
playerIdBytes := []byte(playerId)
payloadBuffer := new(bytes.Buffer)
written, err := payloadBuffer.Write(playerIdBytes)
if err != nil {
return nil, err
}
written, err = payloadBuffer.Write(bundleIdBytes)
if err != nil {
return nil, err
}
var bigEndianTimestamp []byte = make([]byte, 8)
binary.BigEndian.PutUint64(bigEndianTimestamp, timestamp)
if written != len(bundleIdBytes) {
return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(bundleIdBytes)))
}
written, err = payloadBuffer.Write(bigEndianTimestamp)
if err != nil {
return nil, err
}
if written != len(bigEndianTimestamp) {
return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(bigEndianTimestamp)))
}
written, err = payloadBuffer.Write(salt)
if err != nil {
return nil, err
}
if written != len(salt) {
return nil, errors.New(fmt.Sprintf("Failed writing all bytes. Written: %d Length: %d", written, len(salt)))
}
return payloadBuffer.Bytes(), nil
}
I've been trying to check X.509 certificates revocation status in iOS 7.0 using both OCSP and CRL in different moments and the evaluation returns kSecTrustResultUnspecified (that means the certificate is to be trusted) without actually checking with OCSP or CRL sources, as long as I pass all certificates in the chain. I've put any code I think is relevant below, please help!
Thanks!
PS: ocspOnly and crlOnly are booleans that indicate if any of those revocation checking methods are to be used exclusively; certs is an NSArray that contains all certificates in chain except anchor certificates; anchor certificates are set properly before.
int evaluationMethod = kSecRevocationRequirePositiveResponse;
if (ocspOnly) {
evaluationMethod |= kSecRevocationOCSPMethod;
} else if (crlOnly) {
evaluationMethod |= kSecRevocationCRLMethod;
} else {
evaluationMethod |= kSecRevocationUseAnyAvailableMethod;
}
if ((status = SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, SecPolicyCreateRevocation(evaluationMethod), &trust)) != errSecSuccess) {
NSLog(#"Failed to create trust with certificate and policy: %ld", status);
return NO;
}
if ((status = SecTrustSetNetworkFetchAllowed(trust, YES)) != errSecSuccess) {
NSLog(#"Failed to activate network fetch: %ld", status);
}
status = SecTrustEvaluate(trust, &trustResult);
if (status != errSecSuccess) {
NSLog(#"Failed to evaluate trust: %ld", status);
return NO;
}
if (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified)
return YES;
return NO;
PS-2: This question was also asked in iOS Developer Forums here.