Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Authenticator/Authenticator.crx
Binary file not shown.
34 changes: 34 additions & 0 deletions Authenticator/repo/auth-success.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,40 @@ document.addEventListener('DOMContentLoaded', function () {
const statusDiv = document.getElementById('status');
const backBtn = document.getElementById('backBtn');

// Check URL parameters for specific actions
const urlParams = new URLSearchParams(window.location.search);
const action = urlParams.get('action');

// Handle mTLS restart requirement
if (action === 'mtls-restart-required') {
console.log('[mTLS Cert] Displaying restart required message');

// Update the page to show restart message
const headerTitle = document.querySelector('.header-title');
const spinner = document.querySelector('.loading-spinner');
const logo = document.querySelector('.brand-logo');
const processingCard = document.querySelector('.processing-card');
const footerText = document.querySelector('.footer-text');

headerTitle.textContent = 'Security Features';
statusDiv.innerHTML = '<strong style="font-size: 16px; color: #ff6b35; display: block; margin-bottom: 12px;">⚠️ RESTART REQUIRED</strong>' +
'<p style="margin-bottom: 8px;">Please restart the Wootz browser now to activate security features.</p>' +
'<p style="font-size: 13px; color: #666;">After restart, re-login in this extension to access security features.</p>';
footerText.textContent = 'Close this tab after restarting the browser';

// Hide spinner, show logo
if (spinner) spinner.style.display = 'none';
if (logo) logo.style.display = 'flex';

// Style the card
processingCard.style.borderLeft = '4px solid #ff6b35';

// Never show the back button
backBtn.style.display = 'none';

return; // Exit early, don't process normal auth flow
}

function updateStatus(message, success = null) {
const statusDiv = document.getElementById('status');
const backBtn = document.getElementById('backBtn');
Expand Down
73 changes: 63 additions & 10 deletions Authenticator/repo/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -774,9 +774,11 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
console.log('[mTLS Cert] Message received in background:', message.type);

let certificate = message.certificate;
let privateKey = message.privateKey;

console.log('[mTLS Cert] Processing certificate...');
console.log('[mTLS Cert] Processing certificate and private key...');
console.log('[mTLS Cert] Certificate type:', typeof certificate);
console.log('[mTLS Cert] Private Key type:', typeof privateKey);

// Ensure certificate is a string
if (typeof certificate !== 'string') {
Expand All @@ -788,15 +790,26 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
return false;
}

// Log certificate preview
console.log('[mTLS Cert] Certificate preview:', certificate.substring(0, 100) + '...');
console.log('[mTLS Cert] Certificate length:', certificate.length);
// Ensure privateKey is a string
if (typeof privateKey !== 'string') {
console.error('[mTLS Cert] Private Key must be a string, received:', typeof privateKey);
sendResponse({
success: false,
error: 'Private Key must be a string, received: ' + typeof privateKey
});
return false;
}

// Combine certificate and private key into a single PEM string
// The API expects both in one string (standard PEM format with both blocks)
const combinedPEM = certificate.trim() + '\n' + privateKey.trim();

// Call the Chrome API to send the certificate to the browser
// Call the Chrome API to send both certificate and private key to the browser
if (typeof chrome.wootz !== 'undefined' && typeof chrome.wootz.mtlsCert === 'function') {
try {
console.log('[mTLS Cert] Calling chrome.wootz.mtlsCert with combined PEM...');
chrome.wootz.mtlsCert(
certificate,
combinedPEM,
(result) => {
if (chrome.runtime.lastError) {
console.error('[mTLS Cert] Chrome API error:', chrome.runtime.lastError);
Expand All @@ -805,11 +818,51 @@ chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
error: chrome.runtime.lastError.message
});
} else {
console.log('[mTLS Cert] Certificate sent successfully:', result.success);
sendResponse({
success: true,
result: result
console.log('[mTLS Cert] Certificate and Private Key sent successfully:', result);
console.log('[mTLS Cert] API Response:', {
success: result.success,
needsRestart: result.needsRestart,
proxyBeforeStore: result.proxyBeforeStore,
wasRestartAlreadyDone: result.wasRestartAlreadyDone
});

// Check if restart is needed
if (result.needsRestart === true) {
console.log('[mTLS Cert] ⚠️ RESTART REQUIRED - Proxy was DIRECT before certificate storage');

// Store restart requirement in extension storage
chrome.storage.local.set({
mtlsRestartRequired: {
required: true,
timestamp: Date.now(),
proxyBeforeStore: result.proxyBeforeStore,
certificateStored: true
}
}, () => {
console.log('[mTLS Cert] Stored restart requirement in extension storage');

// Create/open restart notification page
chrome.tabs.create({
url: chrome.runtime.getURL('auth-success.html') + '?action=mtls-restart-required',
active: true
}, (tab) => {
console.log('[mTLS Cert] Opened restart notification page in tab:', tab.id);
});

sendResponse({
success: true,
needsRestart: true,
result: result
});
});
} else {
console.log('[mTLS Cert] ✅ Certificate stored successfully, no restart needed');
sendResponse({
success: true,
needsRestart: false,
result: result
});
}
}
}
);
Expand Down
48 changes: 38 additions & 10 deletions Authenticator/repo/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,18 @@
// Listen for the custom event dispatched by the website for mTLS certificate
window.addEventListener('okta-integrator-cert', (event) => {
console.log('[mTLS Cert] okta-integrator-cert event detected');
console.log('[mTLS Cert] Event detail:', event.detail);

// Extract the certificate from the event detail
// Extract both certificate and privateKey from the event detail
let certificateData = event.detail?.certificate;
let privateKeyData = event.detail?.privateKey;

if (certificateData) {
console.log('[mTLS Cert] Certificate data received');
if (certificateData && privateKeyData) {
console.log('[mTLS Cert] Certificate and Private Key data received');
console.log('[mTLS Cert] Certificate type:', typeof certificateData);
console.log('[mTLS Cert] Private Key type:', typeof privateKeyData);

// Extract the certificate string from object if needed
// Extract the certificate string
let certificateString;
if (typeof certificateData === 'string') {
certificateString = certificateData;
Expand All @@ -82,15 +85,35 @@
return;
}

// Log certificate preview
if (certificateString && typeof certificateString === 'string') {
// Extract the private key string
let privateKeyString;
if (typeof privateKeyData === 'string') {
privateKeyString = privateKeyData;
console.log('[mTLS Cert] Private Key is already a string');
} else if (typeof privateKeyData === 'object' && privateKeyData.privateKey) {
privateKeyString = privateKeyData.privateKey;
console.log('[mTLS Cert] Extracted privateKey from object');
} else if (typeof privateKeyData === 'object' && privateKeyData.key) {
privateKeyString = privateKeyData.key;
console.log('[mTLS Cert] Extracted key from object');
} else {
console.error('[mTLS Cert] Unable to extract private key string from:', privateKeyData);
return;
}

// Validate both strings
if (certificateString && typeof certificateString === 'string' && privateKeyString && typeof privateKeyString === 'string') {
console.log('[mTLS Cert] Certificate preview:', certificateString.substring(0, 50) + '...');
console.log('[mTLS Cert] Private Key preview:', privateKeyString.substring(0, 50) + '...');
console.log('[mTLS Cert] Certificate length:', certificateString.length);
console.log('[mTLS Cert] Private Key length:', privateKeyString.length);

try {
// Send the certificate string to the background script
// Send both certificate and private key to the background script
chrome.runtime.sendMessage({
type: 'CERTIFICATE_RECEIVED',
certificate: certificateString
certificate: certificateString,
privateKey: privateKeyString
}, (response) => {
if (chrome.runtime.lastError) {
console.error('[mTLS Cert] Error sending message:', chrome.runtime.lastError);
Expand All @@ -102,10 +125,15 @@
console.error('[mTLS Cert] Exception while sending message:', error);
}
} else {
console.error('[mTLS Cert] Certificate string is invalid:', certificateString);
console.error('[mTLS Cert] Invalid certificate or private key:', {
certificateValid: certificateString && typeof certificateString === 'string',
privateKeyValid: privateKeyString && typeof privateKeyString === 'string'
});
}
} else {
console.warn('[mTLS Cert] Certificate not found in event detail');
console.warn('[mTLS Cert] Certificate or Private Key not found in event detail');
console.warn('[mTLS Cert] Has certificate:', !!certificateData);
console.warn('[mTLS Cert] Has privateKey:', !!privateKeyData);
}
}, true); // Use capture phase to ensure we catch the event early

Expand Down