scep服务器返回了无效的响应,ios - iOS MDM SCEP PKIOperation:SCEP服务器返回了无效的响应 - 堆栈内存溢出...

终于使这项工作奏效了(并引起下一个与SCEP相关的头痛!):

原始代码中的问题概述 :

收件人必须是签署请求的证书: p7Message.certificates[0]

SCEP定义了一些必须存在的Authenticated属性。 这些中, transactionID和senderNonce从原始请求必须发送回( senderNonce发送回作为recipientNonce )

node-forge当前不支持SCEP特定属性的OID。

更新的工作代码 :以下是一些更新的工作代码(请注意,仍然需要进行一些缺失的检查才能进行验证等)。

function pkiOperationScepOperationHandler(req, reply) {

//

// |req.query.message| should contain a Base64 encoded PKCS#7 package.

// The SignedData portion is PKCS#7 EnvelopedData encrypted with the CA

// public key we gave the client in GetCACert. Once decrypted, we have

// ourselves the client's CSR.

//

if(!req.query.message) {

return reply('The CA could not validate the request').code(403);

}

try {

const msgBuffer = new Buffer(req.query.message, 'base64');

const p7Message = forge.pkcs7.messageFromAsn1(

forge.asn1.fromDer(

forge.util.createBuffer(msgBuffer, 'binary')

)

);

// :TODO: Validate integrity

// :TODO: Validated signing

//

// The outter PKCS#7 signed data must contain authenticated

// attributes for transactionID and senderNonce. We will use these

// in our reply back as part of the SCEP spec.

//

const oids = forge.pki.oids;

let origTransactionId = p7Message.rawCapture.authenticatedAttributes.find( attr => {

const oid = forge.asn1.derToOid(attr.value[0].value);

return ('2.16.840.1.113733.1.9.7' === oid); // transactionID

});

if(!origTransactionId) {

return reply('Invalid request payload').code(403);

}

origTransactionId = origTransactionId.value[1].value[0].value; // PrintableString

let origSenderNonce = p7Message.rawCapture.authenticatedAttributes.find( attr => {

const oid = forge.asn1.derToOid(attr.value[0].value);

return ('2.16.840.1.113733.1.9.5' === oid); // senderNonce

});

if(!origSenderNonce) {

return reply('Invalid request payload').code(403);

}

origSenderNonce = origSenderNonce.value[1].value[0].value; // OctetString

const p7EnvelopedData = forge.pkcs7.messageFromAsn1(

forge.asn1.fromDer(

forge.util.createBuffer(new Buffer(p7Message.rawCapture.content.value[0].value[0].value, 'binary'), 'binary')

)

);

// decrypt using our key

p7EnvelopedData.decrypt(p7EnvelopedData.recipients[0], conf.serverConfig.caPrivateKey);

// p7EnvelopedData should contain a PKCS#10 CSR

const csrDataBuffer = new Buffer(p7EnvelopedData.content.getBytes(), 'binary');

const csr = forge.pki.certificationRequestFromAsn1(

forge.asn1.fromDer(

forge.util.createBuffer(csrDataBuffer, 'binary')

),

true // computeHash

);

//

// Create a new cert based on the CSR and sign it

//

// See https://github.com/digitalbazaar/forge/issues/154

//

const signedCert = forge.pki.createCertificate();

signedCert.serialNumber = Date.now().toString();

signedCert.validity.notBefore = new Date();

signedCert.validity.notAfter = new Date();

// expires one year from now (client should contact us before then to renew)

signedCert.validity.notAfter.setFullYear(signedCert.validity.notBefore.getFullYear() + 1);

signedCert.setSubject(csr.subject.attributes);

signedCert.setIssuer(conf.serverConfig.caCert.subject.attributes);

// :TODO: Really, this should come from requested extensions in the CSR

signedCert.setExtensions([

{

name : 'keyUsage',

digitalSignature : true,

keyEncipherment : true,

critical : true,

}

]);

signedCert.publicKey = csr.publicKey;

signedCert.sign(conf.serverConfig.caPrivateKey);

req.log( ['trace' ], { message : 'Signed CSR certificate', cert : forge.pki.certificateToPem(signedCert) } );

const degenerate = forge.pkcs7.createSignedData();

degenerate.addCertificate(signedCert);

degenerate.sign();

const enveloped = forge.pkcs7.createEnvelopedData();

// Recipient is the original requester cert

enveloped.addRecipient(p7Message.certificates[0]);

enveloped.content = forge.asn1.toDer(degenerate.toAsn1());

enveloped.encryptedContent.algorithm = forge.pki.oids['des-EDE3-CBC']; // We set this in GetCACaps

enveloped.encrypt();

// Package up everything in PKCS#7 signed (by us) data

const signed = forge.pkcs7.createSignedData();

signed.addSigner({

key : conf.serverConfig.caPrivateKey,

certificate : conf.serverConfig.caCert,

digestAlgorithm : forge.pki.oids.sha1,

authenticatedAttributes : [

{

type : forge.pki.oids.contentType,

value : forge.pki.oids.data

},

{

type: forge.pki.oids.messageDigest

},

{

type: forge.pki.oids.signingTime,

},

{

name : 'transactionID',

type : '2.16.840.1.113733.1.9.7',

rawValue : forge.asn1.create(

forge.asn1.Class.UNIVERSAL,

forge.asn1.Type.PRINTABLESTRING,

false,

origTransactionId

),

},

{

name : 'messageType',

type : '2.16.840.1.113733.1.9.2',

rawValue : forge.asn1.create(

forge.asn1.Class.UNIVERSAL,

forge.asn1.Type.PRINTABLESTRING,

false,

'3' // CertRep

),

},

{

name : 'senderNonce',

type : '2.16.840.1.113733.1.9.5',

rawValue : forge.asn1.create(

forge.asn1.Class.UNIVERSAL,

forge.asn1.Type.OCTETSTRING,

false,

forge.util.createBuffer(forge.random.getBytes(16)).bytes()

),

},

{

name : 'recipientNonce',

type : '2.16.840.1.113733.1.9.6',

rawValue : forge.asn1.create(

forge.asn1.Class.UNIVERSAL,

forge.asn1.Type.OCTETSTRING,

false,

origSenderNonce),

},

{

name : 'pkiStatus',

type : '2.16.840.1.113733.1.9.3',

rawValue : forge.asn1.create(

forge.asn1.Class.UNIVERSAL,

forge.asn1.Type.PRINTABLESTRING,

false,

'0' // SUCCESS

),

}

]

});

signed.content = forge.asn1.toDer(enveloped.toAsn1());

signed.sign();

const signedDer = new Buffer(forge.asn1.toDer(signed.toAsn1()).getBytes(), 'binary');

return reply(signedDer).bytes(signedDer.length).type('application/x-pki-message');

} catch(e) {

req.log( ['error' ], { message : e.toString() } );

return reply('The CA could not validate the request').code(403);

}

}

这花了几天时间才对。 希望它可以对某人有所帮助!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值