Fix the signing -wip

This commit is contained in:
Kiran 2022-02-21 21:06:25 +05:30
parent aa76970fe7
commit b53c3b41b7
7 changed files with 41 additions and 33 deletions

View File

@ -8,7 +8,6 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@types/xml-crypto": "^1.4.2",
"axios": "^0.24.0", "axios": "^0.24.0",
"next": "12.1.0", "next": "12.1.0",
"node-fetch": "^3.2.0", "node-fetch": "^3.2.0",
@ -29,6 +28,7 @@
"eslint-config-next": "12.0.7", "eslint-config-next": "12.0.7",
"postcss": "8.4.6", "postcss": "8.4.6",
"tailwindcss": "3.0.23", "tailwindcss": "3.0.23",
"typescript": "4.5.4" "typescript": "4.5.4",
"@types/xml-crypto": "^1.4.2"
} }
} }

View File

@ -1,5 +1,5 @@
import type { NextApiRequest, NextApiResponse } from 'next'; import type { NextApiRequest, NextApiResponse } from 'next';
import { createResponseForm, createSAMLResponseXML } from 'utils'; import { createResponseForm, createResponseXML } from 'utils';
import { User } from 'types'; import { User } from 'types';
import config from '../../../lib/env' import config from '../../../lib/env'
import { signResponseXML } from 'utils/response'; import { signResponseXML } from 'utils/response';
@ -32,7 +32,7 @@ export default async function handler(
lastName: 'K', lastName: 'K',
}; };
const xml = await createSAMLResponseXML({ const xml = await createResponseXML({
idpIdentityId: idpIdentityId, idpIdentityId: idpIdentityId,
audience: audience, audience: audience,
acsUrl: acsUrl, acsUrl: acsUrl,

View File

@ -1,23 +1,24 @@
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import path from 'path'; import path from 'path';
const fetchPublicKey = async () => { const fetchPublicKey = async (): Promise<string> => {
return await fs.readFile(path.join('data', 'idp-public.key'), 'utf8'); return await fs.readFile(path.join('data', 'idp-public.key'), 'ascii');
}; };
const fetchPrivateKey = async () => { const fetchPrivateKey = async (): Promise<string> => {
return await fs.readFile(path.join('data', 'idp-private.key'), 'utf8'); return await fs.readFile(path.join('data', 'idp-private.key'), 'ascii');
} }
const extractCert = (certificate: string) => { const stripCertHeaderAndFooter = (cert: string): string => {
return certificate cert = cert.replace(/-+BEGIN CERTIFICATE-+\r?\n?/, '');
.replace('-----BEGIN CERTIFICATE-----', '') cert = cert.replace(/-+END CERTIFICATE-+\r?\n?/, '');
.replace('-----END CERTIFICATE-----', '') cert = cert.replace(/\r\n/g, '\n');
.trim();
return cert;
}; };
export { export {
fetchPublicKey, fetchPublicKey,
fetchPrivateKey, fetchPrivateKey,
extractCert, stripCertHeaderAndFooter,
} }

View File

@ -1,3 +1,3 @@
export { fetchPrivateKey, fetchPublicKey } from './certificate' export * from './certificate'
export {extractSAMLRequestAttributes, createIdPMetadataXML} from './request' export * from './request'
export { createSAMLResponseXML, createResponseForm, signResponseXML } from './response' export * from './response'

View File

@ -1,9 +1,10 @@
import { User } from '../types'; import { User } from '../types';
import xmlbuilder from 'xmlbuilder'; import xmlbuilder from 'xmlbuilder';
import crypto from 'crypto'; import crypto, { sign } from 'crypto';
import {SignedXml, FileKeyInfo} from 'xml-crypto'; import { SignedXml, FileKeyInfo } from 'xml-crypto';
import { fetchPrivateKey, fetchPublicKey, stripCertHeaderAndFooter } from './certificate';
const createSAMLResponseXML = async (params: { const createResponseXML = async (params: {
idpIdentityId: string, idpIdentityId: string,
audience: string, audience: string,
acsUrl: string, acsUrl: string,
@ -142,24 +143,30 @@ const createResponseForm = (relayState: string, encodedSamlResponse: string, acs
}; };
const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Promise<string> => { const signResponseXML = async (xml: string, signingKey: any, publicKey: any): Promise<string> => {
return ''; const sig = new SignedXml();
const responseXPath = '/*[local-name(.)="Response" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:protocol"]';
const issuerXPath = '/*[local-name(.)="Issuer" and namespace-uri(.)="urn:oasis:names:tc:SAML:2.0:assertion"]';
// const sig = new SignedXml(); publicKey = publicKey.replace(/\\n/gm, '\n');
signingKey = signingKey.replace(/\\n/gm, '\n');
// sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; console.log({publicKey, signingKey})
// sig.keyInfoProvider = new PubKeyInfo(publicKey);
// sig.signingKey = signingKey; sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
// sig.addReference(authnXPath, ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'], 'http://www.w3.org/2001/04/xmlenc#sha256'); sig.keyInfoProvider = new FileKeyInfo(stripCertHeaderAndFooter(publicKey));
// sig.computeSignature(xml, { sig.signingKey = signingKey;
// location: { reference: authnXPath + issuerXPath, action: 'after' },
// });
// return sig.getSignedXml(); sig.addReference(responseXPath, ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/2001/10/xml-exc-c14n#'], 'http://www.w3.org/2001/04/xmlenc#sha256');
sig.computeSignature(xml, {
location: { reference: responseXPath + issuerXPath, action: 'after' },
});
return sig.getSignedXml();
} }
export { export {
createSAMLResponseXML, createResponseXML,
createResponseForm, createResponseForm,
signResponseXML signResponseXML
} }